Chapter 8 System Design

MCP Integration — Plugin Protocol

How Claude Code talks to external tools via Model Context Protocol

src/services/mcp/types.tsLines 180
1
import type { Client } from '@modelcontextprotocol/sdk/client/index.js'
2
import type {
3
  Resource,
4
  ServerCapabilities,
5
} from '@modelcontextprotocol/sdk/types.js'
6
import { z } from 'zod/v4'
7
import { lazySchema } from '../../utils/lazySchema.js'
8
 
9
// Configuration schemas and types
10
export const ConfigScopeSchema = lazySchema(() =>
11
  z.enum([
12
    'local',
13
    'user',
14
    'project',
15
    'dynamic',
16
    'enterprise',
17
    'claudeai',
18
    'managed',
19
  ]),
20
)
21
export type ConfigScope = z.infer<ReturnType<typeof ConfigScopeSchema>>
22
 
23
export const TransportSchema = lazySchema(() =>
24
  z.enum(['stdio', 'sse', 'sse-ide', 'http', 'ws', 'sdk']),
25
)
26
export type Transport = z.infer<ReturnType<typeof TransportSchema>>
27
 
28
export const McpStdioServerConfigSchema = lazySchema(() =>
29
  z.object({
30
    type: z.literal('stdio').optional(), // Optional for backwards compatibility
31
    command: z.string().min(1, 'Command cannot be empty'),
32
    args: z.array(z.string()).default([]),
33
    env: z.record(z.string(), z.string()).optional(),
34
  }),
35
)
36
 
37
// Cross-App Access (XAA / SEP-990): just a per-server flag. IdP connection
38
// details (issuer, clientId, callbackPort) come from settings.xaaIdp — configured
39
// once, shared across all XAA-enabled servers. clientId/clientSecret (parent
40
// oauth config + keychain slot) are for the MCP server's AS.
41
const McpXaaConfigSchema = lazySchema(() => z.boolean())
42
 
43
const McpOAuthConfigSchema = lazySchema(() =>
44
  z.object({
45
    clientId: z.string().optional(),
46
    callbackPort: z.number().int().positive().optional(),
47
    authServerMetadataUrl: z
48
      .string()
49
      .url()
50
      .startsWith('https://', {
51
        message: 'authServerMetadataUrl must use https://',
52
      })
53
      .optional(),
54
    xaa: McpXaaConfigSchema().optional(),
55
  }),
56
)
57
 
58
export const McpSSEServerConfigSchema = lazySchema(() =>
59
  z.object({
60
    type: z.literal('sse'),
61
    url: z.string(),
62
    headers: z.record(z.string(), z.string()).optional(),
63
    headersHelper: z.string().optional(),
64
    oauth: McpOAuthConfigSchema().optional(),
65
  }),
66
)
67
 
68
// Internal-only server type for IDE extensions
69
export const McpSSEIDEServerConfigSchema = lazySchema(() =>
70
  z.object({
71
    type: z.literal('sse-ide'),
72
    url: z.string(),
73
    ideName: z.string(),
74
    ideRunningInWindows: z.boolean().optional(),
75
  }),
76
)
77
 
78
// Internal-only server type for IDE extensions
79
export const McpWebSocketIDEServerConfigSchema = lazySchema(() =>
80
  z.object({
Annotations (click the dots)

MCP (Model Context Protocol) lets external services expose tools to Claude Code. A local Python server, a remote REST API, or a cloud service can all become Claude Code tools by implementing the MCP protocol.

🔑Key Insight

MCP supports 6 transport types — from spawning a local subprocess (`stdio`) to connecting to a cloud service (`claudeai-proxy`). The transport is an implementation detail; tool invocation looks identical from Claude's perspective.

The MCPConnectionManager maintains one persistent connection per server. If a server disconnects, it reconnects with exponential backoff. Tools from all connected servers are merged with built-in tools before each query.

ℹ️Info

MCP servers that need OAuth (e.g., a GitHub integration) declare their auth endpoints in config. Claude Code handles PKCE exchange, token storage, and refresh automatically — the server just receives a bearer token.

KEY TAKEAWAYS
  • MCP supports 6 transport types: stdio, SSE, HTTP, WebSocket, SDK, claudeai-proxy
  • Each MCP server connection is managed independently with reconnect logic
  • OAuth flows for MCP servers use PKCE and are proxied through Claude.ai
  • URL elicitation allows MCP servers to request the user open a browser URL
  • Tools from MCP servers are merged with built-in tools at query time
AI Assistant

Ask anything about MCP Integration — Plugin Protocol

Powered by Groq · Enter to send, Shift+Enter for newline