Agentara scheduled-tasks
git clone https://github.com/MagicCube/agentara
T=$(mktemp -d) && git clone --depth=1 https://github.com/MagicCube/agentara "$T" && mkdir -p ~/.claude/skills && cp -r "$T/user-home/.claude/skills/scheduled-tasks" ~/.claude/skills/magiccube-agentara-scheduled-tasks && rm -rf "$T"
user-home/.claude/skills/scheduled-tasks/SKILL.mdOverview
This skill manages Agentara scheduled tasks via the REST API at
http://localhost:1984/api/cronjobs.
A scheduled task has two parts:
- What: an
(natural language prompt sent to the agent)instruction - When: a
object with one ofschedule
/at
(one-shot) ordelay
/pattern
(recurring), plus optionalevery
andlimitimmediately
session_id: contextual vs independent
- Independent (default): omit
. Each trigger creates a new session — the agent has no memory of previous runs. Suitable for most cronjobs.session_id - Contextual: pass a fixed
(generate one viasession_id
). All triggers share the same conversation session — the agent can reference previous runs. Use this only when continuity matters (e.g. daily standup that tracks progress over time).python3 -c "import uuid; print(uuid.uuid4())"
Workflow
Step 1: Understand intent
Ask or infer what the user wants:
| Intent | Action |
|---|---|
| "list cronjobs" / "show scheduled tasks" | List |
| "add a cronjob" / "schedule a task every ..." | Create |
| "update cronjob" / "change schedule to ..." | Update (upsert by ) |
| "delete cronjob" / "remove scheduled task" | Delete |
Step 2: Determine whether session_id is needed
Ask yourself: does this task need to remember context across triggers?
- "Summarize today's news" → No. Each run is self-contained. Omit
.session_id - "Check project progress and compare with yesterday" → Yes. The agent needs prior context. Generate a fixed
.session_id
If unsure, ask the user: "Should each trigger run independently, or do you need them to share conversation history?"
Step 3: Execute
Use
Bash to run curl commands against the API. All examples below use localhost:1984.
IMPORTANT: Never pipe write operations (POST/PUT/DELETE) through
. Ifjqfails to parse the response, thejqrequest has still been sent and executed server-side. Retrying the command will create duplicates or cause unintended side effects. Only usecurlfor read operations (GET). For write operations, output the raw response directly.| jq .
API Reference
List all scheduled tasks
curl -s http://localhost:1984/api/cronjobs | jq .
is safe here because GET is read-only. Never usejqon POST/PUT/DELETE commands.| jq .
Create — independent (no session_id)
Most common case. Each trigger starts a fresh session.
Cron pattern (every day at 9 AM):
curl -s -X POST http://localhost:1984/api/cronjobs \ -H "Content-Type: application/json" \ -d '{ "instruction": "Summarize today'\''s top tech news", "schedule": { "pattern": "0 9 * * *" } }'
Interval (every 30 minutes):
curl -s -X POST http://localhost:1984/api/cronjobs \ -H "Content-Type: application/json" \ -d '{ "instruction": "Check all services are healthy", "schedule": { "every": 1800000 } }'
Cron + limit (every Friday 6 PM, max 10 times):
curl -s -X POST http://localhost:1984/api/cronjobs \ -H "Content-Type: application/json" \ -d '{ "instruction": "Generate weekly project report", "schedule": { "pattern": "0 18 * * 5", "limit": 10 } }'
Interval + immediately (every hour, first run right now):
curl -s -X POST http://localhost:1984/api/cronjobs \ -H "Content-Type: application/json" \ -d '{ "instruction": "Sync upstream repository changes", "schedule": { "every": 3600000, "immediately": true } }'
Delay (one-shot after 10 minutes):
curl -s -X POST http://localhost:1984/api/cronjobs \ -H "Content-Type: application/json" \ -d '{ "instruction": "Remind me to review the report", "schedule": { "delay": 600000 } }'
All schedule options (cron + interval + limit + immediately):
curl -s -X POST http://localhost:1984/api/cronjobs \ -H "Content-Type: application/json" \ -d '{ "instruction": "Run full regression test suite", "schedule": { "pattern": "0 2 * * *", "every": 86400000, "limit": 30, "immediately": true } }'
Create — contextual (with session_id)
First generate a UUID:
SESSION_ID=$(python3 -c "import uuid; print(uuid.uuid4())")
Then pass it. All triggers will share this session's conversation history:
curl -s -X POST http://localhost:1984/api/cronjobs \ -H "Content-Type: application/json" \ -d "{ \"session_id\": \"$SESSION_ID\", \"instruction\": \"Check project progress, compare with yesterday, and flag blockers\", \"schedule\": { \"pattern\": \"0 9 * * 1-5\" } }"
Update a scheduled task
PUT with the scheduler ID in the path. Omit
session_id to keep existing; pass null for independent mode or a UUID for contextual.
curl -s -X PUT http://localhost:1984/api/cronjobs/<scheduled-task-id> \ -H "Content-Type: application/json" \ -d '{ "instruction": "Updated instruction here", "schedule": { "pattern": "0 8 * * *" } }'
Delete a scheduled task
curl -s -X DELETE http://localhost:1984/api/cronjobs/<scheduled-task-id>
Schedule field reference
| Field | Type | Required | Description |
|---|---|---|---|
| number | one of at/delay/pattern/every | Epoch ms for one-shot at a specific time |
| number | one of at/delay/pattern/every | Delay in ms before one-shot (normalized to on save) |
| string | one of at/delay/pattern/every | Cron expression (e.g. ) |
| number | one of at/delay/pattern/every | Interval in ms |
| number | no | Max execution count |
| boolean | no | Run once immediately on registration |
Note: for one-shot, use exactly one of
orat; no other schedule fields are allowed.delayis normalized todelaywhen stored.at
Guided interaction
When the user describes a task in natural language:
- Extract the instruction — what the agent should do.
- Extract the schedule — map natural language to schedule fields:
- "Only once at 2026-03-11 09:00:00" →
, resolve timestamp by running Python code:{ "at": 1773190800000 }import datetime; print(int(datetime.datetime(2026, 3, 11, 9, 0, 0).timestamp() * 1000)) - "10 minutes later" / "in 10 minutes" →
(600000 ms = 10 min){ "delay": 600000 } - "every day at 9am" →
{ "pattern": "0 9 * * *" } - "every 30 minutes" →
{ "every": 1800000 } - "only 5 times" → add
"limit": 5 - "start now" / "run immediately" → add
"immediately": true
- "Only once at 2026-03-11 09:00:00" →
- Decide session_id — does the task need cross-trigger context? If yes, generate a UUID. If no (most cases), omit it.
- Confirm the mapped parameters with the user before executing.
- After execution, show the response (especially the
for future update/delete).id
When modifying an existing task, always use Update (PUT) instead of delete + create. This preserves the task ID and is a single operation. Only use delete when the user explicitly wants to remove a task entirely.
When deleting or updating, first list existing tasks so the user can pick which one to modify.