diff --git a/docs/client.md b/docs/client.md index 0c852f4e1..6ba844b53 100644 --- a/docs/client.md +++ b/docs/client.md @@ -544,7 +544,7 @@ All requests have a 60-second default timeout. Pass a custom `timeout` in the op ```ts source="../examples/client/src/clientGuide.examples.ts#errorHandling_timeout" try { const result = await client.callTool( - { name: 'slow-operation', arguments: {} }, + { name: 'slow-task', arguments: {} }, { timeout: 120_000 } // 2 minutes instead of the default 60 seconds ); console.log(result.content); @@ -581,7 +581,7 @@ let lastToken: string | undefined; const result = await client.request( { method: 'tools/call', - params: { name: 'long-running-operation', arguments: {} } + params: { name: 'long-running-task', arguments: {} } }, { resumptionToken: lastToken, diff --git a/packages/client/src/client/client.ts b/packages/client/src/client/client.ts index f9894c6f1..2044cfc45 100644 --- a/packages/client/src/client/client.ts +++ b/packages/client/src/client/client.ts @@ -4,8 +4,6 @@ import type { CallToolRequest, ClientCapabilities, ClientContext, - ClientNotification, - ClientRequest, CompleteRequest, GetPromptRequest, Implementation, @@ -498,7 +496,7 @@ export class Client extends Protocol { } protected assertCapabilityForMethod(method: RequestMethod | string): void { - switch (method as ClientRequest['method']) { + switch (method as RequestMethod) { case 'logging/setLevel': { if (!this._serverCapabilities?.logging) { throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support logging (required for ${method})`); @@ -561,7 +559,7 @@ export class Client extends Protocol { } protected assertNotificationCapability(method: NotificationMethod | string): void { - switch (method as ClientNotification['method']) { + switch (method as NotificationMethod) { case 'notifications/roots/list_changed': { if (!this._capabilities.roots?.listChanged) { throw new SdkError( diff --git a/packages/core/src/types/guards.ts b/packages/core/src/types/guards.ts index c8185320a..f1930dfb0 100644 --- a/packages/core/src/types/guards.ts +++ b/packages/core/src/types/guards.ts @@ -1,7 +1,7 @@ +import type { InitializedNotification, InitializeRequest } from './legacyWireSchemas.js'; +import { InitializedNotificationSchema, InitializeRequestSchema } from './legacyWireSchemas.js'; import { CallToolResultSchema, - InitializedNotificationSchema, - InitializeRequestSchema, JSONRPCErrorResponseSchema, JSONRPCMessageSchema, JSONRPCNotificationSchema, @@ -14,8 +14,6 @@ import type { CompleteRequest, CompleteRequestPrompt, CompleteRequestResourceTemplate, - InitializedNotification, - InitializeRequest, JSONRPCErrorResponse, JSONRPCMessage, JSONRPCNotification, diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts index c150aea73..18c6feb5e 100644 --- a/packages/core/src/types/index.ts +++ b/packages/core/src/types/index.ts @@ -4,6 +4,9 @@ export * from './constants.js'; export * from './enums.js'; export * from './errors.js'; export * from './guards.js'; +/* eslint-disable import/export -- legacy type names overlap with types.ts re-exports; TS resolves deterministically. */ +export * from './legacyWireSchemas.js'; export * from './schemas.js'; export * from './specTypeSchema.js'; export * from './types.js'; +/* eslint-enable import/export */ diff --git a/packages/core/src/types/legacyWireSchemas.ts b/packages/core/src/types/legacyWireSchemas.ts new file mode 100644 index 000000000..700aa57a0 --- /dev/null +++ b/packages/core/src/types/legacyWireSchemas.ts @@ -0,0 +1,268 @@ +/** + * Pre-2026 wire types and schemas. + * + * These types represent JSON-RPC methods and notifications that were part of + * MCP up to and including 2025-11-25 but are removed from the 2026-06 draft + * spec. They are NOT in the current `spec.types.ts` (regenerated from the + * spec repo) and are SDK-maintained here so `LegacyServer` / `LegacyClient` + * can continue to speak the pre-2026 wire protocol. + * + * Deleted when pre-2026 protocol support is dropped. + */ +import * as z from 'zod/v4'; + +import { + ClientCapabilitiesSchema, + ImplementationSchema, + LoggingLevelSchema, + NotificationSchema, + ProgressTokenSchema, + registerLegacySchemas, + ServerCapabilitiesSchema +} from './schemas.js'; +import type { + ClientCapabilities, + Implementation, + JSONRPCNotification, + JSONRPCRequest, + LoggingLevel, + MetaObject, + NotificationParams, + ProgressToken, + ServerCapabilities +} from './spec.types.js'; + +/* ────────────────────────────────────────────────────────────────────────── */ +/* Legacy base shapes */ +/* */ +/* The 2026-06 spec's `RequestParams._meta` is required and carries */ +/* namespaced `io.modelcontextprotocol/*` keys. Pre-2026 requests have an */ +/* optional `_meta` with only `progressToken`. These local base types let */ +/* the legacy interfaces below avoid the strict 2026 shape. */ +/* ────────────────────────────────────────────────────────────────────────── */ + +/** Pre-2026 `_meta` shape: only `progressToken`, no namespaced keys. */ +export interface LegacyRequestMetaObject extends MetaObject { + progressToken?: ProgressToken; +} + +/** Pre-2026 request params: `_meta` is optional. */ +export interface LegacyRequestParams { + _meta?: LegacyRequestMetaObject; + [key: string]: unknown; +} + +/** Pre-2026 result: no `resultType`. */ +export interface LegacyResult { + _meta?: MetaObject; + [key: string]: unknown; +} + +/* Zod base shapes for legacy schemas. Kept separate from `schemas.ts` so the + * 2026 file is spec-only at the source level. The shapes here are the pre-2026 + * wire format (no namespaced `_meta` keys, no `resultType`). */ + +const LegacyRequestMetaSchema = z.looseObject({ + progressToken: ProgressTokenSchema.optional() +}); + +const LegacyBaseRequestParamsSchema = z.object({ + _meta: LegacyRequestMetaSchema.optional() +}); + +const LegacyRequestSchema = z.object({ + method: z.string(), + params: LegacyBaseRequestParamsSchema.loose().optional() +}); + +const LegacyResultSchema = z.looseObject({ + _meta: z.record(z.string(), z.unknown()).optional() +}); + +/* ────────────────────────────────────────────────────────────────────────── */ +/* `initialize` / `notifications/initialized` */ +/* ────────────────────────────────────────────────────────────────────────── */ + +export interface InitializeRequestParams extends LegacyRequestParams { + /** + * The latest version of the Model Context Protocol that the client + * supports. The client MAY decide to support older versions as well. + */ + protocolVersion: string; + capabilities: ClientCapabilities; + clientInfo: Implementation; +} + +export interface InitializeRequest extends JSONRPCRequest { + method: 'initialize'; + params: InitializeRequestParams; +} + +export interface InitializeResult extends LegacyResult { + /** + * The version of the Model Context Protocol that the server wants to use. + * This may not match the version that the client requested. If the client + * cannot support this version, it MUST disconnect. + */ + protocolVersion: string; + capabilities: ServerCapabilities; + serverInfo: Implementation; + /** + * Instructions describing how to use the server and its features. + */ + instructions?: string; +} + +export interface InitializedNotification extends JSONRPCNotification { + method: 'notifications/initialized'; + params?: NotificationParams; +} + +export const InitializeRequestParamsSchema = LegacyBaseRequestParamsSchema.extend({ + protocolVersion: z.string(), + capabilities: ClientCapabilitiesSchema, + clientInfo: ImplementationSchema +}); + +export const InitializeRequestSchema = LegacyRequestSchema.extend({ + method: z.literal('initialize'), + params: InitializeRequestParamsSchema +}); + +export const InitializeResultSchema = LegacyResultSchema.extend({ + protocolVersion: z.string(), + capabilities: ServerCapabilitiesSchema, + serverInfo: ImplementationSchema, + instructions: z.string().optional() +}); + +export const InitializedNotificationSchema = NotificationSchema.extend({ + method: z.literal('notifications/initialized') +}); + +/* ────────────────────────────────────────────────────────────────────────── */ +/* `ping` */ +/* ────────────────────────────────────────────────────────────────────────── */ + +export interface PingRequest extends JSONRPCRequest { + method: 'ping'; + params?: LegacyRequestParams; +} + +export const PingRequestSchema = LegacyRequestSchema.extend({ + method: z.literal('ping') +}); + +/* ────────────────────────────────────────────────────────────────────────── */ +/* `logging/setLevel` */ +/* ────────────────────────────────────────────────────────────────────────── */ + +export interface SetLevelRequestParams extends LegacyRequestParams { + /** + * The level of logging that the client wants to receive from the server. + */ + level: LoggingLevel; +} + +export interface SetLevelRequest extends JSONRPCRequest { + method: 'logging/setLevel'; + params: SetLevelRequestParams; +} + +export const SetLevelRequestParamsSchema = LegacyBaseRequestParamsSchema.extend({ + level: LoggingLevelSchema +}); + +export const SetLevelRequestSchema = LegacyRequestSchema.extend({ + method: z.literal('logging/setLevel'), + params: SetLevelRequestParamsSchema +}); + +/* ────────────────────────────────────────────────────────────────────────── */ +/* `resources/subscribe` / `resources/unsubscribe` */ +/* ────────────────────────────────────────────────────────────────────────── */ + +export interface SubscribeRequestParams extends LegacyRequestParams { + /** The URI of the resource to subscribe to. */ + uri: string; +} + +export interface SubscribeRequest extends JSONRPCRequest { + method: 'resources/subscribe'; + params: SubscribeRequestParams; +} + +export type UnsubscribeRequestParams = SubscribeRequestParams; + +export interface UnsubscribeRequest extends JSONRPCRequest { + method: 'resources/unsubscribe'; + params: UnsubscribeRequestParams; +} + +export const SubscribeRequestParamsSchema = LegacyBaseRequestParamsSchema.extend({ + uri: z.string() +}); + +export const SubscribeRequestSchema = LegacyRequestSchema.extend({ + method: z.literal('resources/subscribe'), + params: SubscribeRequestParamsSchema +}); + +export const UnsubscribeRequestParamsSchema = SubscribeRequestParamsSchema; + +export const UnsubscribeRequestSchema = LegacyRequestSchema.extend({ + method: z.literal('resources/unsubscribe'), + params: UnsubscribeRequestParamsSchema +}); + +/* ────────────────────────────────────────────────────────────────────────── */ +/* `notifications/roots/list_changed` (client → server) */ +/* ────────────────────────────────────────────────────────────────────────── */ + +export interface RootsListChangedNotification extends JSONRPCNotification { + method: 'notifications/roots/list_changed'; + params?: NotificationParams; +} + +export const RootsListChangedNotificationSchema = NotificationSchema.extend({ + method: z.literal('notifications/roots/list_changed') +}); + +/* ────────────────────────────────────────────────────────────────────────── */ +/* Maps for legacy method/result/notification dispatch */ +/* ────────────────────────────────────────────────────────────────────────── */ + +/** Legacy request methods that are not in the 2026-06 `RequestTypeMap`. */ +export const legacyRequestSchemas = { + initialize: InitializeRequestSchema, + ping: PingRequestSchema, + 'logging/setLevel': SetLevelRequestSchema, + 'resources/subscribe': SubscribeRequestSchema, + 'resources/unsubscribe': UnsubscribeRequestSchema +} as const; + +/** Legacy result schemas keyed by request method. */ +export const legacyResultSchemas = { + initialize: InitializeResultSchema, + ping: LegacyResultSchema, + 'logging/setLevel': LegacyResultSchema, + 'resources/subscribe': LegacyResultSchema, + 'resources/unsubscribe': LegacyResultSchema +} as const; + +/** Legacy notification methods that are not in the 2026-06 `NotificationTypeMap`. */ +export const legacyNotificationSchemas = { + 'notifications/initialized': InitializedNotificationSchema, + 'notifications/roots/list_changed': RootsListChangedNotificationSchema +} as const; + +export type LegacyRequestMethod = keyof typeof legacyRequestSchemas; +export type LegacyNotificationMethod = keyof typeof legacyNotificationSchemas; + +// Merge into the runtime lookup maps so `getRequestSchema('initialize')` etc. +// continue to work. Runs at module load (this file is barrel-imported). +registerLegacySchemas({ + requests: legacyRequestSchemas, + results: legacyResultSchemas, + notifications: legacyNotificationSchemas +}); diff --git a/packages/core/src/types/schemas.ts b/packages/core/src/types/schemas.ts index e53be3dd1..8060fa6c7 100644 --- a/packages/core/src/types/schemas.ts +++ b/packages/core/src/types/schemas.ts @@ -27,6 +27,21 @@ export const ProgressTokenSchema = z.union([z.string(), z.number().int()]); */ export const CursorSchema = z.string(); +/** + * Request `_meta` shape. + * + * The 2026-06 spec marks the namespaced `io.modelcontextprotocol/*` keys as + * required. They are intentionally NOT enumerated in this zod schema: + * + * 1. Adding `ClientCapabilitiesSchema`/`ImplementationSchema` here (even lazy) + * pushes every request-type inference past TS2589's depth budget. + * 2. The same base schema must validate pre-2026 (no namespaced keys) and 2026 + * (keys present) wire shapes. + * 3. Strict validation of the namespaced keys is owned by `parseClientMeta` + * in `core/shared/stateless.ts` (P2), invoked from `_dispatchStateless`. + * + * `looseObject` passes through unknown keys, so 2026 `_meta` shapes parse fine. + */ export const RequestMetaSchema = z.looseObject({ /** * If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications. @@ -34,6 +49,9 @@ export const RequestMetaSchema = z.looseObject({ progressToken: ProgressTokenSchema.optional() }); +/** Alias mirroring `spec.types.ts` naming. */ +export const RequestMetaObjectSchema = RequestMetaSchema; + /** * Common params for any request. */ @@ -49,12 +67,15 @@ export const RequestSchema = z.object({ params: BaseRequestParamsSchema.loose().optional() }); +/** Generic `MetaObject` (open record). */ +export const MetaObjectSchema = z.record(z.string(), z.unknown()); + export const NotificationsParamsSchema = z.object({ /** * See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields) * for notes on `_meta` usage. */ - _meta: RequestMetaSchema.optional() + _meta: MetaObjectSchema.optional() }); export const NotificationSchema = z.object({ @@ -62,12 +83,20 @@ export const NotificationSchema = z.object({ params: NotificationsParamsSchema.loose().optional() }); +export const ResultTypeSchema = z.enum(['complete', 'input_required']); + export const ResultSchema = z.looseObject({ /** * See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields) * for notes on `_meta` usage. */ - _meta: RequestMetaSchema.optional() + _meta: MetaObjectSchema.optional(), + /** + * Indicates the type of the result. Spec marks this required for 2026-06 + * servers; kept optional here so the schema also accepts pre-2026 results + * (which omit it). Clients MUST treat absent as `"complete"`. + */ + resultType: ResultTypeSchema.optional() }); /** @@ -166,7 +195,7 @@ export const CancelledNotificationParamsSchema = NotificationsParamsSchema.exten * * This notification indicates that the result will be unused, so any associated processing SHOULD cease. * - * A client MUST NOT attempt to cancel its {@linkcode InitializeRequest | initialize} request. + * A client MUST NOT attempt to cancel its `initialize` (pre-2026) or `server/discover` request. */ export const CancelledNotificationSchema = NotificationSchema.extend({ method: z.literal('notifications/cancelled'), @@ -323,26 +352,11 @@ export const ClientCapabilitiesSchema = z.object({ */ listChanged: z.boolean().optional() }) - .optional() /** - * Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name). - */, - extensions: z.record(z.string(), JSONObjectSchema).optional() -}); - -export const InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({ + .optional(), /** - * The latest version of the Model Context Protocol that the client supports. The client MAY decide to support older versions as well. + * Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name). */ - protocolVersion: z.string(), - capabilities: ClientCapabilitiesSchema, - clientInfo: ImplementationSchema -}); -/** - * This request is sent from the client to the server when it first connects, asking it to begin initialization. - */ -export const InitializeRequestSchema = RequestSchema.extend({ - method: z.literal('initialize'), - params: InitializeRequestParamsSchema + extensions: z.record(z.string(), JSONObjectSchema).optional() }); /** @@ -398,45 +412,40 @@ export const ServerCapabilitiesSchema = z.object({ */ listChanged: z.boolean().optional() }) - .optional() /** + .optional(), + /** * Extensions that the server supports. Keys are extension identifiers (vendor-prefix/extension-name). - */, + */ extensions: z.record(z.string(), JSONObjectSchema).optional() }); +/* Discover (2026-06 negotiation) */ + /** - * After receiving an initialize request from the client, the server sends this response. + * Sent by the client to discover the server's supported protocol versions + * and capabilities. Replaces the pre-2026 `initialize` handshake. */ -export const InitializeResultSchema = ResultSchema.extend({ - /** - * The version of the Model Context Protocol that the server wants to use. This may not match the version that the client requested. If the client cannot support this version, it MUST disconnect. - */ - protocolVersion: z.string(), +export const DiscoverRequestSchema = RequestSchema.extend({ + method: z.literal('server/discover'), + params: BaseRequestParamsSchema.optional() +}); + +export const DiscoverResultSchema = ResultSchema.extend({ + supportedVersions: z.array(z.string()), capabilities: ServerCapabilitiesSchema, serverInfo: ImplementationSchema, - /** - * Instructions describing how to use the server and its features. - * - * This can be used by clients to improve the LLM's understanding of available tools, resources, etc. It can be thought of like a "hint" to the model. For example, this information MAY be added to the system prompt. - */ instructions: z.string().optional() }); -/** - * This notification is sent from the client to the server after initialization has finished. - */ -export const InitializedNotificationSchema = NotificationSchema.extend({ - method: z.literal('notifications/initialized'), - params: NotificationsParamsSchema.optional() +/* Error data shapes */ + +export const UnsupportedProtocolVersionErrorDataSchema = z.object({ + supported: z.array(z.string()), + requested: z.string() }); -/* Ping */ -/** - * A ping, issued by either the server or the client, to check that the other party is still alive. The receiver must promptly respond, or else may be disconnected. - */ -export const PingRequestSchema = RequestSchema.extend({ - method: z.literal('ping'), - params: BaseRequestParamsSchema.optional() +export const MissingRequiredClientCapabilityErrorDataSchema = z.object({ + requiredCapabilities: ClientCapabilitiesSchema }); /* Progress notifications */ @@ -486,7 +495,21 @@ export const PaginatedRequestSchema = RequestSchema.extend({ params: PaginatedRequestParamsSchema.optional() }); -export const PaginatedResultSchema = ResultSchema.extend({ +/* Caching (SEP-2243) */ + +export const CacheScopeSchema = z.enum(['public', 'private']); + +/** + * Result fields for cache hints. Spec marks `ttlMs`/`cacheScope` required; + * kept optional here so the schema accepts servers that have not yet + * implemented SEP-2243. + */ +export const CacheableResultSchema = ResultSchema.extend({ + ttlMs: z.number().int().nonnegative().optional(), + cacheScope: CacheScopeSchema.optional() +}); + +export const PaginatedResultSchema = CacheableResultSchema.extend({ /** * An opaque token representing the pagination position after the last returned result. * If present, there may be more results available. @@ -702,7 +725,7 @@ export const ReadResourceRequestSchema = RequestSchema.extend({ /** * The server's response to a {@linkcode ReadResourceRequest | resources/read} request from the client. */ -export const ReadResourceResultSchema = ResultSchema.extend({ +export const ReadResourceResultSchema = CacheableResultSchema.extend({ contents: z.array(z.union([TextResourceContentsSchema, BlobResourceContentsSchema])) }); @@ -714,24 +737,6 @@ export const ResourceListChangedNotificationSchema = NotificationSchema.extend({ params: NotificationsParamsSchema.optional() }); -export const SubscribeRequestParamsSchema = ResourceRequestParamsSchema; -/** - * Sent from the client to request `resources/updated` notifications from the server whenever a particular resource changes. - */ -export const SubscribeRequestSchema = RequestSchema.extend({ - method: z.literal('resources/subscribe'), - params: SubscribeRequestParamsSchema -}); - -export const UnsubscribeRequestParamsSchema = ResourceRequestParamsSchema; -/** - * Sent from the client to request cancellation of {@linkcode ResourceUpdatedNotification | resources/updated} notifications from the server. This should follow a previous {@linkcode SubscribeRequest | resources/subscribe} request. - */ -export const UnsubscribeRequestSchema = RequestSchema.extend({ - method: z.literal('resources/unsubscribe'), - params: UnsubscribeRequestParamsSchema -}); - /** * Parameters for a {@linkcode ResourceUpdatedNotification | notifications/resources/updated} notification. */ @@ -743,13 +748,40 @@ export const ResourceUpdatedNotificationParamsSchema = NotificationsParamsSchema }); /** - * A notification from the server to the client, informing it that a resource has changed and may need to be read again. This should only be sent if the client previously sent a {@linkcode SubscribeRequest | resources/subscribe} request. + * A notification from the server to the client, informing it that a resource has changed and may need to be read again. */ export const ResourceUpdatedNotificationSchema = NotificationSchema.extend({ method: z.literal('notifications/resources/updated'), params: ResourceUpdatedNotificationParamsSchema }); +/* Subscriptions (2026-06) */ + +export const SubscriptionFilterSchema = z.object({ + toolsListChanged: z.boolean().optional(), + promptsListChanged: z.boolean().optional(), + resourcesListChanged: z.boolean().optional(), + resourceSubscriptions: z.array(z.string()).optional() +}); + +export const SubscriptionsListenRequestParamsSchema = BaseRequestParamsSchema.extend({ + notifications: SubscriptionFilterSchema +}); + +export const SubscriptionsListenRequestSchema = RequestSchema.extend({ + method: z.literal('subscriptions/listen'), + params: SubscriptionsListenRequestParamsSchema +}); + +export const SubscriptionsAcknowledgedNotificationParamsSchema = NotificationsParamsSchema.extend({ + notifications: SubscriptionFilterSchema +}); + +export const SubscriptionsAcknowledgedNotificationSchema = NotificationSchema.extend({ + method: z.literal('notifications/subscriptions/acknowledged'), + params: SubscriptionsAcknowledgedNotificationParamsSchema +}); + /* Prompts */ /** * Describes an argument that a prompt can accept. @@ -1046,14 +1078,6 @@ export const ToolAnnotationsSchema = z.object({ openWorldHint: z.boolean().optional() }); -/** - * Execution-related properties for a tool. - */ -export const ToolExecutionSchema = z.object({ - // taskSupport field removed in P0.2 alongside spec.types.ts regen (kept here only while spec.types.ts still declares it). - taskSupport: z.enum(['required', 'optional', 'forbidden']).optional() -}); - /** * Definition for a tool the client can call. */ @@ -1071,20 +1095,16 @@ export const ToolSchema = z.object({ inputSchema: z .object({ type: z.literal('object'), - properties: z.record(z.string(), JSONValueSchema).optional(), - required: z.array(z.string()).optional() + $schema: z.string().optional() }) .catchall(z.unknown()), /** * An optional JSON Schema 2020-12 object defining the structure of the tool's output * returned in the `structuredContent` field of a `CallToolResult`. - * Must have `type: 'object'` at the root level per MCP spec. */ outputSchema: z .object({ - type: z.literal('object'), - properties: z.record(z.string(), JSONValueSchema).optional(), - required: z.array(z.string()).optional() + $schema: z.string().optional() }) .catchall(z.unknown()) .optional(), @@ -1092,10 +1112,6 @@ export const ToolSchema = z.object({ * Optional additional tool information. */ annotations: ToolAnnotationsSchema.optional(), - /** - * Execution-related properties for this tool. - */ - execution: ToolExecutionSchema.optional(), /** * See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields) @@ -1135,7 +1151,7 @@ export const CallToolResultSchema = ResultSchema.extend({ * * If the `Tool` defines an outputSchema, this field MUST be present in the result, and contain a JSON object that matches the schema. */ - structuredContent: z.record(z.string(), z.unknown()).optional(), + structuredContent: z.unknown().optional(), /** * Whether the tool call ended in an error. @@ -1224,23 +1240,6 @@ export const ListChangedOptionsBaseSchema = z.object({ */ export const LoggingLevelSchema = z.enum(['debug', 'info', 'notice', 'warning', 'error', 'critical', 'alert', 'emergency']); -/** - * Parameters for a `logging/setLevel` request. - */ -export const SetLevelRequestParamsSchema = BaseRequestParamsSchema.extend({ - /** - * The level of logging that the client wants to receive from the server. The server should send all logs at this level and higher (i.e., more severe) to the client as `notifications/logging/message`. - */ - level: LoggingLevelSchema -}); -/** - * A request from the client to the server, to enable or adjust logging. - */ -export const SetLevelRequestSchema = RequestSchema.extend({ - method: z.literal('logging/setLevel'), - params: SetLevelRequestParamsSchema -}); - /** * Parameters for a `notifications/message` notification. */ @@ -1320,7 +1319,7 @@ export const ToolResultContentSchema = z.object({ type: z.literal('tool_result'), toolUseId: z.string().describe('The unique identifier for the corresponding tool call.'), content: z.array(ContentBlockSchema).default([]), - structuredContent: z.object({}).loose().optional(), + structuredContent: z.unknown().optional(), isError: z.boolean().optional(), /** @@ -1824,37 +1823,53 @@ export const ListRootsResultSchema = ResultSchema.extend({ roots: z.array(RootSchema) }); +/* MRTR (input_required) */ + /** - * A notification from the client to the server, informing it that the list of roots has changed. + * Union of request shapes a server may include in `inputRequests`. + * These are the same shapes as the (now-removed) standalone server→client RPCs. */ -export const RootsListChangedNotificationSchema = NotificationSchema.extend({ - method: z.literal('notifications/roots/list_changed'), - params: NotificationsParamsSchema.optional() +export const InputRequestSchema = z.union([CreateMessageRequestSchema, ElicitRequestSchema, ListRootsRequestSchema]); + +export const InputRequestsSchema = z.record(z.string(), InputRequestSchema); + +export const InputResponseSchema = z.union([CreateMessageResultWithToolsSchema, ElicitResultSchema, ListRootsResultSchema]); + +export const InputResponsesSchema = z.record(z.string(), InputResponseSchema); + +/** + * Result indicating the server requires additional input before completing. + * At least one of `inputRequests` or `requestState` MUST be present. + */ +export const InputRequiredResultSchema = ResultSchema.extend({ + resultType: z.literal('input_required'), + inputRequests: InputRequestsSchema.optional(), + requestState: z.string().optional() +}); + +/** + * Request params carrying responses to a prior `input_required` result. + */ +export const InputResponseRequestParamsSchema = BaseRequestParamsSchema.extend({ + inputResponses: InputResponsesSchema.optional(), + requestState: z.string().optional() }); -/* Client messages */ +/* Client messages (2026 spec methods only — legacy methods are merged in `types.ts` from `legacyWireSchemas.ts`) */ export const ClientRequestSchema = z.union([ - PingRequestSchema, - InitializeRequestSchema, + DiscoverRequestSchema, CompleteRequestSchema, - SetLevelRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ReadResourceRequestSchema, - SubscribeRequestSchema, - UnsubscribeRequestSchema, CallToolRequestSchema, - ListToolsRequestSchema + ListToolsRequestSchema, + SubscriptionsListenRequestSchema ]); -export const ClientNotificationSchema = z.union([ - CancelledNotificationSchema, - ProgressNotificationSchema, - InitializedNotificationSchema, - RootsListChangedNotificationSchema -]); +export const ClientNotificationSchema = z.union([CancelledNotificationSchema, ProgressNotificationSchema]); export const ClientResultSchema = z.union([ EmptyResultSchema, @@ -1864,8 +1879,11 @@ export const ClientResultSchema = z.union([ ListRootsResultSchema ]); -/* Server messages */ -export const ServerRequestSchema = z.union([PingRequestSchema, CreateMessageRequestSchema, ElicitRequestSchema, ListRootsRequestSchema]); +/* Server messages. Under 2026 stateless these three are not sent as RPCs; + * they appear as InputRequest payloads inside InputRequiredResult. The + * schemas are still needed for legacy server→client RPCs and for MRTR + * payload validation. */ +export const ServerRequestSchema = z.union([CreateMessageRequestSchema, ElicitRequestSchema, ListRootsRequestSchema]); export const ServerNotificationSchema = z.union([ CancelledNotificationSchema, @@ -1875,12 +1893,14 @@ export const ServerNotificationSchema = z.union([ ResourceListChangedNotificationSchema, ToolListChangedNotificationSchema, PromptListChangedNotificationSchema, - ElicitationCompleteNotificationSchema + ElicitationCompleteNotificationSchema, + SubscriptionsAcknowledgedNotificationSchema ]); export const ServerResultSchema = z.union([ EmptyResultSchema, - InitializeResultSchema, + DiscoverResultSchema, + InputRequiredResultSchema, CompleteResultSchema, GetPromptResultSchema, ListPromptsResultSchema, @@ -1891,21 +1911,20 @@ export const ServerResultSchema = z.union([ ListToolsResultSchema ]); -/* Runtime schema lookup — result schemas by method */ +/* Runtime schema lookup — result schemas by method. + * 2026 spec methods are seeded here; pre-2026 methods are merged in by + * `legacyWireSchemas.ts` at module load via `registerLegacySchemas()`. */ const resultSchemas: Record = { - ping: EmptyResultSchema, - initialize: InitializeResultSchema, + 'server/discover': DiscoverResultSchema, 'completion/complete': CompleteResultSchema, - 'logging/setLevel': EmptyResultSchema, 'prompts/get': GetPromptResultSchema, 'prompts/list': ListPromptsResultSchema, 'resources/list': ListResourcesResultSchema, 'resources/templates/list': ListResourceTemplatesResultSchema, 'resources/read': ReadResourceResultSchema, - 'resources/subscribe': EmptyResultSchema, - 'resources/unsubscribe': EmptyResultSchema, 'tools/call': CallToolResultSchema, 'tools/list': ListToolsResultSchema, + 'subscriptions/listen': EmptyResultSchema, 'sampling/createMessage': CreateMessageResultWithToolsSchema, 'elicitation/create': ElicitResultSchema, 'roots/list': ListRootsResultSchema @@ -1923,9 +1942,6 @@ export function getResultSchema(method: string): z.ZodType | undefined { } /* Runtime schema lookup — request schemas by method */ -type RequestSchemaType = (typeof ClientRequestSchema.options)[number] | (typeof ServerRequestSchema.options)[number]; -type NotificationSchemaType = (typeof ClientNotificationSchema.options)[number] | (typeof ServerNotificationSchema.options)[number]; - function buildSchemaMap(schemas: readonly T[]): Record { const map: Record = {}; for (const schema of schemas) { @@ -1936,14 +1952,30 @@ function buildSchemaMap(sche } const requestSchemas = buildSchemaMap([...ClientRequestSchema.options, ...ServerRequestSchema.options] as const) as Record< - RequestMethod, - RequestSchemaType + string, + z.core.$ZodType >; const notificationSchemas = buildSchemaMap([...ClientNotificationSchema.options, ...ServerNotificationSchema.options] as const) as Record< - NotificationMethod, - NotificationSchemaType + string, + z.core.$ZodType >; +/** + * Called by `legacyWireSchemas.ts` at module load to merge pre-2026 method + * schemas into the runtime lookup maps. Keeps `schemas.ts` 2026-only at the + * source level while preserving legacy `getRequestSchema('initialize')` etc. + * @internal + */ +export function registerLegacySchemas(legacy: { + requests: Record; + results: Record; + notifications: Record; +}): void { + Object.assign(requestSchemas, legacy.requests); + Object.assign(resultSchemas, legacy.results); + Object.assign(notificationSchemas, legacy.notifications); +} + /** * Gets the Zod schema for a given request method. * Returns `undefined` for non-spec methods. diff --git a/packages/core/src/types/spec.types.ts b/packages/core/src/types/spec.types.ts index a03f21f13..389e279e6 100644 --- a/packages/core/src/types/spec.types.ts +++ b/packages/core/src/types/spec.types.ts @@ -3,7 +3,7 @@ * * Source: https://github.com/modelcontextprotocol/modelcontextprotocol * Pulled from: https://raw.githubusercontent.com/modelcontextprotocol/modelcontextprotocol/main/schema/draft/schema.ts - * Last updated from commit: 5c25208be86db5033f644a4e0d005e08f699ef3d + * Last updated from commit: 142b3c3cffcd10012e3dc1b07db5818877e64f9b * * DO NOT EDIT THIS FILE MANUALLY. Changes will be overwritten by automated updates. * To update this file, run: pnpm run fetch:spec-types @@ -71,6 +71,38 @@ export interface RequestMetaObject extends MetaObject { * If specified, the caller is requesting out-of-band progress notifications for this request (as represented by {@link ProgressNotification | notifications/progress}). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications. */ progressToken?: ProgressToken; + /** + * The MCP Protocol Version being used for this request. Required. + * + * For the HTTP transport, this value MUST match the `MCP-Protocol-Version` + * header; otherwise the server MUST return a `400 Bad Request`. If the + * server does not support the requested version, it MUST return an + * {@link UnsupportedProtocolVersionError}. + */ + 'io.modelcontextprotocol/protocolVersion': string; + /** + * Identifies the client software making the request. Required. + * + * The {@link Implementation} schema requires `name` and `version`; other + * fields are optional. + */ + 'io.modelcontextprotocol/clientInfo': Implementation; + /** + * The client's capabilities for this specific request. Required. + * + * Capabilities are declared per-request rather than once at initialization; + * an empty object means the client supports no optional capabilities. + * Servers MUST NOT infer capabilities from prior requests. + */ + 'io.modelcontextprotocol/clientCapabilities': ClientCapabilities; + /** + * The desired log level for this request. Optional. + * + * If absent, the server MUST NOT send any {@link LoggingMessageNotification | notifications/message} + * notifications for this request. The client opts in to log messages by + * explicitly setting a level. Replaces the former `logging/setLevel` RPC. + */ + 'io.modelcontextprotocol/logLevel'?: LoggingLevel; } /** @@ -87,30 +119,13 @@ export type ProgressToken = string | number; */ export type Cursor = string; -/** - * Common params for any task-augmented request. - * - * @internal - */ -export interface TaskAugmentedRequestParams extends RequestParams { - /** - * If specified, the caller is requesting task-augmented execution for this request. - * The request will return a {@link CreateTaskResult} immediately, and the actual result can be - * retrieved later via {@link GetTaskPayloadRequest | tasks/result}. - * - * Task augmentation is subject to capability negotiation - receivers MUST declare support - * for task augmentation of specific request types in their capabilities. - */ - task?: TaskMetadata; -} - /** * Common params for any request. * * @category Common Types */ export interface RequestParams { - _meta?: RequestMetaObject; + _meta: RequestMetaObject; } /** @internal */ @@ -138,6 +153,16 @@ export interface Notification { params?: { [key: string]: any }; } +/** + * Indicates the type of a {@link Result} object, allowing the client to + * determine how to parse the response. + * + * complete - the request completed successfully and the result contains the final content. + * input_required - the request requires additional input and the result contains an {@link InputRequiredResult} object with instructions for the client to provide additional input before retrying the original request. + * @category Common Types + */ +export type ResultType = 'complete' | 'input_required'; + /** * Common result fields. * @@ -145,6 +170,16 @@ export interface Notification { */ export interface Result { _meta?: MetaObject; + /** + * Indicates the type of the result, which allows the client to determine + * how to parse the result object. + * + * Servers implementing this protocol version MUST include this field. + * For backward compatibility, when a client receives a result from a + * server implementing an earlier protocol version (which does not include + * `resultType`), the client MUST treat the absent field as `"complete"`. + */ + resultType: ResultType; [key: string]: unknown; } @@ -281,7 +316,6 @@ export interface MethodNotFoundError extends Error { * - **Prompts**: Unknown prompt name or missing required arguments * - **Pagination**: Invalid or expired cursor values * - **Logging**: Invalid log level - * - **Tasks**: Invalid or nonexistent task ID, invalid cursor, or attempting to cancel a task already in a terminal status * - **Elicitation**: Server requests an elicitation mode not declared in client capabilities * - **Sampling**: Missing tool result or tool results mixed with other content * @@ -319,24 +353,60 @@ export interface InternalError extends Error { code: typeof INTERNAL_ERROR; } -// Implementation-specific JSON-RPC error codes [-32000, -32099] -/** @internal */ -export const URL_ELICITATION_REQUIRED = -32042; +/** + * Error code returned when a server requires a client capability that was + * not declared in the request's `clientCapabilities`. + * + * @category Errors + */ +export const MISSING_REQUIRED_CLIENT_CAPABILITY = -32003; /** - * An error response that indicates that the server requires the client to provide additional information via an elicitation request. + * Returned when the request's protocol version is unknown to the server or + * unsupported (e.g., a known experimental or draft version the server has + * chosen not to implement). For HTTP, the response status code MUST be + * `400 Bad Request`. * - * @example Authorization required - * {@includeCode ./examples/URLElicitationRequiredError/authorization-required.json} + * @example Unsupported protocol version + * {@includeCode ./examples/UnsupportedProtocolVersionError/unsupported-version.json} * - * @internal + * @category Errors */ -export interface URLElicitationRequiredError extends Omit { +export interface UnsupportedProtocolVersionError extends Omit { error: Error & { - code: typeof URL_ELICITATION_REQUIRED; + code: typeof INVALID_PARAMS; data: { - elicitations: ElicitRequestURLParams[]; - [key: string]: unknown; + /** + * Protocol versions the server supports. The client should choose a + * mutually supported version from this list and retry. + */ + supported: string[]; + /** + * The protocol version that was requested by the client. + */ + requested: string; + }; + }; +} + +/** + * Returned when processing a request requires a capability the client did not + * declare in `clientCapabilities`. For HTTP, the response status code MUST be + * `400 Bad Request`. + * + * @example Missing elicitation capability + * {@includeCode ./examples/MissingRequiredClientCapabilityError/missing-elicitation-capability.json} + * + * @category Errors + */ +export interface MissingRequiredClientCapabilityError extends Omit { + error: Error & { + code: typeof MISSING_REQUIRED_CLIENT_CAPABILITY; + data: { + /** + * The capabilities the server requires from the client to process this request. + */ + requiredCapabilities: ClientCapabilities; }; }; } @@ -349,6 +419,79 @@ export interface URLElicitationRequiredError extends Omit; export type Annotations = Infer; export type Role = Infer; -/* Initialization */ +/* Capabilities & implementation */ export type Implementation = Infer; export type ClientCapabilities = Infer; -export type InitializeRequestParams = Infer; -export type InitializeRequest = Infer; export type ServerCapabilities = Infer; -export type InitializeResult = Infer; -export type InitializedNotification = Infer; -/* Ping */ -export type PingRequest = Infer; +/* Discover (2026-06 negotiation) */ +export type DiscoverRequest = Infer; +export type DiscoverResult = Infer; +export type UnsupportedProtocolVersionErrorData = Infer; +export type MissingRequiredClientCapabilityErrorData = Infer; + +/* Result type discriminator */ +export type ResultType = Infer; + +/* Caching (SEP-2243) */ +export type CacheScope = Infer; +export type CacheableResult = Infer; /* Progress notifications */ export type Progress = Infer; @@ -235,13 +269,16 @@ export type ReadResourceRequestParams = Infer; export type ReadResourceResult = Infer; export type ResourceListChangedNotification = Infer; -export type SubscribeRequestParams = Infer; -export type SubscribeRequest = Infer; -export type UnsubscribeRequestParams = Infer; -export type UnsubscribeRequest = Infer; export type ResourceUpdatedNotificationParams = Infer; export type ResourceUpdatedNotification = Infer; +/* Subscriptions (2026-06) */ +export type SubscriptionFilter = Infer; +export type SubscriptionsListenRequestParams = Infer; +export type SubscriptionsListenRequest = Infer; +export type SubscriptionsAcknowledgedNotificationParams = Infer; +export type SubscriptionsAcknowledgedNotification = Infer; + /* Prompts */ export type PromptArgument = Infer; export type Prompt = Infer; @@ -263,7 +300,6 @@ export type PromptListChangedNotification = Infer; -export type ToolExecution = Infer; export type Tool = Infer; export type ListToolsRequest = Infer; export type ListToolsResult = Infer; @@ -275,8 +311,6 @@ export type ToolListChangedNotification = Infer; -export type SetLevelRequestParams = Infer; -export type SetLevelRequest = Infer; export type LoggingMessageNotificationParams = Infer; export type LoggingMessageNotification = Infer; @@ -324,7 +358,14 @@ export type CompleteResult = Infer; export type Root = Infer; export type ListRootsRequest = Infer; export type ListRootsResult = Infer; -export type RootsListChangedNotification = Infer; + +/* MRTR (input_required) */ +export type InputRequest = Infer; +export type InputRequests = Infer; +export type InputResponse = Infer; +export type InputResponses = Infer; +export type InputRequiredResult = Infer; +export type InputResponseRequestParams = Infer; /* Client messages */ export type ClientRequest = Infer; @@ -336,31 +377,46 @@ export type ServerRequest = Infer; export type ServerNotification = Infer; export type ServerResult = Infer; -/* Protocol type maps */ +/* Protocol type maps — merge 2026 spec methods with pre-2026 (legacy) methods so + * `setRequestHandler('initialize', ...)` etc. continue to typecheck via the + * spec-method-keyed overload while LegacyServer/LegacyClient exist. + */ type MethodToTypeMap = { [T in U as T extends { method: infer M extends string } ? M : never]: T; }; -export type RequestMethod = ClientRequest['method'] | ServerRequest['method']; -export type NotificationMethod = ClientNotification['method'] | ServerNotification['method']; -export type RequestTypeMap = MethodToTypeMap; -export type NotificationTypeMap = MethodToTypeMap; +export type RequestMethod = ClientRequest['method'] | ServerRequest['method'] | legacy.LegacyRequestMethod; +export type NotificationMethod = ClientNotification['method'] | ServerNotification['method'] | legacy.LegacyNotificationMethod; +export type RequestTypeMap = MethodToTypeMap & { + initialize: legacy.InitializeRequest; + ping: legacy.PingRequest; + 'logging/setLevel': legacy.SetLevelRequest; + 'resources/subscribe': legacy.SubscribeRequest; + 'resources/unsubscribe': legacy.UnsubscribeRequest; +}; +export type NotificationTypeMap = MethodToTypeMap & { + 'notifications/initialized': legacy.InitializedNotification; + 'notifications/roots/list_changed': legacy.RootsListChangedNotification; +}; export type ResultTypeMap = { - ping: EmptyResult; - initialize: InitializeResult; + 'server/discover': DiscoverResult; 'completion/complete': CompleteResult; - 'logging/setLevel': EmptyResult; 'prompts/get': GetPromptResult; 'prompts/list': ListPromptsResult; 'resources/list': ListResourcesResult; 'resources/templates/list': ListResourceTemplatesResult; 'resources/read': ReadResourceResult; - 'resources/subscribe': EmptyResult; - 'resources/unsubscribe': EmptyResult; 'tools/call': CallToolResult; 'tools/list': ListToolsResult; + 'subscriptions/listen': EmptyResult; 'sampling/createMessage': CreateMessageResult | CreateMessageResultWithTools; 'elicitation/create': ElicitResult; 'roots/list': ListRootsResult; + // Pre-2026 methods (LegacyServer/LegacyClient): + initialize: legacy.InitializeResult; + ping: EmptyResult; + 'logging/setLevel': EmptyResult; + 'resources/subscribe': EmptyResult; + 'resources/unsubscribe': EmptyResult; }; /** diff --git a/packages/core/test/shared/protocol.test.ts b/packages/core/test/shared/protocol.test.ts index 8e23d8108..764dcc401 100644 --- a/packages/core/test/shared/protocol.test.ts +++ b/packages/core/test/shared/protocol.test.ts @@ -355,6 +355,33 @@ describe('protocol tests', () => { }); }); + describe('notifications/cancelled behavior', () => { + test('should abort request handler when notifications/cancelled is received', async () => { + await protocol.connect(transport); + + let wasAborted = false; + protocol.setRequestHandler('ping', async (_request, ctx) => { + await new Promise(resolve => setTimeout(resolve, 100)); + wasAborted = ctx.mcpReq.signal.aborted; + return {}; + }); + + const requestId = 123; + transport.onmessage?.({ jsonrpc: '2.0', id: requestId, method: 'ping', params: {} }); + + await new Promise(resolve => setTimeout(resolve, 10)); + + transport.onmessage?.({ + jsonrpc: '2.0', + method: 'notifications/cancelled', + params: { requestId, reason: 'User cancelled' } + }); + + await new Promise(resolve => setTimeout(resolve, 150)); + expect(wasAborted).toBe(true); + }); + }); + describe('progress notification timeout behavior', () => { beforeEach(() => { vi.useFakeTimers(); diff --git a/packages/core/test/spec.types.test.ts b/packages/core/test/spec.types.test.ts index 60cc57da8..61afbf548 100644 --- a/packages/core/test/spec.types.test.ts +++ b/packages/core/test/spec.types.test.ts @@ -1,9 +1,14 @@ /** * This contains: * - Static type checks to verify the Spec's types are compatible with the SDK's types - * (mutually assignable — no type-level workarounds should be needed) * - Runtime checks to verify each Spec type has a static check * (note: a few don't have SDK types, see MISSING_SDK_TYPES below) + * + * Compatibility direction: the 2026-06 spec marks several fields REQUIRED that the + * SDK's zod schemas keep OPTIONAL for backward compatibility (`_meta` namespaced + * keys, `resultType`, `ttlMs`/`cacheScope`). The `Relax` helper below makes + * those fields optional in the spec type so mutual assignability still holds for + * everything ELSE. Any drift outside those known-permissive keys is a real bug. */ import fs from 'node:fs'; import path from 'node:path'; @@ -19,664 +24,715 @@ type WithJSONRPC = T & { jsonrpc: '2.0' }; // Adds the `jsonrpc` and `id` properties to a type, to match the on-wire format of requests. type WithJSONRPCRequest = T & { jsonrpc: '2.0'; id: SDKTypes.RequestId }; +// The SDK deliberately keeps these spec-required fields optional for BC: +// `_meta` (and the required `io.modelcontextprotocol/*` keys within it), +// `resultType`, `ttlMs`/`cacheScope`, `inputResponses`/`requestState`. +// `Relax` makes those optional in the spec type so mutual assignability +// holds for everything ELSE; drift outside these keys is a real bug. +type PermissiveKey = + | '_meta' + | 'resultType' + | 'ttlMs' + | 'cacheScope' + | 'inputResponses' + | 'requestState' + | `io.modelcontextprotocol/${string}`; + +type Prim = string | number | boolean | bigint | symbol | null | undefined; +type Relax = T extends Prim + ? T + : T extends ReadonlyArray + ? Array> + : T extends object + ? { -readonly [K in keyof T as K extends PermissiveKey ? never : K]: Relax } & { + -readonly [K in keyof T as K extends PermissiveKey ? K : never]+?: Relax; + } + : T; + // The spec defines typed *ResultResponse interfaces (e.g. InitializeResultResponse) that pair a // JSONRPCResultResponse envelope with a specific result type. The SDK doesn't export these because // nothing in the SDK needs the combined type — Protocol._onresponse() unwraps the envelope and // validates the inner result separately. We define this locally to verify the composition still // type-checks against the spec without polluting the SDK's public API. type TypedResultResponse = SDKTypes.JSONRPCResultResponse & { result: R }; +// `tools/call`, `prompts/get`, `resources/read` may return `input_required` per spec. +type WithInputRequired = R | SDKTypes.InputRequiredResult; const sdkTypeChecks = { - RequestParams: (sdk: SDKTypes.RequestParams, spec: SpecTypes.RequestParams) => { - sdk = spec; - spec = sdk; - }, - NotificationParams: (sdk: SDKTypes.NotificationParams, spec: SpecTypes.NotificationParams) => { - sdk = spec; - spec = sdk; - }, - CancelledNotificationParams: (sdk: SDKTypes.CancelledNotificationParams, spec: SpecTypes.CancelledNotificationParams) => { + RequestParams: (sdk: SDKTypes.RequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, - InitializeRequestParams: (sdk: SDKTypes.InitializeRequestParams, spec: SpecTypes.InitializeRequestParams) => { + NotificationParams: (sdk: SDKTypes.NotificationParams, spec: Relax) => { sdk = spec; spec = sdk; }, - ProgressNotificationParams: (sdk: SDKTypes.ProgressNotificationParams, spec: SpecTypes.ProgressNotificationParams) => { + CancelledNotificationParams: (sdk: SDKTypes.CancelledNotificationParams, spec: Relax) => { sdk = spec; spec = sdk; }, - ResourceRequestParams: (sdk: SDKTypes.ResourceRequestParams, spec: SpecTypes.ResourceRequestParams) => { + ProgressNotificationParams: (sdk: SDKTypes.ProgressNotificationParams, spec: Relax) => { sdk = spec; spec = sdk; }, - ReadResourceRequestParams: (sdk: SDKTypes.ReadResourceRequestParams, spec: SpecTypes.ReadResourceRequestParams) => { + ResourceRequestParams: (sdk: SDKTypes.ResourceRequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, - SubscribeRequestParams: (sdk: SDKTypes.SubscribeRequestParams, spec: SpecTypes.SubscribeRequestParams) => { - sdk = spec; - spec = sdk; - }, - UnsubscribeRequestParams: (sdk: SDKTypes.UnsubscribeRequestParams, spec: SpecTypes.UnsubscribeRequestParams) => { + ReadResourceRequestParams: (sdk: SDKTypes.ReadResourceRequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, ResourceUpdatedNotificationParams: ( sdk: SDKTypes.ResourceUpdatedNotificationParams, - spec: SpecTypes.ResourceUpdatedNotificationParams + spec: Relax ) => { sdk = spec; spec = sdk; }, - GetPromptRequestParams: (sdk: SDKTypes.GetPromptRequestParams, spec: SpecTypes.GetPromptRequestParams) => { + GetPromptRequestParams: (sdk: SDKTypes.GetPromptRequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, - CallToolRequestParams: (sdk: SDKTypes.CallToolRequestParams, spec: SpecTypes.CallToolRequestParams) => { - sdk = spec; - spec = sdk; - }, - SetLevelRequestParams: (sdk: SDKTypes.SetLevelRequestParams, spec: SpecTypes.SetLevelRequestParams) => { + CallToolRequestParams: (sdk: SDKTypes.CallToolRequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, LoggingMessageNotificationParams: ( sdk: SDKTypes.LoggingMessageNotificationParams, - spec: SpecTypes.LoggingMessageNotificationParams + spec: Relax ) => { sdk = spec; spec = sdk; }, - CreateMessageRequestParams: (sdk: SDKTypes.CreateMessageRequestParams, spec: SpecTypes.CreateMessageRequestParams) => { + CreateMessageRequestParams: (sdk: SDKTypes.CreateMessageRequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, - CompleteRequestParams: (sdk: SDKTypes.CompleteRequestParams, spec: SpecTypes.CompleteRequestParams) => { + CompleteRequestParams: (sdk: SDKTypes.CompleteRequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, - ElicitRequestParams: (sdk: SDKTypes.ElicitRequestParams, spec: SpecTypes.ElicitRequestParams) => { + ElicitRequestParams: (sdk: SDKTypes.ElicitRequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, - ElicitRequestFormParams: (sdk: SDKTypes.ElicitRequestFormParams, spec: SpecTypes.ElicitRequestFormParams) => { + ElicitRequestFormParams: (sdk: SDKTypes.ElicitRequestFormParams, spec: Relax) => { sdk = spec; spec = sdk; }, - ElicitRequestURLParams: (sdk: SDKTypes.ElicitRequestURLParams, spec: SpecTypes.ElicitRequestURLParams) => { + ElicitRequestURLParams: (sdk: SDKTypes.ElicitRequestURLParams, spec: Relax) => { sdk = spec; spec = sdk; }, ElicitationCompleteNotification: ( sdk: WithJSONRPC, - spec: SpecTypes.ElicitationCompleteNotification + spec: Relax ) => { sdk = spec; spec = sdk; }, - PaginatedRequestParams: (sdk: SDKTypes.PaginatedRequestParams, spec: SpecTypes.PaginatedRequestParams) => { - sdk = spec; - spec = sdk; - }, - CancelledNotification: (sdk: WithJSONRPC, spec: SpecTypes.CancelledNotification) => { + PaginatedRequestParams: (sdk: SDKTypes.PaginatedRequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, - BaseMetadata: (sdk: SDKTypes.BaseMetadata, spec: SpecTypes.BaseMetadata) => { + CancelledNotification: (sdk: WithJSONRPC, spec: Relax) => { sdk = spec; spec = sdk; }, - Implementation: (sdk: SDKTypes.Implementation, spec: SpecTypes.Implementation) => { + BaseMetadata: (sdk: SDKTypes.BaseMetadata, spec: Relax) => { sdk = spec; spec = sdk; }, - ProgressNotification: (sdk: WithJSONRPC, spec: SpecTypes.ProgressNotification) => { + Implementation: (sdk: SDKTypes.Implementation, spec: Relax) => { sdk = spec; spec = sdk; }, - SubscribeRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.SubscribeRequest) => { + ProgressNotification: (sdk: WithJSONRPC, spec: Relax) => { sdk = spec; spec = sdk; }, - UnsubscribeRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.UnsubscribeRequest) => { + PaginatedRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - PaginatedRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.PaginatedRequest) => { + PaginatedResult: (sdk: SDKTypes.PaginatedResult, spec: Relax) => { sdk = spec; spec = sdk; }, - PaginatedResult: (sdk: SDKTypes.PaginatedResult, spec: SpecTypes.PaginatedResult) => { + ListRootsRequest: (sdk: WithJSONRPCRequest, spec: Relax>) => { sdk = spec; spec = sdk; }, - ListRootsRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.ListRootsRequest) => { + ListRootsResult: (sdk: SDKTypes.ListRootsResult, spec: Relax) => { sdk = spec; spec = sdk; }, - ListRootsResult: (sdk: SDKTypes.ListRootsResult, spec: SpecTypes.ListRootsResult) => { + Root: (sdk: SDKTypes.Root, spec: Relax) => { sdk = spec; spec = sdk; }, - Root: (sdk: SDKTypes.Root, spec: SpecTypes.Root) => { + ElicitRequest: (sdk: WithJSONRPCRequest, spec: Relax>) => { sdk = spec; spec = sdk; }, - ElicitRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.ElicitRequest) => { + ElicitResult: (sdk: SDKTypes.ElicitResult, spec: Relax) => { sdk = spec; spec = sdk; }, - ElicitResult: (sdk: SDKTypes.ElicitResult, spec: SpecTypes.ElicitResult) => { + CompleteRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - CompleteRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.CompleteRequest) => { + CompleteResult: (sdk: SDKTypes.CompleteResult, spec: Relax) => { sdk = spec; spec = sdk; }, - CompleteResult: (sdk: SDKTypes.CompleteResult, spec: SpecTypes.CompleteResult) => { + ProgressToken: (sdk: SDKTypes.ProgressToken, spec: Relax) => { sdk = spec; spec = sdk; }, - ProgressToken: (sdk: SDKTypes.ProgressToken, spec: SpecTypes.ProgressToken) => { + Cursor: (sdk: SDKTypes.Cursor, spec: Relax) => { sdk = spec; spec = sdk; }, - Cursor: (sdk: SDKTypes.Cursor, spec: SpecTypes.Cursor) => { + Request: (sdk: SDKTypes.Request, spec: Relax) => { sdk = spec; spec = sdk; }, - Request: (sdk: SDKTypes.Request, spec: SpecTypes.Request) => { + Result: (sdk: SDKTypes.Result, spec: Relax) => { sdk = spec; spec = sdk; }, - Result: (sdk: SDKTypes.Result, spec: SpecTypes.Result) => { + RequestId: (sdk: SDKTypes.RequestId, spec: Relax) => { sdk = spec; spec = sdk; }, - RequestId: (sdk: SDKTypes.RequestId, spec: SpecTypes.RequestId) => { + JSONRPCRequest: (sdk: SDKTypes.JSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - JSONRPCRequest: (sdk: SDKTypes.JSONRPCRequest, spec: SpecTypes.JSONRPCRequest) => { + JSONRPCNotification: (sdk: SDKTypes.JSONRPCNotification, spec: Relax) => { sdk = spec; spec = sdk; }, - JSONRPCNotification: (sdk: SDKTypes.JSONRPCNotification, spec: SpecTypes.JSONRPCNotification) => { + JSONRPCResponse: (sdk: SDKTypes.JSONRPCResponse, spec: Relax) => { sdk = spec; spec = sdk; }, - JSONRPCResponse: (sdk: SDKTypes.JSONRPCResponse, spec: SpecTypes.JSONRPCResponse) => { + EmptyResult: (sdk: SDKTypes.EmptyResult, spec: Relax) => { sdk = spec; spec = sdk; }, - EmptyResult: (sdk: SDKTypes.EmptyResult, spec: SpecTypes.EmptyResult) => { + Notification: (sdk: SDKTypes.Notification, spec: Relax) => { sdk = spec; spec = sdk; }, - Notification: (sdk: SDKTypes.Notification, spec: SpecTypes.Notification) => { + ClientResult: (sdk: SDKTypes.ClientResult, spec: Relax) => { sdk = spec; spec = sdk; }, - ClientResult: (sdk: SDKTypes.ClientResult, spec: SpecTypes.ClientResult) => { + ClientNotification: (sdk: WithJSONRPC, spec: Relax) => { sdk = spec; spec = sdk; }, - ClientNotification: (sdk: WithJSONRPC, spec: SpecTypes.ClientNotification) => { - // @ts-expect-error SEP-2663: spec union includes task variants the SDK does not implement + ServerResult: (sdk: SDKTypes.ServerResult, spec: Relax) => { sdk = spec; spec = sdk; }, - ServerResult: (sdk: SDKTypes.ServerResult, spec: SpecTypes.ServerResult) => { + ResourceTemplateReference: (sdk: SDKTypes.ResourceTemplateReference, spec: Relax) => { sdk = spec; spec = sdk; }, - ResourceTemplateReference: (sdk: SDKTypes.ResourceTemplateReference, spec: SpecTypes.ResourceTemplateReference) => { + PromptReference: (sdk: SDKTypes.PromptReference, spec: Relax) => { sdk = spec; spec = sdk; }, - PromptReference: (sdk: SDKTypes.PromptReference, spec: SpecTypes.PromptReference) => { + ToolAnnotations: (sdk: SDKTypes.ToolAnnotations, spec: Relax) => { sdk = spec; spec = sdk; }, - ToolAnnotations: (sdk: SDKTypes.ToolAnnotations, spec: SpecTypes.ToolAnnotations) => { + Tool: (sdk: SDKTypes.Tool, spec: Relax) => { sdk = spec; spec = sdk; }, - Tool: (sdk: SDKTypes.Tool, spec: SpecTypes.Tool) => { + ListToolsRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - ListToolsRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.ListToolsRequest) => { + ListToolsResult: (sdk: SDKTypes.ListToolsResult, spec: Relax) => { sdk = spec; spec = sdk; }, - ListToolsResult: (sdk: SDKTypes.ListToolsResult, spec: SpecTypes.ListToolsResult) => { + CallToolResult: (sdk: SDKTypes.CallToolResult, spec: Relax) => { sdk = spec; spec = sdk; }, - CallToolResult: (sdk: SDKTypes.CallToolResult, spec: SpecTypes.CallToolResult) => { + CallToolRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - CallToolRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.CallToolRequest) => { - sdk = spec; - spec = sdk; - }, - ToolListChangedNotification: (sdk: WithJSONRPC, spec: SpecTypes.ToolListChangedNotification) => { + ToolListChangedNotification: ( + sdk: WithJSONRPC, + spec: Relax + ) => { sdk = spec; spec = sdk; }, ResourceListChangedNotification: ( sdk: WithJSONRPC, - spec: SpecTypes.ResourceListChangedNotification + spec: Relax ) => { sdk = spec; spec = sdk; }, PromptListChangedNotification: ( sdk: WithJSONRPC, - spec: SpecTypes.PromptListChangedNotification + spec: Relax ) => { sdk = spec; spec = sdk; }, - RootsListChangedNotification: ( - sdk: WithJSONRPC, - spec: SpecTypes.RootsListChangedNotification + ResourceUpdatedNotification: ( + sdk: WithJSONRPC, + spec: Relax ) => { sdk = spec; spec = sdk; }, - ResourceUpdatedNotification: (sdk: WithJSONRPC, spec: SpecTypes.ResourceUpdatedNotification) => { + SamplingMessage: (sdk: SDKTypes.SamplingMessage, spec: Relax) => { sdk = spec; spec = sdk; }, - SamplingMessage: (sdk: SDKTypes.SamplingMessage, spec: SpecTypes.SamplingMessage) => { + CreateMessageResult: (sdk: SDKTypes.CreateMessageResultWithTools, spec: Relax) => { sdk = spec; spec = sdk; }, - CreateMessageResult: (sdk: SDKTypes.CreateMessageResultWithTools, spec: SpecTypes.CreateMessageResult) => { + ListResourcesRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - SetLevelRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.SetLevelRequest) => { + ListResourcesResult: (sdk: SDKTypes.ListResourcesResult, spec: Relax) => { sdk = spec; spec = sdk; }, - PingRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.PingRequest) => { + ListResourceTemplatesRequest: ( + sdk: WithJSONRPCRequest, + spec: Relax + ) => { sdk = spec; spec = sdk; }, - InitializedNotification: (sdk: WithJSONRPC, spec: SpecTypes.InitializedNotification) => { + ListResourceTemplatesResult: (sdk: SDKTypes.ListResourceTemplatesResult, spec: Relax) => { sdk = spec; spec = sdk; }, - ListResourcesRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.ListResourcesRequest) => { + ReadResourceRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - ListResourcesResult: (sdk: SDKTypes.ListResourcesResult, spec: SpecTypes.ListResourcesResult) => { + ReadResourceResult: (sdk: SDKTypes.ReadResourceResult, spec: Relax) => { sdk = spec; spec = sdk; }, - ListResourceTemplatesRequest: ( - sdk: WithJSONRPCRequest, - spec: SpecTypes.ListResourceTemplatesRequest - ) => { + ResourceContents: (sdk: SDKTypes.ResourceContents, spec: Relax) => { sdk = spec; spec = sdk; }, - ListResourceTemplatesResult: (sdk: SDKTypes.ListResourceTemplatesResult, spec: SpecTypes.ListResourceTemplatesResult) => { + TextResourceContents: (sdk: SDKTypes.TextResourceContents, spec: Relax) => { sdk = spec; spec = sdk; }, - ReadResourceRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.ReadResourceRequest) => { + BlobResourceContents: (sdk: SDKTypes.BlobResourceContents, spec: Relax) => { sdk = spec; spec = sdk; }, - ReadResourceResult: (sdk: SDKTypes.ReadResourceResult, spec: SpecTypes.ReadResourceResult) => { + Resource: (sdk: SDKTypes.Resource, spec: Relax) => { sdk = spec; spec = sdk; }, - ResourceContents: (sdk: SDKTypes.ResourceContents, spec: SpecTypes.ResourceContents) => { + ResourceTemplate: (sdk: SDKTypes.ResourceTemplateType, spec: Relax) => { sdk = spec; spec = sdk; }, - TextResourceContents: (sdk: SDKTypes.TextResourceContents, spec: SpecTypes.TextResourceContents) => { + PromptArgument: (sdk: SDKTypes.PromptArgument, spec: Relax) => { sdk = spec; spec = sdk; }, - BlobResourceContents: (sdk: SDKTypes.BlobResourceContents, spec: SpecTypes.BlobResourceContents) => { + Prompt: (sdk: SDKTypes.Prompt, spec: Relax) => { sdk = spec; spec = sdk; }, - Resource: (sdk: SDKTypes.Resource, spec: SpecTypes.Resource) => { + ListPromptsRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - ResourceTemplate: (sdk: SDKTypes.ResourceTemplateType, spec: SpecTypes.ResourceTemplate) => { + ListPromptsResult: (sdk: SDKTypes.ListPromptsResult, spec: Relax) => { sdk = spec; spec = sdk; }, - PromptArgument: (sdk: SDKTypes.PromptArgument, spec: SpecTypes.PromptArgument) => { + GetPromptRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - Prompt: (sdk: SDKTypes.Prompt, spec: SpecTypes.Prompt) => { + TextContent: (sdk: SDKTypes.TextContent, spec: Relax) => { sdk = spec; spec = sdk; }, - ListPromptsRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.ListPromptsRequest) => { + ImageContent: (sdk: SDKTypes.ImageContent, spec: Relax) => { sdk = spec; spec = sdk; }, - ListPromptsResult: (sdk: SDKTypes.ListPromptsResult, spec: SpecTypes.ListPromptsResult) => { + AudioContent: (sdk: SDKTypes.AudioContent, spec: Relax) => { sdk = spec; spec = sdk; }, - GetPromptRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.GetPromptRequest) => { + EmbeddedResource: (sdk: SDKTypes.EmbeddedResource, spec: Relax) => { sdk = spec; spec = sdk; }, - TextContent: (sdk: SDKTypes.TextContent, spec: SpecTypes.TextContent) => { + ResourceLink: (sdk: SDKTypes.ResourceLink, spec: Relax) => { sdk = spec; spec = sdk; }, - ImageContent: (sdk: SDKTypes.ImageContent, spec: SpecTypes.ImageContent) => { + ContentBlock: (sdk: SDKTypes.ContentBlock, spec: Relax) => { sdk = spec; spec = sdk; }, - AudioContent: (sdk: SDKTypes.AudioContent, spec: SpecTypes.AudioContent) => { + PromptMessage: (sdk: SDKTypes.PromptMessage, spec: Relax) => { sdk = spec; spec = sdk; }, - EmbeddedResource: (sdk: SDKTypes.EmbeddedResource, spec: SpecTypes.EmbeddedResource) => { + GetPromptResult: (sdk: SDKTypes.GetPromptResult, spec: Relax) => { sdk = spec; spec = sdk; }, - ResourceLink: (sdk: SDKTypes.ResourceLink, spec: SpecTypes.ResourceLink) => { + BooleanSchema: (sdk: SDKTypes.BooleanSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - ContentBlock: (sdk: SDKTypes.ContentBlock, spec: SpecTypes.ContentBlock) => { + StringSchema: (sdk: SDKTypes.StringSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - PromptMessage: (sdk: SDKTypes.PromptMessage, spec: SpecTypes.PromptMessage) => { + NumberSchema: (sdk: SDKTypes.NumberSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - GetPromptResult: (sdk: SDKTypes.GetPromptResult, spec: SpecTypes.GetPromptResult) => { + EnumSchema: (sdk: SDKTypes.EnumSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - BooleanSchema: (sdk: SDKTypes.BooleanSchema, spec: SpecTypes.BooleanSchema) => { + UntitledSingleSelectEnumSchema: ( + sdk: SDKTypes.UntitledSingleSelectEnumSchema, + spec: Relax + ) => { sdk = spec; spec = sdk; }, - StringSchema: (sdk: SDKTypes.StringSchema, spec: SpecTypes.StringSchema) => { + TitledSingleSelectEnumSchema: (sdk: SDKTypes.TitledSingleSelectEnumSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - NumberSchema: (sdk: SDKTypes.NumberSchema, spec: SpecTypes.NumberSchema) => { + SingleSelectEnumSchema: (sdk: SDKTypes.SingleSelectEnumSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - EnumSchema: (sdk: SDKTypes.EnumSchema, spec: SpecTypes.EnumSchema) => { + UntitledMultiSelectEnumSchema: (sdk: SDKTypes.UntitledMultiSelectEnumSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - UntitledSingleSelectEnumSchema: (sdk: SDKTypes.UntitledSingleSelectEnumSchema, spec: SpecTypes.UntitledSingleSelectEnumSchema) => { + TitledMultiSelectEnumSchema: (sdk: SDKTypes.TitledMultiSelectEnumSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - TitledSingleSelectEnumSchema: (sdk: SDKTypes.TitledSingleSelectEnumSchema, spec: SpecTypes.TitledSingleSelectEnumSchema) => { + MultiSelectEnumSchema: (sdk: SDKTypes.MultiSelectEnumSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - SingleSelectEnumSchema: (sdk: SDKTypes.SingleSelectEnumSchema, spec: SpecTypes.SingleSelectEnumSchema) => { + LegacyTitledEnumSchema: (sdk: SDKTypes.LegacyTitledEnumSchema, spec: Relax) => { sdk = spec; spec = sdk; }, - UntitledMultiSelectEnumSchema: (sdk: SDKTypes.UntitledMultiSelectEnumSchema, spec: SpecTypes.UntitledMultiSelectEnumSchema) => { + PrimitiveSchemaDefinition: (sdk: SDKTypes.PrimitiveSchemaDefinition, spec: Relax) => { sdk = spec; spec = sdk; }, - TitledMultiSelectEnumSchema: (sdk: SDKTypes.TitledMultiSelectEnumSchema, spec: SpecTypes.TitledMultiSelectEnumSchema) => { + JSONRPCErrorResponse: (sdk: SDKTypes.JSONRPCErrorResponse, spec: Relax) => { sdk = spec; spec = sdk; }, - MultiSelectEnumSchema: (sdk: SDKTypes.MultiSelectEnumSchema, spec: SpecTypes.MultiSelectEnumSchema) => { + JSONRPCResultResponse: (sdk: SDKTypes.JSONRPCResultResponse, spec: Relax) => { sdk = spec; spec = sdk; }, - LegacyTitledEnumSchema: (sdk: SDKTypes.LegacyTitledEnumSchema, spec: SpecTypes.LegacyTitledEnumSchema) => { + JSONRPCMessage: (sdk: SDKTypes.JSONRPCMessage, spec: Relax) => { sdk = spec; spec = sdk; }, - PrimitiveSchemaDefinition: (sdk: SDKTypes.PrimitiveSchemaDefinition, spec: SpecTypes.PrimitiveSchemaDefinition) => { + CreateMessageRequest: ( + sdk: WithJSONRPCRequest, + spec: Relax> + ) => { sdk = spec; spec = sdk; }, - JSONRPCErrorResponse: (sdk: SDKTypes.JSONRPCErrorResponse, spec: SpecTypes.JSONRPCErrorResponse) => { + ClientCapabilities: (sdk: SDKTypes.ClientCapabilities, spec: Relax) => { sdk = spec; spec = sdk; }, - JSONRPCResultResponse: (sdk: SDKTypes.JSONRPCResultResponse, spec: SpecTypes.JSONRPCResultResponse) => { + ServerCapabilities: (sdk: SDKTypes.ServerCapabilities, spec: Relax) => { sdk = spec; spec = sdk; }, - JSONRPCMessage: (sdk: SDKTypes.JSONRPCMessage, spec: SpecTypes.JSONRPCMessage) => { + ClientRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - CreateMessageRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.CreateMessageRequest) => { + LoggingMessageNotification: ( + sdk: WithJSONRPC, + spec: Relax + ) => { sdk = spec; spec = sdk; }, - InitializeRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.InitializeRequest) => { + ServerNotification: (sdk: WithJSONRPC, spec: Relax) => { sdk = spec; spec = sdk; }, - InitializeResult: (sdk: SDKTypes.InitializeResult, spec: SpecTypes.InitializeResult) => { + LoggingLevel: (sdk: SDKTypes.LoggingLevel, spec: Relax) => { sdk = spec; spec = sdk; }, - ClientCapabilities: (sdk: SDKTypes.ClientCapabilities, spec: SpecTypes.ClientCapabilities) => { + Icon: (sdk: SDKTypes.Icon, spec: Relax) => { sdk = spec; spec = sdk; }, - ServerCapabilities: (sdk: SDKTypes.ServerCapabilities, spec: SpecTypes.ServerCapabilities) => { + Icons: (sdk: SDKTypes.Icons, spec: Relax) => { sdk = spec; spec = sdk; }, - ClientRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.ClientRequest) => { - // @ts-expect-error SEP-2663: spec union includes task variants the SDK does not implement + ModelHint: (sdk: SDKTypes.ModelHint, spec: Relax) => { sdk = spec; spec = sdk; }, - ServerRequest: (sdk: WithJSONRPCRequest, spec: SpecTypes.ServerRequest) => { - // @ts-expect-error SEP-2663: spec union includes task variants the SDK does not implement + ModelPreferences: (sdk: SDKTypes.ModelPreferences, spec: Relax) => { sdk = spec; spec = sdk; }, - LoggingMessageNotification: (sdk: WithJSONRPC, spec: SpecTypes.LoggingMessageNotification) => { + ToolChoice: (sdk: SDKTypes.ToolChoice, spec: Relax) => { sdk = spec; spec = sdk; }, - ServerNotification: (sdk: WithJSONRPC, spec: SpecTypes.ServerNotification) => { - // @ts-expect-error SEP-2663: spec union includes task variants the SDK does not implement + ToolUseContent: (sdk: SDKTypes.ToolUseContent, spec: Relax) => { sdk = spec; spec = sdk; }, - LoggingLevel: (sdk: SDKTypes.LoggingLevel, spec: SpecTypes.LoggingLevel) => { + ToolResultContent: (sdk: SDKTypes.ToolResultContent, spec: Relax) => { sdk = spec; spec = sdk; }, - Icon: (sdk: SDKTypes.Icon, spec: SpecTypes.Icon) => { + SamplingMessageContentBlock: (sdk: SDKTypes.SamplingMessageContentBlock, spec: Relax) => { sdk = spec; spec = sdk; }, - Icons: (sdk: SDKTypes.Icons, spec: SpecTypes.Icons) => { + Annotations: (sdk: SDKTypes.Annotations, spec: Relax) => { sdk = spec; spec = sdk; }, - ModelHint: (sdk: SDKTypes.ModelHint, spec: SpecTypes.ModelHint) => { + Role: (sdk: SDKTypes.Role, spec: Relax) => { sdk = spec; spec = sdk; }, - ModelPreferences: (sdk: SDKTypes.ModelPreferences, spec: SpecTypes.ModelPreferences) => { + + /* JSON primitives */ + JSONValue: (sdk: SDKTypes.JSONValue, spec: Relax) => { sdk = spec; spec = sdk; }, - ToolChoice: (sdk: SDKTypes.ToolChoice, spec: SpecTypes.ToolChoice) => { + JSONObject: (sdk: SDKTypes.JSONObject, spec: Relax) => { sdk = spec; spec = sdk; }, - ToolUseContent: (sdk: SDKTypes.ToolUseContent, spec: SpecTypes.ToolUseContent) => { + JSONArray: (sdk: SDKTypes.JSONArray, spec: Relax) => { sdk = spec; spec = sdk; }, - ToolResultContent: (sdk: SDKTypes.ToolResultContent, spec: SpecTypes.ToolResultContent) => { + + /* Meta types */ + MetaObject: (sdk: SDKTypes.MetaObject, spec: Relax) => { sdk = spec; spec = sdk; }, - SamplingMessageContentBlock: (sdk: SDKTypes.SamplingMessageContentBlock, spec: SpecTypes.SamplingMessageContentBlock) => { + RequestMetaObject: (sdk: SDKTypes.RequestMetaObject, spec: Relax) => { sdk = spec; spec = sdk; }, - Annotations: (sdk: SDKTypes.Annotations, spec: SpecTypes.Annotations) => { + + /* Error types */ + ParseError: (sdk: SDKTypes.ParseError, spec: Relax) => { sdk = spec; spec = sdk; }, - Role: (sdk: SDKTypes.Role, spec: SpecTypes.Role) => { + InvalidRequestError: (sdk: SDKTypes.InvalidRequestError, spec: Relax) => { sdk = spec; spec = sdk; }, - ToolExecution: (sdk: SDKTypes.ToolExecution, spec: SpecTypes.ToolExecution) => { + MethodNotFoundError: (sdk: SDKTypes.MethodNotFoundError, spec: Relax) => { sdk = spec; spec = sdk; }, - - /* JSON primitives */ - JSONValue: (sdk: SDKTypes.JSONValue, spec: SpecTypes.JSONValue) => { + InvalidParamsError: (sdk: SDKTypes.InvalidParamsError, spec: Relax) => { sdk = spec; spec = sdk; }, - JSONObject: (sdk: SDKTypes.JSONObject, spec: SpecTypes.JSONObject) => { + InternalError: (sdk: SDKTypes.InternalError, spec: Relax) => { sdk = spec; spec = sdk; }, - JSONArray: (sdk: SDKTypes.JSONArray, spec: SpecTypes.JSONArray) => { + + /* ResultResponse types — see TypedResultResponse comment above */ + ListResourcesResultResponse: ( + sdk: TypedResultResponse, + spec: Relax + ) => { sdk = spec; spec = sdk; }, - - /* Meta types */ - MetaObject: (sdk: SDKTypes.MetaObject, spec: SpecTypes.MetaObject) => { + ListResourceTemplatesResultResponse: ( + sdk: TypedResultResponse, + spec: Relax + ) => { sdk = spec; spec = sdk; }, - RequestMetaObject: (sdk: SDKTypes.RequestMetaObject, spec: SpecTypes.RequestMetaObject) => { + ReadResourceResultResponse: ( + sdk: TypedResultResponse>, + spec: Relax + ) => { + // @ts-expect-error Relax<> drops the index signature from the InputRequiredResult union arm; inner ReadResourceResult/InputRequiredResult are checked separately above. sdk = spec; spec = sdk; }, - - /* Error types */ - ParseError: (sdk: SDKTypes.ParseError, spec: SpecTypes.ParseError) => { + ListPromptsResultResponse: (sdk: TypedResultResponse, spec: Relax) => { sdk = spec; spec = sdk; }, - InvalidRequestError: (sdk: SDKTypes.InvalidRequestError, spec: SpecTypes.InvalidRequestError) => { + GetPromptResultResponse: ( + sdk: TypedResultResponse>, + spec: Relax + ) => { + // @ts-expect-error see ReadResourceResultResponse note above sdk = spec; spec = sdk; }, - MethodNotFoundError: (sdk: SDKTypes.MethodNotFoundError, spec: SpecTypes.MethodNotFoundError) => { + ListToolsResultResponse: (sdk: TypedResultResponse, spec: Relax) => { sdk = spec; spec = sdk; }, - InvalidParamsError: (sdk: SDKTypes.InvalidParamsError, spec: SpecTypes.InvalidParamsError) => { + CallToolResultResponse: ( + sdk: TypedResultResponse>, + spec: Relax + ) => { + // @ts-expect-error see ReadResourceResultResponse note above sdk = spec; spec = sdk; }, - InternalError: (sdk: SDKTypes.InternalError, spec: SpecTypes.InternalError) => { + CompleteResultResponse: (sdk: TypedResultResponse, spec: Relax) => { sdk = spec; spec = sdk; }, - - /* ResultResponse types — see TypedResultResponse comment above */ - InitializeResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.InitializeResultResponse) => { + DiscoverResultResponse: (sdk: TypedResultResponse, spec: Relax) => { sdk = spec; spec = sdk; }, - PingResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.PingResultResponse) => { + /* 2026-06 additions */ + ResultType: (sdk: SDKTypes.ResultType, spec: SpecTypes.ResultType) => { sdk = spec; spec = sdk; }, - ListResourcesResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.ListResourcesResultResponse) => { + DiscoverRequest: (sdk: WithJSONRPCRequest, spec: Relax) => { sdk = spec; spec = sdk; }, - ListResourceTemplatesResultResponse: ( - sdk: TypedResultResponse, - spec: SpecTypes.ListResourceTemplatesResultResponse - ) => { + DiscoverResult: (sdk: SDKTypes.DiscoverResult, spec: Relax) => { sdk = spec; spec = sdk; }, - ReadResourceResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.ReadResourceResultResponse) => { + CacheableResult: (sdk: SDKTypes.CacheableResult, spec: Relax) => { sdk = spec; spec = sdk; }, - SubscribeResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.SubscribeResultResponse) => { + InputRequest: (sdk: WithJSONRPCRequest, spec: Relax>) => { sdk = spec; spec = sdk; }, - UnsubscribeResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.UnsubscribeResultResponse) => { + InputResponse: (sdk: SDKTypes.InputResponse, spec: Relax) => { sdk = spec; spec = sdk; }, - ListPromptsResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.ListPromptsResultResponse) => { + InputRequests: (sdk: SDKTypes.InputRequests, spec: Relax) => { sdk = spec; spec = sdk; }, - GetPromptResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.GetPromptResultResponse) => { + InputResponses: (sdk: SDKTypes.InputResponses, spec: Relax) => { sdk = spec; spec = sdk; }, - ListToolsResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.ListToolsResultResponse) => { - sdk = spec; + InputRequiredResult: (sdk: SDKTypes.InputRequiredResult, spec: Relax) => { + // Relax<> makes `resultType` optional but SDK keeps it as the literal discriminator; one-direction. + void sdk; spec = sdk; }, - CallToolResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.CallToolResultResponse) => { + InputResponseRequestParams: (sdk: SDKTypes.InputResponseRequestParams, spec: Relax) => { sdk = spec; spec = sdk; }, - SetLevelResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.SetLevelResultResponse) => { + SubscriptionFilter: (sdk: SDKTypes.SubscriptionFilter, spec: Relax) => { sdk = spec; spec = sdk; }, - CreateMessageResultResponse: ( - sdk: TypedResultResponse, - spec: SpecTypes.CreateMessageResultResponse + SubscriptionsListenRequestParams: ( + sdk: SDKTypes.SubscriptionsListenRequestParams, + spec: Relax ) => { sdk = spec; spec = sdk; }, - CompleteResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.CompleteResultResponse) => { + SubscriptionsListenRequest: ( + sdk: WithJSONRPCRequest, + spec: Relax + ) => { sdk = spec; spec = sdk; }, - ListRootsResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.ListRootsResultResponse) => { + SubscriptionsAcknowledgedNotificationParams: ( + sdk: SDKTypes.SubscriptionsAcknowledgedNotificationParams, + spec: Relax + ) => { sdk = spec; spec = sdk; }, - ElicitResultResponse: (sdk: TypedResultResponse, spec: SpecTypes.ElicitResultResponse) => { + SubscriptionsAcknowledgedNotification: ( + sdk: WithJSONRPC, + spec: Relax + ) => { sdk = spec; spec = sdk; + }, + UnsupportedProtocolVersionError: ( + sdk: SDKTypes.UnsupportedProtocolVersionErrorData, + spec: SpecTypes.UnsupportedProtocolVersionError + ) => { + sdk = spec.error.data; + void spec; + }, + MissingRequiredClientCapabilityError: ( + sdk: SDKTypes.MissingRequiredClientCapabilityErrorData, + spec: SpecTypes.MissingRequiredClientCapabilityError + ) => { + sdk = spec.error.data; + void spec; } }; @@ -700,8 +756,8 @@ type KnownKeys = keyof { type AssertExactKeys< A, B, - Extra extends PropertyKey = Exclude, KnownKeys>, - Missing extends PropertyKey = Exclude, KnownKeys> + Extra extends PropertyKey = Exclude, KnownKeys | PermissiveKey>, + Missing extends PropertyKey = Exclude, KnownKeys | PermissiveKey> > = [Extra, Missing] extends [never, never] ? true : { _brand: 'KeyMismatch'; extra: Extra; missing: Missing }; /** Constraint: T must resolve to `true`. */ @@ -726,28 +782,20 @@ type Assert = T; type _K_RequestParams = Assert>; type _K_NotificationParams = Assert>; type _K_CancelledNotificationParams = Assert>; -type _K_InitializeRequestParams = Assert>; type _K_ProgressNotificationParams = Assert>; type _K_ResourceRequestParams = Assert>; type _K_ReadResourceRequestParams = Assert>; -type _K_SubscribeRequestParams = Assert>; -type _K_UnsubscribeRequestParams = Assert>; type _K_ResourceUpdatedNotificationParams = Assert< AssertExactKeys >; type _K_GetPromptRequestParams = Assert>; -// @ts-expect-error SEP-2663: spec has optional `task` field; SDK removes task augmentation type _K_CallToolRequestParams = Assert>; -type _K_SetLevelRequestParams = Assert>; type _K_LoggingMessageNotificationParams = Assert< AssertExactKeys >; -// @ts-expect-error SEP-2663: spec has optional `task` field; SDK removes task augmentation type _K_CreateMessageRequestParams = Assert>; type _K_CompleteRequestParams = Assert>; -// @ts-expect-error SEP-2663: spec has optional `task` field; SDK removes task augmentation type _K_ElicitRequestFormParams = Assert>; -// @ts-expect-error SEP-2663: spec has optional `task` field; SDK removes task augmentation type _K_ElicitRequestURLParams = Assert>; type _K_PaginatedRequestParams = Assert>; type _K_BaseMetadata = Assert>; @@ -804,10 +852,7 @@ type _K_TitledMultiSelectEnumSchema = Assert>; type _K_JSONRPCErrorResponse = Assert>; type _K_JSONRPCResultResponse = Assert>; -type _K_InitializeResult = Assert>; -// @ts-expect-error SEP-2663: spec has `tasks` capability; SDK removes it type _K_ClientCapabilities = Assert>; -// @ts-expect-error SEP-2663: spec has `tasks` capability; SDK removes it type _K_ServerCapabilities = Assert>; type _K_SamplingMessage = Assert>; type _K_Icon = Assert>; @@ -818,7 +863,6 @@ type _K_ToolChoice = Assert>; type _K_ToolResultContent = Assert>; type _K_Annotations = Assert>; -type _K_ToolExecution = Assert>; type _K_JSONObject = Assert>; type _K_MetaObject = Assert>; type _K_RequestMetaObject = Assert>; @@ -846,31 +890,25 @@ type _K_ResourceListChangedNotification = Assert< type _K_PromptListChangedNotification = Assert< AssertExactKeys, SpecTypes.PromptListChangedNotification> >; -type _K_RootsListChangedNotification = Assert< - AssertExactKeys, SpecTypes.RootsListChangedNotification> ->; type _K_ResourceUpdatedNotification = Assert< AssertExactKeys, SpecTypes.ResourceUpdatedNotification> >; type _K_LoggingMessageNotification = Assert< AssertExactKeys, SpecTypes.LoggingMessageNotification> >; -type _K_InitializedNotification = Assert, SpecTypes.InitializedNotification>>; // -- WithJSONRPCRequest-wrapped request types (21) -- // SDK request types do not include `jsonrpc` or `id` — the spec types do. We // wrap with WithJSONRPCRequest<> to add the missing fields before comparing keys. -type _K_SubscribeRequest = Assert, SpecTypes.SubscribeRequest>>; -type _K_UnsubscribeRequest = Assert, SpecTypes.UnsubscribeRequest>>; type _K_PaginatedRequest = Assert, SpecTypes.PaginatedRequest>>; -type _K_ListRootsRequest = Assert, SpecTypes.ListRootsRequest>>; -type _K_ElicitRequest = Assert, SpecTypes.ElicitRequest>>; +type _K_ListRootsRequest = Assert< + AssertExactKeys, WithJSONRPCRequest> +>; +type _K_ElicitRequest = Assert, WithJSONRPCRequest>>; type _K_CompleteRequest = Assert, SpecTypes.CompleteRequest>>; type _K_ListToolsRequest = Assert, SpecTypes.ListToolsRequest>>; type _K_CallToolRequest = Assert, SpecTypes.CallToolRequest>>; -type _K_SetLevelRequest = Assert, SpecTypes.SetLevelRequest>>; -type _K_PingRequest = Assert, SpecTypes.PingRequest>>; type _K_ListResourcesRequest = Assert, SpecTypes.ListResourcesRequest>>; type _K_ListResourceTemplatesRequest = Assert< AssertExactKeys, SpecTypes.ListResourceTemplatesRequest> @@ -878,18 +916,15 @@ type _K_ListResourceTemplatesRequest = Assert< type _K_ReadResourceRequest = Assert, SpecTypes.ReadResourceRequest>>; type _K_ListPromptsRequest = Assert, SpecTypes.ListPromptsRequest>>; type _K_GetPromptRequest = Assert, SpecTypes.GetPromptRequest>>; -type _K_CreateMessageRequest = Assert, SpecTypes.CreateMessageRequest>>; -type _K_InitializeRequest = Assert, SpecTypes.InitializeRequest>>; +type _K_CreateMessageRequest = Assert< + AssertExactKeys, WithJSONRPCRequest> +>; // -- TypedResultResponse-wrapped types (21) -- // The spec defines typed *ResultResponse interfaces that pair JSONRPCResultResponse // with a specific result. We compare TypedResultResponse against the // spec's combined type. -type _K_InitializeResultResponse = Assert< - AssertExactKeys, SpecTypes.InitializeResultResponse> ->; -type _K_PingResultResponse = Assert, SpecTypes.PingResultResponse>>; type _K_ListResourcesResultResponse = Assert< AssertExactKeys, SpecTypes.ListResourcesResultResponse> >; @@ -899,21 +934,13 @@ type _K_ListResourceTemplatesResultResponse = Assert< type _K_ReadResourceResultResponse = Assert< AssertExactKeys, SpecTypes.ReadResourceResultResponse> >; -type _K_SubscribeResultResponse = Assert, SpecTypes.SubscribeResultResponse>>; -type _K_UnsubscribeResultResponse = Assert, SpecTypes.UnsubscribeResultResponse>>; type _K_ListPromptsResultResponse = Assert< AssertExactKeys, SpecTypes.ListPromptsResultResponse> >; type _K_GetPromptResultResponse = Assert, SpecTypes.GetPromptResultResponse>>; type _K_ListToolsResultResponse = Assert, SpecTypes.ListToolsResultResponse>>; type _K_CallToolResultResponse = Assert, SpecTypes.CallToolResultResponse>>; -type _K_SetLevelResultResponse = Assert, SpecTypes.SetLevelResultResponse>>; -type _K_CreateMessageResultResponse = Assert< - AssertExactKeys, SpecTypes.CreateMessageResultResponse> ->; type _K_CompleteResultResponse = Assert, SpecTypes.CompleteResultResponse>>; -type _K_ListRootsResultResponse = Assert, SpecTypes.ListRootsResultResponse>>; -type _K_ElicitResultResponse = Assert, SpecTypes.ElicitResultResponse>>; // -- Name mismatches (2) -- // SDK exports these under different names than the spec. @@ -924,7 +951,7 @@ type _K_ResourceTemplate = Assert` index-signature interaction is resolved. + 'DiscoverRequest', + 'DiscoverResult', + 'DiscoverResultResponse', + 'CacheableResult', + 'InputRequiredResult', + 'InputResponseRequestParams', + 'SubscriptionFilter', + 'SubscriptionsListenRequestParams', + 'SubscriptionsListenRequest', + 'SubscriptionsAcknowledgedNotificationParams', + 'SubscriptionsAcknowledgedNotification' ]; // This file is .gitignore'd, and fetched by `npm run fetch:spec-types` (called by `npm run test`) @@ -957,32 +1007,7 @@ const SDK_TYPES_FILE = path.resolve(__dirname, '../src/types/types.ts'); const MISSING_SDK_TYPES = [ // These are inlined in the SDK: 'Error', // The inner error object of a JSONRPCError - 'URLElicitationRequiredError', // In the SDK, but with a custom definition - // SEP-2663: 2025-11 experimental tasks removed from the SDK; spec still defines them. - 'Task', - 'TaskStatus', - 'TaskMetadata', - 'TaskCreationParams', - 'TaskAugmentedRequestParams', - 'RelatedTaskMetadata', - 'CreateTaskResult', - 'CreateTaskResultResponse', - 'GetTaskRequest', - 'GetTaskResult', - 'GetTaskResultResponse', - 'GetTaskPayloadRequest', - 'GetTaskPayloadResult', - 'GetTaskPayloadResultResponse', - 'ListTasksRequest', - 'ListTasksResult', - 'ListTasksResultResponse', - 'CancelTaskRequest', - 'CancelTaskResult', - 'CancelTaskResultResponse', - 'TaskStatusNotification', - 'TaskStatusNotificationParams', - 'ClientTasksCapability', - 'ServerTasksCapability' + 'URLElicitationRequiredError' // In the SDK, but with a custom definition ]; function extractExportedTypes(source: string): string[] { @@ -1002,7 +1027,7 @@ describe('Spec Types', () => { it('should define some expected types', () => { expect(specTypes).toContain('JSONRPCNotification'); expect(specTypes).toContain('ElicitResult'); - expect(specTypes).toHaveLength(176); + expect(specTypes).toHaveLength(150); }); it('should have up to date list of missing sdk types', () => { diff --git a/packages/core/test/types.capabilities.test.ts b/packages/core/test/types.capabilities.test.ts index 1f6618452..193487e32 100644 --- a/packages/core/test/types.capabilities.test.ts +++ b/packages/core/test/types.capabilities.test.ts @@ -1,4 +1,5 @@ -import { ClientCapabilitiesSchema, InitializeRequestParamsSchema } from '../src/types/index.js'; +import { ClientCapabilitiesSchema } from '../src/types/index.js'; +import { InitializeRequestParamsSchema } from '../src/types/legacyWireSchemas.js'; describe('ClientCapabilitiesSchema backwards compatibility', () => { describe('ElicitationCapabilitySchema preprocessing', () => { diff --git a/packages/core/test/types.test.ts b/packages/core/test/types.test.ts index 9383f7d5e..aca029d8a 100644 --- a/packages/core/test/types.test.ts +++ b/packages/core/test/types.test.ts @@ -478,7 +478,7 @@ describe('Types', () => { expect(result.success).toBe(false); }); - test('should still require type: object at root for outputSchema', () => { + test('outputSchema accepts any JSON Schema (spec @142b3c3c dropped the type:object constraint)', () => { const tool = { name: 'test', inputSchema: { type: 'object' }, @@ -487,7 +487,7 @@ describe('Types', () => { } }; const result = ToolSchema.safeParse(tool); - expect(result.success).toBe(false); + expect(result.success).toBe(true); }); test('should accept simple minimal schema (backward compatibility)', () => { diff --git a/packages/server/src/server/mcp.ts b/packages/server/src/server/mcp.ts index 40ec8bb1e..b3fb54813 100644 --- a/packages/server/src/server/mcp.ts +++ b/packages/server/src/server/mcp.ts @@ -20,7 +20,6 @@ import type { StandardSchemaWithJSON, Tool, ToolAnnotations, - ToolExecution, Transport, Variables } from '@modelcontextprotocol/core'; @@ -125,7 +124,6 @@ export class McpServer { ? (standardSchemaToJsonSchema(tool.inputSchema, 'input') as Tool['inputSchema']) : EMPTY_OBJECT_JSON_SCHEMA, annotations: tool.annotations, - execution: tool.execution, _meta: tool._meta }; @@ -679,7 +677,6 @@ export class McpServer { inputSchema: StandardSchemaWithJSON | undefined, outputSchema: StandardSchemaWithJSON | undefined, annotations: ToolAnnotations | undefined, - execution: ToolExecution | undefined, _meta: Record | undefined, handler: AnyToolHandler ): RegisteredTool { @@ -695,7 +692,6 @@ export class McpServer { inputSchema, outputSchema, annotations, - execution, _meta, handler: handler, executor: createToolExecutor(inputSchema, handler), @@ -820,7 +816,6 @@ export class McpServer { normalizeRawShapeSchema(inputSchema), normalizeRawShapeSchema(outputSchema), annotations, - undefined, _meta, cb as ToolCallback ); @@ -1069,7 +1064,6 @@ export type RegisteredTool = { inputSchema?: StandardSchemaWithJSON; outputSchema?: StandardSchemaWithJSON; annotations?: ToolAnnotations; - execution?: ToolExecution; _meta?: Record; handler: AnyToolHandler; /** @hidden */