Skip to main content
These are the tools the agent (Claude) can call from inside its container. They’re exposed by the built-in nanoclaw MCP server (container/agent-runner/src/mcp-tools/), so the agent sees them with the mcp__nanoclaw__ prefix — e.g. mcp__nanoclaw__send_message. As an operator you never call them directly; you see their effects: messages arriving in chats, schedule changes, and approval cards. Each tool module ships with an instructions file that’s composed into the agent’s CLAUDE.md, telling it when and how to use the tools. Per-group MCP servers from the container config add more tools alongside these, under their own prefixes. All tools except list_tasks (read-only) write to the container’s outbound database — the host reads, authorizes, and applies the effects. Approval gating happens host-side; the container is untrusted and never gates itself.

Core messaging

Outbound tools resolve to against the group’s destination map — a unified namespace covering both channels (chats the group is wired to) and agents (sub-agents created with create_agent). If to is omitted, the message goes to the conversation the session is bound to; agents with multiple destinations and no session routing must specify it.

send_message

ParameterTypeRequiredDescription
textstringyesMessage content
tostringnoDestination name (e.g. family, worker-1). Optional with a single destination
Used for mid-turn updates while the agent is still working — final responses go through <message> blocks in the agent’s output, not this tool. Sending to another agent is the same call with to set to the agent’s name.

send_file

ParameterTypeRequiredDescription
pathstringyesFile path, absolute or relative to /workspace/agent/
tostringnoDestination name
textstringnoOptional accompanying message
filenamestringnoDisplay name in chat (default: basename of path)
Copies the file to /workspace/outbox/<id>/ for the host to deliver. Fails if the file doesn’t exist.

edit_message

ParameterTypeRequiredDescription
messageIdintegeryesNumeric id of a previously sent message
textstringyesNew message content
Targets the same destination the original message went to — the routing is looked up from the sent-message record.

add_reaction

ParameterTypeRequiredDescription
messageIdintegeryesNumeric id of the message to react to
emojistringyesEmoji shortcode (e.g. thumbs_up, heart), not the raw character
Lightweight acknowledgment when a full reply would be noise.

Scheduling

These tools manage rows in the host’s messages_in table (kind task). The container can’t write that database directly, so each mutating call emits a system action the host applies during delivery — except list_tasks, which reads the inbound database directly and writes nothing. Timestamps and cron expressions are interpreted in the user’s timezone. See Setting up scheduled tasks for the operator view.

schedule_task

ParameterTypeRequiredDescription
promptstringyesTask instructions
processAfterstringyesISO 8601 timestamp for the first run — UTC or naive local (interpreted in the user’s timezone)
recurrencestringnoCron expression for recurring tasks, evaluated in the user’s timezone
scriptstringnoPre-agent bash script — runs first and only wakes the agent if it prints {"wakeAgent": true, ...}

list_tasks

ParameterTypeRequiredDescription
statusstringnoFilter: pending or paused (default: both)
Returns one row per series — the live occurrence, not the pile of completed firings. The id shown is the series id, which is what the other task tools expect.

update_task

ParameterTypeRequiredDescription
taskIdstringyesSeries id from list_tasks
promptstringnoNew prompt
processAfterstringnoNew next-run timestamp
recurrencestringnoNew cron expression; empty string clears it (task becomes one-shot)
scriptstringnoNew pre-agent script; empty string clears it
Omitted fields are left unchanged. The agent is instructed to prefer this over cancel + reschedule.

cancel_task, pause_task, resume_task

ParameterTypeRequiredDescription
taskIdstringyesSeries id of the task
Paused tasks don’t fire until resumed.

Interactive

ask_user_question

ParameterTypeRequiredDescription
titlestringyesShort card title
questionstringyesThe question text
optionsarrayyesChoices: plain strings or { label, selectedLabel?, value? } objects
timeoutnumbernoSeconds to wait (default: 300)
Blocking — the agent’s turn pauses while it polls for your answer. You see a question card with buttons; tapping one returns its value to the agent (selectedLabel replaces the button text after selection). Errors out if the timeout expires.

send_card

ParameterTypeRequiredDescription
cardobjectyesCard structure: title, description, optional children and actions
fallbackTextstringnoPlain-text fallback for platforms without card support
Non-blocking — renders the card and returns immediately, no response collected.

Agents

create_agent

ParameterTypeRequiredDescription
namestringyesAgent name — also becomes the caller’s destination name for it
instructionsstringnoSeeds the new agent’s CLAUDE.local.md — its starting role and personality. (The tool schema says “CLAUDE.md content”, but the host writes it to CLAUDE.local.md; the composed CLAUDE.md is regenerated by the host)
Provisions a long-lived companion agent: its own group, container, and persistent workspace under groups/<folder>/, wired bidirectionally as a destination on both sides. Fire-and-forget — the call returns immediately and messages queue until the agent is up. Approval-gated by CLI scope: groups with cli_scope: global create directly; everything else (including the default group scope) requires admin approval. There is no send_to_agent tool — messaging an agent is just send_message with to set to its name. See Agent swarms.

Self-modification

Both tools are always approval-gated and fire-and-forget: the request is submitted, an admin gets an approval card, and the agent is notified of the outcome via a system message. Package names are sanitized in the container and re-validated on the host.

install_packages

ParameterTypeRequiredDescription
aptarrayno*apt package names (no version specs or flags)
npmarrayno*npm package names to install globally
reasonstringnoWhy the packages are needed
*At least one apt or npm package required; max 20 per request. On approval the per-agent image is rebuilt and the container restarts — packages persist across all future sessions, unlike a workspace pnpm install.

add_mcp_server

ParameterTypeRequiredDescription
namestringyesUnique server name
commandstringyesCommand to launch the server
argsarraynoCommand arguments
envobjectnoEnvironment variables for the server
On approval the server is added to the group’s container config and the container restarts (no image rebuild needed). The agent is instructed to use "onecli-managed" as the placeholder for credential env vars rather than asking you for keys.

The ncl CLI

Not an MCP tool, but documented alongside them in the agent’s instructions: the agent also has the ncl admin CLI at /usr/local/bin/ncl for querying and modifying NanoClaw’s central configuration — its own group config, destinations, members, and sessions. Read commands are open; write commands return approval-pending and execute only after an admin approves. What it can reach is controlled by the group’s cli_scope — see the ncl CLI reference.
Last modified on June 10, 2026