Skip to content

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.

  1. The model emits a TOOL: directive with a JSON payload containing the tool name and arguments.
  2. Anode validates the call against your permission policy.
  3. If approved, Anode executes the tool and captures the result.
  4. 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.

LevelBehavior
auto_readAlways allowed. No confirmation needed.
external_readExternal service reads and read-only delegated investigation.
state_writeLocal agent state mutations.
confirm_executeRequires confirmation for shell execution.
confirm_writeRequires confirmation for file mutations.
delegatedDelegated to subagent or skill.
interactiveRequires direct user interaction.

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

ParameterTypeRequiredDefaultDescription
commandstringyes-Shell command to execute
cwdstringnoworkspace rootWorking directory
timeout_msintno30000Command 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

ParameterTypeRequiredDefaultDescription
pathstringyes-File path relative to workspace
read_rangearrayno-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_lineintno1First line to read
end_lineintnoend of fileLast line to read
max_bytesintno2097152Byte 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}}

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

ParameterTypeRequiredDefaultDescription
pathsarrayyes-Workspace-relative file paths (max 10).
read_rangearrayno-1-indexed [start, end] slice applied to every path.
start_lineintno-Alternative to read_range; applied to every path.
end_lineintno-Alternative to read_range; applied to every path.
max_bytesintno4194304Total 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 an existing text file. Provide exactly one input shape: edits, old_str/new_str, or unified_diff.

Permission: confirm_write

ParameterTypeRequiredDefaultDescription
pathstringyes-File path relative to workspace
editsarrayone of edits/old_str/unified_diff-Array of edit operations
old_strstringone of edits/old_str/unified_diff-Text to replace in top-level single-replacement form
new_strstringwith old_str-Replacement text for old_str
replace_allboolnofalseReplace every old_str occurrence; otherwise old_str must be unique
unified_diffstringone of edits/old_str/unified_diff-Unified diff patch to apply

Each item in edits:

FieldTypeRequiredDescription
oldstringyesText to find
newstringyesReplacement text
occurrenceintnoWhich 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 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

ParameterTypeRequiredDefaultDescription
patchstringyes-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 a new text file. Fails if the file exists unless overwrite is true.

Permission: confirm_write

ParameterTypeRequiredDefaultDescription
pathstringyes-File path relative to workspace
contentstringyes-File content
overwriteboolnofalseOverwrite existing file
TOOL: {"name": "create_file", "args": {"path": "scripts/deploy.sh", "content": "#!/bin/bash\nset -e\ngo build -o bin/app ./cmd/app"}}

Find files, text, symbols, or behavioral patterns across the workspace.

Permission: auto_read

ParameterTypeRequiredDefaultDescription
modestringno”text”Search mode: files, text, symbols, or agent
querystringno-Search query or pattern
pathstringnoworkspace rootDirectory to search
globstringno-File glob filter
limitintno50Returned result limit.
case_sensitiveboolnofalseCase-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

ParameterTypeRequiredDefaultDescription
patternstringyes-Glob pattern such as **/*.go. Supports recursive **.
pathstringno.Workspace-relative root.
limitintno50Returned match limit.
include_hiddenboolnofalseInclude 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

ParameterTypeRequiredDefaultDescription
patternstringyes-Literal string unless regex is true.
pathstringno.Workspace-relative directory.
globstringno-File glob filter, such as *.go.
case_sensitiveboolnofalseMatch case exactly.
word_matchboolnofalseWhole-word match.
regexboolnofalseTreat pattern as regex.
max_matchesintno50Returned match limit per file.
contextintno0Context lines around each match.
TOOL: {"name": "grep", "args": {"pattern": "TODO", "glob": "*.go", "context": 1}}

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

ParameterTypeRequiredDefaultDescription
rootstringyes-ID of the root element in elements.
elementsobjectyes-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

ParameterTypeRequiredDefaultDescription
typestringnobarbar, line, sparkline, or table.
titlestringno-Optional title.
dataobjectone of data/series-Map of label to value.
seriesarrayone of data/series-Ordered array of {label,value} points.
widthintno40Chart 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

ParameterTypeRequiredDefaultDescription
titlestringno-Task title for display
goalstringyes-What the subagent should accomplish
contextstringno-Additional context for the subagent
tools_allowed[]stringnoprofile defaultTool names or globs the subagent may use; recursive delegation tools are filtered
max_stepsintno20Maximum turns. Values above 40 are reduced to 40.
max_tool_callsintnomax_steps * 3Total tool-call limit
profilestringno”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_onlyboolnofalseRestrict to read-only tools
timeout_secondsintno300Wall-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}}

Consult a second-opinion model for complex reasoning. Useful for architecture decisions or debugging.

Permission: external_read

ParameterTypeRequiredDefaultDescription
questionstringyes-Question to ask the oracle model
contextstringno-Additional context
files[]stringno-File paths to include as context
focusstringno-Area to focus reasoning on
modelstringno-Specific model to use
effortstringnomediumnone, minimal, low, medium, high, xhigh, or max
timeout_secondsintno180Oracle 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"}}

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

ParameterTypeRequiredDefaultDescription
diff_descriptionstringyes-Natural-language description of the diff or change, with enough context for a read-only reviewer.
files[]stringnoall relevantSpecific files to focus.
instructionsstringno-Extra reviewer guidance.
check_scopestringno-Check scope such as all or changes-only.
check_filter[]stringnoallCheck names to run.
checks_onlyboolnofalseReturn only structured check results.
thinkingstringnolowlow or high.
TOOL: {"name": "code_review", "args": {"diff_description": "the uncommitted changes in internal/run", "files": ["internal/run/engine.go"], "thinking": "high"}}

Search the web for current information.

Permission: external_read

ParameterTypeRequiredDefaultDescription
querystringyes-Search query
max_resultsintno10Results to return. Values above 20 are reduced to 20.
recencystringnoanyany, day, week, month, or year. Shorthand such as 24h, 1d, 7d, 30d, and 365d is accepted and reported back as the canonical window.
domains[]stringno-Restrict to specific domains
exclude_domains[]stringno-Exclude specific domains
categorystringno-Exa hint: company, people, news, research, or blog
start_published_datestringno-Exa-only lower publish-date bound (YYYY-MM-DD)
end_published_datestringno-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"]}}

Search local Anode threads and sessions.

Permission: auto_read

ParameterTypeRequiredDefaultDescription
querystringyes-Search query
sourcestringno”local”Thread source
limitintno10Results to return. Values above 50 are reduced to 50.
TOOL: {"name": "find_thread", "args": {"query": "refactor database layer"}}

Read content from a specific thread.

Permission: auto_read

ParameterTypeRequiredDefaultDescription
sourcestringno”local”Thread source
thread_idstringyes-Thread identifier
goalstringno-Reading goal (helps summarize)
max_messagesintno40Messages to return. Values above 80 are reduced to 80.
TOOL: {"name": "read_thread", "args": {"thread_id": "sess_abc123", "goal": "find the auth refactor decision"}}

Create a structured handoff package for another agent or the user.

Permission: delegated

ParameterTypeRequiredDefaultDescription
targetstringno”user”Handoff recipient: user, next_thread, parent, or aggman
reasonstringno-Why the handoff is needed
summarystringyes-Summary of work completed
goalstringno-Single-sentence next-task statement
completed[]stringno-List of completed items
open_questions[]stringno-Unresolved questions
recommended_next_steps[]stringno-Suggested follow-up actions
artifacts[]stringno-Relevant file paths or references
relevant_files[]stringno-Files the receiver should open before starting
followboolnofalseNavigate 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?"]}}

Inspect visual or UI artifacts. Provide either path or target.

Permission: auto_read

ParameterTypeRequiredDefaultDescription
targetstringone of path/target-Named visual target
pathstringone of path/target-Path to image or visual file
questionstringno-What to look for
TOOL: {"name": "look_at", "args": {"path": "manual/screenshot.png", "question": "Is the sidebar alignment correct?"}}

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

ParameterTypeRequiredDefaultDescription
namestringyes-Skill name
inputstringno-Input for the skill
TOOL: {"name": "skill", "args": {"name": "code_review", "input": "Review the changes in internal/auth/"}}

Pause and ask the user a structured question.

Permission: interactive

ParameterTypeRequiredDefaultDescription
questionstringyes-Question text
reasonstringno-Why this information is needed
options[]objectyes-Array of answer options. Each option requires id and label; description is optional.
allow_freeformboolnofalseAllow typed response beyond options
requiredboolnofalseUser must answer before continuing
topicstringno-Optional navigation/topic label. Multi-word topics are hyphenated.
questions[]objectno-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}}

Read the current agent task list.

Permission: auto_read

No parameters.

TOOL: {"name": "todo_read", "args": {}}

Replace the current agent task list.

Permission: state_write

ParameterTypeRequiredDefaultDescription
todos[]objectyes-Array of task items

Each item in todos:

FieldTypeRequiredDescription
idstringnoUnique task identifier. Auto-filled when empty.
contentstringyesTask description
statusstringnoStatus: pending, in_progress, or completed. Aliases such as todo, active, and done normalize to these values.
active_formstringnoOptional 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"}]}}

Persist fine-grained tasks with stable IDs, dependencies, parent/child structure, and status.

Permission: state_write

ParameterTypeRequiredDefaultDescription
actionstringyes-create, list, get, update, or delete.
taskIDstringfor get/update/deleteauto on createStable task ID.
titlestringfor create-Short title.
descriptionstringno-Longer detail or acceptance criteria.
repoURLstringnocurrent workspaceRepository URL/filter.
statusstringnoopen on createopen, in_progress, or completed.
dependsOn[]stringno-Blocking task IDs.
parentIDstringno-Parent task ID.
limitintno0Returned 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.

ParameterTypeRequiredDefaultDescription
operationstringyes-LSP operation to perform
pathstringno-File path (required for most operations)
lineintno-0-indexed line number
characterintno-0-indexed column number
querystringno-Search query (for symbol operations)
includeDeclarationboolnofalseInclude declaration in references
limitintno200Returned result limit. Values above 1000 are reduced to 1000.

Operations:

OperationDescription
goToDefinitionJump to symbol definition
findReferencesFind all references to symbol
hoverGet type or symbol hover info
documentSymbolList symbols in a file
workspaceSymbolSearch symbols across workspace
goToImplementationFind interface implementations
diagnosticsGet file diagnostics
prepareCallHierarchyPrepare call hierarchy item
incomingCallsFind callers of a function
outgoingCallsFind callees of a function
TOOL: {"name": "lsp", "args": {"operation": "findReferences", "path": "internal/run/engine.go", "line": 42, "character": 10}}

Read diagnostics from configured or auto-detected language servers. This registers with lsp.

Permission: auto_read

ParameterTypeRequiredDefaultDescription
pathstringno-Single workspace-relative file path.
paths[]stringno-Multiple workspace-relative file paths. Combined with path.
waitboolnofalseWait for fresh diagnostics.
wait_timeout_msintno10000Wait timeout in milliseconds. Values above 30000 are reduced to 30000.
severitystringnoanyany, error, warning, info, or hint.
TOOL: {"name": "get_diagnostics", "args": {"path": "internal/tools/web_search.go", "severity": "error"}}

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

ParameterTypeRequiredDefaultDescription
recipientstringyes-Mailbox name such as aggman, parent, broadcast, or a worker label. JSON calls may use to as an alias.
messagestringyes-Message body.
typestringnostatusstatus, question, result, error, or broadcast.
fromstringnoanodeSender label.
metadataobjectno-Free-form key/value metadata.
TOOL: {"name": "send_message", "args": {"recipient": "aggman", "message": "phase 1 complete", "type": "result", "from": "worker-a"}}

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

ParameterTypeRequiredDefaultDescription
recipientstringyes-Mailbox name to read.
peekboolnofalseReturn messages without removing them.
TOOL: {"name": "receive_messages", "args": {"recipient": "aggman"}}

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

ParameterTypeRequiredDefaultDescription
namestringyes-Short label such as exa-cache-tuning.
objectivestringno-Plain-English statement of what should improve.
primary_metricstringyes-Metric name such as latency_ms or hit_rate.
unitstringno-Display unit such as ms or %.
directionstringyes-lower or higher.
commandstringno-Benchmark command that emits the metric.
scopearrayno-Informational files or directories in scope.
max_runsintegerno-Experiment run limit before the session stops; 0 or omitted means no run-count limit.
resetbooleannofalseStart 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 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

ParameterTypeRequiredDefaultDescription
commandstringnoconfigured commandOverride command for this run.
timeout_msintegernoconfigured timeoutOverride per-run timeout.
checks_timeout_msintegernoconfigured checks timeoutTimeout for post-run checks.
TOOL: {"name": "run_experiment", "args": {}}

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

ParameterTypeRequiredDefaultDescription
statusstringyes-baseline, keep, discard, crash, or checks_failed.
metric_valuenumbernoparsed metricOverride the parsed metric value.
descriptionstringno-What the run changed or measured.
commit_messagestringno-Git commit subject when status=keep.
TOOL: {"name": "log_experiment", "args": {"status": "baseline", "description": "reference timing"}}

The authoritative list is the current registry:

anode tools list
anode tools show bash
anode tools list --profile review

Use --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.

tools use runs read-only tools directly (auto_read and external_read):

anode tools use read --arg path=README.md
anode 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.

Beyond built-in tools, Anode supports dynamically registered tools from external systems and skills.

Tools discovered from MCP servers. Named mcp__<server>__<tool>.

TOOL: {"name": "mcp__github__create_issue", "args": {"title": "Bug report", "body": "..."}}

Executable scripts in toolbox directories. Named tb__<name>.

TOOL: {"name": "tb__deploy", "args": {"environment": "staging"}}

Tools contributed by process plugins. Named plugin__<plugin>__<tool>.

TOOL: {"name": "plugin__security__scan", "args": {"path": "."}}

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.

Skills invoked via the skill tool. See AGENTS.md and Skills for full details.

SkillPurpose
code_reviewReview code changes for issues
bug_huntSystematically search for bugs
repo_summaryGenerate repository overview
test_failure_analysisDiagnose test failures
docs_writerDraft manual-style documentation
commit_messageWrite commit messages from diffs
ui_consistency_reviewCheck UI for consistency issues
security_reviewSTRIDE + OWASP Top 10 + LLM Top 10 + supply-chain review
simplifyReuse, quality, and efficiency cleanup pass
browse_wikiSearch and read project docs/manual locally
full_output_enforcementGenerate complete code without placeholders/truncation
incidentAlert-link RCA runbook

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.