Tools
A “tool” is a function the agent can call inside the loop. Each tool has a JSONSchema definition, a category tag, and a Go handler. This page is the conceptual overview — for hands-on usage see the per-category guides.
How tools fit into the loop
Tools are resolved at the start of each turn, sent to the LLM as function definitions, and executed by the runner when the model emits a tool call. See Agent Loop for the full cycle.
The catalogue is registered in internal/agent/builtin/tools/all.go::AllWithProvider,
where each tool is appended in order and ApplyBuiltinTags stamps semantic categories at
the end. Memory tools are wired separately by the chat façade.
Categories at a glance
| Category | Examples | What they do |
|---|---|---|
| System | execute_command, shell_tasks, shell_kill, write_file, open_file, download_file | Run commands and write to the local filesystem |
| FileRead | read_file, grep, glob, list_dir | Read and search the local filesystem |
| Logs | read_logs | Tail the daemon log with filtering |
| Remote | connect, ssh_session, ask_agent, ask_agent_stream, ask_agents | Reach other machines |
| Board | issue_list, issue_get, issue_create, issue_update, issue_close | CRUD over the issue board |
| Meta | todo_write, skill_list, skill_run, delegate_task, task_status | Self-management and delegation |
| Help | help | Read-only help registry |
| Permissions | permissions_helper | Introspect the permission policy |
| Research | web_search, web_fetch | SDKRouter-backed; only present if SDKROUTER_API_KEY is set |
| Gen | generate_parser | Generate CSS/XPath/regex selectors |
The full list with parameters, notes, and code pointers is in report 04 §2.
System tools
The most-used tools the agent reaches for first.
| Tool | Params | Notes |
|---|---|---|
execute_command | {command: string} | Stream-based PTY. Floor-checked for unsafe patterns. |
shell_tasks | {id?, action: start | stop | status, command?} | Long-running background tasks tracked across turns. |
shell_kill | {id: string} | Clean SIGTERM + SIGKILL fallback. |
write_file | {path: string, content: string} | Floor-checked path; atomic write via temp + rename. |
open_file | {path: string} | Renders in Desktop. No-op in CLI / SDK. |
download_file | {url: string, path: string} | Chunked; floor-checks the target path. |
FileRead tools
| Tool | Params | Notes |
|---|---|---|
read_file | {path, offset?, limit?} | Line-numbered output, 64 KiB cap, binary detection. |
grep | {path, pattern, mode: files | content | count, -i?, -n?, -A/-B/-C?} | Ripgrep-backed, 10 s timeout, respects .gitignore. |
glob | {path, glob} | Ripgrep-backed pattern match, ~1000-file limit. |
list_dir | {path, recursive?} | Shallow or recursive listing, 10k-file cap. |
Remote tools
The cross-machine surface — see Agent Communication for the full story.
| Tool | Purpose |
|---|---|
connect | Dispatcher: list, exec, whoami, share, … on a target machine. |
ssh_session | Persistent multi-command session on a target. See Remote Sessions. |
ask_agent | Single remote agent call, unary. |
ask_agent_stream | Single remote agent call, streamed. |
ask_agents | Fan-out to many agents in parallel. |
Meta tools
| Tool | Purpose |
|---|---|
todo_write | Replace the visible task list. Mirrors to the Board if CMDOP_TODO_PERSIST=on and a parent issue is set. |
skill_list | Enumerate installed skills. |
skill_run | Run a skill in a sub-session with full tool access. |
delegate_task | Spawn a subagent with the parent provider (or SDKRouter fallback). |
task_status | Query a subagent’s state and output snippet. |
Permissions and the floor
Every tool call from a remote agent passes through the gate. The gate consults the non-bypassable floor first, then rules, then mode default. See Permissions.
Local chat (cmdop chat, TUI, SDK on the same OAuth identity) does not go through the
gate by design — the floor still applies (it is a code-level safety net), but rule and
mode gating is skipped.
Tool definitions and JSONSchema
Each tool ships a core.ToolDef with a JSONSchema describing its parameters. The runner
converts these into llm.ToolDef entries on every turn unless the intent router vetoes
(rare; the router is off by default).
type ToolDef struct {
Name string
Description string
Schema json.RawMessage
}If you are reading this to add a tool, see internal/agent/builtin/tools/system/system.go
and internal/agent/builtin/tools/all.go for the registration pattern.
Conditional tools (SDKRouter)
web_search and web_fetch are only registered when SDKROUTER_API_KEY is set.
generate_parser is wired through the parser package and may also be conditional. If the
agent says “I don’t have a web tool”, check the env var first.
Cache discipline
Tool definitions are part of the static system prefix that providers cache. Adding or removing tools mid-session invalidates the cache for that session — try not to flip optional tools on and off during a single conversation.
Tools are not user-extensible at runtime. To add a tool you ship a new daemon binary. For one-off integrations use Skills instead.
Related
TAGS: tools, builtin, tool-catalog, jsonschema DEPENDS_ON: [agent-loop, permissions, agent-communication]