MCP gives Claude Code a second source of capabilities. Built-in tools are not the whole story: once a server is connected, its tools, resources, and prompts become available to the client. The interesting part is that Claude Code does not build a separate agent runtime for those tools. It translates an external tool into the same general tool surface used by the agent loop.
That design choice is the thread for this series:
The more extensible the system becomes, the more important a single, uniform interface becomes.
This opening article is a map of the territory. Later articles will follow each section of the pipeline in detail.
The path from configuration to a callable tool
A server entry in .mcp.json or user settings does not immediately become something the model can call. It crosses several gates:
- Merge configuration scopes. Claude Code combines the relevant configuration sources and resolves overrides.
- Apply policy. Allowlists, denylists, and enterprise rules may remove a server before connection is attempted.
- Obtain approval. A project-level server can require the user's approval before first use.
- Connect through the selected transport. A local child process and a remote HTTP service have different connection paths.
- Negotiate capabilities. Client and server establish which MCP features are supported.
- Discover capabilities. The client fetches the server's tools, resources, and prompts.
-
Adapt tools. Each server tool becomes an
MCPToolwith a Claude Code-compatible name and schema. - Add it to the agent's tool list. At that point, the LLM can select it as if it were an ordinary tool.
Each stage can fail differently. A failed connection becomes a connection failure. An expired authorization becomes an authentication problem. A policy rejection is quieter: the server can disappear before the user ever sees a connection state.
That distinction matters when debugging MCP. “The tool is missing” can mean a configuration merge issue, a policy decision, an approval requirement, an authentication failure, or a transport failure—not merely that tools/list failed.
For the user-facing setup model and supported scopes, see the official Claude Code MCP documentation.
Connection is a lifecycle, not a one-time request
Internally, a server is not simply connected or disconnected. The connection layer distinguishes states such as connected, failed, pending, disabled, and needing authentication. That state model prevents a transient transport error from being confused with an OAuth flow that still needs a browser-based decision.
The implementation also treats a connection as a cacheable resource. A connection is memoized by server name and configuration, then its derived data—such as discovered tools and resources—is cached alongside it. When the transport closes, those caches are cleared so the next request takes the reconnection path instead of continuing to use stale discovery results.
This is especially important for remote MCP servers. A session can expire even when the endpoint remains reachable. Claude Code recognizes the relevant JSON-RPC session-expiry failure, clears its cached connection state, reconnects, and retries once. It is a small recovery rule with a large practical effect: “the server is up” is not the same as “this session is valid.”
There is also an intentional split in retry behavior. Remote transports can receive bounded automatic reconnect attempts with exponential backoff. Local stdio and SDK-backed processes are excluded. A network connection may recover after a short interruption; a local process that exited is more likely to have a bad command, missing environment variable, or a real crash. Retrying blindly would obscure that diagnosis.
Standard transports and product transports
The MCP specification defines the standard stdio and Streamable HTTP transports; the older HTTP-plus-SSE approach is deprecated. The protocol's transport specification is deliberately narrow: it standardizes interoperable ways to exchange JSON-RPC messages rather than every integration a product might need. See MCP's transport specification.
Claude Code's client has a broader set of branches in practice. In addition to standard local and remote paths, the codebase contains support for compatibility SSE paths, WebSocket-based paths, IDE-oriented variants, SDK bridges, a Claude.ai proxy, and an in-process transport.
This is not a contradiction. It is the boundary between a protocol and a product:
- The protocol defines the portable contract that independent clients and servers can share.
- The product still needs integrations for its IDE, browser, SDK, and internal process boundaries.
The in-process transport makes this visible. It passes messages through in-memory queues rather than a network connection or child process. The SDK bridge similarly carries MCP JSON-RPC messages across Claude Code's own control channel. Neither changes the model-facing idea of a tool; both solve deployment-specific plumbing.
How an external tool becomes a Claude Code tool
The key adapter is naming. A discovered MCP tool is exposed as:
mcp__<server>__<tool>
That prefix gives tools from different servers a stable namespace and lets the rest of Claude Code treat them like entries in a common list. The tool's inputSchema is passed through as JSON Schema rather than translated into a separate handwritten validation model.
The result is deliberately mundane: a model sees a tool name, a description, and a schema. It does not need a separate mental model for “MCP mode.”
The adapter also exposes one limitation of every string-based namespace: server names containing the separator can be ambiguous. Names are convenient as human-facing identifiers, but they are a brittle serialization format when later parsing needs to recover structural boundaries.
Claude Code also registers resource-listing and resource-reading functionality globally rather than once per server. That avoids presenting the model with a growing cluster of nearly identical resource tools as more servers are connected. Large or binary resource results can be stored as files and replaced with a path reference, and MCP output has a configurable size limit. Both measures keep a capable external server from consuming the entire working context.
MCP permissions: special matching, ordinary decisions
MCP has one notable extension in Claude Code's permission grammar. A rule can match an entire server, for example:
mcp__calendar
mcp__calendar__*
That is more useful than approving every tool individually when a server offers a coherent, trusted capability. It also allows a user or administrator to deny an entire integration at the same level of abstraction at which it was installed.
But the MCP tool itself does not carry a private permission engine. Its local permission check returns passthrough; the shared permission system performs the actual rule matching. If no rule resolves the request, the general engine falls back to asking the user.
This is a useful division of responsibility. A tool such as Bash may need command-specific safety analysis. An MCP tool is too varied for one universal semantic rule. Claude Code instead centralizes the decision in the policy layer, where the server namespace provides the necessary grouping mechanism.
Beyond tools: resources, prompts, and elicitation
MCP is often described as “a way to add tools,” but that is only one of its three major capability families:
- Tools let the model perform an action.
- Resources let a server provide readable, addressable information.
- Prompts let a server provide reusable prompt templates.
Claude Code gates each downstream feature independently after capability negotiation. A server may be useful as a tool provider without offering resources, or vice versa.
Elicitation is the more interactive extension. It lets a server request structured input while an interaction is in progress. Claude Code supports form and URL modes, and places hooks in front of the UI so an installation can handle certain requests programmatically. This is a good example of the difference between adopting an MCP feature and shipping it in a real product: protocol support establishes the message exchange; a client still decides how a person sees, approves, or automates that exchange.
Authentication is part of the tool experience
For HTTP servers, authorization is not a detached setup screen. An authorization failure can surface to the model as a synthetic authentication tool result containing the URL needed to continue the flow. Under the hood, the client uses authorization-code OAuth with PKCE, a local loopback callback, a timeout, and secure credential storage.
This makes authentication another state transition in the lifecycle rather than an unstructured fatal error. Enterprise environments add another layer: a token-exchange flow can reuse an existing identity-provider session across eligible servers, reducing repeated logins without changing the core tool interface.
Claude Code can reverse roles
The architecture becomes clearer when the direction is reversed. Claude Code can also start an MCP server and expose its own internal tools through tools/list, using stdio for another MCP client to consume.
That works because tool definitions are not fundamentally tied to one transport. The same internal schema can be used directly by the agent loop or converted to JSON Schema and advertised over MCP. Claude Code is therefore not permanently “an MCP client”; MCP is one of the ways its tool model can cross a process boundary.
What the rest of the series will explain
This map suggests the chapters ahead:
- Connection setup, scopes, and the handshake.
- Local and remote transports.
- Tool discovery, naming, schemas, and output control.
- Server-level permission rules.
- OAuth and enterprise authentication.
- Resources and elicitation.
- Claude Code acting as an MCP server.
- Where MCP stops—and where Skills, built-in Tools, and Plugins begin.
The central question is not “How do I add another tool?” It is: how can an agent accept many independently built capabilities without becoming a pile of special cases? Claude Code's answer is to make the boundary adaptable, then keep the agent-facing interface uniform.
Top comments (2)
The 8-gate map is the most useful part — it turns a vague "the tool is missing" report into a diagnosable question. I'd love to see the series cover what happens mid-run: with connections memoized as cacheable resources, a remote server could reconnect with different capabilities than what the agent was approved for. Does the uniform tool surface re-validate at dispatch time, or only at discovery?
On Tokenade, the exposure map is what I'd audit first: which tools load at session start, and which ones ever get called. The gap between the two is where the cost hides.