NanoClaw includes a built-in task scheduler that runs agents on a schedule. In v2, tasks are stored asDocumentation Index
Fetch the complete documentation index at: https://docs.nanoclaw.dev/llms.txt
Use this file to discover all available pages before exploring further.
messages_in rows with kind='task' — there is no separate task table. Tasks support cron-based recurrence with series tracking.
What is a scheduled task?
A scheduled task is:- A
messages_inrow withkind='task'and aprocess_aftertimestamp - Executed in the context of a specific agent group session
- Has access to all agent tools (Bash, browser, MCP, etc.)
- Can send messages via the
send_messageMCP tool - Supports recurring execution via cron expressions
Tasks use the same message infrastructure as interactive messages. They are written to
inbound.db and processed by the agent-runner’s poll loop.Schedule types
Cron expressions (recurrence)
Tasks can have arecurrence field containing a cron expression:
0 9 * * *— every day at 9:00 AM0 */2 * * *— every 2 hours0 0 * * 1— every Monday at midnight
TZ env, .env, or system default, validated as IANA). Cron expressions are evaluated in this timezone.
One-time tasks
Tasks without arecurrence field run once when process_after is reached:
- After completion, the task row is marked
completed - No new rows are created
Task lifecycle
Creation
Tasks are created via theschedule_task MCP tool inside the container:
- Agent calls
schedule_taskwhich writes akind='system'outbound message with action fields - The delivery path routes this to
handleScheduleTaskon the host - Host creates a
kind='task'row ininbound.dbwithprocess_afterand optionalrecurrence - A
series_idis set to the task’s own ID (for tracking recurring instances)
Execution
Execution flow:- Host sweep runs every 60 seconds and finds tasks where
process_after <= now - Wakes the session’s container (or spawns a new one)
- Agent-runner’s poll loop picks up the task as a pending message
- Agent executes the task prompt
- Host sweep syncs
processing_ackfromoutbound.dbto mark the task completed - For recurring tasks, a new row is created with the next
process_after
Tasks share the container concurrency pool with interactive messages. If all container slots are busy, tasks wait until a slot is available.
Recurring tasks
Recurring tasks use a series model:- Each occurrence gets a new
messages_inrow sharing the sameseries_id - When a recurring task completes, the host sweep calls
getCompletedRecurring()to find it insertRecurrence()creates the next-run row with the updatedprocess_after- The
series_idlinks all occurrences together
Post-execution
After a task completes:- Processing acknowledged — host sweep syncs
processing_ackfromoutbound.db - Status updated — task row marked
completed - Next occurrence — for recurring tasks, a new pending row is created
- Container continues — the container stays alive for other messages (no immediate shutdown)
Task management operations
Tasks are managed via MCP tools available inside the container:schedule_task
Creates a new task. The agent writes a system message tooutbound.db, and the host creates the task in inbound.db.
cancel_task
Marks all live rows in the task’s series ascompleted and nulls the recurrence. This stops the task permanently.
pause_task
Toggles a pending task topaused status. Paused tasks are not picked up by the host sweep.
resume_task
Toggles a paused task back topending status. The task resumes on the next sweep cycle.
update_task
Merges content updates in-place (prompt, script). Can also updateprocess_after and recurrence independently. Matches by ID or series_id so recurring task updates hit the live next-occurrence row.
update_task returns 0 when no live row matches, triggering a system notification back to the agent (“no live task matched”).Task scripts
For recurring tasks, you can add ascript — a bash command that runs before the agent. If the script determines no action is needed, the agent is never invoked.
How scripts work
- The script runs first (30-second timeout)
- It prints JSON to stdout:
{ "wakeAgent": true/false, "data": {...} } - If
wakeAgentisfalse, the task completes silently - If
wakeAgentistrue, the agent wakes with the script’s data plus the prompt
When NOT to use scripts
If a task requires agent judgment every time (daily briefings, reminders, reports), skip the script — just use a regular prompt.Sending messages from tasks
Tasks can send messages using thesend_message MCP tool. The delivery system routes these through the standard delivery pipeline with the same authorization checks as interactive messages.
Silent tasks:
If a task doesn’t call send_message, it completes silently — the result is tracked via processing_ack but no message is sent to any channel.
Sequence numbers
All host-written messages (including tasks) use even-parity sequence numbers allocated vianextEvenSeq(). This ensures host writes and container writes never collide on sequence numbers.
Error handling
Task errors don’t stop the recurring schedule:- Task fails during execution
- Processing acknowledged with error state
- For recurring tasks, next occurrence is still created
- No message sent to chat unless task explicitly sends before error