Skip to content

Commit 425f79f

Browse files
Document resumability gating change and session-404 error status
Migration guide notes: unknown future protocol versions in an initialize body no longer enable resumability behavior, and the 404/-32001 'Session not found' response on session-ID mismatch is an SDK convention that may be re-derived for the 2026 protocol revision - clients should key off the HTTP status, not the code. Changeset for the server package included.
1 parent 6870ae4 commit 425f79f

3 files changed

Lines changed: 28 additions & 1 deletion

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@modelcontextprotocol/server': patch
3+
---
4+
5+
Bound the protocol-version checks gating SSE resumability behavior (priming events and `closeSSEStream` callbacks) in the Streamable HTTP server transport. Previously an open-ended `>= '2025-11-25'` comparison let unknown future protocol version strings from an `initialize`
6+
request body enable this behavior; the version must now also be one of the transport's supported protocol versions. Behavior for all currently supported protocol versions is unchanged.

docs/migration-SKILL.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,10 +503,19 @@ The 2025-11 task side-channel through `Protocol` is removed (was always `@experi
503503

504504
NOT removed (wire surface, kept for 2025-11-25 interop): task Zod schemas + inferred types (`Task`, `TaskStatus`, `TaskMetadata`, `RelatedTaskMetadata`, `CreateTaskResult`, `GetTask*`, `ListTasks*`, `CancelTask*`, `TaskStatusNotification*`, `TaskAugmentedRequestParams`), task members of the request/result/notification unions, the `tasks` capability key, `isTaskAugmentedRequestParams`, `RELATED_TASK_META_KEY`. Inbound `tasks/*` requests → `-32601`.
505505

506-
## 13. Client Behavioral Changes
506+
## 13. Behavioral Changes
507+
508+
### Client
507509

508510
`Client.listPrompts()`, `listResources()`, `listResourceTemplates()`, `listTools()` now return empty results when the server lacks the corresponding capability (instead of sending the request). Set `enforceStrictCapabilities: true` in `ClientOptions` to throw an error instead.
509511

512+
### Server (Streamable HTTP transport)
513+
514+
No code changes required; these are wire-behavior notes:
515+
516+
- Resumability behavior (SSE priming events, `closeSSEStream` / `closeStandaloneSSEStream` callbacks) is only enabled for protocol versions in the transport's supported-versions list that are `>= 2025-11-25`. Unknown future version strings in an `initialize` request body no longer enable it. Behavior for all currently supported protocol versions is unchanged.
517+
- Session-ID mismatch still responds `404 Not Found` with JSON-RPC error code `-32001` (`Session not found`), unchanged from v1. This `-32001` usage is an SDK convention, not a spec-assigned code, and may be re-derived as 2026 protocol revision error handling is adopted — migrated client code should key off the HTTP `404` status, not the `-32001` code.
518+
510519
## 14. Runtime-Specific JSON Schema Validators (Enhancement)
511520

512521
The SDK now auto-selects the appropriate JSON Schema validator based on runtime:

docs/migration.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,14 @@ app.use(hostHeaderValidation(['example.com']));
334334

335335
Note: the v2 signature takes a plain `string[]` instead of an options object.
336336

337+
### Resumability gating for unknown protocol versions (Streamable HTTP server)
338+
339+
The server-side Streamable HTTP transport enables resumability behavior introduced with protocol version `2025-11-25` — SSE priming events and the `closeSSEStream` / `closeStandaloneSSEStream` callbacks — based on the client's protocol version. Previously this was an
340+
open-ended `protocolVersion >= '2025-11-25'` comparison, so an unrecognized future version string in an `initialize` request body (which, unlike the `MCP-Protocol-Version` header, is not validated against the supported-versions list) silently enabled the behavior.
341+
342+
The check is now bounded: the version must be one of the transport's supported protocol versions (after `connect()`, the server's `supportedProtocolVersions`) **and** at least `2025-11-25`. Behavior for all currently supported protocol versions (`2024-10-07` through
343+
`2025-11-25`) is unchanged. Clients claiming an unknown future protocol version in the initialize body are now treated like clients without empty-SSE-data support: no priming event is sent and no early-close callbacks are provided.
344+
337345
### `setRequestHandler` and `setNotificationHandler` use method strings
338346

339347
The low-level `setRequestHandler` and `setNotificationHandler` methods on `Client`, `Server`, and `Protocol` now take a method string instead of a Zod schema.
@@ -989,6 +997,10 @@ The following APIs are unchanged between v1 and v2 (only the import paths change
989997
- All Zod schemas and type definitions from `types.ts` (except the aliases listed above)
990998
- Tool, prompt, and resource callback return types
991999

1000+
**Session-ID mismatch responses**: when session management is enabled and a request carries an `Mcp-Session-Id` header that doesn't match the active session, the Streamable HTTP server transport responds `404 Not Found` with a JSON-RPC error body using code `-32001` and
1001+
message `Session not found` — unchanged from v1. Note that this use of `-32001` is an SDK convention, not a spec-assigned error code, and it is expected to be re-derived as error handling for the 2026 protocol revision (`2026-07-28`) is adopted. Avoid hard-coding the
1002+
`-32001` code in client logic; key off the HTTP `404` status instead.
1003+
9921004
## Using an LLM to migrate your code
9931005

9941006
An LLM-optimized version of this guide is available at [`docs/migration-SKILL.md`](migration-SKILL.md). It contains dense mapping tables designed for tools like Claude Code to mechanically apply all the changes described above. You can paste it into your LLM context or load it as

0 commit comments

Comments
 (0)