Tools and approvals
Tools are how a model reaches outside its own context window. A tool reads a file, writes one, queries a database, calls an API. Without tools, the model is a closed system; with tools, it can act on the world. Polycode treats tools as a separate authorization surface from providers — configuring a provider lets a model talk; the approval gate decides what it’s allowed to do — and asks for explicit permission before a mutating tool runs against your machine. This article walks the model end-to-end.
What counts as a tool
Polycode exposes two families:
- Built-in file tools — a fixed set of nine scoped filesystem tools shipped with the app: Read file, Write file, Edit file, Delete file, Rename file, File info, List directory, Find files, and Grep search. They run inside Polycode’s sandbox and operate only on the folders you grant as projects. There is no shell or arbitrary-exec tool — the Mac App Store sandbox prohibits spawning user binaries, so Polycode doesn’t ship one.
- MCP server tools — anything reachable through the Model Context Protocol. You add a server, Polycode speaks MCP to it, and the server’s tools appear inline in the catalog next to the built-in tools. This is the extension surface: Postgres, GitHub, your internal API gateway, a homegrown service — anything that exposes an HTTP MCP endpoint.
Polycode is a first-class MCP host
The Model Context Protocol is how a host application advertises tools to a model and routes the model’s tool-call decisions back to those tools. In Polycode it is the tool layer — a model that wants to call a function calls it the same way whether the tool came from a built-in or from an MCP server.
Polycode connects to MCP servers over the streamable-HTTP transport — a server is an HTTP endpoint, local or remote. (Stdio/child-process MCP servers, which require spawning arbitrary binaries, are not supported under the App Sandbox.) Add a server two ways from Settings → MCP servers:
- Browse registry opens a searchable browser over the official MCP registry
(
registry.modelcontextprotocol.io). Type to search server-side, page through results, and click Add on any HTTP-capable entry. If the registry is unreachable on first load, a small curated fallback list is shown instead. - Add opens a sheet for a custom endpoint — a name and a base URL like
https://mcp.example.com/server, plus an optional Read-only toggle (“Disable tool invocation; only list tools and read resources”).
A status strip at the bottom of the sidebar summarizes connected servers — MCP · N connected, with an error count and a live status dot, and a gear that opens MCP settings. Per-server detail lives in Settings → MCP servers and in the inspector, not in the sidebar strip.
Per-tool approval defaults
Polycode does not have a “trust everything” switch, nor a per-conversation on/off list. Instead, every tool carries a default approval you set once, globally, in Settings → Tools — “Default approval per tool. Native and MCP-hosted tools share this surface.” The control is a three-way segmented picker:
- Always — skip the prompt and run the call (treated as approved for the session).
- Ask — present the approval card every time a new call comes up.
- Deny — skip the prompt and reject the call outright.
The defaults are deliberately asymmetric: read-only tools (Read file, List directory, Grep search, Find files, File info) default to Always, so reads run silently; mutating tools (Write, Edit, Delete, Rename) default to Ask, so you see a prompt before anything on disk changes. You can override any tool either direction — flip a read to Ask to review every new path, or set a tool to Deny to block it everywhere. MCP-hosted tools sit in the same list with the same picker; a server that doesn’t declare read-only status is treated as mutating (defaults to Ask).
The inline approval card
When a tool defaults to Ask and there’s no session grant covering it,
Polycode pauses that peer’s stream and surfaces an inline approval card in the
conversation. The card titles itself “Approve read?” for a read or
“Approve toolname?” for a write, names the provider that asked
(“…wants to run”), and shows a details well — the target path, the
scope (read-only or read/write), and the tool’s action description.
It offers a Deny button, an Approve button (the default action —
Return approves), and a Remember for this session checkbox:
- Deny — the call doesn’t run; the peer is told and continues without that information.
- Approve (unchecked) — the call runs this once. The next matching call prompts again.
- Approve with Remember for this session checked — the call runs and Polycode caches the grant for the rest of the conversation.
If several peers in a fan-out request the same call, you see one card — “Approving here applies to all N peers” — and resolving it resolves them all.
Session grants and the cache
A “remember” grant is scoped to the project, the tool, and the target
directory — not to a single file and not globally. Approving Edit file on
src/foo.swift caches a grant for that tool anywhere under src/ in that
project; a call to a different directory prompts again. The grant lasts until
the conversation changes — opening or switching to another session clears
the whole session cache, so a fresh chat starts clean.
Settings → Tools surfaces these grants under Active session approvals
(each row shows the tool and its path prefix — (any path) when no path was
involved). A Clear session cache button drops every cached grant at once;
clearing is non-destructive — the next matching call simply prompts again.
There is no global “trusted forever” state: the persistent part is the per-tool
Always / Ask / Deny default, and session grants always evaporate with the
conversation.
Reviewing file changes (the diff viewer)
When a write-class file tool (Write, Edit, Rename, Delete) wants to run, its approval card carries a View diff button. Opening it shows exactly what the call will change before you approve:
- Create / Edit / Delete render a unified before/after diff with
@@hunk headers,+added lines (green) and-removed lines (red). - Rename shows From: and To: paths.
Read-only tools show “Read-only preview not required” and MCP tools show “No diff preview for MCP tool” — neither offers a diff. The diff is the surface that lets you see a mutating tool’s exact effect before granting it.
The agent-loop soft cap
When a peer runs an agentic tool loop — calling tools, reading results, calling again — Polycode caps how far it runs before checking in with you. After 25 tool calls (the default per-provider soft cap) the loop pauses and a warning banner appears above the conversation:
Polycode has called 25 tools while answering with provider. Continue?
Two choices: Continue 25 more (Return) advances the budget by another 25,
or Stop and summarize (Escape) ends that peer’s loop with one final
text turn while other peers keep going. Each peer’s loop is capped
independently, so concurrent pauses queue (the banner shows +N more). If the
window isn’t focused when a loop pauses, Polycode can post a notification —
toggle it under Settings → Privacy → Notifications (“Notify when an agent
loop pauses at the tool-call soft cap”).
Tools and fan-out
In a fan-out, peers and the primary do not get the same tool set. Under Polycode’s scoping rule (Pattern C):
- Fan-out peers see read-only tools only. A peer can read a file, list a directory, or grep — and different peers may make different read calls on the same prompt — but a peer can never call Write, Edit, Delete, or Rename, nor any tool from a write-capable MCP server.
- Write-class tools run on the primary only. When the round closes and your primary peer synthesizes, it’s the one that can act on disk.
This keeps a four-way fan-out from issuing four conflicting edits to the same file. The audit trail still lives in the inspector: each peer’s trace card lists the tools it called, a target-path summary, the latency, and the approval outcome, attributed per peer.
Revoking access
- Block a tool globally — set its default to Deny in Settings → Tools. It stops running in every conversation.
- Drop remembered grants — Clear session cache in Settings → Tools (or just start/switch conversations).
- Remove an MCP server — disconnect or delete it in Settings → MCP servers. That removes its tools from every conversation at once.
What’s next
- The inspector — read the full per-tool, per-peer audit trail for any past exchange.
- Setting up providers — providers and tools are separate surfaces; this is where you configure the model side.
- Fan-out and consensus — how peers’ parallel tool calls fold back into a single synthesized reply.