Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Tools: Overview

Tools are the agent’s hands. A tool is a capability the model can invoke mid-conversation, run a shell command, fetch an HTTP URL, extract a PDF, open a browser, write a file, read a sensor. Every tool call is subject to security policy and produces a tool receipt.

Tools are not to be confused with zeroclaw CLI subcommands. CLI commands are for operators; tools are for the agent.

An agent gets its tools through the skill, knowledge, and MCP bundles it references; see Agents for how bundles attach to an agent.

Built-in tools

A minimal build ships with:

ToolWhat it does
shellExecute a shell command in the workspace directory. Subject to command allow/deny lists
file_readRead a file with line numbers; supports partial reads and PDF text extraction (path must be inside the workspace unless autonomy permits otherwise)
file_writeWrite a file (same path constraint)
file_editReplace an exact string match in a file with new content
glob_searchList files matching a glob pattern within the workspace
content_searchSearch file contents by regex within the workspace (ripgrep with grep fallback)
http_requestHTTP GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS to allowlisted domains
web_search_toolWeb search. Provider is configurable: DuckDuckGo (default, no key), Brave, Tavily, SearXNG, or Jina
web_fetchFetch a page and return clean plain text
browserHeadless-browser automation. See Browser automation
memory_recallSearch long-term memory for relevant facts, preferences, or context
memory_storeStore a fact, preference, or note in long-term memory
ask_userSend a question to the active channel and wait for a reply. Supports optional choices for structured responses (inline keyboard on Telegram, numbered list on CLI). On ACP, choices are required: free-form ask awaits the ACP elicitation RFD. Parameters: question (required), choices (optional list), timeout_secs (default 600).
escalate_to_humanSend a structured escalation message with urgency routing. high / critical urgency additionally notifies any channels listed in [escalation] alert_channels. Parameters: summary (required), context (optional), urgency (low/medium/high/critical, default medium), wait_for_response (bool, default false), timeout_secs (default 600). On ACP, wait_for_response: true fails immediately if the channel cannot receive free-form replies (awaits ACP elicitation RFD).

Always registered alongside the built-ins:

ToolNotes
cron_*Manage scheduled jobs: cron_add, cron_list, cron_remove, cron_update, cron_run, cron_runs
scheduleShell-only one-shot/recurring scheduling
memory_forget, memory_export, memory_purgeLong-term memory management
spawn_subagent, delegateRun a subtask in a child agent

Conditionally registered:

ToolEnabled by
Hardware probes--features hardware: GPIO, I2C, SPI reads/writes
pdf_read--features rag-pdf
sop_* toolsRegistered when sop.sops_dir is configured: run and inspect SOPs
discord_searchRegistered when a Discord alias has archive enabled

Extension protocols

Beyond built-in tools, ZeroClaw supports the MCP (Model Context Protocol) extension surface. Connect any MCP server (Claude Code’s filesystem, Playwright, your own) and the agent picks up its tools at startup.

For IDE-side integration where an editor drives ZeroClaw as a subprocess, see ACP: Agent Client Protocol lives under channels since it’s an inbound session-management surface, not a tool the agent invokes.

Authoring a tool

Implement the Tool trait in zeroclaw-api:

#![allow(unused)]
fn main() {
#[async_trait]
pub trait Tool: Send + Sync + Attributable {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn parameters_schema(&self) -> serde_json::Value;   // JSON Schema for args
    async fn execute(&self, args: serde_json::Value) -> anyhow::Result<ToolResult>;
}
}

Every Tool is also Attributable, so a tool call’s log emissions and audit traces carry the same <kind>.<alias> attribution the rest of the runtime uses.

Register via the runtime’s tool factory. See Developing → Plugin protocol for the full pattern.

Describing tools to the model

Tool descriptions are Mozilla Fluent strings: one per tool, localised per locale. This keeps tool descriptions terse in the model’s context window while allowing UI localisation.

Source of truth: crates/zeroclaw-runtime/locales/en/tools.ftl. Translations are generated and maintained via cargo fluent fill --locale <code> (see Maintainers → Docs & Translations).

Risk and approval

Every tool invocation is classified by risk:

  • Low (read-only, no side effects): file_read, memory_recall, http_request GET to allowed domains
  • Medium (mutates local state): file_write, shell with known safe commands
  • High (destructive or remote side effects): shell with unknown commands, http_request POST to unconstrained URLs

The autonomy level determines what each risk tier can do without operator approval. Default (Supervised): low runs, medium asks, high blocks.

Every tool invocation, approved or blocked, produces a tool receipt in the audit log.

Disabling tools on non-CLI channels

The schema has no per-channel tools_allow / tools_deny field. Tool gating lives on the agent’s risk profile ([risk_profiles.<alias>]):

  • excluded_tools removes the listed tools from every non-CLI channel (Discord, Telegram, Bluesky, Matrix, Slack, etc.) while leaving the local CLI untouched. The granularity is binary (CLI vs non-CLI), not per-channel.
  • allowed_tools is the inverse: an allowlist of tools the agent may call in agentic mode (empty means no authorization constraint).

If you need finer-grained gating, drop the profile’s level to read_only or supervised and rely on the per-profile auto_approve / always_ask lists to gate sensitive tools behind operator approval.

See Autonomy levels for the full set of per-profile fields.

See also