In Finch, everything the agent can call — reading files, running searches, switching themes, installing mini tools, connecting MCP servers — is a "tool." These come from several different sources. Knowing where they come from, how they're named, and how they're authorized helps you decide whether a capability deserves its own mini tool, and how a mini tool's tools should coexist with the built-in ones.
Four layers of tools
| Layer | Source | Notes |
|---|---|---|
| Agent runtime built-ins | The agent core Finch depends on (the pi binary) | File I/O, search, terminal, and other primitives shipped with the agent core, outside Finch's tool registry |
| Tool suites | Finch's own source code | Composite tools with an action parameter, covering memory, skills, sessions, app control, automation, and other product features |
| Mini tool–contributed tools | Installed and enabled mini tools, via ctx.tools.register() | See the mini tools guide |
| MCP-contributed tools | External MCP servers connected dynamically through the official MCP bridge mini tool | Fixed naming: mcp__<server>__<tool> |
To the model, all four layers look the same — just a function call. The real differences are in naming conventions and the permission gateway, covered below.
Agent runtime built-in tools
These come from the agent core Finch depends on. Finch only holds their permission policy (whether confirmation is required, timeouts) — it doesn't reimplement the execution logic.
| Tool | Purpose |
|---|---|
Read | Read files (supports line offset/limit, images, PDFs) |
Write | Create/overwrite text files |
Edit | Precise text replacement on files already read |
Grep | Regex content search (glob filters, context lines, multiple output modes) |
Glob | Filename pattern matching |
Bash | Run shell commands; dangerous commands (rm, git reset --hard, etc.) are treated differently from read-only ones |
WebSearch | Web search |
WebFetch | Fetch a single page and convert to text/Markdown |
AskUserQuestion | Structured multiple-choice question cards, used instead of plain-text prompts |
TodoWrite | Maintain a to-do checklist to show progress during long tasks |
Skill | Backs /skill references inserted in the Composer |
This is the "infrastructure" layer. Mini tools don't need to — and shouldn't — reimplement file I/O or search; just assume these already exist.
Tool suites
Finch's own product features aren't split into dozens of tiny tools. Instead they're consolidated into 7 "dispatcher tools," each reusing one tool definition via an action parameter. When the model omits action, it gets the full usage manual for that tool (like a built-in --help).
| Tool | Purpose | Common actions |
|---|---|---|
Memory | Medium/long-term memory, persisted to MEMORY.md / daily logs / Space memory | remember / replace / forget / search |
Skills | Discover and invoke SKILL.md skill packages | list / invoke |
Session | Operations within the current session | search (past sessions) / extendDir (trust a new directory) / attach (push a file into the composer) / rename |
AppCall | App-level control + user profile writes | info / setAppearance / listSpaces / listModels / createSpace / checkUpdate / saveProfile, etc. |
ToolSearch | Discover and activate dynamic tools not yet loaded in the session (see below) | pass query/source/limit |
MiniTool | Manage installed mini tools (via the @finchtoys/minitools CLI) | list / add / update / remove / enable / disable / reload |
Schedule | Manage scheduled automation tasks | list / create / update / enable / disable / delete / run / history |
This "dispatcher" design is a Finch-specific architectural choice, not a requirement of the mini tool API — a mini tool can group related capabilities into one tool with an action parameter the same way, or register several independent tools, depending on how you want the model to discover and call them.
Dynamic tools and ToolSearch
Not every tool is injected into the model's tool list at the start of a new session — tool definitions consume context, and more tools means lower selection accuracy. Finch uses exposure to distinguish two strategies:
startup(default): injected as soon as a new session starts, e.g. the built-ins and dispatcher tools listed above.dynamic: not in the initial tool table; must be activated before it can be called. Typical examples are tools exposed by MCP servers and the large pool of mini tool tools discovered on demand.
When the model needs an uncommon tool, it first calls ToolSearch with a natural-language query. Finch "activates" matching tools into the current session, and the model can then call them on the next step. MCP-contributed tools follow the fixed naming mcp__<server>__<tool> (e.g. mcp__tavily__tavily_search) and are never preloaded — they must be activated via ToolSearch source="mcp" first.
How mini tool–contributed tools are named
Tools a mini tool registers via ctx.tools.register({ name, ... }) are exposed to the model as <mini-tool-id>_<name> (e.g. a mini tool with id myextension registering search_docs shows up as myextension_search_docs).
If a mini tool registers tools on behalf of another mini tool (e.g. the official MCP bridge registering tools contributed by other mini tools' MCP servers), it can set an owner field on the tool definition, attributing the tool's origin, permission ownership, and UI counters to the contributor rather than the actual registrant. This is the mechanism the official MCP bridge itself uses; ordinary mini tools generally don't need it.
Permissions and execution policy
Every tool call goes through a policy check before executing, with three possible outcomes:
| Policy | Behavior | Applies to |
|---|---|---|
Fully auto-approved (autoAllow) | Runs immediately, no permission card | AskUserQuestion/TodoWrite/Skill, and every Finch dispatcher tool except MiniTool (Memory/Skills/Session/AppCall/ToolSearch/Schedule) |
Fast lane (acceptCallsAutoAllow) | Auto-approved only when the user switches to "Accept Calls" permission mode; still requires confirmation in default mode | Read/Write/Edit/Grep/Glob/WebSearch/WebFetch, and read-only Bash commands |
| Confirm every time (permission card) | A permission card is shown every call, requiring manual approval | Dangerous Bash commands, all mini tool–contributed tools, and the MiniTool dispatcher tool itself |
Key takeaway: mini tool–contributed tools are never auto-approved, regardless of permission mode — every call goes through a permission card. This is intentional: built-in tools and Finch's own dispatcher tools have been audited, while mini tool code comes from third parties and can't get the same trust level. When designing a mini tool's tools, factor this in: if an action gets called frequently, consider turning it into a one-time configuration step (stored in ctx.storage/ctx.settings) rather than triggering a fresh tool call every turn.
Bash is judged separately as "read-only vs. dangerous": read-only commands (ls, git status) use the fast lane; commands like rm and git reset --hard always require confirmation, regardless of permission mode.
Implications for mini tool developers
- Check this list before writing a new tool. File I/O, search, web fetch, and to-do tracking already exist — don't reinvent them in a mini tool.
- Tool names won't collide with built-ins: the model-facing name is automatically prefixed with
<mini-tool-id>_, but your description still needs to make clear what your tool does differently from general tools like Read/Grep — otherwise the model may default to the familiar built-in. descriptiondrives selection probability. Built-in and dispatcher tool descriptions live in the system prompt permanently and are carefully tuned; your mini tool's tools only appear once installed and enabled, so the description needs to be specific enough about when to trigger it to win against other candidates.- Don't assume you'll be called without approval. Design the interaction assuming every call shows the user a permission card first — put the key information (what it does, its scope) in
title/description, not just in the code.
Reference
- Tool registration and execution API: see
ctx.toolsin the mini tools guide - Full type definitions: npm package
@finchtoys/minitool-api