From 2b8fd17a38c67a4edb1826bff1880f3b1066b8c6 Mon Sep 17 00:00:00 2001 From: Felix Weinberger Date: Fri, 17 Jul 2026 14:54:12 +0000 Subject: [PATCH] Align SEP-2575 checks with spec PR #3002: serverInfo in result _meta, clientInfo optional Spec PR #3002 (part of the final 2026-07-28 revision) moved serverInfo from the DiscoverResult body to _meta['io.modelcontextprotocol/serverInfo'] and demoted the request envelope's clientInfo from required to SHOULD. The checks still asserted the old shape, failing SDKs that follow the final revision. - Vendor schema types at spec commit 71e30695. - server-stateless: drop the missing-clientInfo rejection case and assert the opposite (a clientInfo-less request must be served, new check sep-2575-request-meta-client-info-optional); discover no longer requires body serverInfo; new SHOULD-level check sep-2575-server-identifies-in-result-meta (WARNING when the _meta identity is absent, SKIPPED when discover itself failed). - request-metadata (client side): the clientInfo SHOULD moves out of the MUST check into its own id sep-2575-client-sends-client-info (WARNING on absence), so requirement levels never blend in one check id. - Mock servers and the everything-server example emit the _meta identity and accept clientInfo-less requests. --- .../servers/typescript/everything-server.ts | 12 +- src/mock-server/mock-server.test.ts | 5 +- src/mock-server/stateless.ts | 20 ++- src/scenarios/client/request-metadata.ts | 27 +++- src/scenarios/server/stateless.ts | 100 ++++++++++--- src/spec-types/2025-03-26.ts | 4 +- src/spec-types/2025-06-18.ts | 26 +--- src/spec-types/2025-11-25.ts | 28 +--- src/spec-types/SOURCE | 2 +- src/spec-types/draft.ts | 133 ++++++++++++------ 10 files changed, 237 insertions(+), 120 deletions(-) diff --git a/examples/servers/typescript/everything-server.ts b/examples/servers/typescript/everything-server.ts index 39be2f06..f01c89fb 100644 --- a/examples/servers/typescript/everything-server.ts +++ b/examples/servers/typescript/everything-server.ts @@ -1266,11 +1266,11 @@ app.post('/mcp', async (req, res) => { // Per-Request Metadata Integrity Checks (Fields verification). // A request missing any required `_meta` field is malformed: -32602 and, - // on HTTP, status 400 Bad Request. + // on HTTP, status 400 Bad Request. `clientInfo` is a SHOULD since spec + // PR #3002 and is never required. if ( !meta || !meta['io.modelcontextprotocol/protocolVersion'] || - !meta['io.modelcontextprotocol/clientInfo'] || !meta['io.modelcontextprotocol/clientCapabilities'] ) { return res.status(400).json({ @@ -1372,7 +1372,13 @@ app.post('/mcp', async (req, res) => { // served on this path, so the capability must be declared too. resources: {} }, - serverInfo: { name: 'everything-stateless-server', version: '1.0.0' } + // Spec PR #3002: server identity lives in the result `_meta`. + _meta: { + 'io.modelcontextprotocol/serverInfo': { + name: 'everything-stateless-server', + version: '1.0.0' + } + } } }); } diff --git a/src/mock-server/mock-server.test.ts b/src/mock-server/mock-server.test.ts index 2d26cf54..3c3a1d7d 100644 --- a/src/mock-server/mock-server.test.ts +++ b/src/mock-server/mock-server.test.ts @@ -252,7 +252,10 @@ describe('createServerStateless', () => { ); expect(status).toBe(200); expect(body.result.supportedVersions).toEqual(STATELESS_SPEC_VERSIONS); - expect(body.result.serverInfo.name).toBe('conformance-mock-server'); + // Spec PR #3002: server identity lives in the result `_meta`. + expect(body.result._meta['io.modelcontextprotocol/serverInfo'].name).toBe( + 'conformance-mock-server' + ); } finally { await srv.close(); } diff --git a/src/mock-server/stateless.ts b/src/mock-server/stateless.ts index 2a69f987..9968d419 100644 --- a/src/mock-server/stateless.ts +++ b/src/mock-server/stateless.ts @@ -1,8 +1,9 @@ /** * Stateless mock server: 2026-x lifecycle (SEP-2575). * - * No initialize handshake. Validates `_meta` (protocolVersion / clientInfo / - * clientCapabilities) and the `MCP-Protocol-Version` header on every request, + * No initialize handshake. Validates `_meta` (protocolVersion / + * clientCapabilities — `clientInfo` is a SHOULD since spec PR #3002 and is + * never required) and the `MCP-Protocol-Version` header on every request, * serves `server/discover`, and routes other methods to the supplied handlers. * Implemented with raw express so it can front-run SDK support. */ @@ -14,9 +15,13 @@ import type { MockServer, RequestHandlers } from './index'; import { STATELESS_SPEC_VERSIONS } from '../connection/select'; import { capabilitiesFromHandlers } from './stateful'; +/** + * The required per-request `_meta` keys. `io.modelcontextprotocol/clientInfo` + * is deliberately absent: spec PR #3002 demoted it to SHOULD, so a request + * without it is valid. + */ const META_KEYS = [ 'io.modelcontextprotocol/protocolVersion', - 'io.modelcontextprotocol/clientInfo', 'io.modelcontextprotocol/clientCapabilities' ] as const; @@ -156,7 +161,14 @@ export function validateStatelessRequest( result: withRequiredDraftResultFields(method, { supportedVersions, capabilities, - serverInfo: { name: 'conformance-mock-server', version: '1.0.0' } + // Spec PR #3002: server identity lives in the result `_meta`, not + // the DiscoverResult body. + _meta: { + 'io.modelcontextprotocol/serverInfo': { + name: 'conformance-mock-server', + version: '1.0.0' + } + } }) } }; diff --git a/src/scenarios/client/request-metadata.ts b/src/scenarios/client/request-metadata.ts index 61dc5e11..2d1d5dc2 100644 --- a/src/scenarios/client/request-metadata.ts +++ b/src/scenarios/client/request-metadata.ts @@ -32,6 +32,7 @@ const STATUS_SEVERITY: Record = { export const DECLARED_CHECK_IDS = [ 'sep-2575-http-client-sends-version-header', 'sep-2575-client-populates-meta', + 'sep-2575-client-sends-client-info', 'sep-2575-http-version-header-matches-meta', 'sep-2575-client-declares-roots-capability', 'sep-2575-client-declares-sampling-capability', @@ -161,17 +162,19 @@ export class RequestMetadataScenario implements Scenario { // 2. "Every client request MUST include the following // io.modelcontextprotocol/* fields in _meta: protocolVersion, - // clientInfo, clientCapabilities." + // clientCapabilities." clientInfo is a SHOULD since spec PR #3002 and + // is tracked by its own check below, so requirement levels never blend + // in one check id. const hasClientInfo = meta?.['io.modelcontextprotocol/clientInfo']; const hasCapabilities = meta?.['io.modelcontextprotocol/clientCapabilities']; - const metaIsValid = metaVersion && hasClientInfo && hasCapabilities; + const metaIsValid = metaVersion && hasCapabilities; this.addOrUpdateCheck({ id: 'sep-2575-client-populates-meta', name: 'ClientPopulatesMeta', description: - 'Client populates _meta on every request with all three required fields', + 'Client populates _meta on every request with the required fields (protocolVersion, clientCapabilities)', status: metaIsValid ? 'SUCCESS' : 'FAILURE', timestamp: new Date().toISOString(), specReferences: [ @@ -183,6 +186,24 @@ export class RequestMetadataScenario implements Scenario { details: { method: request.method, meta } }); + // 2b. clientInfo SHOULD (spec PR #3002): absence is a WARNING, never a + // FAILURE — a dedicated id so adoption is trackable on its own. + this.addOrUpdateCheck({ + id: 'sep-2575-client-sends-client-info', + name: 'ClientSendsClientInfo', + description: + "Client SHOULD include io.modelcontextprotocol/clientInfo in every request's _meta (spec PR #3002)", + status: hasClientInfo ? 'SUCCESS' : 'WARNING', + timestamp: new Date().toISOString(), + specReferences: [ + { + id: 'SEP-2575', + url: 'https://modelcontextprotocol.io/specification/draft/basic/index#meta' + } + ], + details: { method: request.method, meta } + }); + // 3. "The header value MUST match the io.modelcontextprotocol/protocolVersion // field carried in the request body's _meta." Only comparable when both // are present; absence is already covered by the two checks above, so diff --git a/src/scenarios/server/stateless.ts b/src/scenarios/server/stateless.ts index 917e3436..849437a0 100644 --- a/src/scenarios/server/stateless.ts +++ b/src/scenarios/server/stateless.ts @@ -29,13 +29,14 @@ export class ServerStatelessScenario implements ClientScenario { **Server Implementation Requirements:** **Endpoints**: -- \`server/discover\`: Returns supportedVersions, capabilities, and serverInfo metadata. +- \`server/discover\`: Returns supportedVersions and capabilities; SHOULD identify itself via \`_meta['io.modelcontextprotocol/serverInfo']\` (spec PR #3002). - \`tools/call\`: Implement structural test tools like \`test_missing_capability\` requiring explicit capabilities in \`_meta\`. **Grouped Specification Requirements**: -1. **Per-Request _meta Validation (5 Checks)** - - Rejects requests missing \`_meta\` or lacking structural required internal subfields (\`protocolVersion\`, \`clientInfo\`, \`clientCapabilities\`) with a JSON-RPC \`-32602 Invalid params\` error signature and an HTTP status code \`400 Bad Request\`. +1. **Per-Request _meta Validation (4 Checks)** + - Rejects requests missing \`_meta\` or lacking structural required internal subfields (\`protocolVersion\`, \`clientCapabilities\`) with a JSON-RPC \`-32602 Invalid params\` error signature and an HTTP status code \`400 Bad Request\`. + - Serves requests whose \`_meta\` omits \`clientInfo\` (a SHOULD since spec PR #3002 — servers MUST NOT require it). 2. **Discovery & Capabilities (3 Checks)** - Implements \`server/discover\` mapping exact mandatory protocol elements. - Dynamically checks prompt capability declaration constraints, validates that active RPC handlers match advertised discovery capacities. @@ -332,20 +333,8 @@ export class ServerStatelessScenario implements ClientScenario { }, rpcId: 102 }, - { - slug: 'missing-client-info', - description: - 'Rejects request with _meta missing io.modelcontextprotocol/clientInfo', - params: { - _meta: { - 'io.modelcontextprotocol/protocolVersion': - validMeta['io.modelcontextprotocol/protocolVersion'], - 'io.modelcontextprotocol/clientCapabilities': - validMeta['io.modelcontextprotocol/clientCapabilities'] - } - }, - rpcId: 103 - }, + // No 'missing-client-info' case: spec PR #3002 demoted clientInfo to + // SHOULD, so its absence is valid (asserted positively below). { slug: 'missing-client-capabilities', description: @@ -411,6 +400,45 @@ export class ServerStatelessScenario implements ClientScenario { ); } + // Positive companion (spec PR #3002): clientInfo is a SHOULD — a request + // whose _meta omits it MUST be served, not rejected. + const noClientInfoProbe = await sendRpc( + 'server/discover', + { + _meta: { + 'io.modelcontextprotocol/protocolVersion': + validMeta['io.modelcontextprotocol/protocolVersion'], + 'io.modelcontextprotocol/clientCapabilities': + validMeta['io.modelcontextprotocol/clientCapabilities'] + } + }, + undefined, + 105 + ).catch(() => null); + const noClientInfoData: any = noClientInfoProbe?.data; + await runCheck( + 'sep-2575-request-meta-client-info-optional', + 'RequestMetaClientInfoOptional', + 'Serves requests whose _meta omits io.modelcontextprotocol/clientInfo (clientInfo is a SHOULD).', + () => { + if (!noClientInfoProbe) + return { error: 'clientInfo-less probe failed completely' }; + if (noClientInfoData?.error) { + return { + error: `Expected a result, got error ${noClientInfoData.error.code}: ${noClientInfoData.error.message}`, + details: { response: noClientInfoData } + }; + } + if (noClientInfoProbe.res?.status !== 200) { + return { + error: `Expected HTTP 200, got status code ${noClientInfoProbe.res?.status}`, + details: { response: noClientInfoData } + }; + } + return { details: { response: noClientInfoData } }; + } + ); + // ========================================== // 2. Discovery & Capabilities (4 Checks) // ========================================== @@ -448,10 +476,12 @@ export class ServerStatelessScenario implements ClientScenario { () => { if (discoverRpcError) return { error: `Discovery failed: ${discoverRpcError.message}` }; + // Mandatory body fields per the final revision (spec PR #3002 removed + // body serverInfo — identity is a SHOULD in the result _meta, checked + // separately below). if ( !discoverResult?.supportedVersions || - !discoverResult?.capabilities || - !discoverResult?.serverInfo + !discoverResult?.capabilities ) { return { error: 'Missing mandatory fields in discover response setup', @@ -462,6 +492,38 @@ export class ServerStatelessScenario implements ClientScenario { } ); + await runCheck( + 'sep-2575-server-identifies-in-result-meta', + 'ServerIdentifiesInResultMeta', + "Servers SHOULD identify themselves via _meta['io.modelcontextprotocol/serverInfo'] on responses (spec PR #3002).", + () => { + if (discoverRpcError) + // Discover itself failed (already a FAILURE on the implements- + // discover check): nothing is known about identity, so the gap + // must not read as an intentional absence. + return { + skipped: true, + details: { + note: `Prerequisite missing: ${discoverRpcError.message}` + } + }; + const metaServerInfo = + discoverResult?._meta?.['io.modelcontextprotocol/serverInfo']; + if (!metaServerInfo?.name || !metaServerInfo?.version) { + const bodyServerInfo = discoverResult?.serverInfo; + return { + // SHOULD-level: WARNING, never FAILURE. + warning: true, + error: bodyServerInfo + ? 'serverInfo found only in the pre-#3002 result body, not in _meta' + : 'No serverInfo in the discover result _meta', + details: { result: discoverResult } + }; + } + return { details: { serverInfo: metaServerInfo } }; + } + ); + await runCheck( 'sep-2575-server-declares-prompts-in-discover', 'ServerDeclaresPromptsInDiscover', diff --git a/src/spec-types/2025-03-26.ts b/src/spec-types/2025-03-26.ts index a4b3a9d9..6da0f596 100644 --- a/src/spec-types/2025-03-26.ts +++ b/src/spec-types/2025-03-26.ts @@ -1234,9 +1234,7 @@ export type ClientResult = EmptyResult | CreateMessageResult | ListRootsResult; /* Server messages */ export type ServerRequest = - | PingRequest - | CreateMessageRequest - | ListRootsRequest; + PingRequest | CreateMessageRequest | ListRootsRequest; export type ServerNotification = | CancelledNotification diff --git a/src/spec-types/2025-06-18.ts b/src/spec-types/2025-06-18.ts index 8778ec07..0df081ee 100644 --- a/src/spec-types/2025-06-18.ts +++ b/src/spec-types/2025-06-18.ts @@ -6,10 +6,7 @@ * @category JSON-RPC */ export type JSONRPCMessage = - | JSONRPCRequest - | JSONRPCNotification - | JSONRPCResponse - | JSONRPCError; + JSONRPCRequest | JSONRPCNotification | JSONRPCResponse | JSONRPCError; /** @internal */ export const LATEST_PROTOCOL_VERSION = "2025-06-18"; @@ -1134,11 +1131,7 @@ export interface Annotations { * @category Content */ export type ContentBlock = - | TextContent - | ImageContent - | AudioContent - | ResourceLink - | EmbeddedResource; + TextContent | ImageContent | AudioContent | ResourceLink | EmbeddedResource; /** * Text provided to or from an LLM. @@ -1490,10 +1483,7 @@ export interface ElicitRequest extends Request { * @category `elicitation/create` */ export type PrimitiveSchemaDefinition = - | StringSchema - | NumberSchema - | BooleanSchema - | EnumSchema; + StringSchema | NumberSchema | BooleanSchema | EnumSchema; /** * @category `elicitation/create` @@ -1586,18 +1576,12 @@ export type ClientNotification = /** @internal */ export type ClientResult = - | EmptyResult - | CreateMessageResult - | ListRootsResult - | ElicitResult; + EmptyResult | CreateMessageResult | ListRootsResult | ElicitResult; /* Server messages */ /** @internal */ export type ServerRequest = - | PingRequest - | CreateMessageRequest - | ListRootsRequest - | ElicitRequest; + PingRequest | CreateMessageRequest | ListRootsRequest | ElicitRequest; /** @internal */ export type ServerNotification = diff --git a/src/spec-types/2025-11-25.ts b/src/spec-types/2025-11-25.ts index 332c3f0e..b734ae30 100644 --- a/src/spec-types/2025-11-25.ts +++ b/src/spec-types/2025-11-25.ts @@ -6,9 +6,7 @@ * @category JSON-RPC */ export type JSONRPCMessage = - | JSONRPCRequest - | JSONRPCNotification - | JSONRPCResponse; + JSONRPCRequest | JSONRPCNotification | JSONRPCResponse; /** @internal */ export const LATEST_PROTOCOL_VERSION = "2025-11-25"; @@ -1740,11 +1738,7 @@ export interface Annotations { * @category Content */ export type ContentBlock = - | TextContent - | ImageContent - | AudioContent - | ResourceLink - | EmbeddedResource; + TextContent | ImageContent | AudioContent | ResourceLink | EmbeddedResource; /** * Text provided to or from an LLM. @@ -2219,8 +2213,7 @@ export interface ElicitRequestURLParams extends TaskAugmentedRequestParams { * @category `elicitation/create` */ export type ElicitRequestParams = - | ElicitRequestFormParams - | ElicitRequestURLParams; + ElicitRequestFormParams | ElicitRequestURLParams; /** * A request from the server to elicit additional information from the user via the client. @@ -2239,10 +2232,7 @@ export interface ElicitRequest extends JSONRPCRequest { * @category `elicitation/create` */ export type PrimitiveSchemaDefinition = - | StringSchema - | NumberSchema - | BooleanSchema - | EnumSchema; + StringSchema | NumberSchema | BooleanSchema | EnumSchema; /** * @category `elicitation/create` @@ -2343,8 +2333,7 @@ export interface TitledSingleSelectEnumSchema { */ // Combined single selection enumeration export type SingleSelectEnumSchema = - | UntitledSingleSelectEnumSchema - | TitledSingleSelectEnumSchema; + UntitledSingleSelectEnumSchema | TitledSingleSelectEnumSchema; /** * Schema for multiple-selection enumeration without display titles for options. @@ -2437,8 +2426,7 @@ export interface TitledMultiSelectEnumSchema { */ // Combined multiple selection enumeration export type MultiSelectEnumSchema = - | UntitledMultiSelectEnumSchema - | TitledMultiSelectEnumSchema; + UntitledMultiSelectEnumSchema | TitledMultiSelectEnumSchema; /** * Use TitledSingleSelectEnumSchema instead. @@ -2464,9 +2452,7 @@ export interface LegacyTitledEnumSchema { */ // Union type for all enum schemas export type EnumSchema = - | SingleSelectEnumSchema - | MultiSelectEnumSchema - | LegacyTitledEnumSchema; + SingleSelectEnumSchema | MultiSelectEnumSchema | LegacyTitledEnumSchema; /** * The client's response to an elicitation request. diff --git a/src/spec-types/SOURCE b/src/spec-types/SOURCE index 33d35e99..a4891c9d 100644 --- a/src/spec-types/SOURCE +++ b/src/spec-types/SOURCE @@ -1 +1 @@ -modelcontextprotocol@f817239f4d6b1efff2c4dfc2f7af85c985d73076 +modelcontextprotocol@71e306956a4959c9655e5036be215d41986596e6 diff --git a/src/spec-types/draft.ts b/src/spec-types/draft.ts index c48f9d71..110485f6 100644 --- a/src/spec-types/draft.ts +++ b/src/spec-types/draft.ts @@ -4,12 +4,7 @@ * @category Common Types */ export type JSONValue = - | string - | number - | boolean - | null - | JSONObject - | JSONArray; + string | number | boolean | null | JSONObject | JSONArray; /** * @category Common Types @@ -29,9 +24,7 @@ export type JSONArray = JSONValue[]; * @category JSON-RPC */ export type JSONRPCMessage = - | JSONRPCRequest - | JSONRPCNotification - | JSONRPCResponse; + JSONRPCRequest | JSONRPCNotification | JSONRPCResponse; /** @internal */ export const LATEST_PROTOCOL_VERSION = "2026-07-28"; @@ -82,12 +75,19 @@ export interface RequestMetaObject extends MetaObject { */ "io.modelcontextprotocol/protocolVersion": string; /** - * Identifies the client software making the request. Required. + * Identifies the client software making the request. Clients SHOULD + * include this field on every request unless specifically configured not + * to do so. * * The {@link Implementation} schema requires `name` and `version`; other * fields are optional. + * + * The value is self-reported by the client and is not verified by the + * protocol. It is intended for display, logging, and debugging. Servers + * SHOULD NOT use it to change their behavior, and SHOULD NOT rely on it for + * security decisions. */ - "io.modelcontextprotocol/clientInfo": Implementation; + "io.modelcontextprotocol/clientInfo"?: Implementation; /** * The client's capabilities for this specific request. Required. * @@ -133,6 +133,30 @@ export interface NotificationMetaObject extends MetaObject { "io.modelcontextprotocol/subscriptionId"?: RequestId; } +/** + * Extends {@link MetaObject} with additional result-specific fields. All key naming rules from `MetaObject` apply. + * + * @see {@link MetaObject} for key naming rules and reserved prefixes. + * @see [General fields: `_meta`](/specification/draft/basic/index#meta) for more details. + * @category Common Types + */ +export interface ResultMetaObject extends MetaObject { + /** + * Identifies the server software producing the response. Servers SHOULD + * include this field on every response unless specifically configured not + * to do so. + * + * The {@link Implementation} schema requires `name` and `version`; other + * fields are optional. + * + * The value is self-reported by the server and is not verified by the + * protocol. It is intended for display, logging, and debugging. Clients + * SHOULD NOT use it to change their behavior, and SHOULD NOT rely on it for + * security decisions. + */ + "io.modelcontextprotocol/serverInfo"?: Implementation; +} + /** * A progress token, used to associate progress notifications with the original request. * @@ -197,7 +221,7 @@ export type ResultType = "complete" | "input_required" | string; * @category Common Types */ export interface Result { - _meta?: MetaObject; + _meta?: ResultMetaObject; /** * Indicates the type of the result, which allows the client to determine * how to parse the result object. @@ -511,15 +535,11 @@ export type EmptyResult = Result; /** @internal */ export type InputRequest = - | CreateMessageRequest - | ListRootsRequest - | ElicitRequest; + CreateMessageRequest | ListRootsRequest | ElicitRequest; /** @internal */ export type InputResponse = - | CreateMessageResult - | ListRootsResult - | ElicitResult; + CreateMessageResult | ListRootsResult | ElicitResult; /** * A map of server-initiated requests that the client must fulfill. @@ -665,10 +685,6 @@ export interface DiscoverResult extends CacheableResult { * The capabilities of the server. */ capabilities: ServerCapabilities; - /** - * Information about the server software implementation. - */ - serverInfo: Implementation; /** * Natural-language guidance describing the server and its features. * @@ -1300,6 +1316,40 @@ export interface SubscriptionsListenRequest extends JSONRPCRequest { params: SubscriptionsListenRequestParams; } +/** + * Extends {@link ResultMetaObject} with the subscription-stream identifier carried by a + * {@link SubscriptionsListenResult}. All key naming rules from `MetaObject` apply. + * + * @see {@link MetaObject} for key naming rules and reserved prefixes. + * @category `subscriptions/listen` + */ +export interface SubscriptionsListenResultMeta extends ResultMetaObject { + /** + * Identifies the subscription stream this response closes, so the client can + * correlate it with the originating subscription — mirroring the same key on + * the stream's notifications. The value is the JSON-RPC ID of the + * `subscriptions/listen` request that opened the stream (and equals this + * response's `id`). + */ + "io.modelcontextprotocol/subscriptionId": RequestId; +} + +/** + * The response to a {@link SubscriptionsListenRequest | subscriptions/listen} + * request, signalling that the subscription has ended gracefully (for example, + * during server shutdown). Because the listen stream is long-lived, this result + * is sent only when the server tears the subscription down; an abrupt transport + * close carries no response. The result body is otherwise empty. + * + * @example Subscription closed gracefully + * {@includeCode ./examples/SubscriptionsListenResult/listen-closed.json} + * + * @category `subscriptions/listen` + */ +export interface SubscriptionsListenResult extends Result { + _meta: SubscriptionsListenResultMeta; +} + /** * Parameters for a {@link SubscriptionsAcknowledgedNotification | notifications/subscriptions/acknowledged} notification. * @@ -1316,10 +1366,16 @@ export interface SubscriptionsAcknowledgedNotificationParams extends Notificatio } /** - * Sent by the server as the first message on a - * {@link SubscriptionsListenRequest | subscriptions/listen} stream to acknowledge - * that the subscription has been established and to report which notification - * types it agreed to honor. + * Sent by the server to acknowledge that a + * {@link SubscriptionsListenRequest | subscriptions/listen} subscription has been + * established and to report which notification types it agreed to honor. + * + * This notification MUST be the first message the server sends carrying the + * subscription's ID in `io.modelcontextprotocol/subscriptionId`. The server MUST + * NOT send any notification on the subscription before acknowledging it. On + * stdio, where every subscription shares one channel, this ordering is defined + * per subscription ID and not per channel: messages belonging to other + * subscriptions MAY be interleaved before it. * * @example Listen acknowledged * {@includeCode ./examples/SubscriptionsAcknowledgedNotification/listen-acknowledged.json} @@ -2234,11 +2290,7 @@ export interface Annotations { * @category Content */ export type ContentBlock = - | TextContent - | ImageContent - | AudioContent - | ResourceLink - | EmbeddedResource; + TextContent | ImageContent | AudioContent | ResourceLink | EmbeddedResource; /** * Text provided to or from an LLM. @@ -2778,8 +2830,7 @@ export interface ElicitRequestURLParams { * @category `elicitation/create` */ export type ElicitRequestParams = - | ElicitRequestFormParams - | ElicitRequestURLParams; + ElicitRequestFormParams | ElicitRequestURLParams; /** * A request from the server to elicit additional information from the user via the client. @@ -2801,10 +2852,7 @@ export interface ElicitRequest { * @category `elicitation/create` */ export type PrimitiveSchemaDefinition = - | StringSchema - | NumberSchema - | BooleanSchema - | EnumSchema; + StringSchema | NumberSchema | BooleanSchema | EnumSchema; /** * @example Email input schema @@ -2929,8 +2977,7 @@ export interface TitledSingleSelectEnumSchema { */ // Combined single selection enumeration export type SingleSelectEnumSchema = - | UntitledSingleSelectEnumSchema - | TitledSingleSelectEnumSchema; + UntitledSingleSelectEnumSchema | TitledSingleSelectEnumSchema; /** * Schema for multiple-selection enumeration without display titles for options. @@ -3029,8 +3076,7 @@ export interface TitledMultiSelectEnumSchema { */ // Combined multiple selection enumeration export type MultiSelectEnumSchema = - | UntitledMultiSelectEnumSchema - | TitledMultiSelectEnumSchema; + UntitledMultiSelectEnumSchema | TitledMultiSelectEnumSchema; /** * Use {@link TitledSingleSelectEnumSchema} instead. @@ -3056,9 +3102,7 @@ export interface LegacyTitledEnumSchema { */ // Union type for all enum schemas export type EnumSchema = - | SingleSelectEnumSchema - | MultiSelectEnumSchema - | LegacyTitledEnumSchema; + SingleSelectEnumSchema | MultiSelectEnumSchema | LegacyTitledEnumSchema; /** * The result returned by the client for an {@link ElicitRequest| elicitation/create} request. @@ -3134,6 +3178,7 @@ export type ServerResult = | ListResourceTemplatesResult | ListResourcesResult | ReadResourceResult + | SubscriptionsListenResult | CallToolResult | ListToolsResult | InputRequiredResult;