the claude code sourcemaps leaked march 31
1import type { Client } from '@modelcontextprotocol/sdk/client/index.js'
2import type {
3 Resource,
4 ServerCapabilities,
5} from '@modelcontextprotocol/sdk/types.js'
6import { z } from 'zod/v4'
7import { lazySchema } from '../../utils/lazySchema.js'
8
9// Configuration schemas and types
10export const ConfigScopeSchema = lazySchema(() =>
11 z.enum([
12 'local',
13 'user',
14 'project',
15 'dynamic',
16 'enterprise',
17 'claudeai',
18 'managed',
19 ]),
20)
21export type ConfigScope = z.infer<ReturnType<typeof ConfigScopeSchema>>
22
23export const TransportSchema = lazySchema(() =>
24 z.enum(['stdio', 'sse', 'sse-ide', 'http', 'ws', 'sdk']),
25)
26export type Transport = z.infer<ReturnType<typeof TransportSchema>>
27
28export 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.
41const McpXaaConfigSchema = lazySchema(() => z.boolean())
42
43const 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
58export 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
69export 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
79export const McpWebSocketIDEServerConfigSchema = lazySchema(() =>
80 z.object({
81 type: z.literal('ws-ide'),
82 url: z.string(),
83 ideName: z.string(),
84 authToken: z.string().optional(),
85 ideRunningInWindows: z.boolean().optional(),
86 }),
87)
88
89export const McpHTTPServerConfigSchema = lazySchema(() =>
90 z.object({
91 type: z.literal('http'),
92 url: z.string(),
93 headers: z.record(z.string(), z.string()).optional(),
94 headersHelper: z.string().optional(),
95 oauth: McpOAuthConfigSchema().optional(),
96 }),
97)
98
99export const McpWebSocketServerConfigSchema = lazySchema(() =>
100 z.object({
101 type: z.literal('ws'),
102 url: z.string(),
103 headers: z.record(z.string(), z.string()).optional(),
104 headersHelper: z.string().optional(),
105 }),
106)
107
108export const McpSdkServerConfigSchema = lazySchema(() =>
109 z.object({
110 type: z.literal('sdk'),
111 name: z.string(),
112 }),
113)
114
115// Config type for Claude.ai proxy servers
116export const McpClaudeAIProxyServerConfigSchema = lazySchema(() =>
117 z.object({
118 type: z.literal('claudeai-proxy'),
119 url: z.string(),
120 id: z.string(),
121 }),
122)
123
124export const McpServerConfigSchema = lazySchema(() =>
125 z.union([
126 McpStdioServerConfigSchema(),
127 McpSSEServerConfigSchema(),
128 McpSSEIDEServerConfigSchema(),
129 McpWebSocketIDEServerConfigSchema(),
130 McpHTTPServerConfigSchema(),
131 McpWebSocketServerConfigSchema(),
132 McpSdkServerConfigSchema(),
133 McpClaudeAIProxyServerConfigSchema(),
134 ]),
135)
136
137export type McpStdioServerConfig = z.infer<
138 ReturnType<typeof McpStdioServerConfigSchema>
139>
140export type McpSSEServerConfig = z.infer<
141 ReturnType<typeof McpSSEServerConfigSchema>
142>
143export type McpSSEIDEServerConfig = z.infer<
144 ReturnType<typeof McpSSEIDEServerConfigSchema>
145>
146export type McpWebSocketIDEServerConfig = z.infer<
147 ReturnType<typeof McpWebSocketIDEServerConfigSchema>
148>
149export type McpHTTPServerConfig = z.infer<
150 ReturnType<typeof McpHTTPServerConfigSchema>
151>
152export type McpWebSocketServerConfig = z.infer<
153 ReturnType<typeof McpWebSocketServerConfigSchema>
154>
155export type McpSdkServerConfig = z.infer<
156 ReturnType<typeof McpSdkServerConfigSchema>
157>
158export type McpClaudeAIProxyServerConfig = z.infer<
159 ReturnType<typeof McpClaudeAIProxyServerConfigSchema>
160>
161export type McpServerConfig = z.infer<ReturnType<typeof McpServerConfigSchema>>
162
163export type ScopedMcpServerConfig = McpServerConfig & {
164 scope: ConfigScope
165 // For plugin-provided servers: the providing plugin's LoadedPlugin.source
166 // (e.g. 'slack@anthropic'). Stashed at config-build time so the channel
167 // gate doesn't have to race AppState.plugins.enabled hydration.
168 pluginSource?: string
169}
170
171export const McpJsonConfigSchema = lazySchema(() =>
172 z.object({
173 mcpServers: z.record(z.string(), McpServerConfigSchema()),
174 }),
175)
176
177export type McpJsonConfig = z.infer<ReturnType<typeof McpJsonConfigSchema>>
178
179// Server connection types
180export type ConnectedMCPServer = {
181 client: Client
182 name: string
183 type: 'connected'
184 capabilities: ServerCapabilities
185 serverInfo?: {
186 name: string
187 version: string
188 }
189 instructions?: string
190 config: ScopedMcpServerConfig
191 cleanup: () => Promise<void>
192}
193
194export type FailedMCPServer = {
195 name: string
196 type: 'failed'
197 config: ScopedMcpServerConfig
198 error?: string
199}
200
201export type NeedsAuthMCPServer = {
202 name: string
203 type: 'needs-auth'
204 config: ScopedMcpServerConfig
205}
206
207export type PendingMCPServer = {
208 name: string
209 type: 'pending'
210 config: ScopedMcpServerConfig
211 reconnectAttempt?: number
212 maxReconnectAttempts?: number
213}
214
215export type DisabledMCPServer = {
216 name: string
217 type: 'disabled'
218 config: ScopedMcpServerConfig
219}
220
221export type MCPServerConnection =
222 | ConnectedMCPServer
223 | FailedMCPServer
224 | NeedsAuthMCPServer
225 | PendingMCPServer
226 | DisabledMCPServer
227
228// Resource types
229export type ServerResource = Resource & { server: string }
230
231// MCP CLI State types
232export interface SerializedTool {
233 name: string
234 description: string
235 inputJSONSchema?: {
236 [x: string]: unknown
237 type: 'object'
238 properties?: {
239 [x: string]: unknown
240 }
241 }
242 isMcp?: boolean
243 originalToolName?: string // Original unnormalized tool name from MCP server
244}
245
246export interface SerializedClient {
247 name: string
248 type: 'connected' | 'failed' | 'needs-auth' | 'pending' | 'disabled'
249 capabilities?: ServerCapabilities
250}
251
252export interface MCPCliState {
253 clients: SerializedClient[]
254 configs: Record<string, ScopedMcpServerConfig>
255 tools: SerializedTool[]
256 resources: Record<string, ServerResource[]>
257 normalizedNames?: Record<string, string> // Maps normalized names to original names
258}