Back
Coding

Agent Tool Architecture And MCP: How Claude Code Turns A Model Into An Operator

A model cannot read a file on its own. Claude Code's tool system is four layers that bridge the gap: a common interface, a registry, a seven-phase dispatch pipeline, and a concurrency scheduler. Here is how each layer works, what MCP adds, and why the design matters for any agent you build.

8 min read
Updated Aug 19, 2026
QUICK ANSWER

A large language model is a text-in, text-out function.

Key Takeaways
  • This guide provides comprehensive, actionable information
  • Consider your specific workflow needs when evaluating options
  • Explore our curated IDEs & Coding Tools tools for specific recommendations
  • AI coding tools range from code completion to autonomous development

The model is stateless; the tool system is not

A large language model is a text-in, text-out function. It has no memory of your filesystem, no ability to run a command, and no way to know what a browser sees. Everything that makes Claude Code feel like an operator -- reading files, editing code, running Bash, fetching a page -- comes from a tool system that sits between the model and the world.

That system is built in four layers. The model emits tool calls as text blocks. The tool system validates them, checks permissions, runs them, and hands the results back as text blocks the model can read. The loop is simple; the engineering inside it is not.

4
layers in the tool stack
7
phases in the dispatch pipeline
43+
tools sharing one interface

Layer 1: the Tool Interface

Every tool in the system implements the same interface, defined in Tool.ts. A tool declares its name, its input schema, whether it is safe to run concurrently, and how it wants permissions handled. The rest of the system does not need to know what the tool does -- only how to call it and how to decide whether to call it.

This uniformity is why the system can grow. BashTool, FileReadTool, WebFetchTool, and tools for spawning subagents or scheduling cron jobs all go through the same 30-method interface. New capabilities are added by writing a new tool, not by changing the dispatcher.

The interface is also fail-closed. If a tool forgets to declare concurrency safety, the scheduler treats it as unsafe and runs it serially. If it forgets to declare a default permission level, the user is asked. The system contains the model by defaulting to the restrictive option.

Layer 2: the Registry

The registry assembles the pool of available tools. Some are always loaded: 16 base tools that handle files, shell, search, and conversation. Others are gated by feature flags, environment variables, or platform checks -- powershell support only appears on Windows, for example.

MCP tools plug in here too. The Model Context Protocol lets an external server expose tools to the agent through a standard transport. From the registry's point of view, an MCP tool is just another entry: it has a name, a schema, and a caller. The difference is that the implementation lives in a separate process, which means an MCP server can wrap a database, a browser, a design tool, or anything else without changing the agent's core.

Layer 3: the Dispatch Pipeline

When the model emits a tool call, the message is not executed immediately. It passes through seven phases:

  1. Extraction. The parser finds tool_use blocks in the assistant message and separates them from ordinary text.
  2. Input validation. Zod schemas validate the raw input. Wrong type, missing field, or malformed path: error before any code runs.
  3. Pre-tool hooks. External scripts can allow, deny, or modify the input. A hook might strip secrets from a prompt or block edits to a protected directory.
  4. Permission check. Deny rules, ask rules, tool-specific checks, safety checks, and permission mode are resolved in priority order.
  5. Execution. tool.call() runs the actual operation.
  6. Post-tool hooks. Scripts fire after execution, often to audit what happened or to clean up side effects.
  7. Result mapping. The output is converted into a tool_result block with the original tool_use_id and appended to the conversation.

Permission rules come from multiple sources: policy, project, user settings, flags, CLI arguments, command context, and session state. They resolve in priority order, and deny rules are final. A hook can tighten a decision but cannot loosen it. This preserves the fail-closed property: the most restrictive rule wins.

Permission rules are resolved, not overridden

The permission system has six layers, checked in order. A deny rule stops everything. An ask rule prompts the user unless the session is in sandbox auto-allow mode. Tool-specific checks catch things BashTool can judge but FileReadTool cannot. Safety checks protect paths like .git/ and .claude/ and are immune to bypass. Permission mode applies the user's configured default. Allow rules are checked last.

The important thing about this stack is that it is additive. You cannot override a deny with an allow from somewhere else. If any layer says no, the answer is no. This is the opposite of many plugin systems, where the last registered handler wins. For an agent that runs shell commands on your machine, the conservative design is the only safe one.

Layer 4: the Concurrency Scheduler

Modern models can emit several tool calls at once. The scheduler decides which of them can run in parallel and which must wait. A tool declares whether each input is concurrency-safe. Calls that are safe and independent are batched together and run concurrently, up to a limit of 10. Calls that are unsafe or have dependencies run serially.

Context modifiers, such as EnterWorktree changing the working directory, are applied between batches, not inside them. That prevents a race where one parallel tool changes directory while another is reading a relative path. The scheduler enforces the model's plan rather than guessing it.

The model itself is told in the system prompt to use the pattern correctly: make independent calls in parallel, and chain dependent commands into a single Bash call with &&. The scheduler then makes sure the model's intent survives contact with the operating system.

Streaming execution adds one more guard

When streaming is enabled, tools start executing while the model is still generating. Each completed tool_use block is queued as soon as it appears. The streaming executor adds Bash error cascading: if a Bash command fails while sibling tools are running in parallel, the siblings are aborted.

The reasoning is that a failed Bash command usually means shared context is now invalid. Continuing with file reads or edits against a filesystem that may be in a broken state is worse than stopping and asking. The cascade is specific to Bash because filesystem and build state are usually shared; a failed web fetch would not abort a file read in the same batch.

A worked example: reading a file

When the model decides to read /src/index.ts, the pipeline does the following:

  1. Extraction finds the tool_use block with name file_read and the argument object.
  2. Tool lookup resolves it to FileReadTool.
  3. Zod validates {file_path: "/src/index.ts"}.
  4. Pre-tool hooks fire and do not modify the input.
  5. Permission check: read tools are generally allowed, with safety checks for protected paths.
  6. Execution: FileReadTool.call() reads the file, applies line numbering in cat -n format, and handles special cases.
  7. Result mapping wraps the contents in a tool_result block referencing the original tool_use_id.
  8. The result is appended to the conversation as a user message, and the model continues.

Every tool call follows this shape. What changes is the validation schema, the permission rules, and the body of tool.call(). The pipeline is the invariant.

Three principles that survive any agent design

Fail closed by default. Unknown tool: error. Invalid input: error. No concurrency declaration: serial. No permission declaration: ask. Every missing declaration punts to safety rather than assuming the model knows best.

The model is the scheduler's author, not its replacement. The system prompt tells the model how to express parallelism. The scheduler enforces that plan. This keeps the intelligence in the model and the safety in code.

One interface, many capabilities. Bash, web fetch, subagent spawn, cron job, and push notification all look the same to the dispatcher. The special cases live inside the tools, not in routing logic that grows with every new capability.

When something goes wrong, which layer to fix

IfThe model calls the wrong tool or hallucinates arguments
Look at prompts and schemas. A clearer description and a tighter Zod schema usually beat more rules. The model cannot invent what the schema forbids.
IfIt runs commands you did not expect
Look at permission rules. Deny rules should be final and specific. Ask rules are useful defaults for anything destructive.
IfParallel calls corrupt shared state
Look at concurrency declarations. Either the tool should declare the input unsafe, or the model should chain dependent commands with && into one call.
IfYou want to add a custom capability
Build or wrap a tool, not a dispatcher. A new MCP server is often faster than a new core tool and keeps the failure mode isolated.

The same architecture appears in other agents, even when the names differ. If you are building one yourself, the lesson is to keep the dispatcher dumb, the tools strict, and permission resolution conservative. The model will surprise you; the system should not.

For the rules that govern how Claude Code uses these tools in a project, see the guide on CLAUDE.md in practice. For the engines that run the models behind the agent, see inference engines compared.

FREQUENTLY ASKED QUESTIONS
How does a coding agent turn LLM outputs into file edits, shell commands and web searches?
A large language model is a text-in, text-out function.
How do AI coding tools integrate with my IDE?
Most AI coding tools integrate as IDE extensions or plugins, providing inline suggestions, code completion, and chat interfaces. Integration quality varies by tool and IDE. This guide covers integration options and setup for different tools.
Do AI coding tools work offline?
Most AI coding tools require internet connectivity for their AI models, though some offer limited offline capabilities. Code completion and suggestions typically need cloud access. This guide explains connectivity requirements for different tools.
EXPLORE TOOLS

Ready to try AI tools? Explore our curated directory:

SHARE THIS GUIDE

A large language model is a text-in, text-out function.

Share on X LinkedIn Reddit Email
Copied to clipboard