The MCP Ecosystem

How MCP (Model Context Protocol) servers integrate into Claude Code — from discovery through authentication to tool execution. This is the extensibility backbone: any external tool, resource, or command can be registered via MCP and used alongside built-in tools.

The five layers

1. Discovery: where are the servers?

MCP servers are discovered from 7 configuration scopes with defined precedence:

claudeai (lowest) → plugins → user → project → local → dynamic → enterprise (highest)

Three deduplication strategies prevent the same server from appearing twice: plugin dedup (by command/URL signature), claude.ai dedup, and CCR proxy URL unwrapping.

2. Connection: how do they connect?

8 transport types cover every deployment scenario:

Transport Use case Auth mechanism
stdio Local process (most common) None
SSE Remote HTTP/SSE servers OAuth via ClaudeAuthProvider
HTTP Streamable Modern HTTP servers OAuth + session ingress JWT
WebSocket Remote WebSocket servers Headers, TLS
SDK Agent SDK in-process None (same process)
claude.ai proxy Claude.ai hosted connectors Bearer token, auto-retry 401
SSE-IDE / WS-IDE IDE extension proxies authToken header

Connection management uses exponential backoff reconnection (1s initial, 30s max, 5 attempts) for remote transports. State updates are batched at 16ms intervals to prevent UI thrashing when many servers connect simultaneously.

3. Authentication: how do they auth?

Two OAuth flows:

Tokens stored in platform keychain, not config files. Auth probe results cached 15 minutes to avoid repeated failures. Step-up auth handles 403 insufficient_scope by forcing PKCE re-auth instead of useless token refresh.

Vendor normalization fixes non-standard OAuth errors (e.g., Slack's invalid_refresh_token → standard invalid_grant).

4. Tool conversion: how do MCP tools become Claude Code tools?

MCP tools are converted to native Tool objects by spreading the MCPTool template:

Tool pool assembly: built-in tools form a sorted prefix, MCP tools form a sorted suffix. This partitioning preserves prompt cache when MCP servers change. Built-in tools win on name conflicts.

5. Execution: how do MCP tool calls work?

  1. ensureConnectedClient() verifies or re-establishes connection
  2. callMCPToolWithUrlElicitationRetry() executes with signal and progress callback
  3. On McpSessionExpiredError (HTTP 404, JSON-RPC -32001), retries once
  4. Default timeout: ~27.8 hours (DEFAULT_MCP_TOOL_TIMEOUT_MS = 100_000_000)

Error handling: McpAuthError transitions server to needs-auth state. McpToolCallError surfaces as tool_result is_error=true. All errors produce conversation messages, never crashes.

Policy enforcement

Change notification

When a server notifies that its tools/prompts/resources changed (ToolListChangedNotification, etc.), the cache is invalidated and tools are re-fetched. This enables dynamic tool registration without reconnection.

Design tensions

  1. 7 scopes — flexible but complex. Enterprise override simplifies managed environments at the cost of user freedom.
  2. Tool name prefixing — prevents collisions but makes tool names verbose and unfamiliar.
  3. Cache partitioning — MCP as suffix preserves built-in cache, but all MCP tool cache breaks when any server changes.
  4. Very long default timeout — prevents premature timeout on slow tools but masks broken connections.