Distributing Tools, tool_choice, and MCP Servers

Domain 2.3, 2.4, and 2.5: scoping each agent's tools so selection stays reliable, the three tool_choice modes, wiring MCP servers with project vs user scope and env-var secrets, and using the built-in tools — including the Edit-fails-so-Read-then-Write fallback.

The rest of Domain 2 is about the tools an agent has access to: how many, which ones, and how they’re wired in. This post covers distributing tools across agents and forcing tool choice (2.3), integrating MCP servers (2.4), and using the built-in tools effectively (2.5). The tool_choice modes and the built-in tool behaviors are verified against anthropic 0.120.0 and Claude Code; MCP-server scoping comes from the current Claude Code documentation.

Too many tools is a design bug

A counterintuitive but heavily-tested principle: giving an agent more tools makes it worse at using them. An agent with 18 tools chooses less reliably than one with 4–5, because every extra tool adds decision complexity — more near-neighbors to confuse, more chances to misroute. And an agent handed tools outside its specialization tends to misuse them: a synthesis agent given a web-search tool will attempt searches it should have left to the researcher.

The fix is scoped tool access: give each agent only the tools its role needs, with a small number of limited cross-role tools for genuine high-frequency needs. A synthesis agent doesn’t get the full search toolkit; it might get a single narrow verify_fact tool for the common case, while complex retrieval routes back through the coordinator. This is the same scoping discipline as tool descriptions, applied at the level of which tools exist for whom. When an exam item describes an agent misusing a tool, the fix is almost always “it shouldn’t have had that tool,” not “write a better prompt.”

A related move: replace a generic tool with a constrained one. A broad fetch_url that will pull anything becomes load_document that validates the URL is a document — narrowing the tool narrows the ways it can be misused.

tool_choice: auto, any, forced

Sometimes you need to control whether and which tool the model calls, and that’s tool_choice. Verified — anthropic 0.120.0 exposes exactly these modes:

  • "auto" (the default) — the model may call a tool or may return text. Right for open-ended turns.
  • "any": the model must call a tool, but chooses which. Use this to guarantee structured output: the model can’t respond with conversational prose, so a downstream parser always gets a tool call.
  • Forced{"type": "tool", "name": "extract_metadata"} — the model must call that specific tool. Use it to ensure a particular step runs first (extract metadata before any enrichment), then continue in follow-up turns.

The exam distinction to keep straight: "any" guarantees a tool call; forced guarantees the named tool. Reach for "any" when several extraction schemas exist and you just need one of them chosen; reach for forced when a specific tool must run before others. Both defeat the failure mode where the model returns chatty text when you needed structured data.

Integrating MCP servers

MCP servers extend the agent with external tools, and where you configure them decides who gets them. Two scopes, from the current Claude Code docs:

  • Project scope.mcp.json at the repo root, committed to version control. This is shared team tooling: everyone who checks out the repo gets these servers.
  • User scope~/.claude.json, personal and not shared. This is where personal or experimental servers go, so you can try one without imposing it on teammates.

Secrets never get committed. .mcp.json supports environment-variable expansion — you write ${GITHUB_TOKEN} and the value is read from the environment at runtime, so the config is shareable while the credential stays out of the repo:

{
  "mcpServers": {
    "github": {
      "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
    }
  }
}

A few operational facts the exam draws on. Tools from all configured servers are discovered at connection time and available simultaneously — the agent sees the union. MCP resources (as opposed to tools) expose content catalogs — issue summaries, a documentation hierarchy, a database schema — which give the agent visibility into available data without spending exploratory tool calls to discover it. And a practical tuning note: enhance your MCP tool descriptions so the agent prefers them over a built-in like Grep when the MCP tool is more capable — a thin MCP description loses to the built-in the model already trusts. Finally, prefer community MCP servers for standard integrations (Jira, GitHub) and reserve custom servers for genuinely team-specific workflows; reimplementing a standard integration is wasted effort and another thing to maintain.

The built-in tools

Task 2.5 is about using Claude Code’s built-in tools well, and it rewards knowing each one’s job:

  • Grep — search file contents for a pattern (a function name, an error string, an import).
  • Glob — find files by path/name pattern (**/*.test.tsx).
  • Read / Write — full-file read and write.
  • Edit — a targeted modification, located by unique text matching.

The most-tested behavior is Edit’s failure mode: Edit requires the text it’s replacing to be unique in the file. If the anchor text appears more than once, Edit can’t tell which occurrence you mean and it fails. The reliable fallback is Read the file, then Write it back with the change — you take full control of the content rather than relying on a unique anchor. Knowing this fallback is knowing why “just use Edit” isn’t always the answer.

The deeper skill is how you combine these to understand a codebase without drowning in it: don’t read every file upfront. Start with Grep to find entry points and callers, then Read to follow imports and trace flows from there — building understanding incrementally. Tracing a function’s usage means first finding all its exported names, then Grep-ing each name across the codebase. This is context management in miniature: pull in what a question needs, not the whole tree, which is exactly the discipline Domain 5 formalizes. (This is Claude Code’s live behavior, which I can confirm directly; no key needed.)

Final thoughts

Tool access is as much a design decision as tool design: scope each agent to the few tools its role needs, constrain generic tools, and use tool_choice ("any" for guaranteed structured output, forced for a required-first step) to control the model when you must. MCP servers wire in at project scope (shared, committed) or user scope (personal), with env-var expansion keeping secrets out of the repo, and resources cutting exploratory calls. Among the built-ins, Grep-then-Read builds understanding incrementally, and Read+Write is the fallback when Edit’s unique-anchor requirement can’t be met. Fewer, well-scoped, well-described tools beat a big undifferentiated pile every time.

Next: Arc 3 opens with CLAUDE.md and path-specific rules — the configuration hierarchy that tells Claude Code your project’s conventions.

Comments