From d4854bce6071dd7f8b2fd1e31ead5c7038d82df2 Mon Sep 17 00:00:00 2001 From: Peter Alexander Date: Sun, 7 Jun 2026 13:57:24 +0100 Subject: [PATCH 1/6] Align draft schema with spec docs - Declare the reserved io.modelcontextprotocol/subscriptionId _meta key via a new NotificationMetaObject type, including the rule for deriving the value from the subscriptions/listen request's JSON-RPC ID - Rewrite the three list_changed notification doc comments to reflect the opt-in subscriptions model instead of unsolicited delivery - Add the HEADER_MISMATCH (-32001) error code and HeaderMismatchError type required by the Streamable HTTP transport's header validation - Update cacheScope JSDoc to the authorization-context caching model used by the caching utility doc - Make CancelledNotificationParams.requestId required - Describe cancellation as client-initiated, with one server-side use: on stdio a server sends notifications/cancelled solely to terminate a subscriptions/listen stream - Give ListRootsRequest a minimal params shape instead of RequestParams, matching other server-initiated input requests - Remove ProgressNotification from ClientNotification: only clients issue requests, so only servers report progress Regenerated schema.json and schema.mdx. --- docs/specification/draft/schema.mdx | 121 +++++++++++++++++++--------- schema/draft/schema.json | 118 +++++++++++++++++++++------ schema/draft/schema.ts | 81 +++++++++++++++---- 3 files changed, 242 insertions(+), 78 deletions(-) diff --git a/docs/specification/draft/schema.mdx b/docs/specification/draft/schema.mdx index d9ed12511..4d0891243 100644 --- a/docs/specification/draft/schema.mdx +++ b/docs/specification/draft/schema.mdx @@ -148,11 +148,23 @@ deprecated features registry.

+
+ +### `NotificationMetaObject` + +
interface NotificationMetaObject {
  "io.modelcontextprotocol/subscriptionId"?: string;
  [key: string]: unknown;
}

Extends MetaObject with additional notification-specific fields. All key naming rules from MetaObject apply.

Identifies the subscription stream a notification was delivered on. The +server MUST include this key on every notification delivered via a subscriptions/listen stream, so the +client can correlate the notification with the originating subscription.

The value is derived from the JSON-RPC ID of the subscriptions/listen +request that opened the stream: the decimal string representation of the +ID if it is a number, or the ID verbatim if it is a string.

+
+ +
### `NotificationParams` -
interface NotificationParams {
  _meta?: MetaObject;
}

Common params for any notification.

+
interface NotificationParams {
  _meta?: NotificationMetaObject;
}

Common params for any notification.

@@ -246,6 +258,27 @@ input_required - the request requires additional input and the result conta +
+ +### `HEADER_MISMATCH` + +
HEADER_MISMATCH: -32001

Error code returned when the HTTP headers of a request do not match the +corresponding values in the request body, or required headers are +missing or malformed.

+
+ + +
+ +### `HeaderMismatchError` + +
interface HeaderMismatchError {
  jsonrpc: "2.0";
  id?: RequestId;
  error: Error & { code: -32001 };
}

Returned when a server rejects a request because the values in the HTTP +headers do not match the corresponding values in the request body, or +because required headers are missing or malformed. For HTTP, the response +status code MUST be 400 Bad Request.

+
+ +
### `InternalError` @@ -604,7 +637,7 @@ without nested objects or arrays.

### `CancelledNotification` -
interface CancelledNotification {
  jsonrpc: "2.0";
  method: "notifications/cancelled";
  params: CancelledNotificationParams;
}

This notification can be sent by either side to indicate that it is cancelling a previously-issued request.

The request SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.

This notification indicates that the result will be unused, so any associated processing SHOULD cease.

Example: User-requested cancellation
{
"jsonrpc": "2.0",
"method": "notifications/cancelled",
"params": {
"requestId": "123",
"reason": "User requested cancellation"
}
}
+
interface CancelledNotification {
  jsonrpc: "2.0";
  method: "notifications/cancelled";
  params: CancelledNotificationParams;
}

This notification is sent by the client to indicate that it is cancelling a request it previously issued.

On stdio, the server also sends this notification, solely to terminate a subscriptions/listen stream: it references the ID of the subscriptions/listen request that opened the stream. Servers MUST NOT use this notification to cancel any other request.

The request SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.

This notification indicates that the result will be unused, so any associated processing SHOULD cease.

Example: User-requested cancellation
{
"jsonrpc": "2.0",
"method": "notifications/cancelled",
"params": {
"requestId": "123",
"reason": "User requested cancellation"
}
}
@@ -612,7 +645,7 @@ without nested objects or arrays.

### `CancelledNotificationParams` -
interface CancelledNotificationParams {
  _meta?: MetaObject;
  requestId?: RequestId;
  reason?: string;
}

Parameters for a notifications/cancelled notification.

Example: User-requested cancellation
{
"requestId": "123",
"reason": "User requested cancellation"
}

The ID of the request to cancel.

This MUST correspond to the ID of a request previously issued in the same direction.

An optional string describing the reason for the cancellation. This MAY be logged or presented to the user.

+
interface CancelledNotificationParams {
  _meta?: NotificationMetaObject;
  requestId: RequestId;
  reason?: string;
}

Parameters for a notifications/cancelled notification.

Example: User-requested cancellation
{
"requestId": "123",
"reason": "User requested cancellation"
}

The ID of the request to cancel.

This MUST correspond to the ID of a request the client previously issued.

An optional string describing the reason for the cancellation. This MAY be logged or presented to the user.

@@ -633,9 +666,9 @@ deprecated features registry.

interface LoggingMessageNotificationParams {
  _meta?: MetaObject;
  level: LoggingLevel;
  logger?: string;
  data: unknown;
}

Parameters for a notifications/message notification.

Deprecated as of protocol version 2026-07-28 (SEP-2577). +

interface LoggingMessageNotificationParams {
  _meta?: NotificationMetaObject;
  level: LoggingLevel;
  logger?: string;
  data: unknown;
}

Parameters for a notifications/message notification.

Deprecated as of protocol version 2026-07-28 (SEP-2577). Remains in the specification for at least twelve months; see the -deprecated features registry.

Example: Log database connection failed
{
"level": "error",
"logger": "database",
"data": {
"error": "Connection failed",
"details": {
"host": "localhost",
"port": 5432
}
}
}

The severity of this log message.

An optional name of the logger issuing this message.

The data to be logged, such as a string message or an object. Any JSON serializable type is allowed here.

+deprecated features registry.

Example: Log database connection failed
{
"level": "error",
"logger": "database",
"data": {
"error": "Connection failed",
"details": {
"host": "localhost",
"port": 5432
}
}
}

The severity of this log message.

An optional name of the logger issuing this message.

The data to be logged, such as a string message or an object. Any JSON serializable type is allowed here.

@@ -654,7 +687,7 @@ deprecated features registry.

interface ProgressNotificationParams {
  _meta?: MetaObject;
  progressToken: ProgressToken;
  progress: number;
  total?: number;
  message?: string;
}

Parameters for a notifications/progress notification.

Example: Progress message
{
"progressToken": "oivaizmir",
"progress": 50,
"total": 100,
"message": "Reticulating splines..."
}

The progress token which was given in the initial request, used to associate this notification with the request that is proceeding.

The progress thus far. This should increase every time progress is made, even if the total is unknown.

Total number of items to process (or total progress required), if known.

An optional message describing the current progress.

+
interface ProgressNotificationParams {
  _meta?: NotificationMetaObject;
  progressToken: ProgressToken;
  progress: number;
  total?: number;
  message?: string;
}

Parameters for a notifications/progress notification.

Example: Progress message
{
"progressToken": "oivaizmir",
"progress": 50,
"total": 100,
"message": "Reticulating splines..."
}

The progress token which was given in the initial request, used to associate this notification with the request that is proceeding.

The progress thus far. This should increase every time progress is made, even if the total is unknown.

Total number of items to process (or total progress required), if known.

An optional message describing the current progress.

@@ -665,7 +698,7 @@ deprecated features registry.

interface PromptListChangedNotification {
  jsonrpc: "2.0";
  method: "notifications/prompts/list_changed";
  params?: NotificationParams;
}

An optional notification from the server to the client, informing it that the list of prompts it offers has changed. This may be issued by servers without any previous subscription from the client.

Example: Prompts list changed
{
"jsonrpc": "2.0",
"method": "notifications/prompts/list_changed"
}
+
interface PromptListChangedNotification {
  jsonrpc: "2.0";
  method: "notifications/prompts/list_changed";
  params?: NotificationParams;
}

An optional notification from the server to the client, informing it that the list of prompts it offers has changed. This is only delivered on a subscriptions/listen stream when the client requested it via the promptsListChanged filter field.

Example: Prompts list changed
{
"jsonrpc": "2.0",
"method": "notifications/prompts/list_changed"
}
@@ -676,7 +709,7 @@ deprecated features registry.

interface ResourceListChangedNotification {
  jsonrpc: "2.0";
  method: "notifications/resources/list_changed";
  params?: NotificationParams;
}

An optional notification from the server to the client, informing it that the list of resources it can read from has changed. This may be issued by servers without any previous subscription from the client.

Example: Resources list changed
{
"jsonrpc": "2.0",
"method": "notifications/resources/list_changed"
}
+
interface ResourceListChangedNotification {
  jsonrpc: "2.0";
  method: "notifications/resources/list_changed";
  params?: NotificationParams;
}

An optional notification from the server to the client, informing it that the list of resources it can read from has changed. This is only delivered on a subscriptions/listen stream when the client requested it via the resourcesListChanged filter field.

Example: Resources list changed
{
"jsonrpc": "2.0",
"method": "notifications/resources/list_changed"
}
@@ -695,7 +728,7 @@ deprecated features registry.

interface ResourceUpdatedNotificationParams {
  _meta?: MetaObject;
  uri: string;
}

Parameters for a notifications/resources/updated notification.

Example: File resource updated
{
"uri": "file:///project/src/main.rs"
}

The URI of the resource that has been updated. This might be a sub-resource of the one that the client actually subscribed to.

+
interface ResourceUpdatedNotificationParams {
  _meta?: NotificationMetaObject;
  uri: string;
}

Parameters for a notifications/resources/updated notification.

Example: File resource updated
{
"uri": "file:///project/src/main.rs"
}

The URI of the resource that has been updated. This might be a sub-resource of the one that the client actually subscribed to.

@@ -716,7 +749,7 @@ types it agreed to honor.

interface SubscriptionsAcknowledgedNotificationParams {
  _meta?: MetaObject;
  notifications: SubscriptionFilter;
}

Parameters for a notifications/subscriptions/acknowledged notification.

The subset of requested notification types the server agreed to honor. +

interface SubscriptionsAcknowledgedNotificationParams {
  _meta?: NotificationMetaObject;
  notifications: SubscriptionFilter;
}

Parameters for a notifications/subscriptions/acknowledged notification.

The subset of requested notification types the server agreed to honor. Only includes notification types the server actually supports; if the client requested an unsupported type (e.g., promptsListChanged when the server has no prompts), it is omitted from this set.

@@ -730,7 +763,7 @@ the server has no prompts), it is omitted from this set.

### `ToolListChangedNotification` -
interface ToolListChangedNotification {
  jsonrpc: "2.0";
  method: "notifications/tools/list_changed";
  params?: NotificationParams;
}

An optional notification from the server to the client, informing it that the list of tools it offers has changed. This may be issued by servers without any previous subscription from the client.

Example: Tools list changed
{
"jsonrpc": "2.0",
"method": "notifications/tools/list_changed"
}
+
interface ToolListChangedNotification {
  jsonrpc: "2.0";
  method: "notifications/tools/list_changed";
  params?: NotificationParams;
}

An optional notification from the server to the client, informing it that the list of tools it offers has changed. This is only delivered on a subscriptions/listen stream when the client requested it via the toolsListChanged filter field.

Example: Tools list changed
{
"jsonrpc": "2.0",
"method": "notifications/tools/list_changed"
}
@@ -749,7 +782,7 @@ the server has no prompts), it is omitted from this set.

### `ElicitationCompleteNotificationParams` -
interface ElicitationCompleteNotificationParams {
  _meta?: MetaObject;
  elicitationId: string;
}

Parameters for a notifications/elicitation/complete notification.

The ID of the elicitation that completed.

+
interface ElicitationCompleteNotificationParams {
  _meta?: NotificationMetaObject;
  elicitationId: string;
}

Parameters for a notifications/elicitation/complete notification.

The ID of the elicitation that completed.

@@ -865,10 +898,12 @@ If present, there may be more results available.

Indicates the intended scope of the cached response, analogous to HTTP Cache-Control: public vs Cache-Control: private.

  • "public": Any client or intermediary (e.g., shared gateway, proxy) -MAY cache the response and serve it to any user.
  • "private": Only the requesting user's client MAY cache the response. -Shared caches (e.g., multi-tenant gateways) MUST NOT serve a cached -copy to a different user.
+milliseconds after receiving the response.

Indicates the intended scope of the cached response, analogous to HTTP Cache-Control: public vs Cache-Control: private.

  • "public": The response does not contain user-specific data. Any +client or intermediary (e.g., shared gateway, caching proxy) MAY cache +the response and serve it across authorization contexts.
  • "private": The response MAY be cached and reused only within the +same authorization context. Caches MUST NOT be shared across +authorization contexts (e.g., a different access token requires a +different cache).
@@ -925,10 +960,12 @@ If present, there may be more results available.

Indicates the intended scope of the cached response, analogous to HTTP Cache-Control: public vs Cache-Control: private.

  • "public": Any client or intermediary (e.g., shared gateway, proxy) -MAY cache the response and serve it to any user.
  • "private": Only the requesting user's client MAY cache the response. -Shared caches (e.g., multi-tenant gateways) MUST NOT serve a cached -copy to a different user.
+milliseconds after receiving the response.

Indicates the intended scope of the cached response, analogous to HTTP Cache-Control: public vs Cache-Control: private.

  • "public": The response does not contain user-specific data. Any +client or intermediary (e.g., shared gateway, caching proxy) MAY cache +the response and serve it across authorization contexts.
  • "private": The response MAY be cached and reused only within the +same authorization context. Caches MUST NOT be shared across +authorization contexts (e.g., a different access token requires a +different cache).
@@ -981,10 +1018,12 @@ server implementing an earlier protocol version (which does not include re client MAY cache this response before re-fetching. Semantics are analogous to HTTP Cache-Control max-age.

  • If 0, The response SHOULD be considered immediately stale, The client MAY re-fetch every time the result is needed.
  • If positive, the client SHOULD consider the result fresh for this many -milliseconds after receiving the response.

Indicates the intended scope of the cached response, analogous to HTTP Cache-Control: public vs Cache-Control: private.

  • "public": Any client or intermediary (e.g., shared gateway, proxy) -MAY cache the response and serve it to any user.
  • "private": Only the requesting user's client MAY cache the response. -Shared caches (e.g., multi-tenant gateways) MUST NOT serve a cached -copy to a different user.
+milliseconds after receiving the response.

Indicates the intended scope of the cached response, analogous to HTTP Cache-Control: public vs Cache-Control: private.

  • "public": The response does not contain user-specific data. Any +client or intermediary (e.g., shared gateway, caching proxy) MAY cache +the response and serve it across authorization contexts.
  • "private": The response MAY be cached and reused only within the +same authorization context. Caches MUST NOT be shared across +authorization contexts (e.g., a different access token requires a +different cache).
@@ -1019,10 +1058,12 @@ If present, there may be more results available.

Indicates the intended scope of the cached response, analogous to HTTP Cache-Control: public vs Cache-Control: private.

  • "public": Any client or intermediary (e.g., shared gateway, proxy) -MAY cache the response and serve it to any user.
  • "private": Only the requesting user's client MAY cache the response. -Shared caches (e.g., multi-tenant gateways) MUST NOT serve a cached -copy to a different user.
+milliseconds after receiving the response.

Indicates the intended scope of the cached response, analogous to HTTP Cache-Control: public vs Cache-Control: private.

  • "public": The response does not contain user-specific data. Any +client or intermediary (e.g., shared gateway, caching proxy) MAY cache +the response and serve it across authorization contexts.
  • "private": The response MAY be cached and reused only within the +same authorization context. Caches MUST NOT be shared across +authorization contexts (e.g., a different access token requires a +different cache).
@@ -1044,13 +1085,13 @@ if present).