MCP Client

Description

The MCP client (src/services/mcp/client.ts) manages connections to MCP servers, handles 8 transport types, converts MCP tools into Claude Code's native Tool format, and provides error recovery with session retry and reconnection. It is the core runtime component of the mcp-subsystem.

Transport types

connectToServer() creates the appropriate transport based on serverRef.type:

Transport Type key SDK class Auth Use case
stdio stdio StdioClientTransport none Local process servers
SSE sse SSEClientTransport OAuth via ClaudeAuthProvider Remote HTTP/SSE servers
SSE-IDE sse-ide SSEClientTransport none IDE extension proxy
WebSocket ws WebSocketTransport headers, TLS Remote WebSocket servers
WS-IDE ws-ide WebSocketTransport authToken header IDE WebSocket proxy
HTTP Streamable http StreamableHTTPClientTransport OAuth, session ingress JWT Modern HTTP servers
SDK sdk SdkControlTransport in-process Agent SDK in-process
Claude.ai Proxy claudeai-proxy StreamableHTTPClientTransport Bearer token, auto-retry 401 Claude.ai hosted connectors

Platform-specific behavior

Tool conversion

fetchToolsForClient() converts MCP protocol tools to Claude Code Tool objects:

  1. Requests tools/list via MCP protocol
  2. Sanitizes Unicode in tool data
  3. For each tool, spreads the MCPTool template and overrides:
  4. name — prefixed mcp__<server>__<tool> (unless CLAUDE_AGENT_SDK_MCP_NO_PREFIX)
  5. call — wraps MCP tool invocation with retry logic
  6. description — capped at 2,048 chars (MAX_MCP_DESCRIPTION_LENGTH)
  7. isConcurrencySafe — derived from MCP readOnlyHint
  8. isDestructive — derived from MCP destructiveHint
  9. isOpenWorld — derived from MCP openWorldHint
  10. Results are LRU-cached (MCP_FETCH_CACHE_SIZE = 20)

Tool call execution

When an MCP tool is called: 1. ensureConnectedClient() verifies or re-establishes the connection 2. callMCPToolWithUrlElicitationRetry() executes with signal, metadata, and progress callback 3. On McpSessionExpiredError (HTTP 404, JSON-RPC code -32001), retries once (MAX_SESSION_RETRIES = 1) 4. Default timeout is extremely long: DEFAULT_MCP_TOOL_TIMEOUT_MS = 100_000_000 (~27.8 hours)

Error handling

Error type Trigger Recovery
McpAuthError Auth failure during tool call Server transitions to needs-auth state
McpSessionExpiredError HTTP 404 + JSON-RPC -32001 Automatic reconnect + retry (1 attempt)
McpToolCallError MCP tool returns isError: true Surfaced to agent as tool error
Connection lost Transport disconnect Exponential backoff reconnect (5 attempts, 1s-30s)

Auth caching

MCP_AUTH_CACHE_TTL_MS = 15 * 60 * 1000 (15 minutes) — servers that recently returned 401 skip re-probing for this duration, avoiding repeated auth failures.

Trade-offs

  1. 8 transport types — comprehensive coverage but significant code surface area. Each transport has different auth, error, and timeout behaviors.
  2. Very long default timeout (~27.8 hours) — prevents premature timeout on slow tools but means truly broken connections take a long time to fail. Individual tools should set shorter timeouts.
  3. LRU tool cache — avoids re-fetching tool lists on every call but means tool list changes on the server aren't immediately visible. Cache size of 20 is tuned for typical MCP usage.
  4. Single session retry — recovers from transient session loss without infinite loops. More retries might recover more cases but risk masking server bugs.

Depends on

Key claims

Relations

Sources

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