The tools described on this page apply to the API backend (the default). When using the ACP backend, the external agent process provides its own tools — Fabro’s built-in tools are not used.
Core tools
These tools are registered for every provider profile:Provider-specific tools
Some tools are only available with certain LLM providers:Tool reference
shell
Executes the command as Bash source in the sandbox’s working directory, equivalent tobash -c <command>. The shell is not a login shell, and Fabro adds no shell options of its own — no errexit, no pipefail. Docker and Daytona sandboxes require /bin/bash; local sandboxes resolve bash through the worker’s PATH.
To run something under a different interpreter, say so in the command itself (sh -c ..., a script with a #!/bin/sh shebang, or an explicit set -o pipefail); those run beneath Fabro’s Bash boundary.
The timeout defaults to the provider’s configured value (10s for most providers, 120s for Anthropic) and is capped at the maximum (600s / 10 minutes). If the command exceeds the timeout, Fabro kills the process and returns a “Command timed out” message along with any output captured so far.
The output includes the exit code, stdout, and stderr.
read_file
Reads a file and returns its contents with line numbers.
Output is formatted with line numbers (e.g.
1 | fn main() {), making it easy for agents to reference specific lines when editing.
write_file
Creates or overwrites a file.write_file replaces the entire file. For changes to an existing file, prefer edit_file, which only replaces the string you name.edit_file
Replaces a string in an existing file. Available for Anthropic and Gemini providers.
If
old_string is not found, the tool returns an error. If multiple occurrences exist and replace_all is false, the tool returns an error asking for more context or to set replace_all.
Because old_string must match the file exactly, an edit built from a stale or remembered version of the file fails rather than silently applying somewhere unintended.
grep
Searches file contents with a regex pattern. The sandbox uses ripgrep whenrg is on the path and falls back to POSIX grep otherwise, detected once and cached per sandbox. Keep patterns portable across both rather than relying on ripgrep-only syntax.
Results are returned as
file:line:content lines.
glob
Finds files matching a glob pattern.
Returns matching file paths, one per line, sorted lexicographically by their path relative to the search root.
Patterns are case-sensitive and relative to
path: * and ? stay within one path segment, bracket expressions such as [abc] match one character, and ** crosses directories when used as a complete segment. Leading dots are matched normally. For example, *.rs searches only the root of path, and **/*.rs searches recursively. Patterns must use /, be relative, and cannot contain a backslash or .. segment.
web_search
Searches the web using the Brave Search API.
Requires
BRAVE_SEARCH_API_KEY to be configured for the current runtime. Runs read it from the server vault (fabro secret set BRAVE_SEARCH_API_KEY <key>) — workers start from a cleared environment and this key is not inherited, so exporting it in the server’s shell has no effect. The standalone agent CLI reads it from the invoking shell instead. Returns numbered results with title, URL, and description.
web_fetch
Fetches content from a URL and optionally summarizes it with an LLM.
HTML content is automatically converted to Markdown (with script and style tags stripped). Output is capped at 100KB. When a
prompt is provided and a summarizer model is configured, the fetched content is passed to a lightweight LLM call that returns a concise answer.
apply_patch
Applies a v4a-format patch to create, update, or delete files. Available for OpenAI providers.
The v4a format uses
*** Begin Patch / *** End Patch delimiters with *** Add File:, *** Delete File:, and *** Update File: operations.
read_many_files
Reads multiple files in a single tool call. Available for Gemini.
Returns each file’s contents prefixed with
=== path ===.
list_dir
Lists directory contents with optional depth control. Available for Gemini.
Directories are suffixed with
/ in the output.
update_plan
Maintains the current task plan. Available for OpenAI providers.
The submitted list replaces the current plan for that OpenAI session. Fabro reconciles steps by exact step text, emits
todo.created, todo.updated, and todo.deleted events for changes, and projects the current list into run state.
TaskCreate, TaskUpdate, TaskGet, and TaskList
Maintains a shared task list for Anthropic providers. The list is scoped to the root agent session, so sub-agents share the same task projection.TaskCreate creates a task with subject, description, optional activeForm, and optional metadata. TaskUpdate changes an existing task by taskId; setting status to deleted removes it from the projection. TaskGet returns full details for one task, while TaskList returns the current shared task list.
Like update_plan, task changes are persisted as todo.created, todo.updated, and todo.deleted events and replay into run state.
When an Anthropic session has not used TaskCreate or TaskUpdate for ten assistant turns, Fabro may inject a system reminder asking the agent to keep task state current. The reminder is only added when both tools are available and resets after the agent uses either tool.
Tool execution
Parallel execution
When an LLM returns multiple tool calls in a single response, Fabro can execute them in parallel. Independent tool calls run concurrently, while the results are collected in order. If the agent session is cancelled, pending tool calls return a “Cancelled” error.Argument validation
Before executing a tool, Fabro validates the arguments against the tool’s JSON Schema. Invalid arguments are rejected with a descriptive error before the tool executor runs.Output truncation
Tool output is truncated before being stored in conversation history to prevent context window bloat. Each tool has default limits:
Limits can be overridden per-tool via
SessionConfig.tool_output_limits.
Error handling
When a tool call fails, the error is returned to the agent as a tool result with an error flag — the agent loop continues. Tool errors do not fail the stage. The LLM sees the error message and decides how to respond: retry the call, try an alternative approach, or move on. Common error cases:Timeouts
Shell commands have two timeout settings:
The agent can request a specific timeout via the
timeout_ms parameter, but it’s always capped at the maximum.
Extending with MCP
Additional tools can be added via MCP servers. MCP tools appear alongside built-in tools in the agent’s tool set and follow the same permission and execution model.Further reading
Permissions
How permissions control which tools are available.
Environments
Sandbox providers where tools execute.
MCP
Extend agents with Model Context Protocol servers.
Sub-agents
Sub-agents inherit tools from their parent session.