@ai-sdk/mcp
Advanced tools
| import { convertUint8ArrayToBase64, isRecord } from '@ai-sdk/provider-utils'; | ||
| type HeaderValueType = 'boolean' | 'integer' | 'string'; | ||
| export type MCPToolHeaderBinding = { | ||
| headerName: string; | ||
| path: string[]; | ||
| valueType: HeaderValueType; | ||
| }; | ||
| export type MCPToolHeaderBindingsResult = | ||
| | { success: true; bindings: MCPToolHeaderBinding[] } | ||
| | { success: false; error: string }; | ||
| const HTTP_TOKEN_PATTERN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; | ||
| const BASE64_SENTINEL_PATTERN = /^=\?base64\?.*\?=$/; | ||
| export function encodeMCPHeaderValue(value: string): string { | ||
| const isPlainAscii = [...value].every(character => { | ||
| const code = character.charCodeAt(0); | ||
| return code === 0x09 || (code >= 0x20 && code <= 0x7e); | ||
| }); | ||
| if ( | ||
| isPlainAscii && | ||
| value.trim() === value && | ||
| !BASE64_SENTINEL_PATTERN.test(value) | ||
| ) { | ||
| return value; | ||
| } | ||
| return `=?base64?${convertUint8ArrayToBase64(new TextEncoder().encode(value))}?=`; | ||
| } | ||
| export function getMCPToolHeaderBindings( | ||
| inputSchema: unknown, | ||
| ): MCPToolHeaderBindingsResult { | ||
| if (!isRecord(inputSchema)) { | ||
| return { | ||
| success: false, | ||
| error: 'inputSchema must be a JSON Schema object', | ||
| }; | ||
| } | ||
| const bindings: MCPToolHeaderBinding[] = []; | ||
| const headerNames = new Set<string>(); | ||
| let error: string | undefined; | ||
| const visit = ( | ||
| value: unknown, | ||
| path: string[], | ||
| staticallyReachable: boolean, | ||
| ): void => { | ||
| if (error != null || !isRecord(value)) { | ||
| return; | ||
| } | ||
| if ('x-mcp-header' in value) { | ||
| if (!staticallyReachable || path.length === 0) { | ||
| error = 'x-mcp-header is not on a statically reachable property'; | ||
| return; | ||
| } | ||
| const headerName = value['x-mcp-header']; | ||
| if ( | ||
| typeof headerName !== 'string' || | ||
| !HTTP_TOKEN_PATTERN.test(headerName) | ||
| ) { | ||
| error = 'x-mcp-header must be a non-empty HTTP token'; | ||
| return; | ||
| } | ||
| const normalizedHeaderName = headerName.toLowerCase(); | ||
| if (headerNames.has(normalizedHeaderName)) { | ||
| error = `x-mcp-header value "${headerName}" is not unique`; | ||
| return; | ||
| } | ||
| const valueType = value.type; | ||
| if ( | ||
| valueType !== 'boolean' && | ||
| valueType !== 'integer' && | ||
| valueType !== 'string' | ||
| ) { | ||
| error = | ||
| 'x-mcp-header can only annotate boolean, integer, or string properties'; | ||
| return; | ||
| } | ||
| headerNames.add(normalizedHeaderName); | ||
| bindings.push({ headerName, path, valueType }); | ||
| } | ||
| for (const [key, child] of Object.entries(value)) { | ||
| if (key === 'x-mcp-header') { | ||
| continue; | ||
| } | ||
| if (key === 'properties' && isRecord(child)) { | ||
| for (const [propertyName, propertySchema] of Object.entries(child)) { | ||
| visit(propertySchema, [...path, propertyName], staticallyReachable); | ||
| } | ||
| } else { | ||
| visit(child, path, false); | ||
| } | ||
| } | ||
| }; | ||
| visit(inputSchema, [], true); | ||
| return error == null | ||
| ? { success: true, bindings } | ||
| : { success: false, error }; | ||
| } | ||
| function getValueAtPath( | ||
| value: Record<string, unknown>, | ||
| path: string[], | ||
| ): unknown { | ||
| let current: unknown = value; | ||
| for (const segment of path) { | ||
| if (!isRecord(current)) { | ||
| return undefined; | ||
| } | ||
| current = current[segment]; | ||
| } | ||
| return current; | ||
| } | ||
| export function createMCPToolHeaders({ | ||
| bindings, | ||
| args, | ||
| }: { | ||
| bindings: MCPToolHeaderBinding[]; | ||
| args: Record<string, unknown>; | ||
| }): Record<string, string> { | ||
| const headers: Record<string, string> = {}; | ||
| for (const binding of bindings) { | ||
| const value = getValueAtPath(args, binding.path); | ||
| if (value == null) { | ||
| continue; | ||
| } | ||
| if ( | ||
| (binding.valueType === 'string' && typeof value !== 'string') || | ||
| (binding.valueType === 'boolean' && typeof value !== 'boolean') || | ||
| (binding.valueType === 'integer' && !Number.isSafeInteger(value)) | ||
| ) { | ||
| throw new TypeError( | ||
| `Tool argument "${binding.path.join('.')}" does not match its x-mcp-header type`, | ||
| ); | ||
| } | ||
| headers[`Mcp-Param-${binding.headerName}`] = encodeMCPHeaderValue( | ||
| String(value), | ||
| ); | ||
| } | ||
| return headers; | ||
| } |
+8
-0
| # @ai-sdk/mcp | ||
| ## 2.0.33 | ||
| ### Patch Changes | ||
| - 1f29230: feat(mcp): harden oauth client registration according to latest protocol | ||
| - 0c60a40: feat(mcp): add mcp 2026 streamable HTTP support | ||
| - e6a9927: feat(mcp): add the latest 2026 protocol discovery foundation | ||
| ## 2.0.32 | ||
@@ -4,0 +12,0 @@ |
+54
-3
@@ -19,2 +19,3 @@ import { z } from 'zod/v4'; | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| }, z.core.$loose>; | ||
@@ -25,3 +26,3 @@ }, z.core.$strict>; | ||
| jsonrpc: z.ZodLiteral<"2.0">; | ||
| id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>; | ||
| id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>; | ||
| error: z.ZodObject<{ | ||
@@ -60,6 +61,7 @@ code: z.ZodNumber; | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| }, z.core.$loose>; | ||
| }, z.core.$strict>, z.ZodObject<{ | ||
| jsonrpc: z.ZodLiteral<"2.0">; | ||
| id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>; | ||
| id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>; | ||
| error: z.ZodObject<{ | ||
@@ -84,2 +86,3 @@ code: z.ZodNumber; | ||
| refresh_token: z.ZodOptional<z.ZodString>; | ||
| issuer: z.ZodOptional<z.ZodString>; | ||
| authorization_server: z.ZodOptional<z.ZodString>; | ||
@@ -93,2 +96,4 @@ token_endpoint: z.ZodOptional<z.ZodString>; | ||
| registration_endpoint: z.ZodOptional<z.ZodString>; | ||
| authorization_response_iss_parameter_supported: z.ZodOptional<z.ZodBoolean>; | ||
| client_id_metadata_document_supported: z.ZodOptional<z.ZodBoolean>; | ||
| scopes_supported: z.ZodOptional<z.ZodArray<z.ZodString>>; | ||
@@ -113,2 +118,4 @@ response_types_supported: z.ZodArray<z.ZodString>; | ||
| registration_endpoint: z.ZodOptional<z.ZodString>; | ||
| authorization_response_iss_parameter_supported: z.ZodOptional<z.ZodBoolean>; | ||
| client_id_metadata_document_supported: z.ZodOptional<z.ZodBoolean>; | ||
| scopes_supported: z.ZodOptional<z.ZodArray<z.ZodString>>; | ||
@@ -128,2 +135,3 @@ response_types_supported: z.ZodArray<z.ZodString>; | ||
| client_secret_expires_at: z.ZodOptional<z.ZodNumber>; | ||
| issuer: z.ZodOptional<z.ZodString>; | ||
| authorization_server: z.ZodOptional<z.ZodString>; | ||
@@ -134,2 +142,3 @@ token_endpoint: z.ZodOptional<z.ZodString>; | ||
| redirect_uris: z.ZodArray<z.ZodString>; | ||
| application_type: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"native">, z.ZodLiteral<"web">]>>; | ||
| token_endpoint_auth_method: z.ZodOptional<z.ZodString>; | ||
@@ -160,2 +169,3 @@ grant_types: z.ZodOptional<z.ZodArray<z.ZodString>>; | ||
| interface OAuthAuthorizationServerInformation { | ||
| issuer?: string; | ||
| authorizationServerUrl: string; | ||
@@ -221,2 +231,6 @@ tokenEndpoint: string; | ||
| callbackState?: string; | ||
| /** | ||
| * Value of the `iss` parameter from the authorization response. | ||
| */ | ||
| callbackIssuer?: string; | ||
| scope?: string; | ||
@@ -237,2 +251,6 @@ resourceMetadataUrl?: URL; | ||
| /** | ||
| * Request-specific HTTP headers produced from MCP tool parameters. | ||
| */ | ||
| headers?: Record<string, string>; | ||
| /** | ||
| * Associates an outgoing message with an incoming request. | ||
@@ -258,2 +276,14 @@ */ | ||
| /** | ||
| * Whether this transport can probe for stateless MCP protocol versions. | ||
| * | ||
| * Custom transports default to the legacy initialization flow unless they | ||
| * explicitly opt in. | ||
| */ | ||
| supportsProtocolVersionDiscovery?: boolean; | ||
| /** | ||
| * Whether this transport mirrors x-mcp-header tool parameters into request | ||
| * headers. | ||
| */ | ||
| supportsMcpToolParameterHeaders?: boolean; | ||
| /** | ||
| * Initialize and start the transport | ||
@@ -412,2 +442,3 @@ */ | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| protocolVersion: z.ZodString; | ||
@@ -447,2 +478,3 @@ capabilities: z.ZodObject<{ | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| nextCursor: z.ZodOptional<z.ZodString>; | ||
@@ -454,3 +486,3 @@ tools: z.ZodArray<z.ZodObject<{ | ||
| inputSchema: z.ZodObject<{ | ||
| type: z.ZodLiteral<"object">; | ||
| type: z.ZodOptional<z.ZodUnknown>; | ||
| properties: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
@@ -468,2 +500,3 @@ }, z.core.$loose>; | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| nextCursor: z.ZodOptional<z.ZodString>; | ||
@@ -482,2 +515,3 @@ resources: z.ZodArray<z.ZodObject<{ | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| content: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{ | ||
@@ -516,2 +550,3 @@ type: z.ZodLiteral<"text">; | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| toolResult: z.ZodUnknown; | ||
@@ -522,2 +557,3 @@ }, z.core.$loose>]>; | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| resourceTemplates: z.ZodArray<z.ZodObject<{ | ||
@@ -534,2 +570,3 @@ uriTemplate: z.ZodString; | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| contents: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{ | ||
@@ -570,2 +607,3 @@ uri: z.ZodString; | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| completion: z.ZodObject<{ | ||
@@ -580,2 +618,3 @@ values: z.ZodArray<z.ZodString>; | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| nextCursor: z.ZodOptional<z.ZodString>; | ||
@@ -596,2 +635,3 @@ prompts: z.ZodArray<z.ZodObject<{ | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| description: z.ZodOptional<z.ZodString>; | ||
@@ -643,2 +683,3 @@ messages: z.ZodArray<z.ZodObject<{ | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| action: z.ZodUnion<readonly [z.ZodLiteral<"accept">, z.ZodLiteral<"decline">, z.ZodLiteral<"cancel">]>; | ||
@@ -653,2 +694,12 @@ content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | ||
| /** | ||
| * Whether transports that support stateless protocol discovery should probe | ||
| * with `server/discover` before falling back to legacy initialization. | ||
| * | ||
| * Disable this for legacy servers that require `initialize` to be the first | ||
| * request. | ||
| * | ||
| * @default true | ||
| */ | ||
| protocolVersionDiscovery?: boolean; | ||
| /** | ||
| * Options that bound or cancel transport startup and the initialize request. | ||
@@ -655,0 +706,0 @@ */ |
@@ -23,6 +23,7 @@ import { IOType } from 'node:child_process'; | ||
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | ||
| resultType: z.ZodOptional<z.ZodString>; | ||
| }, z.core.$loose>; | ||
| }, z.core.$strict>, z.ZodObject<{ | ||
| jsonrpc: z.ZodLiteral<"2.0">; | ||
| id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>; | ||
| id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>; | ||
| error: z.ZodObject<{ | ||
@@ -46,2 +47,6 @@ code: z.ZodNumber; | ||
| /** | ||
| * Request-specific HTTP headers produced from MCP tool parameters. | ||
| */ | ||
| headers?: Record<string, string>; | ||
| /** | ||
| * Associates an outgoing message with an incoming request. | ||
@@ -67,2 +72,14 @@ */ | ||
| /** | ||
| * Whether this transport can probe for stateless MCP protocol versions. | ||
| * | ||
| * Custom transports default to the legacy initialization flow unless they | ||
| * explicitly opt in. | ||
| */ | ||
| supportsProtocolVersionDiscovery?: boolean; | ||
| /** | ||
| * Whether this transport mirrors x-mcp-header tool parameters into request | ||
| * headers. | ||
| */ | ||
| supportsMcpToolParameterHeaders?: boolean; | ||
| /** | ||
| * Initialize and start the transport | ||
@@ -112,2 +129,3 @@ */ | ||
| declare class StdioMCPTransport implements MCPTransport { | ||
| readonly supportsProtocolVersionDiscovery = true; | ||
| private process?; | ||
@@ -114,0 +132,0 @@ private abortController; |
@@ -16,3 +16,5 @@ // src/tool/json-rpc-message.ts | ||
| }); | ||
| var ResultSchema = BaseParamsSchema; | ||
| var ResultSchema = BaseParamsSchema.extend({ | ||
| resultType: z.optional(z.string()) | ||
| }); | ||
| var RequestSchema = z.object({ | ||
@@ -50,2 +52,9 @@ method: z.string(), | ||
| }).loose(); | ||
| var DiscoverResultSchema = ResultSchema.extend({ | ||
| supportedVersions: z.array(z.string()), | ||
| capabilities: ServerCapabilitiesSchema, | ||
| instructions: z.optional(z.string()), | ||
| ttlMs: z.optional(z.number()), | ||
| cacheScope: z.optional(z.union([z.literal("public"), z.literal("private")])) | ||
| }); | ||
| var InitializeResultSchema = ResultSchema.extend({ | ||
@@ -67,6 +76,6 @@ protocolVersion: z.string(), | ||
| description: z.optional(z.string()), | ||
| inputSchema: z.object({ | ||
| type: z.literal("object"), | ||
| inputSchema: z.looseObject({ | ||
| type: z.optional(z.unknown()), | ||
| properties: z.optional(z.object({}).loose()) | ||
| }).loose(), | ||
| }), | ||
| /** | ||
@@ -260,3 +269,3 @@ * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema | ||
| jsonrpc: z2.literal(JSONRPC_VERSION), | ||
| id: z2.union([z2.string(), z2.number().int()]), | ||
| id: z2.optional(z2.union([z2.string(), z2.number().int()])), | ||
| error: z2.object({ | ||
@@ -370,2 +379,3 @@ code: z2.number().int(), | ||
| constructor(server) { | ||
| this.supportsProtocolVersionDiscovery = true; | ||
| this.abortController = new AbortController(); | ||
@@ -372,0 +382,0 @@ this.readBuffer = new ReadBuffer(); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../../src/tool/json-rpc-message.ts","../../src/tool/types.ts","../../src/error/mcp-client-error.ts","../../src/tool/mcp-stdio/create-child-process.ts","../../src/tool/mcp-stdio/get-environment.ts","../../src/tool/mcp-stdio/mcp-stdio-transport.ts"],"sourcesContent":["import { parseJSON } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport { BaseParamsSchema, RequestSchema, ResultSchema } from './types';\n\nconst JSONRPC_VERSION = '2.0';\n\nconst JSONRPCRequestSchema = z\n .object({\n jsonrpc: z.literal(JSONRPC_VERSION),\n id: z.union([z.string(), z.number().int()]),\n })\n .merge(RequestSchema)\n .strict();\n\nexport type JSONRPCRequest = z.infer<typeof JSONRPCRequestSchema>;\n\nconst JSONRPCResponseSchema = z\n .object({\n jsonrpc: z.literal(JSONRPC_VERSION),\n id: z.union([z.string(), z.number().int()]),\n result: ResultSchema,\n })\n .strict();\n\nexport type JSONRPCResponse = z.infer<typeof JSONRPCResponseSchema>;\n\nconst JSONRPCErrorSchema = z\n .object({\n jsonrpc: z.literal(JSONRPC_VERSION),\n id: z.union([z.string(), z.number().int()]),\n error: z.object({\n code: z.number().int(),\n message: z.string(),\n data: z.optional(z.unknown()),\n }),\n })\n .strict();\n\nexport type JSONRPCError = z.infer<typeof JSONRPCErrorSchema>;\n\nconst JSONRPCNotificationSchema = z\n .object({\n jsonrpc: z.literal(JSONRPC_VERSION),\n })\n .merge(\n z.object({\n method: z.string(),\n params: z.optional(BaseParamsSchema),\n }),\n )\n .strict();\n\nexport type JSONRPCNotification = z.infer<typeof JSONRPCNotificationSchema>;\n\nexport const JSONRPCMessageSchema = z.union([\n JSONRPCRequestSchema,\n JSONRPCNotificationSchema,\n JSONRPCResponseSchema,\n JSONRPCErrorSchema,\n]);\n\nexport type JSONRPCMessage = z.infer<typeof JSONRPCMessageSchema>;\n\nexport function validateJSONRPCMessage(message: unknown): JSONRPCMessage {\n return JSONRPCMessageSchema.parse(message);\n}\n\nexport async function parseJSONRPCMessage(\n text: string,\n): Promise<JSONRPCMessage> {\n return validateJSONRPCMessage(await parseJSON({ text }));\n}\n","import { z } from 'zod/v4';\nimport type { JSONObject } from '@ai-sdk/provider';\nimport type { FlexibleSchema, Tool } from '@ai-sdk/provider-utils';\n\nexport const LATEST_PROTOCOL_VERSION = '2025-11-25';\nexport const SUPPORTED_PROTOCOL_VERSIONS = [\n LATEST_PROTOCOL_VERSION,\n '2025-06-18',\n '2025-03-26',\n '2024-11-05',\n];\n\nexport type McpProviderMetadata = {\n clientName?: string;\n title?: string;\n toolName?: string;\n app?: JSONObject;\n};\n\n/** MCP tool metadata - keys should follow MCP _meta key format specification */\nconst ToolMetaSchema = z.optional(z.record(z.string(), z.unknown()));\nexport type ToolMeta = z.infer<typeof ToolMetaSchema>;\n\nexport type ToolSchemas =\n | Record<\n string,\n {\n inputSchema: FlexibleSchema<JSONObject | unknown>;\n outputSchema?: FlexibleSchema<JSONObject | unknown>;\n }\n >\n | 'automatic'\n | undefined;\n\n/** Base MCP tool type with execute and _meta */\ntype McpToolBase<INPUT = unknown, OUTPUT = CallToolResult> = Tool<\n INPUT,\n OUTPUT\n> &\n Required<Pick<Tool<INPUT, OUTPUT>, 'execute'>> & {\n _meta?: ToolMeta;\n };\n\nexport type McpToolSet<TOOL_SCHEMAS extends ToolSchemas = 'automatic'> =\n TOOL_SCHEMAS extends Record<\n string,\n { inputSchema: FlexibleSchema<any>; outputSchema?: FlexibleSchema<any> }\n >\n ? {\n [K in keyof TOOL_SCHEMAS]: TOOL_SCHEMAS[K] extends {\n inputSchema: FlexibleSchema<infer INPUT>;\n outputSchema: FlexibleSchema<infer OUTPUT>;\n }\n ? McpToolBase<INPUT, OUTPUT>\n : TOOL_SCHEMAS[K] extends {\n inputSchema: FlexibleSchema<infer INPUT>;\n }\n ? McpToolBase<INPUT, CallToolResult>\n : never;\n }\n : Record<string, McpToolBase<unknown, CallToolResult>>;\n\nconst ClientOrServerImplementationSchema = z.looseObject({\n name: z.string(),\n version: z.string(),\n title: z.optional(z.string()),\n});\n\n// Maps to `Implementation` in the MCP specification\nexport type Configuration = z.infer<typeof ClientOrServerImplementationSchema>;\n\nexport const BaseParamsSchema = z.looseObject({\n _meta: z.optional(z.object({}).loose()),\n});\ntype BaseParams = z.infer<typeof BaseParamsSchema>;\nexport const ResultSchema = BaseParamsSchema;\n\nexport const RequestSchema = z.object({\n method: z.string(),\n params: z.optional(BaseParamsSchema),\n});\nexport type Request = z.infer<typeof RequestSchema>;\nexport type RequestOptions = {\n signal?: AbortSignal;\n timeout?: number;\n maxTotalTimeout?: number;\n};\n\nexport type Notification = z.infer<typeof RequestSchema>;\n\n/** @see https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation */\nconst ElicitationCapabilitySchema = z\n .object({\n applyDefaults: z.optional(z.boolean()),\n })\n .loose();\n\nconst ServerCapabilitiesSchema = z.looseObject({\n experimental: z.optional(z.object({}).loose()),\n logging: z.optional(z.object({}).loose()),\n completions: z.optional(z.object({}).loose()),\n prompts: z.optional(\n z.looseObject({\n listChanged: z.optional(z.boolean()),\n }),\n ),\n resources: z.optional(\n z.looseObject({\n subscribe: z.optional(z.boolean()),\n listChanged: z.optional(z.boolean()),\n }),\n ),\n tools: z.optional(\n z.looseObject({\n listChanged: z.optional(z.boolean()),\n }),\n ),\n elicitation: z.optional(ElicitationCapabilitySchema),\n});\n\nexport type ServerCapabilities = z.infer<typeof ServerCapabilitiesSchema>;\nexport const ClientCapabilitiesSchema = z\n .object({\n elicitation: z.optional(ElicitationCapabilitySchema),\n })\n .loose();\n\nexport type ClientCapabilities = z.infer<typeof ClientCapabilitiesSchema>;\nexport type ElicitationCapability = z.infer<typeof ElicitationCapabilitySchema>;\n\nexport const InitializeResultSchema = ResultSchema.extend({\n protocolVersion: z.string(),\n capabilities: ServerCapabilitiesSchema,\n serverInfo: ClientOrServerImplementationSchema,\n instructions: z.optional(z.string()),\n});\nexport type InitializeResult = z.infer<typeof InitializeResultSchema>;\n\nexport type PaginatedRequest = Request & {\n params?: BaseParams & {\n cursor?: string;\n };\n};\n\nconst PaginatedResultSchema = ResultSchema.extend({\n nextCursor: z.optional(z.string()),\n});\n\nconst ToolSchema = z\n .object({\n name: z.string(),\n /**\n * @see https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool\n */\n title: z.optional(z.string()),\n description: z.optional(z.string()),\n inputSchema: z\n .object({\n type: z.literal('object'),\n properties: z.optional(z.object({}).loose()),\n })\n .loose(),\n /**\n * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema\n */\n outputSchema: z.optional(z.object({}).loose()),\n annotations: z.optional(\n z\n .object({\n title: z.optional(z.string()),\n })\n .loose(),\n ),\n _meta: ToolMetaSchema,\n })\n .loose();\nexport type MCPTool = z.infer<typeof ToolSchema>;\nexport const ListToolsResultSchema = PaginatedResultSchema.extend({\n tools: z.array(ToolSchema),\n});\nexport type ListToolsResult = z.infer<typeof ListToolsResultSchema>;\n\nconst TextContentSchema = z\n .object({\n type: z.literal('text'),\n text: z.string(),\n })\n .loose();\nconst ImageContentSchema = z\n .object({\n type: z.literal('image'),\n data: z.base64(),\n mimeType: z.string(),\n })\n .loose();\nexport const ResourceSchema = z\n .object({\n uri: z.string(),\n name: z.string(),\n title: z.optional(z.string()),\n description: z.optional(z.string()),\n mimeType: z.optional(z.string()),\n size: z.optional(z.number()),\n })\n .loose();\nexport type MCPResource = z.infer<typeof ResourceSchema>;\n\nexport const ListResourcesResultSchema = PaginatedResultSchema.extend({\n resources: z.array(ResourceSchema),\n});\nexport type ListResourcesResult = z.infer<typeof ListResourcesResultSchema>;\n\nconst ResourceContentsSchema = z\n .object({\n /**\n * The URI of this resource.\n */\n uri: z.string(),\n /**\n * Optional display name of the resource content.\n */\n name: z.optional(z.string()),\n /**\n * Optional human readable title.\n */\n title: z.optional(z.string()),\n /**\n * The MIME type of this resource, if known.\n */\n mimeType: z.optional(z.string()),\n })\n .loose();\nconst TextResourceContentsSchema = ResourceContentsSchema.extend({\n text: z.string(),\n});\nconst BlobResourceContentsSchema = ResourceContentsSchema.extend({\n blob: z.base64(),\n});\nconst EmbeddedResourceSchema = z\n .object({\n type: z.literal('resource'),\n resource: z.union([TextResourceContentsSchema, BlobResourceContentsSchema]),\n })\n .loose();\nconst ResourceLinkContentSchema = z\n .object({\n type: z.literal('resource_link'),\n uri: z.string(),\n name: z.string(),\n description: z.optional(z.string()),\n mimeType: z.optional(z.string()),\n })\n .loose();\n\nexport const CallToolResultSchema = ResultSchema.extend({\n content: z.array(\n z.union([\n TextContentSchema,\n ImageContentSchema,\n EmbeddedResourceSchema,\n ResourceLinkContentSchema,\n ]),\n ),\n /**\n * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content\n */\n structuredContent: z.optional(z.unknown()),\n isError: z.boolean().default(false).optional(),\n}).or(\n ResultSchema.extend({\n toolResult: z.unknown(),\n }),\n);\nexport type CallToolResult = z.infer<typeof CallToolResultSchema>;\n\nconst ResourceTemplateSchema = z\n .object({\n uriTemplate: z.string(),\n name: z.string(),\n title: z.optional(z.string()),\n description: z.optional(z.string()),\n mimeType: z.optional(z.string()),\n })\n .loose();\n\nexport const ListResourceTemplatesResultSchema = ResultSchema.extend({\n resourceTemplates: z.array(ResourceTemplateSchema),\n});\nexport type ListResourceTemplatesResult = z.infer<\n typeof ListResourceTemplatesResultSchema\n>;\n\nexport const ReadResourceResultSchema = ResultSchema.extend({\n contents: z.array(\n z.union([TextResourceContentsSchema, BlobResourceContentsSchema]),\n ),\n});\nexport type ReadResourceResult = z.infer<typeof ReadResourceResultSchema>;\n\n// Completions\nconst PromptReferenceSchema = z\n .object({\n type: z.literal('ref/prompt'),\n name: z.string(),\n })\n .loose();\n\nconst ResourceReferenceSchema = z\n .object({\n type: z.literal('ref/resource'),\n uri: z.string(),\n })\n .loose();\n\nconst CompletionArgumentSchema = z\n .object({\n name: z.string(),\n value: z.string(),\n })\n .loose();\n\nexport const CompleteRequestParamsSchema = BaseParamsSchema.extend({\n ref: z.union([PromptReferenceSchema, ResourceReferenceSchema]),\n argument: CompletionArgumentSchema,\n context: z.optional(\n z\n .object({\n arguments: z.record(z.string(), z.string()),\n })\n .loose(),\n ),\n});\nexport type CompleteRequestParams = z.infer<typeof CompleteRequestParamsSchema>;\n\nexport const CompleteResultSchema = ResultSchema.extend({\n completion: z\n .object({\n values: z.array(z.string()).max(100),\n total: z.optional(z.number().int()),\n hasMore: z.optional(z.boolean()),\n })\n .loose(),\n});\nexport type CompleteResult = z.infer<typeof CompleteResultSchema>;\n\n// Prompts\nconst PromptArgumentSchema = z\n .object({\n name: z.string(),\n description: z.optional(z.string()),\n required: z.optional(z.boolean()),\n })\n .loose();\n\nexport const PromptSchema = z\n .object({\n name: z.string(),\n title: z.optional(z.string()),\n description: z.optional(z.string()),\n arguments: z.optional(z.array(PromptArgumentSchema)),\n })\n .loose();\nexport type MCPPrompt = z.infer<typeof PromptSchema>;\n\nexport const ListPromptsResultSchema = PaginatedResultSchema.extend({\n prompts: z.array(PromptSchema),\n});\nexport type ListPromptsResult = z.infer<typeof ListPromptsResultSchema>;\n\nconst PromptMessageSchema = z\n .object({\n role: z.union([z.literal('user'), z.literal('assistant')]),\n content: z.union([\n TextContentSchema,\n ImageContentSchema,\n EmbeddedResourceSchema,\n ResourceLinkContentSchema,\n ]),\n })\n .loose();\nexport type MCPPromptMessage = z.infer<typeof PromptMessageSchema>;\n\nexport const GetPromptResultSchema = ResultSchema.extend({\n description: z.optional(z.string()),\n messages: z.array(PromptMessageSchema),\n});\nexport type GetPromptResult = z.infer<typeof GetPromptResultSchema>;\n\nconst ElicitationRequestParamsSchema = BaseParamsSchema.extend({\n message: z.string(),\n requestedSchema: z.unknown(),\n});\n\nexport const ElicitationRequestSchema = RequestSchema.extend({\n method: z.literal('elicitation/create'),\n params: ElicitationRequestParamsSchema,\n});\n\nexport type ElicitationRequest = z.infer<typeof ElicitationRequestSchema>;\n\nexport const ElicitResultSchema = ResultSchema.extend({\n action: z.union([\n z.literal('accept'),\n z.literal('decline'),\n z.literal('cancel'),\n ]),\n content: z.optional(z.record(z.string(), z.unknown())),\n});\n\nexport type ElicitResult = z.infer<typeof ElicitResultSchema>;\n","import { AISDKError } from '@ai-sdk/provider';\n\nconst name = 'AI_MCPClientError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * An error occurred with the MCP client.\n */\nexport class MCPClientError extends AISDKError {\n private readonly [symbol] = true;\n readonly data?: unknown;\n\n /**\n * JSON-RPC error code from the server response, per the JSON-RPC 2.0\n * spec (e.g. `-32601` method-not-found, `-32602` invalid-params, or\n * MCP-specific codes such as `-32002` resource-not-found). This is the\n * application-level error code populated from `error.code` in the\n * server's JSON-RPC error payload. Distinct from `statusCode`, which\n * is the HTTP transport status.\n */\n readonly code?: number;\n\n /**\n * HTTP status code from the failed response, when the error originated\n * from the streamable HTTP transport. Undefined for stdio transport\n * errors and for failures that do not have an associated response\n * status (e.g. network errors, abort). Distinct from `code`, which is\n * the JSON-RPC application error code.\n */\n readonly statusCode?: number;\n\n /**\n * URL of the MCP endpoint the failing request was sent to, when the\n * error originated from an HTTP transport failure.\n */\n readonly url?: string;\n\n /**\n * Body of the failing HTTP response, decoded as text, when available.\n * Undefined when the body could not be read or the error did not have\n * an associated response.\n */\n readonly responseBody?: string;\n\n constructor({\n name = 'MCPClientError',\n message,\n cause,\n data,\n code,\n statusCode,\n url,\n responseBody,\n }: {\n name?: string;\n message: string;\n cause?: unknown;\n data?: unknown;\n code?: number;\n statusCode?: number;\n url?: string;\n responseBody?: string;\n }) {\n super({ name, message, cause });\n this.data = data;\n this.code = code;\n this.statusCode = statusCode;\n this.url = url;\n this.responseBody = responseBody;\n }\n\n static isInstance(error: unknown): error is MCPClientError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { getEnvironment } from './get-environment';\nimport type { StdioConfig } from './mcp-stdio-transport';\n\nexport function createChildProcess(\n config: StdioConfig,\n signal: AbortSignal,\n): ChildProcess {\n return spawn(config.command, config.args ?? [], {\n env: getEnvironment(config.env),\n stdio: ['pipe', 'pipe', config.stderr ?? 'inherit'],\n shell: false,\n signal,\n windowsHide: globalThis.process.platform === 'win32' && isElectron(),\n cwd: config.cwd,\n });\n}\n\nfunction isElectron() {\n return 'type' in globalThis.process;\n}\n","/**\n * Constructs the environment variables for the child process.\n *\n * @param customEnv - Custom environment variables to merge with default environment variables.\n * @returns The environment variables for the child process.\n */\nexport function getEnvironment(\n customEnv?: Record<string, string>,\n): Record<string, string> {\n const DEFAULT_INHERITED_ENV_VARS =\n globalThis.process.platform === 'win32'\n ? [\n 'APPDATA',\n 'HOMEDRIVE',\n 'HOMEPATH',\n 'LOCALAPPDATA',\n 'PATH',\n 'PROCESSOR_ARCHITECTURE',\n 'SYSTEMDRIVE',\n 'SYSTEMROOT',\n 'TEMP',\n 'USERNAME',\n 'USERPROFILE',\n ]\n : ['HOME', 'LOGNAME', 'PATH', 'SHELL', 'TERM', 'USER'];\n\n const env: Record<string, string> = customEnv ? { ...customEnv } : {};\n\n for (const key of DEFAULT_INHERITED_ENV_VARS) {\n const value = globalThis.process.env[key];\n if (value === undefined) {\n continue;\n }\n\n if (value.startsWith('()')) {\n continue;\n }\n\n env[key] = value;\n }\n\n return env;\n}\n","import type { ChildProcess, IOType } from 'node:child_process';\nimport type { Stream } from 'node:stream';\nimport { parseJSONRPCMessage, type JSONRPCMessage } from '../json-rpc-message';\nimport type { MCPTransport } from '../mcp-transport';\nimport { MCPClientError } from '../../error/mcp-client-error';\nimport { createChildProcess } from './create-child-process';\n\nexport interface StdioConfig {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n stderr?: IOType | Stream | number;\n cwd?: string;\n}\n\nexport class StdioMCPTransport implements MCPTransport {\n private process?: ChildProcess;\n private abortController: AbortController = new AbortController();\n private readBuffer: ReadBuffer = new ReadBuffer();\n private serverParams: StdioConfig;\n\n onclose?: () => void;\n onerror?: (error: unknown) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n constructor(server: StdioConfig) {\n this.serverParams = server;\n }\n\n async start(): Promise<void> {\n if (this.process) {\n throw new MCPClientError({\n message: 'StdioMCPTransport already started.',\n });\n }\n\n return new Promise((resolve, reject) => {\n try {\n const process = createChildProcess(\n this.serverParams,\n this.abortController.signal,\n );\n\n this.process = process;\n\n this.process.on('error', error => {\n if (error.name === 'AbortError') {\n this.onclose?.();\n return;\n }\n\n reject(error);\n this.onerror?.(error);\n });\n\n this.process.on('spawn', () => {\n resolve();\n });\n\n this.process.on('close', _code => {\n this.process = undefined;\n this.onclose?.();\n });\n\n this.process.stdin?.on('error', error => {\n this.onerror?.(error);\n });\n\n this.process.stdout?.on('data', chunk => {\n this.readBuffer.append(chunk);\n void this.processReadBuffer();\n });\n\n this.process.stdout?.on('error', error => {\n this.onerror?.(error);\n });\n } catch (error) {\n reject(error);\n this.onerror?.(error);\n }\n });\n }\n\n private async processReadBuffer() {\n while (true) {\n const line = this.readBuffer.readLine();\n if (line === null) {\n break;\n }\n\n try {\n const message = await deserializeMessage(line);\n this.onmessage?.(message);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n }\n\n async close(): Promise<void> {\n this.abortController.abort();\n this.process = undefined;\n this.readBuffer.clear();\n }\n\n send(message: JSONRPCMessage): Promise<void> {\n return new Promise(resolve => {\n if (!this.process?.stdin) {\n throw new MCPClientError({\n message: 'StdioClientTransport not connected',\n });\n }\n\n const json = serializeMessage(message);\n if (this.process.stdin.write(json)) {\n resolve();\n } else {\n this.process.stdin.once('drain', resolve);\n }\n });\n }\n}\n\nclass ReadBuffer {\n private buffer?: Buffer;\n\n append(chunk: Buffer): void {\n this.buffer = this.buffer ? Buffer.concat([this.buffer, chunk]) : chunk;\n }\n\n readLine(): string | null {\n if (!this.buffer) return null;\n\n const index = this.buffer.indexOf('\\n');\n if (index === -1) {\n return null;\n }\n\n const line = this.buffer.toString('utf8', 0, index);\n this.buffer = this.buffer.subarray(index + 1);\n return line;\n }\n\n clear(): void {\n this.buffer = undefined;\n }\n}\n\nfunction serializeMessage(message: JSONRPCMessage): string {\n return JSON.stringify(message) + '\\n';\n}\n\nexport async function deserializeMessage(\n line: string,\n): Promise<JSONRPCMessage> {\n return parseJSONRPCMessage(line);\n}\n"],"mappings":"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","names":["z","z","name","_a","_b","_a","_b"]} | ||
| {"version":3,"sources":["../../src/tool/json-rpc-message.ts","../../src/tool/types.ts","../../src/error/mcp-client-error.ts","../../src/tool/mcp-stdio/create-child-process.ts","../../src/tool/mcp-stdio/get-environment.ts","../../src/tool/mcp-stdio/mcp-stdio-transport.ts"],"sourcesContent":["import { parseJSON } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport { BaseParamsSchema, RequestSchema, ResultSchema } from './types';\n\nconst JSONRPC_VERSION = '2.0';\n\nconst JSONRPCRequestSchema = z\n .object({\n jsonrpc: z.literal(JSONRPC_VERSION),\n id: z.union([z.string(), z.number().int()]),\n })\n .merge(RequestSchema)\n .strict();\n\nexport type JSONRPCRequest = z.infer<typeof JSONRPCRequestSchema>;\n\nconst JSONRPCResponseSchema = z\n .object({\n jsonrpc: z.literal(JSONRPC_VERSION),\n id: z.union([z.string(), z.number().int()]),\n result: ResultSchema,\n })\n .strict();\n\nexport type JSONRPCResponse = z.infer<typeof JSONRPCResponseSchema>;\n\nconst JSONRPCErrorSchema = z\n .object({\n jsonrpc: z.literal(JSONRPC_VERSION),\n id: z.optional(z.union([z.string(), z.number().int()])),\n error: z.object({\n code: z.number().int(),\n message: z.string(),\n data: z.optional(z.unknown()),\n }),\n })\n .strict();\n\nexport type JSONRPCError = z.infer<typeof JSONRPCErrorSchema>;\n\nconst JSONRPCNotificationSchema = z\n .object({\n jsonrpc: z.literal(JSONRPC_VERSION),\n })\n .merge(\n z.object({\n method: z.string(),\n params: z.optional(BaseParamsSchema),\n }),\n )\n .strict();\n\nexport type JSONRPCNotification = z.infer<typeof JSONRPCNotificationSchema>;\n\nexport const JSONRPCMessageSchema = z.union([\n JSONRPCRequestSchema,\n JSONRPCNotificationSchema,\n JSONRPCResponseSchema,\n JSONRPCErrorSchema,\n]);\n\nexport type JSONRPCMessage = z.infer<typeof JSONRPCMessageSchema>;\n\nexport function validateJSONRPCMessage(message: unknown): JSONRPCMessage {\n return JSONRPCMessageSchema.parse(message);\n}\n\nexport async function parseJSONRPCMessage(\n text: string,\n): Promise<JSONRPCMessage> {\n return validateJSONRPCMessage(await parseJSON({ text }));\n}\n","import { z } from 'zod/v4';\nimport type { JSONObject } from '@ai-sdk/provider';\nimport type { FlexibleSchema, Tool } from '@ai-sdk/provider-utils';\n\nexport const LATEST_PROTOCOL_VERSION = '2026-07-28';\nexport const LATEST_LEGACY_PROTOCOL_VERSION = '2025-11-25';\nexport const SUPPORTED_PROTOCOL_VERSIONS = [\n LATEST_PROTOCOL_VERSION,\n LATEST_LEGACY_PROTOCOL_VERSION,\n '2025-06-18',\n '2025-03-26',\n '2024-11-05',\n];\n\nexport type McpProviderMetadata = {\n clientName?: string;\n title?: string;\n toolName?: string;\n app?: JSONObject;\n};\n\n/** MCP tool metadata - keys should follow MCP _meta key format specification */\nconst ToolMetaSchema = z.optional(z.record(z.string(), z.unknown()));\nexport type ToolMeta = z.infer<typeof ToolMetaSchema>;\n\nexport type ToolSchemas =\n | Record<\n string,\n {\n inputSchema: FlexibleSchema<JSONObject | unknown>;\n outputSchema?: FlexibleSchema<JSONObject | unknown>;\n }\n >\n | 'automatic'\n | undefined;\n\n/** Base MCP tool type with execute and _meta */\ntype McpToolBase<INPUT = unknown, OUTPUT = CallToolResult> = Tool<\n INPUT,\n OUTPUT\n> &\n Required<Pick<Tool<INPUT, OUTPUT>, 'execute'>> & {\n _meta?: ToolMeta;\n };\n\nexport type McpToolSet<TOOL_SCHEMAS extends ToolSchemas = 'automatic'> =\n TOOL_SCHEMAS extends Record<\n string,\n { inputSchema: FlexibleSchema<any>; outputSchema?: FlexibleSchema<any> }\n >\n ? {\n [K in keyof TOOL_SCHEMAS]: TOOL_SCHEMAS[K] extends {\n inputSchema: FlexibleSchema<infer INPUT>;\n outputSchema: FlexibleSchema<infer OUTPUT>;\n }\n ? McpToolBase<INPUT, OUTPUT>\n : TOOL_SCHEMAS[K] extends {\n inputSchema: FlexibleSchema<infer INPUT>;\n }\n ? McpToolBase<INPUT, CallToolResult>\n : never;\n }\n : Record<string, McpToolBase<unknown, CallToolResult>>;\n\nconst ClientOrServerImplementationSchema = z.looseObject({\n name: z.string(),\n version: z.string(),\n title: z.optional(z.string()),\n});\n\n// Maps to `Implementation` in the MCP specification\nexport type Configuration = z.infer<typeof ClientOrServerImplementationSchema>;\n\nexport const BaseParamsSchema = z.looseObject({\n _meta: z.optional(z.object({}).loose()),\n});\ntype BaseParams = z.infer<typeof BaseParamsSchema>;\nexport const ResultSchema = BaseParamsSchema.extend({\n resultType: z.optional(z.string()),\n});\n\nexport const RequestSchema = z.object({\n method: z.string(),\n params: z.optional(BaseParamsSchema),\n});\nexport type Request = z.infer<typeof RequestSchema>;\nexport type RequestOptions = {\n signal?: AbortSignal;\n timeout?: number;\n maxTotalTimeout?: number;\n};\n\nexport type Notification = z.infer<typeof RequestSchema>;\n\n/** @see https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation */\nconst ElicitationCapabilitySchema = z\n .object({\n applyDefaults: z.optional(z.boolean()),\n })\n .loose();\n\nconst ServerCapabilitiesSchema = z.looseObject({\n experimental: z.optional(z.object({}).loose()),\n logging: z.optional(z.object({}).loose()),\n completions: z.optional(z.object({}).loose()),\n prompts: z.optional(\n z.looseObject({\n listChanged: z.optional(z.boolean()),\n }),\n ),\n resources: z.optional(\n z.looseObject({\n subscribe: z.optional(z.boolean()),\n listChanged: z.optional(z.boolean()),\n }),\n ),\n tools: z.optional(\n z.looseObject({\n listChanged: z.optional(z.boolean()),\n }),\n ),\n elicitation: z.optional(ElicitationCapabilitySchema),\n});\n\nexport type ServerCapabilities = z.infer<typeof ServerCapabilitiesSchema>;\nexport const ClientCapabilitiesSchema = z\n .object({\n elicitation: z.optional(ElicitationCapabilitySchema),\n })\n .loose();\n\nexport type ClientCapabilities = z.infer<typeof ClientCapabilitiesSchema>;\nexport type ElicitationCapability = z.infer<typeof ElicitationCapabilitySchema>;\n\nexport const DiscoverResultSchema = ResultSchema.extend({\n supportedVersions: z.array(z.string()),\n capabilities: ServerCapabilitiesSchema,\n instructions: z.optional(z.string()),\n ttlMs: z.optional(z.number()),\n cacheScope: z.optional(z.union([z.literal('public'), z.literal('private')])),\n});\nexport type DiscoverResult = z.infer<typeof DiscoverResultSchema>;\n\nexport const InitializeResultSchema = ResultSchema.extend({\n protocolVersion: z.string(),\n capabilities: ServerCapabilitiesSchema,\n serverInfo: ClientOrServerImplementationSchema,\n instructions: z.optional(z.string()),\n});\nexport type InitializeResult = z.infer<typeof InitializeResultSchema>;\n\nexport type PaginatedRequest = Request & {\n params?: BaseParams & {\n cursor?: string;\n };\n};\n\nconst PaginatedResultSchema = ResultSchema.extend({\n nextCursor: z.optional(z.string()),\n});\n\nconst ToolSchema = z\n .object({\n name: z.string(),\n /**\n * @see https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool\n */\n title: z.optional(z.string()),\n description: z.optional(z.string()),\n inputSchema: z.looseObject({\n type: z.optional(z.unknown()),\n properties: z.optional(z.object({}).loose()),\n }),\n /**\n * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema\n */\n outputSchema: z.optional(z.object({}).loose()),\n annotations: z.optional(\n z\n .object({\n title: z.optional(z.string()),\n })\n .loose(),\n ),\n _meta: ToolMetaSchema,\n })\n .loose();\nexport type MCPTool = z.infer<typeof ToolSchema>;\nexport const ListToolsResultSchema = PaginatedResultSchema.extend({\n tools: z.array(ToolSchema),\n});\nexport type ListToolsResult = z.infer<typeof ListToolsResultSchema>;\n\nconst TextContentSchema = z\n .object({\n type: z.literal('text'),\n text: z.string(),\n })\n .loose();\nconst ImageContentSchema = z\n .object({\n type: z.literal('image'),\n data: z.base64(),\n mimeType: z.string(),\n })\n .loose();\nexport const ResourceSchema = z\n .object({\n uri: z.string(),\n name: z.string(),\n title: z.optional(z.string()),\n description: z.optional(z.string()),\n mimeType: z.optional(z.string()),\n size: z.optional(z.number()),\n })\n .loose();\nexport type MCPResource = z.infer<typeof ResourceSchema>;\n\nexport const ListResourcesResultSchema = PaginatedResultSchema.extend({\n resources: z.array(ResourceSchema),\n});\nexport type ListResourcesResult = z.infer<typeof ListResourcesResultSchema>;\n\nconst ResourceContentsSchema = z\n .object({\n /**\n * The URI of this resource.\n */\n uri: z.string(),\n /**\n * Optional display name of the resource content.\n */\n name: z.optional(z.string()),\n /**\n * Optional human readable title.\n */\n title: z.optional(z.string()),\n /**\n * The MIME type of this resource, if known.\n */\n mimeType: z.optional(z.string()),\n })\n .loose();\nconst TextResourceContentsSchema = ResourceContentsSchema.extend({\n text: z.string(),\n});\nconst BlobResourceContentsSchema = ResourceContentsSchema.extend({\n blob: z.base64(),\n});\nconst EmbeddedResourceSchema = z\n .object({\n type: z.literal('resource'),\n resource: z.union([TextResourceContentsSchema, BlobResourceContentsSchema]),\n })\n .loose();\nconst ResourceLinkContentSchema = z\n .object({\n type: z.literal('resource_link'),\n uri: z.string(),\n name: z.string(),\n description: z.optional(z.string()),\n mimeType: z.optional(z.string()),\n })\n .loose();\n\nexport const CallToolResultSchema = ResultSchema.extend({\n content: z.array(\n z.union([\n TextContentSchema,\n ImageContentSchema,\n EmbeddedResourceSchema,\n ResourceLinkContentSchema,\n ]),\n ),\n /**\n * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content\n */\n structuredContent: z.optional(z.unknown()),\n isError: z.boolean().default(false).optional(),\n}).or(\n ResultSchema.extend({\n toolResult: z.unknown(),\n }),\n);\nexport type CallToolResult = z.infer<typeof CallToolResultSchema>;\n\nconst ResourceTemplateSchema = z\n .object({\n uriTemplate: z.string(),\n name: z.string(),\n title: z.optional(z.string()),\n description: z.optional(z.string()),\n mimeType: z.optional(z.string()),\n })\n .loose();\n\nexport const ListResourceTemplatesResultSchema = ResultSchema.extend({\n resourceTemplates: z.array(ResourceTemplateSchema),\n});\nexport type ListResourceTemplatesResult = z.infer<\n typeof ListResourceTemplatesResultSchema\n>;\n\nexport const ReadResourceResultSchema = ResultSchema.extend({\n contents: z.array(\n z.union([TextResourceContentsSchema, BlobResourceContentsSchema]),\n ),\n});\nexport type ReadResourceResult = z.infer<typeof ReadResourceResultSchema>;\n\n// Completions\nconst PromptReferenceSchema = z\n .object({\n type: z.literal('ref/prompt'),\n name: z.string(),\n })\n .loose();\n\nconst ResourceReferenceSchema = z\n .object({\n type: z.literal('ref/resource'),\n uri: z.string(),\n })\n .loose();\n\nconst CompletionArgumentSchema = z\n .object({\n name: z.string(),\n value: z.string(),\n })\n .loose();\n\nexport const CompleteRequestParamsSchema = BaseParamsSchema.extend({\n ref: z.union([PromptReferenceSchema, ResourceReferenceSchema]),\n argument: CompletionArgumentSchema,\n context: z.optional(\n z\n .object({\n arguments: z.record(z.string(), z.string()),\n })\n .loose(),\n ),\n});\nexport type CompleteRequestParams = z.infer<typeof CompleteRequestParamsSchema>;\n\nexport const CompleteResultSchema = ResultSchema.extend({\n completion: z\n .object({\n values: z.array(z.string()).max(100),\n total: z.optional(z.number().int()),\n hasMore: z.optional(z.boolean()),\n })\n .loose(),\n});\nexport type CompleteResult = z.infer<typeof CompleteResultSchema>;\n\n// Prompts\nconst PromptArgumentSchema = z\n .object({\n name: z.string(),\n description: z.optional(z.string()),\n required: z.optional(z.boolean()),\n })\n .loose();\n\nexport const PromptSchema = z\n .object({\n name: z.string(),\n title: z.optional(z.string()),\n description: z.optional(z.string()),\n arguments: z.optional(z.array(PromptArgumentSchema)),\n })\n .loose();\nexport type MCPPrompt = z.infer<typeof PromptSchema>;\n\nexport const ListPromptsResultSchema = PaginatedResultSchema.extend({\n prompts: z.array(PromptSchema),\n});\nexport type ListPromptsResult = z.infer<typeof ListPromptsResultSchema>;\n\nconst PromptMessageSchema = z\n .object({\n role: z.union([z.literal('user'), z.literal('assistant')]),\n content: z.union([\n TextContentSchema,\n ImageContentSchema,\n EmbeddedResourceSchema,\n ResourceLinkContentSchema,\n ]),\n })\n .loose();\nexport type MCPPromptMessage = z.infer<typeof PromptMessageSchema>;\n\nexport const GetPromptResultSchema = ResultSchema.extend({\n description: z.optional(z.string()),\n messages: z.array(PromptMessageSchema),\n});\nexport type GetPromptResult = z.infer<typeof GetPromptResultSchema>;\n\nconst ElicitationRequestParamsSchema = BaseParamsSchema.extend({\n message: z.string(),\n requestedSchema: z.unknown(),\n});\n\nexport const ElicitationRequestSchema = RequestSchema.extend({\n method: z.literal('elicitation/create'),\n params: ElicitationRequestParamsSchema,\n});\n\nexport type ElicitationRequest = z.infer<typeof ElicitationRequestSchema>;\n\nexport const ElicitResultSchema = ResultSchema.extend({\n action: z.union([\n z.literal('accept'),\n z.literal('decline'),\n z.literal('cancel'),\n ]),\n content: z.optional(z.record(z.string(), z.unknown())),\n});\n\nexport type ElicitResult = z.infer<typeof ElicitResultSchema>;\n","import { AISDKError } from '@ai-sdk/provider';\n\nconst name = 'AI_MCPClientError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * An error occurred with the MCP client.\n */\nexport class MCPClientError extends AISDKError {\n private readonly [symbol] = true;\n readonly data?: unknown;\n\n /**\n * JSON-RPC error code from the server response, per the JSON-RPC 2.0\n * spec (e.g. `-32601` method-not-found, `-32602` invalid-params, or\n * MCP-specific codes such as `-32002` resource-not-found). This is the\n * application-level error code populated from `error.code` in the\n * server's JSON-RPC error payload. Distinct from `statusCode`, which\n * is the HTTP transport status.\n */\n readonly code?: number;\n\n /**\n * HTTP status code from the failed response, when the error originated\n * from the streamable HTTP transport. Undefined for stdio transport\n * errors and for failures that do not have an associated response\n * status (e.g. network errors, abort). Distinct from `code`, which is\n * the JSON-RPC application error code.\n */\n readonly statusCode?: number;\n\n /**\n * URL of the MCP endpoint the failing request was sent to, when the\n * error originated from an HTTP transport failure.\n */\n readonly url?: string;\n\n /**\n * Body of the failing HTTP response, decoded as text, when available.\n * Undefined when the body could not be read or the error did not have\n * an associated response.\n */\n readonly responseBody?: string;\n\n constructor({\n name = 'MCPClientError',\n message,\n cause,\n data,\n code,\n statusCode,\n url,\n responseBody,\n }: {\n name?: string;\n message: string;\n cause?: unknown;\n data?: unknown;\n code?: number;\n statusCode?: number;\n url?: string;\n responseBody?: string;\n }) {\n super({ name, message, cause });\n this.data = data;\n this.code = code;\n this.statusCode = statusCode;\n this.url = url;\n this.responseBody = responseBody;\n }\n\n static isInstance(error: unknown): error is MCPClientError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { getEnvironment } from './get-environment';\nimport type { StdioConfig } from './mcp-stdio-transport';\n\nexport function createChildProcess(\n config: StdioConfig,\n signal: AbortSignal,\n): ChildProcess {\n return spawn(config.command, config.args ?? [], {\n env: getEnvironment(config.env),\n stdio: ['pipe', 'pipe', config.stderr ?? 'inherit'],\n shell: false,\n signal,\n windowsHide: globalThis.process.platform === 'win32' && isElectron(),\n cwd: config.cwd,\n });\n}\n\nfunction isElectron() {\n return 'type' in globalThis.process;\n}\n","/**\n * Constructs the environment variables for the child process.\n *\n * @param customEnv - Custom environment variables to merge with default environment variables.\n * @returns The environment variables for the child process.\n */\nexport function getEnvironment(\n customEnv?: Record<string, string>,\n): Record<string, string> {\n const DEFAULT_INHERITED_ENV_VARS =\n globalThis.process.platform === 'win32'\n ? [\n 'APPDATA',\n 'HOMEDRIVE',\n 'HOMEPATH',\n 'LOCALAPPDATA',\n 'PATH',\n 'PROCESSOR_ARCHITECTURE',\n 'SYSTEMDRIVE',\n 'SYSTEMROOT',\n 'TEMP',\n 'USERNAME',\n 'USERPROFILE',\n ]\n : ['HOME', 'LOGNAME', 'PATH', 'SHELL', 'TERM', 'USER'];\n\n const env: Record<string, string> = customEnv ? { ...customEnv } : {};\n\n for (const key of DEFAULT_INHERITED_ENV_VARS) {\n const value = globalThis.process.env[key];\n if (value === undefined) {\n continue;\n }\n\n if (value.startsWith('()')) {\n continue;\n }\n\n env[key] = value;\n }\n\n return env;\n}\n","import type { ChildProcess, IOType } from 'node:child_process';\nimport type { Stream } from 'node:stream';\nimport { parseJSONRPCMessage, type JSONRPCMessage } from '../json-rpc-message';\nimport type { MCPTransport } from '../mcp-transport';\nimport { MCPClientError } from '../../error/mcp-client-error';\nimport { createChildProcess } from './create-child-process';\n\nexport interface StdioConfig {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n stderr?: IOType | Stream | number;\n cwd?: string;\n}\n\nexport class StdioMCPTransport implements MCPTransport {\n readonly supportsProtocolVersionDiscovery = true;\n private process?: ChildProcess;\n private abortController: AbortController = new AbortController();\n private readBuffer: ReadBuffer = new ReadBuffer();\n private serverParams: StdioConfig;\n\n onclose?: () => void;\n onerror?: (error: unknown) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n constructor(server: StdioConfig) {\n this.serverParams = server;\n }\n\n async start(): Promise<void> {\n if (this.process) {\n throw new MCPClientError({\n message: 'StdioMCPTransport already started.',\n });\n }\n\n return new Promise((resolve, reject) => {\n try {\n const process = createChildProcess(\n this.serverParams,\n this.abortController.signal,\n );\n\n this.process = process;\n\n this.process.on('error', error => {\n if (error.name === 'AbortError') {\n this.onclose?.();\n return;\n }\n\n reject(error);\n this.onerror?.(error);\n });\n\n this.process.on('spawn', () => {\n resolve();\n });\n\n this.process.on('close', _code => {\n this.process = undefined;\n this.onclose?.();\n });\n\n this.process.stdin?.on('error', error => {\n this.onerror?.(error);\n });\n\n this.process.stdout?.on('data', chunk => {\n this.readBuffer.append(chunk);\n void this.processReadBuffer();\n });\n\n this.process.stdout?.on('error', error => {\n this.onerror?.(error);\n });\n } catch (error) {\n reject(error);\n this.onerror?.(error);\n }\n });\n }\n\n private async processReadBuffer() {\n while (true) {\n const line = this.readBuffer.readLine();\n if (line === null) {\n break;\n }\n\n try {\n const message = await deserializeMessage(line);\n this.onmessage?.(message);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n }\n\n async close(): Promise<void> {\n this.abortController.abort();\n this.process = undefined;\n this.readBuffer.clear();\n }\n\n send(message: JSONRPCMessage): Promise<void> {\n return new Promise(resolve => {\n if (!this.process?.stdin) {\n throw new MCPClientError({\n message: 'StdioClientTransport not connected',\n });\n }\n\n const json = serializeMessage(message);\n if (this.process.stdin.write(json)) {\n resolve();\n } else {\n this.process.stdin.once('drain', resolve);\n }\n });\n }\n}\n\nclass ReadBuffer {\n private buffer?: Buffer;\n\n append(chunk: Buffer): void {\n this.buffer = this.buffer ? Buffer.concat([this.buffer, chunk]) : chunk;\n }\n\n readLine(): string | null {\n if (!this.buffer) return null;\n\n const index = this.buffer.indexOf('\\n');\n if (index === -1) {\n return null;\n }\n\n const line = this.buffer.toString('utf8', 0, index);\n this.buffer = this.buffer.subarray(index + 1);\n return line;\n }\n\n clear(): void {\n this.buffer = undefined;\n }\n}\n\nfunction serializeMessage(message: JSONRPCMessage): string {\n return JSON.stringify(message) + '\\n';\n}\n\nexport async function deserializeMessage(\n line: string,\n): Promise<JSONRPCMessage> {\n return parseJSONRPCMessage(line);\n}\n"],"mappings":"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","names":["z","z","name","_a","_b","_a","_b"]} |
+3
-3
| { | ||
| "name": "@ai-sdk/mcp", | ||
| "version": "2.0.32", | ||
| "version": "2.0.33", | ||
| "type": "module", | ||
@@ -35,4 +35,4 @@ "license": "Apache-2.0", | ||
| "pkce-challenge": "^5.0.1", | ||
| "@ai-sdk/provider-utils": "5.0.27", | ||
| "@ai-sdk/provider": "4.0.7" | ||
| "@ai-sdk/provider": "4.0.7", | ||
| "@ai-sdk/provider-utils": "5.0.27" | ||
| }, | ||
@@ -39,0 +39,0 @@ "devDependencies": { |
+15
-0
@@ -62,2 +62,13 @@ # AI SDK - Model Context Protocol Client | ||
| ## Protocol versions | ||
| The client supports legacy MCP protocol versions through the `initialize` | ||
| handshake and MCP `2026-07-28` through stateless protocol discovery. The | ||
| built-in stdio transport probes with `server/discover` and falls back to the | ||
| legacy handshake when connected to an older server. | ||
| Custom transports can opt into the same negotiation by setting | ||
| `supportsProtocolVersionDiscovery` to `true`. Modern requests include the | ||
| protocol version, client capabilities, and client information in `_meta`. | ||
| For streaming responses, close the MCP client when the stream finishes: | ||
@@ -94,2 +105,6 @@ | ||
| Session persistence applies only to legacy MCP protocol versions. MCP | ||
| `2026-07-28` is stateless and does not use session ids or cached initialize | ||
| results. | ||
| ```ts | ||
@@ -96,0 +111,0 @@ import { createMCPClient } from '@ai-sdk/mcp'; |
@@ -30,3 +30,3 @@ import { parseJSON } from '@ai-sdk/provider-utils'; | ||
| jsonrpc: z.literal(JSONRPC_VERSION), | ||
| id: z.union([z.string(), z.number().int()]), | ||
| id: z.optional(z.union([z.string(), z.number().int()])), | ||
| error: z.object({ | ||
@@ -33,0 +33,0 @@ code: z.number().int(), |
+251
-22
@@ -29,10 +29,18 @@ import type { JSONObject, JSONSchema7, JSONValue } from '@ai-sdk/provider'; | ||
| type MCPTransportConfig, | ||
| type MCPTransportSendOptions, | ||
| } from './mcp-transport'; | ||
| import { getMCPAppToolMeta, MCP_APP_MIME_TYPE } from './mcp-apps'; | ||
| import { | ||
| createMCPToolHeaders, | ||
| getMCPToolHeaderBindings, | ||
| type MCPToolHeaderBinding, | ||
| } from './mcp-http-headers'; | ||
| import { | ||
| CallToolResultSchema, | ||
| CompleteResultSchema, | ||
| DiscoverResultSchema, | ||
| ElicitationRequestSchema, | ||
| ElicitResultSchema, | ||
| InitializeResultSchema, | ||
| LATEST_LEGACY_PROTOCOL_VERSION, | ||
| LATEST_PROTOCOL_VERSION, | ||
@@ -70,5 +78,8 @@ ListResourceTemplatesResultSchema, | ||
| type InitializeResult, | ||
| type DiscoverResult, | ||
| } from './types'; | ||
| const CLIENT_VERSION = '1.0.0'; | ||
| const DEFAULT_MAX_TOOL_CALL_RETRIES = 0; | ||
| const DEFAULT_PROTOCOL_DISCOVERY_TIMEOUT = 1000; | ||
| const MODERN_PROTOCOL_ERROR_CODES = [-32020, -32021, -32022]; | ||
@@ -236,2 +247,12 @@ const DEFAULT_RETRY_ERROR_CODES = [ | ||
| /** | ||
| * Whether transports that support stateless protocol discovery should probe | ||
| * with `server/discover` before falling back to legacy initialization. | ||
| * | ||
| * Disable this for legacy servers that require `initialize` to be the first | ||
| * request. | ||
| * | ||
| * @default true | ||
| */ | ||
| protocolVersionDiscovery?: boolean; | ||
| /** | ||
| * Options that bound or cancel transport startup and the initialize request. | ||
@@ -394,2 +415,3 @@ */ | ||
| private transport: MCPTransport; | ||
| private protocolVersionDiscovery: boolean; | ||
| private onUncaughtError?: (error: unknown) => void; | ||
@@ -409,3 +431,3 @@ private maxRetries: number; | ||
| private _initializeResult: InitializeResult = { | ||
| protocolVersion: LATEST_PROTOCOL_VERSION, | ||
| protocolVersion: LATEST_LEGACY_PROTOCOL_VERSION, | ||
| capabilities: {}, | ||
@@ -415,2 +437,5 @@ serverInfo: this._serverInfo, | ||
| private _serverInstructions?: string; | ||
| private protocolEra: 'legacy' | 'modern' = 'legacy'; | ||
| private protocolVersion = LATEST_LEGACY_PROTOCOL_VERSION; | ||
| private toolHeaderBindings = new Map<string, MCPToolHeaderBinding[]>(); | ||
| private isClosed = true; | ||
@@ -431,2 +456,3 @@ private elicitationRequestHandler?: ( | ||
| initializationOptions, | ||
| protocolVersionDiscovery = true, | ||
| }: MCPClientConfig) { | ||
@@ -438,2 +464,3 @@ this.onUncaughtError = onUncaughtError; | ||
| this.initializationOptions = initializationOptions; | ||
| this.protocolVersionDiscovery = protocolVersionDiscovery; | ||
@@ -521,2 +548,16 @@ if (isCustomMcpTransport(transportConfig)) { | ||
| if ( | ||
| this.protocolVersionDiscovery && | ||
| this.transport.supportsProtocolVersionDiscovery | ||
| ) { | ||
| const discovered = await this.tryProtocolDiscovery(signal); | ||
| if (discovered) { | ||
| return this; | ||
| } | ||
| } | ||
| this.protocolEra = 'legacy'; | ||
| this.protocolVersion = LATEST_LEGACY_PROTOCOL_VERSION; | ||
| this.setTransportProtocolVersion(this.protocolVersion); | ||
| const result = await this.request({ | ||
@@ -526,3 +567,3 @@ request: { | ||
| params: { | ||
| protocolVersion: LATEST_PROTOCOL_VERSION, | ||
| protocolVersion: LATEST_LEGACY_PROTOCOL_VERSION, | ||
| capabilities: this.clientCapabilities, | ||
@@ -578,2 +619,71 @@ clientInfo: this.clientInfo, | ||
| private async tryProtocolDiscovery( | ||
| signal: AbortSignal | undefined, | ||
| ): Promise<boolean> { | ||
| this.protocolEra = 'modern'; | ||
| this.protocolVersion = LATEST_PROTOCOL_VERSION; | ||
| this.setTransportProtocolVersion(this.protocolVersion); | ||
| try { | ||
| const result = await this.request({ | ||
| request: { method: 'server/discover' }, | ||
| resultSchema: DiscoverResultSchema, | ||
| options: { | ||
| signal, | ||
| timeout: DEFAULT_PROTOCOL_DISCOVERY_TIMEOUT, | ||
| }, | ||
| }); | ||
| this.applyDiscoverResult(result); | ||
| return true; | ||
| } catch (error) { | ||
| if ( | ||
| MCPClientError.isInstance(error) && | ||
| error.code != null && | ||
| MODERN_PROTOCOL_ERROR_CODES.includes(error.code) | ||
| ) { | ||
| throw error; | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| private applyDiscoverResult(result: DiscoverResult): void { | ||
| if (!result.supportedVersions.includes(this.protocolVersion)) { | ||
| throw new MCPClientError({ | ||
| message: `Server does not support the requested protocol version: ${this.protocolVersion}`, | ||
| }); | ||
| } | ||
| const serverInfo = result._meta?.['io.modelcontextprotocol/serverInfo']; | ||
| if ( | ||
| serverInfo != null && | ||
| typeof serverInfo === 'object' && | ||
| 'name' in serverInfo && | ||
| typeof serverInfo.name === 'string' && | ||
| 'version' in serverInfo && | ||
| typeof serverInfo.version === 'string' | ||
| ) { | ||
| this._serverInfo = serverInfo as Configuration; | ||
| } | ||
| this.serverCapabilities = result.capabilities; | ||
| this._serverInstructions = result.instructions; | ||
| this._initializeResult = { | ||
| protocolVersion: this.protocolVersion, | ||
| capabilities: result.capabilities, | ||
| serverInfo: this._serverInfo, | ||
| instructions: result.instructions, | ||
| }; | ||
| } | ||
| private setTransportProtocolVersion(version: string): void { | ||
| if (this.transport.setProtocolVersion) { | ||
| this.transport.setProtocolVersion(version); | ||
| } else { | ||
| this.transport.protocolVersion = version; | ||
| } | ||
| } | ||
| private applyInitializeResult(result: InitializeResult): void { | ||
@@ -587,9 +697,7 @@ if (!SUPPORTED_PROTOCOL_VERSIONS.includes(result.protocolVersion)) { | ||
| this.serverCapabilities = result.capabilities; | ||
| this.protocolEra = 'legacy'; | ||
| this.protocolVersion = result.protocolVersion; | ||
| this._serverInfo = result.serverInfo; | ||
| this._initializeResult = result; | ||
| if (this.transport.setProtocolVersion) { | ||
| this.transport.setProtocolVersion(result.protocolVersion); | ||
| } else { | ||
| this.transport.protocolVersion = result.protocolVersion; | ||
| } | ||
| this.setTransportProtocolVersion(result.protocolVersion); | ||
| this._serverInstructions = result.instructions; | ||
@@ -606,8 +714,7 @@ } | ||
| message: JSONRPCMessage, | ||
| signal: AbortSignal | undefined, | ||
| options?: MCPTransportSendOptions, | ||
| ): Promise<void> { | ||
| return this.transport.send( | ||
| message, | ||
| signal == null ? undefined : { signal }, | ||
| ); | ||
| return options == null | ||
| ? this.transport.send(message) | ||
| : this.transport.send(message, options); | ||
| } | ||
@@ -618,2 +725,3 @@ | ||
| case 'initialize': | ||
| case 'server/discover': | ||
| break; | ||
@@ -694,7 +802,25 @@ case 'completion/complete': | ||
| const messageId = this.requestMessageId++; | ||
| const preparedRequest = | ||
| this.protocolEra === 'modern' | ||
| ? { | ||
| ...request, | ||
| params: { | ||
| ...request.params, | ||
| _meta: { | ||
| ...request.params?._meta, | ||
| 'io.modelcontextprotocol/protocolVersion': | ||
| this.protocolVersion, | ||
| 'io.modelcontextprotocol/clientCapabilities': | ||
| this.clientCapabilities, | ||
| 'io.modelcontextprotocol/clientInfo': this.clientInfo, | ||
| }, | ||
| }, | ||
| } | ||
| : request; | ||
| const jsonrpcRequest: JSONRPCRequest = { | ||
| ...request, | ||
| ...preparedRequest, | ||
| jsonrpc: '2.0', | ||
| id: messageId, | ||
| }; | ||
| const headers = this.getToolRequestHeaders(preparedRequest); | ||
@@ -747,2 +873,17 @@ const rejectWithAbortError = () => { | ||
| try { | ||
| if ( | ||
| this.protocolEra === 'modern' && | ||
| response.result.resultType == null | ||
| ) { | ||
| throw new MCPClientError({ | ||
| message: 'Modern MCP result is missing resultType', | ||
| }); | ||
| } | ||
| if (response.result.resultType === 'input_required') { | ||
| throw new MCPClientError({ | ||
| message: | ||
| 'Server requested additional input, but multi round-trip requests are not supported yet', | ||
| }); | ||
| } | ||
| const result = resultSchema.parse(response.result); | ||
@@ -752,6 +893,8 @@ cleanup(); | ||
| } catch (error) { | ||
| const parseError = new MCPClientError({ | ||
| message: 'Failed to parse server response', | ||
| cause: error, | ||
| }); | ||
| const parseError = MCPClientError.isInstance(error) | ||
| ? error | ||
| : new MCPClientError({ | ||
| message: 'Failed to parse server response', | ||
| cause: error, | ||
| }); | ||
| rejectAndCleanup(parseError); | ||
@@ -767,6 +910,10 @@ } | ||
| const sendOptions: MCPTransportSendOptions = { | ||
| ...(transportSignal == null ? {} : { signal: transportSignal }), | ||
| ...(headers == null ? {} : { headers }), | ||
| }; | ||
| const sendPromise = | ||
| transportSignal == null | ||
| ? this.transport.send(jsonrpcRequest) | ||
| : this.send(jsonrpcRequest, transportSignal); | ||
| Object.keys(sendOptions).length === 0 | ||
| ? this.send(jsonrpcRequest) | ||
| : this.send(jsonrpcRequest, sendOptions); | ||
@@ -786,3 +933,3 @@ sendPromise.catch(error => { | ||
| } = {}): Promise<ListToolsResult> { | ||
| return this.request({ | ||
| const result = await this.request({ | ||
| request: { method: 'tools/list', params }, | ||
@@ -792,4 +939,71 @@ resultSchema: ListToolsResultSchema, | ||
| }); | ||
| return this.prepareToolDefinitions(result, params?.cursor == null); | ||
| } | ||
| private prepareToolDefinitions( | ||
| definitions: ListToolsResult, | ||
| resetHeaderBindings = false, | ||
| ): ListToolsResult { | ||
| if ( | ||
| this.protocolEra !== 'modern' || | ||
| !this.transport.supportsMcpToolParameterHeaders | ||
| ) { | ||
| return definitions; | ||
| } | ||
| if (resetHeaderBindings) { | ||
| this.toolHeaderBindings.clear(); | ||
| } | ||
| const tools = definitions.tools.filter(toolDefinition => { | ||
| const result = getMCPToolHeaderBindings(toolDefinition.inputSchema); | ||
| if (!result.success) { | ||
| this.onError( | ||
| new MCPClientError({ | ||
| message: `Ignoring MCP tool "${toolDefinition.name}": ${result.error}`, | ||
| }), | ||
| ); | ||
| return false; | ||
| } | ||
| this.toolHeaderBindings.set(toolDefinition.name, result.bindings); | ||
| return true; | ||
| }); | ||
| return { ...definitions, tools }; | ||
| } | ||
| private getToolRequestHeaders( | ||
| request: Request, | ||
| ): Record<string, string> | undefined { | ||
| if ( | ||
| this.protocolEra !== 'modern' || | ||
| request.method !== 'tools/call' || | ||
| typeof request.params?.name !== 'string' | ||
| ) { | ||
| return undefined; | ||
| } | ||
| const bindings = this.toolHeaderBindings.get(request.params.name); | ||
| if (bindings == null || bindings.length === 0) { | ||
| return undefined; | ||
| } | ||
| const args = request.params.arguments; | ||
| if (args == null || typeof args !== 'object' || Array.isArray(args)) { | ||
| return undefined; | ||
| } | ||
| try { | ||
| return createMCPToolHeaders({ | ||
| bindings, | ||
| args: args as Record<string, unknown>, | ||
| }); | ||
| } catch (error) { | ||
| throw new MCPClientError({ | ||
| message: `Failed to create MCP headers for tool "${request.params.name}"`, | ||
| cause: error, | ||
| }); | ||
| } | ||
| } | ||
| private async callToolWithRetry({ | ||
@@ -957,3 +1171,6 @@ options, | ||
| await waitForAbort( | ||
| this.send(jsonrpcNotification, options?.signal), | ||
| this.send( | ||
| jsonrpcNotification, | ||
| options?.signal == null ? undefined : { signal: options.signal }, | ||
| ), | ||
| options?.signal, | ||
@@ -988,2 +1205,3 @@ ); | ||
| ): McpToolSet<TOOL_SCHEMAS> { | ||
| definitions = this.prepareToolDefinitions(definitions); | ||
| const tools: Record<string, Tool & { _meta?: ToolMeta }> = {}; | ||
@@ -1303,2 +1521,13 @@ | ||
| private onResponse(response: JSONRPCResponse | JSONRPCError): void { | ||
| if (response.id == null) { | ||
| this.onError( | ||
| new MCPClientError({ | ||
| message: `Protocol error: Received a response without a message ID: ${JSON.stringify( | ||
| response, | ||
| )}`, | ||
| }), | ||
| ); | ||
| return; | ||
| } | ||
| const messageId = Number(response.id); | ||
@@ -1305,0 +1534,0 @@ const handler = this.responseHandlers.get(messageId); |
@@ -13,3 +13,3 @@ import { | ||
| } from './json-rpc-message'; | ||
| import type { MCPTransport } from './mcp-transport'; | ||
| import type { MCPTransport, MCPTransportSendOptions } from './mcp-transport'; | ||
| import { VERSION } from '../version'; | ||
@@ -23,3 +23,7 @@ import { | ||
| } from './oauth'; | ||
| import { LATEST_PROTOCOL_VERSION } from './types'; | ||
| import { | ||
| LATEST_LEGACY_PROTOCOL_VERSION, | ||
| LATEST_PROTOCOL_VERSION, | ||
| } from './types'; | ||
| import { encodeMCPHeaderValue } from './mcp-http-headers'; | ||
@@ -38,2 +42,4 @@ function isMessageEvent(event: string | undefined): boolean { | ||
| export class HttpMCPTransport implements MCPTransport { | ||
| readonly supportsProtocolVersionDiscovery = true; | ||
| readonly supportsMcpToolParameterHeaders = true; | ||
| private url: URL; | ||
@@ -96,3 +102,4 @@ private abortController?: AbortController; | ||
| this.sessionId = initialSessionId; | ||
| this.protocolVersion = initialProtocolVersion; | ||
| this.protocolVersion = | ||
| initialProtocolVersion ?? LATEST_LEGACY_PROTOCOL_VERSION; | ||
| this.onSessionIdChange = onSessionIdChange; | ||
@@ -106,4 +113,25 @@ this.onSessionExpired = onSessionExpired; | ||
| this.protocolVersion = version; | ||
| if (!this.abortController) { | ||
| return; | ||
| } | ||
| if (this.isModernProtocol()) { | ||
| this.inboundSseConnection?.close(); | ||
| this.inboundSseConnection = undefined; | ||
| return; | ||
| } | ||
| if (!this.inboundSseConnection) { | ||
| this.startInboundSse(); | ||
| } | ||
| } | ||
| private isModernProtocol(): boolean { | ||
| return ( | ||
| (this.protocolVersion ?? LATEST_PROTOCOL_VERSION) === | ||
| LATEST_PROTOCOL_VERSION | ||
| ); | ||
| } | ||
| private async commonHeaders({ | ||
@@ -119,6 +147,7 @@ base, | ||
| ...base, | ||
| 'mcp-protocol-version': this.protocolVersion ?? LATEST_PROTOCOL_VERSION, | ||
| 'mcp-protocol-version': | ||
| this.protocolVersion ?? LATEST_LEGACY_PROTOCOL_VERSION, | ||
| }; | ||
| if (includeSessionId && this.sessionId) { | ||
| if (!this.isModernProtocol() && includeSessionId && this.sessionId) { | ||
| headers['mcp-session-id'] = this.sessionId; | ||
@@ -151,2 +180,6 @@ } | ||
| private applySessionIdFromResponse(response: Response): void { | ||
| if (this.isModernProtocol()) { | ||
| return; | ||
| } | ||
| const sessionId = response.headers.get('mcp-session-id'); | ||
@@ -200,3 +233,8 @@ if (sessionId) { | ||
| this.startInboundSse(); | ||
| if ( | ||
| this.protocolVersion != null && | ||
| this.protocolVersion !== LATEST_PROTOCOL_VERSION | ||
| ) { | ||
| this.startInboundSse(); | ||
| } | ||
| } | ||
@@ -210,2 +248,3 @@ | ||
| if ( | ||
| !this.isModernProtocol() && | ||
| this.sessionId && | ||
@@ -232,3 +271,3 @@ this.terminateSessionOnClose && | ||
| message: JSONRPCMessage, | ||
| options?: { signal?: AbortSignal }, | ||
| options?: MCPTransportSendOptions, | ||
| ): Promise<void> { | ||
@@ -256,2 +295,8 @@ options?.signal?.throwIfAborted(); | ||
| Accept: 'application/json, text/event-stream', | ||
| ...(this.isModernProtocol() ? options?.headers : {}), | ||
| ...(this.isModernProtocol() && | ||
| 'method' in message && | ||
| 'id' in message | ||
| ? this.getStandardRequestHeaders(message) | ||
| : {}), | ||
| }, | ||
@@ -297,3 +342,3 @@ includeSessionId: !isInitializeRequest, | ||
| // Do not await to avoid blocking send() | ||
| if (!this.inboundSseConnection) { | ||
| if (!this.isModernProtocol() && !this.inboundSseConnection) { | ||
| this.startInboundSse(); | ||
@@ -306,6 +351,21 @@ } | ||
| const text = await response.text().catch(() => null); | ||
| if ('id' in message && text != null) { | ||
| const jsonRpcMessage = await parseJSONRPCMessage(text).catch( | ||
| () => undefined, | ||
| ); | ||
| if (jsonRpcMessage != null && 'error' in jsonRpcMessage) { | ||
| this.onmessage?.( | ||
| jsonRpcMessage.id == null | ||
| ? { ...jsonRpcMessage, id: message.id } | ||
| : jsonRpcMessage, | ||
| ); | ||
| return; | ||
| } | ||
| } | ||
| let errorMessage = `MCP HTTP Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`; | ||
| if (response.status === 404) { | ||
| if (sessionIdForRequest) { | ||
| if (!this.isModernProtocol() && sessionIdForRequest) { | ||
| this.expireSessionId(sessionIdForRequest); | ||
@@ -315,3 +375,3 @@ | ||
| '. The MCP session expired. Create a new client without `initialSessionId` to start a fresh session'; | ||
| } else { | ||
| } else if (!this.isModernProtocol()) { | ||
| errorMessage += | ||
@@ -430,2 +490,23 @@ '. This server does not support HTTP transport. Try using `sse` transport instead'; | ||
| private getStandardRequestHeaders( | ||
| message: Extract<JSONRPCMessage, { method: string; id: unknown }>, | ||
| ): Record<string, string> { | ||
| const headers: Record<string, string> = { | ||
| 'Mcp-Method': message.method, | ||
| }; | ||
| const params = message.params; | ||
| const name = | ||
| message.method === 'resources/read' | ||
| ? params?.uri | ||
| : message.method === 'tools/call' || message.method === 'prompts/get' | ||
| ? params?.name | ||
| : undefined; | ||
| if (typeof name === 'string') { | ||
| headers['Mcp-Name'] = encodeMCPHeaderValue(name); | ||
| } | ||
| return headers; | ||
| } | ||
| private getNextReconnectionDelay(attempt: number): number { | ||
@@ -466,2 +547,6 @@ const { | ||
| ): void { | ||
| if (this.isModernProtocol()) { | ||
| return; | ||
| } | ||
| void this.openInboundSse(triedAuth, resumeToken).catch(error => { | ||
@@ -480,2 +565,6 @@ if (error instanceof Error && error.name === 'AbortError') { | ||
| ): Promise<void> { | ||
| if (this.isModernProtocol()) { | ||
| return; | ||
| } | ||
| try { | ||
@@ -482,0 +571,0 @@ const sessionIdForRequest = this.sessionId; |
@@ -17,3 +17,3 @@ import { | ||
| } from './oauth'; | ||
| import { LATEST_PROTOCOL_VERSION } from './types'; | ||
| import { LATEST_LEGACY_PROTOCOL_VERSION } from './types'; | ||
@@ -73,3 +73,4 @@ function isMessageEvent(event: string | undefined): boolean { | ||
| ...base, | ||
| 'mcp-protocol-version': this.protocolVersion ?? LATEST_PROTOCOL_VERSION, | ||
| 'mcp-protocol-version': | ||
| this.protocolVersion ?? LATEST_LEGACY_PROTOCOL_VERSION, | ||
| }; | ||
@@ -76,0 +77,0 @@ |
@@ -17,2 +17,3 @@ import type { ChildProcess, IOType } from 'node:child_process'; | ||
| export class StdioMCPTransport implements MCPTransport { | ||
| readonly supportsProtocolVersionDiscovery = true; | ||
| private process?: ChildProcess; | ||
@@ -19,0 +20,0 @@ private abortController: AbortController = new AbortController(); |
@@ -7,2 +7,3 @@ import type { FetchFunction } from '@ai-sdk/provider-utils'; | ||
| import type { OAuthClientProvider } from './oauth'; | ||
| import { LATEST_PROTOCOL_VERSION } from './types'; | ||
@@ -20,2 +21,7 @@ /** | ||
| /** | ||
| * Request-specific HTTP headers produced from MCP tool parameters. | ||
| */ | ||
| headers?: Record<string, string>; | ||
| /** | ||
| * Associates an outgoing message with an incoming request. | ||
@@ -45,2 +51,16 @@ */ | ||
| /** | ||
| * Whether this transport can probe for stateless MCP protocol versions. | ||
| * | ||
| * Custom transports default to the legacy initialization flow unless they | ||
| * explicitly opt in. | ||
| */ | ||
| supportsProtocolVersionDiscovery?: boolean; | ||
| /** | ||
| * Whether this transport mirrors x-mcp-header tool parameters into request | ||
| * headers. | ||
| */ | ||
| supportsMcpToolParameterHeaders?: boolean; | ||
| /** | ||
| * Initialize and start the transport | ||
@@ -167,3 +187,7 @@ */ | ||
| case 'http': | ||
| return new HttpMCPTransport(config); | ||
| return new HttpMCPTransport({ | ||
| ...config, | ||
| initialProtocolVersion: | ||
| config.initialProtocolVersion ?? LATEST_PROTOCOL_VERSION, | ||
| }); | ||
| default: | ||
@@ -170,0 +194,0 @@ throw new MCPClientError({ |
@@ -5,3 +5,3 @@ import { delay } from '@ai-sdk/provider-utils'; | ||
| import { | ||
| LATEST_PROTOCOL_VERSION, | ||
| LATEST_LEGACY_PROTOCOL_VERSION, | ||
| type MCPTool, | ||
@@ -167,3 +167,3 @@ type MCPResource, | ||
| result: this.initializeResult || { | ||
| protocolVersion: LATEST_PROTOCOL_VERSION, | ||
| protocolVersion: LATEST_LEGACY_PROTOCOL_VERSION, | ||
| serverInfo: { | ||
@@ -170,0 +170,0 @@ name: 'mock-mcp-server', |
@@ -42,2 +42,3 @@ import { z } from 'zod/v4'; | ||
| refresh_token: z.string().optional(), | ||
| issuer: SafeUrlSchema.optional(), | ||
| authorization_server: SafeUrlSchema.optional(), | ||
@@ -70,2 +71,4 @@ token_endpoint: SafeUrlSchema.optional(), | ||
| registration_endpoint: SafeUrlSchema.optional(), | ||
| authorization_response_iss_parameter_supported: z.boolean().optional(), | ||
| client_id_metadata_document_supported: z.boolean().optional(), | ||
| scopes_supported: z.array(z.string()).optional(), | ||
@@ -92,2 +95,4 @@ response_types_supported: z.array(z.string()), | ||
| registration_endpoint: SafeUrlSchema.optional(), | ||
| authorization_response_iss_parameter_supported: z.boolean().optional(), | ||
| client_id_metadata_document_supported: z.boolean().optional(), | ||
| scopes_supported: z.array(z.string()).optional(), | ||
@@ -120,2 +125,3 @@ response_types_supported: z.array(z.string()), | ||
| client_secret_expires_at: z.number().optional(), | ||
| issuer: SafeUrlSchema.optional(), | ||
| authorization_server: SafeUrlSchema.optional(), | ||
@@ -129,2 +135,5 @@ token_endpoint: SafeUrlSchema.optional(), | ||
| redirect_uris: z.array(SafeUrlSchema), | ||
| application_type: z | ||
| .union([z.literal('native'), z.literal('web')]) | ||
| .optional(), | ||
| token_endpoint_auth_method: z.string().optional(), | ||
@@ -131,0 +140,0 @@ grant_types: z.array(z.string()).optional(), |
+75
-1
@@ -34,2 +34,3 @@ import pkceChallenge from 'pkce-challenge'; | ||
| export interface OAuthAuthorizationServerInformation { | ||
| issuer?: string; | ||
| authorizationServerUrl: string; | ||
@@ -126,2 +127,16 @@ tokenEndpoint: string; | ||
| function validateAuthorizationResponseIssuer({ | ||
| callbackIssuer, | ||
| expectedIssuer, | ||
| }: { | ||
| callbackIssuer: string | undefined; | ||
| expectedIssuer: string; | ||
| }): void { | ||
| if (callbackIssuer != null && callbackIssuer !== expectedIssuer) { | ||
| throw new MCPClientOAuthError({ | ||
| message: `OAuth authorization response issuer ${callbackIssuer} does not match expected issuer ${expectedIssuer}`, | ||
| }); | ||
| } | ||
| } | ||
| function createAuthorizationServerInformation( | ||
@@ -132,2 +147,3 @@ authorizationServerUrl: string | URL, | ||
| return { | ||
| issuer: metadata?.issuer ?? String(authorizationServerUrl), | ||
| authorizationServerUrl: normalizeUrl(authorizationServerUrl), | ||
@@ -148,2 +164,3 @@ tokenEndpoint: normalizeUrl( | ||
| ...tokens, | ||
| issuer: authorizationServerInformation.issuer, | ||
| authorization_server: authorizationServerInformation.authorizationServerUrl, | ||
@@ -162,2 +179,3 @@ token_endpoint: authorizationServerInformation.tokenEndpoint, | ||
| ...clientInformation, | ||
| issuer: authorizationServerInformation.issuer, | ||
| authorization_server: authorizationServerInformation.authorizationServerUrl, | ||
@@ -169,2 +187,3 @@ token_endpoint: authorizationServerInformation.tokenEndpoint, | ||
| function getAuthorizationServerInformationFromCredentials(credentials?: { | ||
| issuer?: string; | ||
| authorization_server?: string; | ||
@@ -178,2 +197,3 @@ token_endpoint?: string; | ||
| return { | ||
| issuer: credentials.issuer, | ||
| authorizationServerUrl: normalizeUrl(credentials.authorization_server), | ||
@@ -203,2 +223,3 @@ tokenEndpoint: normalizeUrl(credentials.token_endpoint), | ||
| return { | ||
| issuer: providerAuthorizationServerInformation.issuer, | ||
| authorizationServerUrl: normalizeUrl( | ||
@@ -269,2 +290,6 @@ providerAuthorizationServerInformation.authorizationServerUrl, | ||
| if ( | ||
| (storedAuthorizationServerInformation.issuer != null && | ||
| currentAuthorizationServerInformation.issuer != null && | ||
| storedAuthorizationServerInformation.issuer !== | ||
| currentAuthorizationServerInformation.issuer) || | ||
| storedAuthorizationServerInformation.authorizationServerUrl !== | ||
@@ -1062,2 +1087,5 @@ currentAuthorizationServerInformation.authorizationServerUrl || | ||
| const applicationType = | ||
| clientMetadata.application_type ?? | ||
| inferOAuthApplicationType(clientMetadata.redirect_uris); | ||
| const response = await (fetchFn ?? fetch)(registrationUrl, { | ||
@@ -1068,3 +1096,6 @@ method: 'POST', | ||
| }, | ||
| body: JSON.stringify(clientMetadata), | ||
| body: JSON.stringify({ | ||
| ...clientMetadata, | ||
| application_type: applicationType, | ||
| }), | ||
| }); | ||
@@ -1079,2 +1110,18 @@ | ||
| function inferOAuthApplicationType(redirectUris: string[]): 'native' | 'web' { | ||
| const isNativeRedirectUri = (redirectUri: string): boolean => { | ||
| const url = new URL(redirectUri); | ||
| return ( | ||
| ((url.protocol === 'http:' || url.protocol === 'https:') && | ||
| (url.hostname === 'localhost' || | ||
| url.hostname.endsWith('.localhost') || | ||
| url.hostname === '127.0.0.1' || | ||
| url.hostname === '[::1]')) || | ||
| (url.protocol !== 'http:' && url.protocol !== 'https:') | ||
| ); | ||
| }; | ||
| return redirectUris.every(isNativeRedirectUri) ? 'native' : 'web'; | ||
| } | ||
| export async function auth( | ||
@@ -1086,2 +1133,6 @@ provider: OAuthClientProvider, | ||
| callbackState?: string; | ||
| /** | ||
| * Value of the `iss` parameter from the authorization response. | ||
| */ | ||
| callbackIssuer?: string; | ||
| scope?: string; | ||
@@ -1147,2 +1198,3 @@ resourceMetadataUrl?: URL; | ||
| callbackState, | ||
| callbackIssuer, | ||
| scope, | ||
@@ -1155,2 +1207,3 @@ resourceMetadataUrl, | ||
| callbackState?: string; | ||
| callbackIssuer?: string; | ||
| scope?: string; | ||
@@ -1212,2 +1265,16 @@ resourceMetadataUrl?: URL; | ||
| let clientInformation = await Promise.resolve(provider.clientInformation()); | ||
| if (clientInformation?.issuer != null) { | ||
| const storedAuthorizationServerInformation = | ||
| await getStoredAuthorizationServerInformation({ | ||
| provider, | ||
| clientInformation, | ||
| }); | ||
| if (storedAuthorizationServerInformation) { | ||
| assertAuthorizationServerInformationMatches({ | ||
| storedAuthorizationServerInformation, | ||
| currentAuthorizationServerInformation, | ||
| }); | ||
| } | ||
| } | ||
| if (!clientInformation) { | ||
@@ -1261,2 +1328,9 @@ if (authorizationCode !== undefined) { | ||
| } | ||
| validateAuthorizationResponseIssuer({ | ||
| callbackIssuer, | ||
| expectedIssuer: | ||
| storedAuthorizationServerInformation.issuer ?? | ||
| metadata?.issuer ?? | ||
| String(authorizationServerUrl), | ||
| }); | ||
| assertAuthorizationServerInformationMatches({ | ||
@@ -1263,0 +1337,0 @@ storedAuthorizationServerInformation, |
+19
-8
@@ -5,5 +5,7 @@ import { z } from 'zod/v4'; | ||
| export const LATEST_PROTOCOL_VERSION = '2025-11-25'; | ||
| export const LATEST_PROTOCOL_VERSION = '2026-07-28'; | ||
| export const LATEST_LEGACY_PROTOCOL_VERSION = '2025-11-25'; | ||
| export const SUPPORTED_PROTOCOL_VERSIONS = [ | ||
| LATEST_PROTOCOL_VERSION, | ||
| LATEST_LEGACY_PROTOCOL_VERSION, | ||
| '2025-06-18', | ||
@@ -77,3 +79,5 @@ '2025-03-26', | ||
| type BaseParams = z.infer<typeof BaseParamsSchema>; | ||
| export const ResultSchema = BaseParamsSchema; | ||
| export const ResultSchema = BaseParamsSchema.extend({ | ||
| resultType: z.optional(z.string()), | ||
| }); | ||
@@ -133,2 +137,11 @@ export const RequestSchema = z.object({ | ||
| export const DiscoverResultSchema = ResultSchema.extend({ | ||
| supportedVersions: z.array(z.string()), | ||
| capabilities: ServerCapabilitiesSchema, | ||
| instructions: z.optional(z.string()), | ||
| ttlMs: z.optional(z.number()), | ||
| cacheScope: z.optional(z.union([z.literal('public'), z.literal('private')])), | ||
| }); | ||
| export type DiscoverResult = z.infer<typeof DiscoverResultSchema>; | ||
| export const InitializeResultSchema = ResultSchema.extend({ | ||
@@ -160,8 +173,6 @@ protocolVersion: z.string(), | ||
| description: z.optional(z.string()), | ||
| inputSchema: z | ||
| .object({ | ||
| type: z.literal('object'), | ||
| properties: z.optional(z.object({}).loose()), | ||
| }) | ||
| .loose(), | ||
| inputSchema: z.looseObject({ | ||
| type: z.optional(z.unknown()), | ||
| properties: z.optional(z.object({}).loose()), | ||
| }), | ||
| /** | ||
@@ -168,0 +179,0 @@ * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
653728
11%32
3.23%10459
10.4%173
9.49%