> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nanoclaw.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent MCP tools

> Every MCP tool the agent can call inside its container — messaging, interactive cards, sub-agents, and self-modification.

These are the tools the agent 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](/reference/container-config) add more tools alongside these, under their own prefixes.

These tools 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`). `to` is required: every `send_message` and `send_file` call names its destination explicitly.

### `send_message`

| Parameter | Type   | Required | Description                                  |
| --------- | ------ | -------- | -------------------------------------------- |
| `text`    | string | yes      | Message content                              |
| `to`      | string | yes      | Destination name (e.g. `family`, `worker-1`) |

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`

| Parameter  | Type   | Required | Description                                            |
| ---------- | ------ | -------- | ------------------------------------------------------ |
| `path`     | string | yes      | File path, absolute or relative to `/workspace/agent/` |
| `to`       | string | yes      | Destination name                                       |
| `text`     | string | no       | Optional accompanying message                          |
| `filename` | string | no       | Display 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`

| Parameter   | Type    | Required | Description                             |
| ----------- | ------- | -------- | --------------------------------------- |
| `messageId` | integer | yes      | Numeric id of a previously sent message |
| `text`      | string  | yes      | New message content                     |

Targets the same destination the original message went to — the routing is looked up from the sent-message record.

### `add_reaction`

| Parameter   | Type    | Required | Description                                                        |
| ----------- | ------- | -------- | ------------------------------------------------------------------ |
| `messageId` | integer | yes      | Numeric id of the message to react to                              |
| `emoji`     | string  | yes      | Emoji shortcode (e.g. `thumbs_up`, `heart`), not the raw character |

Lightweight acknowledgment when a full reply would be noise.

## Scheduling

Scheduling is no longer an MCP tool. The `schedule_task`, `list_tasks`, `update_task`, `cancel_task`, `pause_task`, and `resume_task` tools were removed. Scheduling now lives in the `ncl` admin CLI as the `tasks` resource — the agent runs `ncl tasks create | list | get | run | update | pause | resume | cancel | delete` through the same CLI it already uses for group config. See the [`ncl tasks` reference](/reference/ncl-cli#tasks) and [Setting up scheduled tasks](/guides/scheduled-tasks).

## Interactive

### `ask_user_question`

| Parameter  | Type   | Required | Description                                                           |
| ---------- | ------ | -------- | --------------------------------------------------------------------- |
| `title`    | string | yes      | Short card title                                                      |
| `question` | string | yes      | The question text                                                     |
| `options`  | array  | yes      | Choices: plain strings or `{ label, selectedLabel?, value? }` objects |
| `timeout`  | number | no       | Seconds 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`

| Parameter      | Type   | Required | Description                                                               |
| -------------- | ------ | -------- | ------------------------------------------------------------------------- |
| `card`         | object | yes      | Card structure: `title`, `description`, optional `children` and `actions` |
| `fallbackText` | string | no       | Plain-text fallback for platforms without card support                    |

Non-blocking — renders the card and returns immediately, no response collected.

## Agents

### `create_agent`

| Parameter      | Type   | Required | Description                                                                                                                                                                                                                     |
| -------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`         | string | yes      | Agent name — also becomes the caller's destination name for it                                                                                                                                                                  |
| `instructions` | string | no       | Seeds the new agent's starting role and personality. The host stages it to the group's `instructions.prepend.md` (standing instructions, composed into the agent's `CLAUDE.md` at spawn) — not the composed `CLAUDE.md` itself. |

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](/guides/multi-agent-swarm).

## 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`

| Parameter | Type   | Required | Description                                   |
| --------- | ------ | -------- | --------------------------------------------- |
| `apt`     | array  | no\*     | apt package names (no version specs or flags) |
| `npm`     | array  | no\*     | npm package names to install globally         |
| `reason`  | string | no       | Why 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`

| Parameter | Type   | Required | Description                          |
| --------- | ------ | -------- | ------------------------------------ |
| `name`    | string | yes      | Unique server name                   |
| `command` | string | yes      | Command to launch the server         |
| `args`    | array  | no       | Command arguments                    |
| `env`     | object | no       | Environment variables for the server |

On approval the server is added to the group's [container config](/reference/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](/reference/ncl-cli#access-control).
