Tools
Tools are how Anode touches the world: read files, search code, run commands, edit files, call MCP servers, spawn subagents, and search the web. You control which tools exist and what they can do with permissions and configuration.
External fetch is a thin surface: web_search is the only first-class network
primitive, and bash + curl is the recommended fallback for raw page bodies.
The OpenAI shell_command request shape is accepted via canonical-name
aliasing and dispatched to bash.
How Tool Calls Work
Section titled “How Tool Calls Work”- The model emits a
TOOL:directive with a JSON payload containing the tool name and arguments. - Anode validates the call against your permission policy.
- If approved, Anode executes the tool and captures the result.
- The result returns to the model as context for the next turn.
TOOL: {"name": "read", "args": {"path": "src/main.go"}}Tools require different permission levels. Read-only tools run automatically. Write tools and shell commands require confirmation unless you set a permissive approval mode.
Permission Levels
Section titled “Permission Levels”| Level | Behavior |
|---|---|
auto_read | Always allowed. No confirmation needed. |
external_read | External service reads and read-only delegated investigation. |
state_write | Local agent state mutations. |
confirm_execute | Requires confirmation for shell execution. |
confirm_write | Requires confirmation for file mutations. |
delegated | Delegated to subagent or skill. |
interactive | Requires direct user interaction. |
Built-In Tools
Section titled “Built-In Tools”The unfiltered built-in registry loads the core tool set before dynamic
language-server tools. Profiles then filter that registry by allowlist and
read-only policy: craft exposes the normal working set, review is read-only,
and study adds coordination tools. Autoresearch tools are present for TUI
research workflows. The lsp and
get_diagnostics tools register only when a language server is configured or
auto-detected. MCP, toolbox, skill-local MCP, and process-plugin tools are
registered dynamically.
Run a shell command in the workspace.
Permission: confirm_execute
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
command | string | yes | - | Shell command to execute |
cwd | string | no | workspace root | Working directory |
timeout_ms | int | no | 30000 | Command timeout in milliseconds. Values above 1800000 are reduced to 1800000. |
TOOL: {"name": "bash", "args": {"command": "go test ./...", "timeout_ms": 60000}}Read a text file with line numbers. By default, returns the first 1000 lines.
Use read_range, start_line, and end_line to slice large files.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | yes | - | File path relative to workspace |
read_range | array | no | - | 1-indexed positive [start, end] range. Length 1 reads from start through the end of file. Takes precedence over start_line and end_line. |
start_line | int | no | 1 | First line to read |
end_line | int | no | end of file | Last line to read |
max_bytes | int | no | 2097152 | Byte ceiling on numbered output after line slicing. |
read truncates in two stages: it first reads up to a 2 MiB file prefix, then
applies max_bytes to the numbered slice. The structured result sets
file_capped for the prefix limit and truncated if either stage trims output.
Use read_range, start_line, or end_line for normal large-file focusing;
max_bytes is mainly a guard against single huge lines.
TOOL: {"name": "read", "args": {"path": "internal/app/app.go", "start_line": 1, "end_line": 50}}multi_read
Section titled “multi_read”Read up to 10 text files in one round-trip. Each file is rendered as if by
read (numbered lines, same 2 MiB per-file cap) and separated by
===== <path> ===== banners. Use this instead of emitting N parallel read
calls when you already know the paths.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
paths | array | yes | - | Workspace-relative file paths (max 10). |
read_range | array | no | - | 1-indexed [start, end] slice applied to every path. |
start_line | int | no | - | Alternative to read_range; applied to every path. |
end_line | int | no | - | Alternative to read_range; applied to every path. |
max_bytes | int | no | 4194304 | Total byte ceiling across all files. Files past the ceiling are skipped with a truncation note. |
A failure on one path is recorded inline (banner plus [error: ...]) and the
other paths still return; the structured result lists per-file metadata under
files.
TOOL: {"name": "multi_read", "args": {"paths": ["go.mod", "go.sum"]}}TOOL: {"name": "multi_read", "args": {"paths": ["internal/tools/read.go", "internal/tools/multi_read.go"], "read_range": [1, 40]}}edit_file
Section titled “edit_file”Edit an existing text file. Provide exactly one input shape: edits, old_str/new_str, or unified_diff.
Permission: confirm_write
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | yes | - | File path relative to workspace |
edits | array | one of edits/old_str/unified_diff | - | Array of edit operations |
old_str | string | one of edits/old_str/unified_diff | - | Text to replace in top-level single-replacement form |
new_str | string | with old_str | - | Replacement text for old_str |
replace_all | bool | no | false | Replace every old_str occurrence; otherwise old_str must be unique |
unified_diff | string | one of edits/old_str/unified_diff | - | Unified diff patch to apply |
Each item in edits:
| Field | Type | Required | Description |
|---|---|---|---|
old | string | yes | Text to find |
new | string | yes | Replacement text |
occurrence | int | no | Which occurrence to replace, 1-indexed. 0 means the old text must be unique. |
TOOL: {"name": "edit_file", "args": {"path": "main.go", "edits": [{"old": "fmt.Println(\"hello\")", "new": "fmt.Println(\"goodbye\")", "occurrence": 1}]}}apply_patch
Section titled “apply_patch”Apply a unified diff to the workspace. Provide the diff in patch; input and diff are accepted as aliases. Anode validates the patch before approval.
Permission: confirm_write
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
patch | string | yes | - | Unified diff. input and diff are accepted as aliases for compatibility. |
TOOL: {"name": "apply_patch", "args": {"patch": "--- a/main.go\n+++ b/main.go\n@@ -1 +1 @@\n-old\n+new\n"}}create_file
Section titled “create_file”Create a new text file. Fails if the file exists unless overwrite is true.
Permission: confirm_write
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | yes | - | File path relative to workspace |
content | string | yes | - | File content |
overwrite | bool | no | false | Overwrite existing file |
TOOL: {"name": "create_file", "args": {"path": "scripts/deploy.sh", "content": "#!/bin/bash\nset -e\ngo build -o bin/app ./cmd/app"}}finder
Section titled “finder”Find files, text, symbols, or behavioral patterns across the workspace.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
mode | string | no | ”text” | Search mode: files, text, symbols, or agent |
query | string | no | - | Search query or pattern |
path | string | no | workspace root | Directory to search |
glob | string | no | - | File glob filter |
limit | int | no | 50 | Returned result limit. |
case_sensitive | bool | no | false | Case-sensitive matching |
mode=agent delegates behavioral or cross-module searches to a read-only
search subagent. If delegation is unavailable or fails, Anode falls back to
text search and sets agent_fallback in the structured result data.
TOOL: {"name": "finder", "args": {"mode": "text", "query": "func NewServer", "glob": "*.go"}}Match files by glob pattern.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
pattern | string | yes | - | Glob pattern such as **/*.go. Supports recursive **. |
path | string | no | . | Workspace-relative root. |
limit | int | no | 50 | Returned match limit. |
include_hidden | bool | no | false | Include dot-prefixed entries. |
TOOL: {"name": "glob", "args": {"pattern": "**/*_test.go", "path": "internal", "limit": 100}}Search file contents with ripgrep when available, with a POSIX grep fallback. Captured stdout is limited to 256 KiB and marked truncated when exceeded.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
pattern | string | yes | - | Literal string unless regex is true. |
path | string | no | . | Workspace-relative directory. |
glob | string | no | - | File glob filter, such as *.go. |
case_sensitive | bool | no | false | Match case exactly. |
word_match | bool | no | false | Whole-word match. |
regex | bool | no | false | Treat pattern as regex. |
max_matches | int | no | 50 | Returned match limit per file. |
context | int | no | 0 | Context lines around each match. |
TOOL: {"name": "grep", "args": {"pattern": "TODO", "glob": "*.go", "context": 1}}render
Section titled “render”Emit a structured render spec the TUI displays as rich components (cards, tables, metrics, status lines, etc.). Headless consumers receive the same JSON in tool result data.render_spec so the output round-trips outside the TUI.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
root | string | yes | - | ID of the root element in elements. |
elements | object | yes | - | Map of element id → {type, props, children}. children is an array of element id strings. Types are PascalCase component names. |
Supported component types: Box, Text, Heading, Divider, Newline, Spacer, BarChart, Sparkline, Table, List, Card, StatusLine, KeyValue, Badge, ProgressBar, Metric, Callout, Timeline.
TOOL: {"name": "render", "args": {"root": "card", "elements": {"card": {"type": "Card", "props": {"title": "Health"}, "children": ["s"]}, "s": {"type": "StatusLine", "props": {"text": "API", "status": "success"}, "children": []}}}}Render a small terminal chart from structured data.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
type | string | no | bar | bar, line, sparkline, or table. |
title | string | no | - | Optional title. |
data | object | one of data/series | - | Map of label to value. |
series | array | one of data/series | - | Ordered array of {label,value} points. |
width | int | no | 40 | Chart width for bar/line charts. |
TOOL: {"name": "chart", "args": {"type": "bar", "title": "latency", "data": {"p50": 12, "p95": 45}}}Spawn a bounded subagent for independent work. The subagent runs in its own context with limited tools and turns. Child tasks cannot spawn further delegated agents; task, oracle, and code_review are filtered even when requested in tools_allowed.
Permission: delegated
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
title | string | no | - | Task title for display |
goal | string | yes | - | What the subagent should accomplish |
context | string | no | - | Additional context for the subagent |
tools_allowed | []string | no | profile default | Tool names or globs the subagent may use; recursive delegation tools are filtered |
max_steps | int | no | 20 | Maximum turns. Values above 40 are reduced to 40. |
max_tool_calls | int | no | max_steps * 3 | Total tool-call limit |
profile | string | no | ”craft” | craft default, quick fast/shallow, study thorough/deep, find retrieval-focused, review critique, or oracle read-only advisor. Aliases: smart -> craft, rush -> quick, deep -> study, search -> find. |
read_only | bool | no | false | Restrict to read-only tools |
timeout_seconds | int | no | 300 | Wall-clock timeout in seconds. Values above 1800 are reduced to 1800. |
TOOL: {"name": "task", "args": {"title": "Audit auth middleware", "goal": "Review all authentication middleware for security issues", "read_only": true, "max_steps": 30}}oracle
Section titled “oracle”Consult a second-opinion model for complex reasoning. Useful for architecture decisions or debugging.
Permission: external_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
question | string | yes | - | Question to ask the oracle model |
context | string | no | - | Additional context |
files | []string | no | - | File paths to include as context |
focus | string | no | - | Area to focus reasoning on |
model | string | no | - | Specific model to use |
effort | string | no | medium | none, minimal, low, medium, high, xhigh, or max |
timeout_seconds | int | no | 180 | Oracle runtime timeout in seconds. Values above 600 are reduced to 600. |
TOOL: {"name": "oracle", "args": {"question": "Is this concurrency pattern safe?", "files": ["internal/run/engine.go"], "focus": "race conditions"}}code_review
Section titled “code_review”Run a structured read-only review pass over a described diff or file set. The reviewer uses read/search tools, not shell diff commands, so include files when exact file context matters.
Permission: external_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
diff_description | string | yes | - | Natural-language description of the diff or change, with enough context for a read-only reviewer. |
files | []string | no | all relevant | Specific files to focus. |
instructions | string | no | - | Extra reviewer guidance. |
check_scope | string | no | - | Check scope such as all or changes-only. |
check_filter | []string | no | all | Check names to run. |
checks_only | bool | no | false | Return only structured check results. |
thinking | string | no | low | low or high. |
TOOL: {"name": "code_review", "args": {"diff_description": "the uncommitted changes in internal/run", "files": ["internal/run/engine.go"], "thinking": "high"}}web_search
Section titled “web_search”Search the web for current information.
Permission: external_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | yes | - | Search query |
max_results | int | no | 10 | Results to return. Values above 20 are reduced to 20. |
recency | string | no | any | any, day, week, month, or year. Shorthand such as 24h, 1d, 7d, 30d, and 365d is accepted and reported back as the canonical window. |
domains | []string | no | - | Restrict to specific domains |
exclude_domains | []string | no | - | Exclude specific domains |
category | string | no | - | Exa hint: company, people, news, research, or blog |
start_published_date | string | no | - | Exa-only lower publish-date bound (YYYY-MM-DD) |
end_published_date | string | no | - | Exa-only upper publish-date bound (YYYY-MM-DD) |
TOOL: {"name": "web_search", "args": {"query": "Go 1.23 iterator proposal", "max_results": 3, "domains": ["go.dev"]}}find_thread
Section titled “find_thread”Search local Anode threads and sessions.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | yes | - | Search query |
source | string | no | ”local” | Thread source |
limit | int | no | 10 | Results to return. Values above 50 are reduced to 50. |
TOOL: {"name": "find_thread", "args": {"query": "refactor database layer"}}read_thread
Section titled “read_thread”Read content from a specific thread.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
source | string | no | ”local” | Thread source |
thread_id | string | yes | - | Thread identifier |
goal | string | no | - | Reading goal (helps summarize) |
max_messages | int | no | 40 | Messages to return. Values above 80 are reduced to 80. |
TOOL: {"name": "read_thread", "args": {"thread_id": "sess_abc123", "goal": "find the auth refactor decision"}}handoff
Section titled “handoff”Create a structured handoff package for another agent or the user.
Permission: delegated
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
target | string | no | ”user” | Handoff recipient: user, next_thread, parent, or aggman |
reason | string | no | - | Why the handoff is needed |
summary | string | yes | - | Summary of work completed |
goal | string | no | - | Single-sentence next-task statement |
completed | []string | no | - | List of completed items |
open_questions | []string | no | - | Unresolved questions |
recommended_next_steps | []string | no | - | Suggested follow-up actions |
artifacts | []string | no | - | Relevant file paths or references |
relevant_files | []string | no | - | Files the receiver should open before starting |
follow | bool | no | false | Navigate to the spawned thread when supported |
TOOL: {"name": "handoff", "args": {"summary": "Migrated auth to JWT tokens", "completed": ["Updated middleware", "Added token refresh"], "open_questions": ["Should refresh tokens expire?"]}}look_at
Section titled “look_at”Inspect visual or UI artifacts. Provide either path or target.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
target | string | one of path/target | - | Named visual target |
path | string | one of path/target | - | Path to image or visual file |
question | string | no | - | What to look for |
TOOL: {"name": "look_at", "args": {"path": "manual/screenshot.png", "question": "Is the sidebar alignment correct?"}}list_skills
Section titled “list_skills”List available built-in, user, and workspace skills so the model can choose a valid skill name before loading instructions.
Permission: auto_read
No parameters.
TOOL: {"name": "list_skills", "args": {}}Load a predefined Anode skill. The tool returns the skill’s instructions to the model and can activate skill-local MCP tools. It does not create a child run by itself. See AGENTS.md and Skills for skill configuration.
Permission: delegated
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | yes | - | Skill name |
input | string | no | - | Input for the skill |
TOOL: {"name": "skill", "args": {"name": "code_review", "input": "Review the changes in internal/auth/"}}ask_user
Section titled “ask_user”Pause and ask the user a structured question.
Permission: interactive
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
question | string | yes | - | Question text |
reason | string | no | - | Why this information is needed |
options | []object | yes | - | Array of answer options. Each option requires id and label; description is optional. |
allow_freeform | bool | no | false | Allow typed response beyond options |
required | bool | no | false | User must answer before continuing |
topic | string | no | - | Optional navigation/topic label. Multi-word topics are hyphenated. |
questions | []object | no | - | Optional follow-up questions asked together as a questionnaire (max 3 follow-ups; root question + up to 3). Each entry has question, options, and optional reason/topic/allow_freeform/required. |
TOOL: {"name": "ask_user", "args": {"question": "Which database driver?", "options": [{"id": "postgres", "label": "PostgreSQL"}, {"id": "sqlite", "label": "SQLite"}], "allow_freeform": true}}todo_read
Section titled “todo_read”Read the current agent task list.
Permission: auto_read
No parameters.
TOOL: {"name": "todo_read", "args": {}}todo_write
Section titled “todo_write”Replace the current agent task list.
Permission: state_write
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
todos | []object | yes | - | Array of task items |
Each item in todos:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | Unique task identifier. Auto-filled when empty. |
content | string | yes | Task description |
status | string | no | Status: pending, in_progress, or completed. Aliases such as todo, active, and done normalize to these values. |
active_form | string | no | Optional short phrase for the in-progress form. activeForm is accepted as an input alias. |
TOOL: {"name": "todo_write", "args": {"todos": [{"id": "1", "content": "Fix auth bug", "status": "in_progress"}, {"id": "2", "content": "Add tests", "status": "pending"}]}}task_list
Section titled “task_list”Persist fine-grained tasks with stable IDs, dependencies, parent/child structure, and status.
Permission: state_write
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
action | string | yes | - | create, list, get, update, or delete. |
taskID | string | for get/update/delete | auto on create | Stable task ID. |
title | string | for create | - | Short title. |
description | string | no | - | Longer detail or acceptance criteria. |
repoURL | string | no | current workspace | Repository URL/filter. |
status | string | no | open on create | open, in_progress, or completed. |
dependsOn | []string | no | - | Blocking task IDs. |
parentID | string | no | - | Parent task ID. |
limit | int | no | 0 | Returned task limit for list; 0 returns all matches. |
TOOL: {"name": "task_list", "args": {"action": "create", "title": "Document provider retries"}}task_list update treats omitted optional fields as “leave unchanged” and
explicit blank description, repoURL, or parentID values as clear
operations. dependsOn: [] clears dependencies. The task graph rejects new
parent/dependency cycles, including direct self-references.
Code intelligence via language servers. Provides go-to-definition, references, hover, and more.
Permission: auto_read
Availability: conditional. The tool appears only when Anode finds a configured or auto-detected language server. See Language Server Protocol.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
operation | string | yes | - | LSP operation to perform |
path | string | no | - | File path (required for most operations) |
line | int | no | - | 0-indexed line number |
character | int | no | - | 0-indexed column number |
query | string | no | - | Search query (for symbol operations) |
includeDeclaration | bool | no | false | Include declaration in references |
limit | int | no | 200 | Returned result limit. Values above 1000 are reduced to 1000. |
Operations:
| Operation | Description |
|---|---|
goToDefinition | Jump to symbol definition |
findReferences | Find all references to symbol |
hover | Get type or symbol hover info |
documentSymbol | List symbols in a file |
workspaceSymbol | Search symbols across workspace |
goToImplementation | Find interface implementations |
diagnostics | Get file diagnostics |
prepareCallHierarchy | Prepare call hierarchy item |
incomingCalls | Find callers of a function |
outgoingCalls | Find callees of a function |
TOOL: {"name": "lsp", "args": {"operation": "findReferences", "path": "internal/run/engine.go", "line": 42, "character": 10}}get_diagnostics
Section titled “get_diagnostics”Read diagnostics from configured or auto-detected language servers. This
registers with lsp.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | string | no | - | Single workspace-relative file path. |
paths | []string | no | - | Multiple workspace-relative file paths. Combined with path. |
wait | bool | no | false | Wait for fresh diagnostics. |
wait_timeout_ms | int | no | 10000 | Wait timeout in milliseconds. Values above 30000 are reduced to 30000. |
severity | string | no | any | any, error, warning, info, or hint. |
TOOL: {"name": "get_diagnostics", "args": {"path": "internal/tools/web_search.go", "severity": "error"}}send_message
Section titled “send_message”Post an in-process coordination message to a named mailbox. study can send
and receive messages; the built-in aggman profile is read-only, so it can
receive and summarize messages but cannot send them.
Permission: state_write
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
recipient | string | yes | - | Mailbox name such as aggman, parent, broadcast, or a worker label. JSON calls may use to as an alias. |
message | string | yes | - | Message body. |
type | string | no | status | status, question, result, error, or broadcast. |
from | string | no | anode | Sender label. |
metadata | object | no | - | Free-form key/value metadata. |
TOOL: {"name": "send_message", "args": {"recipient": "aggman", "message": "phase 1 complete", "type": "result", "from": "worker-a"}}receive_messages
Section titled “receive_messages”Drain or peek at coordination messages addressed to a named recipient. Use this as an aggregator mailbox reader, or as a worker checking for instructions from a parent process.
Permission: auto_read
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
recipient | string | yes | - | Mailbox name to read. |
peek | bool | no | false | Return messages without removing them. |
TOOL: {"name": "receive_messages", "args": {"recipient": "aggman"}}init_experiment
Section titled “init_experiment”Initialize an autoresearch session. The session records a benchmark command,
the primary metric, and whether higher or lower values are better. The normal
loop is init_experiment, then repeated run_experiment and log_experiment
calls.
Permission: confirm_write
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | yes | - | Short label such as exa-cache-tuning. |
objective | string | no | - | Plain-English statement of what should improve. |
primary_metric | string | yes | - | Metric name such as latency_ms or hit_rate. |
unit | string | no | - | Display unit such as ms or %. |
direction | string | yes | - | lower or higher. |
command | string | no | - | Benchmark command that emits the metric. |
scope | array | no | - | Informational files or directories in scope. |
max_runs | integer | no | - | Experiment run limit before the session stops; 0 or omitted means no run-count limit. |
reset | boolean | no | false | Start a fresh session even when one is active. |
TOOL: {"name": "init_experiment", "args": {"name": "exa-tuning", "primary_metric": "p95_ms", "direction": "lower", "command": "go test -bench=BenchmarkExaSearch ./internal/tools/...", "max_runs": 5}}run_experiment
Section titled “run_experiment”Run the configured benchmark command, parse the primary metric, and create a
pending result. Every run_experiment call must be followed by
log_experiment to commit the result.
Permission: state_write
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
command | string | no | configured command | Override command for this run. |
timeout_ms | integer | no | configured timeout | Override per-run timeout. |
checks_timeout_ms | integer | no | configured checks timeout | Timeout for post-run checks. |
TOOL: {"name": "run_experiment", "args": {}}log_experiment
Section titled “log_experiment”Commit the pending autoresearch run. Use baseline for the first reference run,
keep for an improvement to retain, discard for a change to drop, crash for
a failed benchmark, and checks_failed when validation failed.
Permission: state_write
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
status | string | yes | - | baseline, keep, discard, crash, or checks_failed. |
metric_value | number | no | parsed metric | Override the parsed metric value. |
description | string | no | - | What the run changed or measured. |
commit_message | string | no | - | Git commit subject when status=keep. |
TOOL: {"name": "log_experiment", "args": {"status": "baseline", "description": "reference timing"}}Inspect The Actual Registry
Section titled “Inspect The Actual Registry”The authoritative list is the current registry:
anode tools listanode tools show bashanode tools list --profile reviewUse --profile to see what a specific profile can actually call after allowlists, read-only filtering, disabled tools, web access settings, MCP, toolbox, and plugin discovery are applied.
Invoke Read-Only Tools From The CLI
Section titled “Invoke Read-Only Tools From The CLI”tools use runs read-only tools directly (auto_read and external_read):
anode tools use read --arg path=README.mdanode tools use read --json '{"path":"README.md","max_bytes":4000}'anode tools use chart --arg type=bar --arg-json data='{"fixed":3,"open":1}'Use --allow-non-read only when you intentionally want direct invocation of state-writing, file-writing, execute, delegated, or interactive tools.
Dynamic Tools
Section titled “Dynamic Tools”Beyond built-in tools, Anode supports dynamically registered tools from external systems and skills.
MCP tools
Section titled “MCP tools”Tools discovered from MCP servers. Named mcp__<server>__<tool>.
TOOL: {"name": "mcp__github__create_issue", "args": {"title": "Bug report", "body": "..."}}Toolbox tools
Section titled “Toolbox tools”Executable scripts in toolbox directories. Named tb__<name>.
TOOL: {"name": "tb__deploy", "args": {"environment": "staging"}}Plugin tools
Section titled “Plugin tools”Tools contributed by process plugins. Named plugin__<plugin>__<tool>.
TOOL: {"name": "plugin__security__scan", "args": {"path": "."}}Skill-local MCP tools
Section titled “Skill-local MCP tools”Skills can activate bundled MCP servers when skills.allowMCP or the workspace MCP environment gate allows it. Skill-local tools use the same MCP naming and permission checks as other MCP tools.
Built-In Skills
Section titled “Built-In Skills”Skills invoked via the skill tool. See AGENTS.md and Skills for full details.
| Skill | Purpose |
|---|---|
code_review | Review code changes for issues |
bug_hunt | Systematically search for bugs |
repo_summary | Generate repository overview |
test_failure_analysis | Diagnose test failures |
docs_writer | Draft manual-style documentation |
commit_message | Write commit messages from diffs |
ui_consistency_review | Check UI for consistency issues |
security_review | STRIDE + OWASP Top 10 + LLM Top 10 + supply-chain review |
simplify | Reuse, quality, and efficiency cleanup pass |
browse_wiki | Search and read project docs/manual locally |
full_output_enforcement | Generate complete code without placeholders/truncation |
incident | Alert-link RCA runbook |
Disable Tools
Section titled “Disable Tools”Disable specific tools globally via config.json:
{ "tools": { "disabled": ["web_search", "mcp__*"] }}Values support glob patterns. Disabled tools are removed from the agent’s available tool set.
Keep Going
Section titled “Keep Going”- Permissions - control what tools can do
- AGENTS.md and Skills - extend Anode with custom skills
- MCP - connect external tool servers
- Toolbox - add tools via shell scripts