MCP Subsystem

Description

The MCP subsystem implements Model Context Protocol support in Claude Code, allowing external tools, resources, and commands to be registered from MCP servers and used alongside built-in tools. It handles server discovery across 7 configuration scopes, manages connections with multiple transport types, converts MCP tools into Claude Code's native Tool format, and handles authentication including OAuth flows. The implementation lives in src/services/mcp/ (22 files) with supporting tool modules.

Architecture

The subsystem has four main layers:

1. Configuration and discovery (config.ts)

Server definitions are loaded from 7 scopes with increasing precedence: plugins, user settings (~/.claude/settings.json), project settings (.mcp.json), local settings, dynamic (runtime), claude.ai connectors, and enterprise managed. Enterprise config takes exclusive control when present — nothing else loads.

2. Connection management (MCPConnectionManager.tsx, useManageMCPConnections.ts)

A React context provider manages connection lifecycle. Servers can be in 5 states: Connected, Failed, NeedsAuth, Pending, or Disabled. Reconnection uses exponential backoff (1s initial, 30s max, 5 attempts).

3. Client and transport (client.ts)

The MCP client supports 8 transport types (stdio, SSE, SSE-IDE, WebSocket, WS-IDE, HTTP streamable, SDK in-process, and claude.ai proxy). Each transport handles auth, headers, timeouts, and error recovery differently. See mcp-client for details.

4. Tool conversion

MCP tools are converted to Claude Code Tool objects by spreading the MCPTool template and overriding name, call, description, checkPermissions, and behavioral hints. Tool names are prefixed as mcp__<server>__<tool> (unless CLAUDE_AGENT_SDK_MCP_NO_PREFIX). Descriptions are capped at 2,048 characters.

Tool files

Module Purpose
MCPTool Base template tool, overridden per MCP server tool
McpAuthTool Triggers OAuth/auth flow for servers in needs-auth state
ListMcpResourcesTool Lists available MCP resources from connected servers
ReadMcpResourceTool Reads content from a specific MCP resource

Integration with tool system

MCP tools are assembled into the tool pool via assembleToolPool(): 1. Built-in tools form a contiguous prefix (sorted alphabetically) 2. MCP tools form a suffix (also sorted alphabetically) 3. This partition preserves prompt cache when MCP servers change 4. Built-in tools win on name conflicts

Deduplication

Three strategies prevent duplicate server registrations:

  1. Plugin dedup (dedupPluginMcpServers) — by signature (stdio command array or URL). Manual config wins over plugin; first plugin wins ties.
  2. Claude.ai dedup (dedupClaudeAiMcpServers) — only enabled manual servers count as targets.
  3. CCR proxy unwrap (unwrapCcrProxyUrl) — extracts original vendor URL from CCR proxy path markers so a proxied server and its direct URL are recognized as the same server.

Policy enforcement

Trade-offs

  1. 7 config scopes — powerful flexibility but complex precedence rules. Enterprise override simplifies for managed environments but blocks user customization entirely.
  2. Tool name prefixing (mcp__server__tool) — prevents name collisions but makes tool names verbose. SDK mode can disable this.
  3. Cache-aware ordering — MCP tools as a sorted suffix preserves built-in cache but means MCP tool cache is invalidated when any MCP server changes.
  4. Fail-open auth — servers that fail auth go to NeedsAuth state rather than being silently dropped. The user sees the state and can act.

Depends on

Key claims

Relations

Sources

src-20260409-a5fc157bc756, source code analysis of src/services/mcp/