diff --git a/.changeset/era-gate-explicit-schema-handlers.md b/.changeset/era-gate-explicit-schema-handlers.md deleted file mode 100644 index db051a95b9..0000000000 --- a/.changeset/era-gate-explicit-schema-handlers.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/server': patch ---- - -A server can now serve, and a client can now call, `tasks/get` and `tasks/cancel` of the Tasks extension (SEP-2663) on a 2026-07-28 connection, when the handler is registered and the request is sent with an explicit schema. Every other method that a protocol revision removed is still refused. If one server factory serves both eras and such a handler is meant for 2025-era clients only, register it only when `ctx.era === 'legacy'`. diff --git a/.changeset/lazy-tool-schema-conversion.md b/.changeset/lazy-tool-schema-conversion.md deleted file mode 100644 index 61d75a3f1c..0000000000 --- a/.changeset/lazy-tool-schema-conversion.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/server': patch ---- - -`registerTool` no longer converts tool schemas up front, so a server built per request stops converting every tool on every request. The warning about an invalid `x-mcp-header` declaration now appears each time tools are listed, not when the tool is registered. diff --git a/.changeset/node-hono-regular-dependency.md b/.changeset/node-hono-regular-dependency.md deleted file mode 100644 index 1a70253b0c..0000000000 --- a/.changeset/node-hono-regular-dependency.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/node': patch ---- - -`hono` is now a regular dependency of `@modelcontextprotocol/node`, so installs with strict peer-dependency checking no longer fail on the `hono` peer that `@hono/node-server` requires. No runtime change. diff --git a/.changeset/one-instance-per-request.md b/.changeset/one-instance-per-request.md deleted file mode 100644 index fe83fc4193..0000000000 --- a/.changeset/one-instance-per-request.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -'@modelcontextprotocol/server': minor -'@modelcontextprotocol/node': patch -'@modelcontextprotocol/express': patch -'@modelcontextprotocol/fastify': patch -'@modelcontextprotocol/hono': patch ---- - -A `Server` or `McpServer` now serves one connection at a time, and a Streamable HTTP server transport without sessions (`sessionIdGenerator: undefined`) serves one request. An app that uses one server object, or one stateless transport, for every HTTP request fails on the second request after this upgrade. Build the server and the transport per request instead. - -What keeps working without a change: - -- `createMcpHandler(buildServer)` and `serveStdio(buildServer)`, where `buildServer` returns a new server on every call. -- A handler that builds a new server and a new stateless transport for each request. -- One server and one transport per session (a transport with a `sessionIdGenerator`). -- Connecting a server again after `close()`. -- `Client`. - -What fails now, how it shows, and what to change: - -- One server object with a new stateless transport per request (`const server = new McpServer(...)` outside the handler, `await server.connect(transport)` inside it): the second HTTP request the process receives fails, and so does every later one. `connect()` rejects with an `SdkError` of code `ALREADY_CONNECTED`. If the handler closes the transport when the response ends, requests that arrive one after the other still work and a request that overlaps another one fails. Change: move `new McpServer(...)` and its registrations into the handler. -- One stateless transport for every request (a transport built once with `sessionIdGenerator: undefined`): the second HTTP request fails. `WebStandardStreamableHTTPServerTransport.handleRequest()` rejects with `Stateless transport cannot be reused across requests. Create a new transport per request.`, and `NodeStreamableHTTPServerTransport.handleRequest()` answers `500`. Change: build the server and the transport inside the handler and connect them there. -- `createMcpHandler(() => server)` with a server built once: a request that arrives after the previous response has been read to its end still works. A request that arrives while another one is being served is answered `500` with the JSON-RPC error `-32603` (`Internal server error`); the reason is reported only through the `onerror` option. Change: pass a function that builds the server, as in `createMcpHandler(buildServer)`. -- One server object for every session: the `initialize` request of the second session fails with `ALREADY_CONNECTED`. Change: build a server per session. - -What the caller sees when `connect()` or `handleRequest()` rejects depends on the host. Express 5, Fastify and Hono answer `500`. A plain `node:http` listener without its own error handling gets an unhandled rejection, which ends the process. - -The README examples of `@modelcontextprotocol/express`, `@modelcontextprotocol/fastify`, `@modelcontextprotocol/hono` and `@modelcontextprotocol/node`, and the handler examples in the JSDoc of `WebStandardStreamableHTTPServerTransport` and `NodeStreamableHTTPServerTransport`, now build a server and a transport per request. diff --git a/.changeset/origin-scheme-entries.md b/.changeset/origin-scheme-entries.md deleted file mode 100644 index 2f3513dc0a..0000000000 --- a/.changeset/origin-scheme-entries.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/server': minor ---- - -`allowedOrigins` and `validateOriginHeader` accept lowercase entries of the form `://*`, such as `moz-extension://*` or `chrome-extension://*`, which admit every origin of that scheme. This lets a server admit MCP clients that run as a browser extension when the extension ID cannot be listed, as on Firefox, where it differs on every install. `http://*` and `https://*` are not honoured, and the defaults are unchanged. diff --git a/.changeset/package-license-field.md b/.changeset/package-license-field.md deleted file mode 100644 index 68cd32c989..0000000000 --- a/.changeset/package-license-field.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/codemod': patch -'@modelcontextprotocol/core': patch -'@modelcontextprotocol/server': patch -'@modelcontextprotocol/server-legacy': patch -'@modelcontextprotocol/node': patch -'@modelcontextprotocol/express': patch -'@modelcontextprotocol/fastify': patch -'@modelcontextprotocol/hono': patch ---- - -The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. diff --git a/.changeset/probe-unusable-2xx-reply-message.md b/.changeset/probe-unusable-2xx-reply-message.md deleted file mode 100644 index 13309768ff..0000000000 --- a/.changeset/probe-unusable-2xx-reply-message.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@modelcontextprotocol/client': patch ---- - -With `versionNegotiation` in `'auto'` or pin mode, a `server/discover` probe answered with a 2xx that carries no usable reply (a body that -is not JSON under `application/json`, a bare `204`, a missing or unaccepted content type) still rejects `connect()` with -`EraNegotiationFailed`; an empty SSE stream or a `202` surfaces as the probe timeout instead. The message now says -`the server answered with an unusable reply (...)` instead of reading like a network failure. To connect to a 2025 server behind a front that -answers the probe this way, pass `connect(transport, { prior: { kind: 'legacy' } })` or use `mode: 'legacy'`. diff --git a/.changeset/redirects-within-origin.md b/.changeset/redirects-within-origin.md deleted file mode 100644 index 7d1ff8593c..0000000000 --- a/.changeset/redirects-within-origin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/client': minor ---- - -The HTTP client transports and the OAuth client helpers now follow a redirect only when it stays within the origin of the request (same scheme, host and port, or http to https on the same host with default ports) and keeps the method (a 307 or 308, or any redirect of a GET). Any other redirect is not followed. A transport then fails the request with an error that names the target; the session is kept and later messages still send. OAuth metadata discovery moves on to the next well-known URL, and any other OAuth request fails with an error that gives the status. Same-origin redirects that keep the method keep working on Node, up to five in a row, and no code changes are needed there. If your endpoint redirects to another origin, configure the transport with the URL it redirects to. A `requestInit.redirect` of `'error'` or `'manual'` is passed to fetch as it is for the requests a transport sends to the server (POST, GET and DELETE of the Streamable HTTP transport, POST of the SSE transport); for its OAuth requests, and for any other value, `requestInit.redirect` is not consulted by default. Browsers do not expose the target of a redirect to a page, so there a redirected request fails instead of being followed. Setting `redirectPolicy: 'follow'` on a transport leaves its redirects to the fetch implementation, as before this change. diff --git a/.changeset/register-prompt-context-only-overload.md b/.changeset/register-prompt-context-only-overload.md deleted file mode 100644 index 26203274ea..0000000000 --- a/.changeset/register-prompt-context-only-overload.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/server': patch ---- - -`McpServer.registerPrompt()` now types the callback correctly when no `argsSchema` is given: its one parameter is the server context. Before, reading `ctx.mcpReq` there was a type error although it worked at runtime. Prompts registered with an `argsSchema` are unchanged. diff --git a/.changeset/sse-connect-retry-once.md b/.changeset/sse-connect-retry-once.md deleted file mode 100644 index cb90c3aa39..0000000000 --- a/.changeset/sse-connect-retry-once.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/client': patch ---- - -`SSEClientTransport` now retries the SSE connection once after `onUnauthorized()` resolves, as documented. If the retry is also answered with 401, `start()` rejects with `SdkHttpError` (`ClientHttpAuthentication`) instead of calling `onUnauthorized()` again. A 401 on a later reconnect of a stream that had opened still gets one refresh. diff --git a/packages/client/CHANGELOG.md b/packages/client/CHANGELOG.md index a4c620cc35..6ad9ae191b 100644 --- a/packages/client/CHANGELOG.md +++ b/packages/client/CHANGELOG.md @@ -1,5 +1,28 @@ # @modelcontextprotocol/client +## 2.3.0 + +### Minor Changes + +- [#2901](https://github.com/modelcontextprotocol/typescript-sdk/pull/2901) [`433eb41`](https://github.com/modelcontextprotocol/typescript-sdk/commit/433eb413dc305ebeb93b8ebcde0095a8fc0d5fa0) Thanks [@claude](https://github.com/apps/claude)! - The HTTP client transports and the OAuth client helpers now follow a redirect only when it stays within the origin of the request (same scheme, host and port, or http to https on the same host with default ports) and keeps the method (a 307 or 308, or any redirect of a GET). Any other redirect is not followed. A transport then fails the request with an error that names the target; the session is kept and later messages still send. OAuth metadata discovery moves on to the next well-known URL, and any other OAuth request fails with an error that gives the status. Same-origin redirects that keep the method keep working on Node, up to five in a row, and no code changes are needed there. If your endpoint redirects to another origin, configure the transport with the URL it redirects to. A `requestInit.redirect` of `'error'` or `'manual'` is passed to fetch as it is for the requests a transport sends to the server (POST, GET and DELETE of the Streamable HTTP transport, POST of the SSE transport); for its OAuth requests, and for any other value, `requestInit.redirect` is not consulted by default. Browsers do not expose the target of a redirect to a page, so there a redirected request fails instead of being followed. Setting `redirectPolicy: 'follow'` on a transport leaves its redirects to the fetch implementation, as before this change. + +### Patch Changes + +- [#2599](https://github.com/modelcontextprotocol/typescript-sdk/pull/2599) [`5238fba`](https://github.com/modelcontextprotocol/typescript-sdk/commit/5238fba4424f82ec1ae9f6f458dd655ab322062d) Thanks [@freya0926](https://github.com/freya0926)! - A server can now serve, and a client can now call, `tasks/get` and `tasks/cancel` of the Tasks extension (SEP-2663) on a 2026-07-28 connection, when the handler is registered and the request is sent with an explicit schema. Every other method that a protocol revision removed is still refused. If one server factory serves both eras and such a handler is meant for 2025-era clients only, register it only when `ctx.era === 'legacy'`. + +- [#2908](https://github.com/modelcontextprotocol/typescript-sdk/pull/2908) [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1) Thanks [@claude](https://github.com/apps/claude)! - The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. + +- [#2903](https://github.com/modelcontextprotocol/typescript-sdk/pull/2903) [`e765b3b`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e765b3be84b7eba1837ba8da84acd6898cc47c65) Thanks [@claude](https://github.com/apps/claude)! - With `versionNegotiation` in `'auto'` or pin mode, a `server/discover` probe answered with a 2xx that carries no usable reply (a body that + is not JSON under `application/json`, a bare `204`, a missing or unaccepted content type) still rejects `connect()` with + `EraNegotiationFailed`; an empty SSE stream or a `202` surfaces as the probe timeout instead. The message now says + `the server answered with an unusable reply (...)` instead of reading like a network failure. To connect to a 2025 server behind a front that + answers the probe this way, pass `connect(transport, { prior: { kind: 'legacy' } })` or use `mode: 'legacy'`. + +- [#2905](https://github.com/modelcontextprotocol/typescript-sdk/pull/2905) [`c0cd01a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/c0cd01a21d867e57b29d7216416b25bf36898292) Thanks [@claude](https://github.com/apps/claude)! - `SSEClientTransport` now retries the SSE connection once after `onUnauthorized()` resolves, as documented. If the retry is also answered with 401, `start()` rejects with `SdkHttpError` (`ClientHttpAuthentication`) instead of calling `onUnauthorized()` again. A 401 on a later reconnect of a stream that had opened still gets one refresh. + +- Updated dependencies [[`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1)]: + - @modelcontextprotocol/core@2.3.0 + ## 2.2.0 ### Minor Changes diff --git a/packages/client/package.json b/packages/client/package.json index 66621972f9..b9b60f11c1 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/client", - "version": "2.2.0", + "version": "2.3.0", "description": "Model Context Protocol implementation for TypeScript - Client package", "license": "Apache-2.0", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/codemod/CHANGELOG.md b/packages/codemod/CHANGELOG.md index f40b02ca33..07211bd43f 100644 --- a/packages/codemod/CHANGELOG.md +++ b/packages/codemod/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelcontextprotocol/codemod +## 2.3.0 + +### Patch Changes + +- [#2908](https://github.com/modelcontextprotocol/typescript-sdk/pull/2908) [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1) Thanks [@claude](https://github.com/apps/claude)! - The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. + ## 2.2.0 ### Patch Changes diff --git a/packages/codemod/package.json b/packages/codemod/package.json index cb8fe9b436..7f5cee40c6 100644 --- a/packages/codemod/package.json +++ b/packages/codemod/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/codemod", - "version": "2.2.0", + "version": "2.3.0", "description": "Codemod to migrate MCP TypeScript SDK code from v1 to v2", "license": "Apache-2.0", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/core-internal/CHANGELOG.md b/packages/core-internal/CHANGELOG.md index fcf3a8c856..78a9f80338 100644 --- a/packages/core-internal/CHANGELOG.md +++ b/packages/core-internal/CHANGELOG.md @@ -1,5 +1,12 @@ # @modelcontextprotocol/core-internal +## 2.0.3 + +### Patch Changes + +- Updated dependencies [[`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1)]: + - @modelcontextprotocol/core@2.3.0 + ## 2.0.2 ### Patch Changes diff --git a/packages/core-internal/package.json b/packages/core-internal/package.json index 07754feab9..3afe12009a 100644 --- a/packages/core-internal/package.json +++ b/packages/core-internal/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/core-internal", "private": true, - "version": "2.0.2", + "version": "2.0.3", "description": "Model Context Protocol implementation for TypeScript - Core package", "license": "Apache-2.0", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 669b0d07dd..39e2b1d8c3 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,11 @@ # @modelcontextprotocol/core +## 2.3.0 + +### Patch Changes + +- [#2908](https://github.com/modelcontextprotocol/typescript-sdk/pull/2908) [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1) Thanks [@claude](https://github.com/apps/claude)! - The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. + ## 2.2.0 ### Minor Changes diff --git a/packages/core/package.json b/packages/core/package.json index 8ba5d6c88b..c5696165d1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/core", - "version": "2.2.0", + "version": "2.3.0", "description": "Model Context Protocol for TypeScript — public Zod schemas (spec + OAuth/OpenID)", "license": "Apache-2.0", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/middleware/express/CHANGELOG.md b/packages/middleware/express/CHANGELOG.md index 951a2cc210..19c75a1531 100644 --- a/packages/middleware/express/CHANGELOG.md +++ b/packages/middleware/express/CHANGELOG.md @@ -1,5 +1,33 @@ # @modelcontextprotocol/express +## 2.0.2 + +### Patch Changes + +- [#2918](https://github.com/modelcontextprotocol/typescript-sdk/pull/2918) [`84804c2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/84804c22e45a662675a198f853b7f00063838a8d) Thanks [@claude](https://github.com/apps/claude)! - A `Server` or `McpServer` now serves one connection at a time, and a Streamable HTTP server transport without sessions (`sessionIdGenerator: undefined`) serves one request. An app that uses one server object, or one stateless transport, for every HTTP request fails on the second request after this upgrade. Build the server and the transport per request instead. + + What keeps working without a change: + - `createMcpHandler(buildServer)` and `serveStdio(buildServer)`, where `buildServer` returns a new server on every call. + - A handler that builds a new server and a new stateless transport for each request. + - One server and one transport per session (a transport with a `sessionIdGenerator`). + - Connecting a server again after `close()`. + - `Client`. + + What fails now, how it shows, and what to change: + - One server object with a new stateless transport per request (`const server = new McpServer(...)` outside the handler, `await server.connect(transport)` inside it): the second HTTP request the process receives fails, and so does every later one. `connect()` rejects with an `SdkError` of code `ALREADY_CONNECTED`. If the handler closes the transport when the response ends, requests that arrive one after the other still work and a request that overlaps another one fails. Change: move `new McpServer(...)` and its registrations into the handler. + - One stateless transport for every request (a transport built once with `sessionIdGenerator: undefined`): the second HTTP request fails. `WebStandardStreamableHTTPServerTransport.handleRequest()` rejects with `Stateless transport cannot be reused across requests. Create a new transport per request.`, and `NodeStreamableHTTPServerTransport.handleRequest()` answers `500`. Change: build the server and the transport inside the handler and connect them there. + - `createMcpHandler(() => server)` with a server built once: a request that arrives after the previous response has been read to its end still works. A request that arrives while another one is being served is answered `500` with the JSON-RPC error `-32603` (`Internal server error`); the reason is reported only through the `onerror` option. Change: pass a function that builds the server, as in `createMcpHandler(buildServer)`. + - One server object for every session: the `initialize` request of the second session fails with `ALREADY_CONNECTED`. Change: build a server per session. + + What the caller sees when `connect()` or `handleRequest()` rejects depends on the host. Express 5, Fastify and Hono answer `500`. A plain `node:http` listener without its own error handling gets an unhandled rejection, which ends the process. + + The README examples of `@modelcontextprotocol/express`, `@modelcontextprotocol/fastify`, `@modelcontextprotocol/hono` and `@modelcontextprotocol/node`, and the handler examples in the JSDoc of `WebStandardStreamableHTTPServerTransport` and `NodeStreamableHTTPServerTransport`, now build a server and a transport per request. + +- [#2908](https://github.com/modelcontextprotocol/typescript-sdk/pull/2908) [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1) Thanks [@claude](https://github.com/apps/claude)! - The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. + +- Updated dependencies [[`5238fba`](https://github.com/modelcontextprotocol/typescript-sdk/commit/5238fba4424f82ec1ae9f6f458dd655ab322062d), [`4d94e7b`](https://github.com/modelcontextprotocol/typescript-sdk/commit/4d94e7b1ccf769d94a7bbba7789f1ee6c7dfdd8c), [`84804c2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/84804c22e45a662675a198f853b7f00063838a8d), [`e55f9ac`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e55f9ac1b1cae413599b499cbaa45c0378edba78), [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1), [`2237555`](https://github.com/modelcontextprotocol/typescript-sdk/commit/2237555ed036c3e80341c0f3c28684e9c3ff0728)]: + - @modelcontextprotocol/server@2.3.0 + ## 2.0.1 ### Patch Changes diff --git a/packages/middleware/express/package.json b/packages/middleware/express/package.json index 7cc6b47a6e..8b2d903744 100644 --- a/packages/middleware/express/package.json +++ b/packages/middleware/express/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/express", "private": false, - "version": "2.0.1", + "version": "2.0.2", "description": "Express adapters for the Model Context Protocol TypeScript server SDK - Express middleware", "license": "Apache-2.0", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/middleware/fastify/CHANGELOG.md b/packages/middleware/fastify/CHANGELOG.md index 35823f1e73..3031e99db2 100644 --- a/packages/middleware/fastify/CHANGELOG.md +++ b/packages/middleware/fastify/CHANGELOG.md @@ -1,5 +1,33 @@ # @modelcontextprotocol/fastify +## 2.0.1 + +### Patch Changes + +- [#2918](https://github.com/modelcontextprotocol/typescript-sdk/pull/2918) [`84804c2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/84804c22e45a662675a198f853b7f00063838a8d) Thanks [@claude](https://github.com/apps/claude)! - A `Server` or `McpServer` now serves one connection at a time, and a Streamable HTTP server transport without sessions (`sessionIdGenerator: undefined`) serves one request. An app that uses one server object, or one stateless transport, for every HTTP request fails on the second request after this upgrade. Build the server and the transport per request instead. + + What keeps working without a change: + - `createMcpHandler(buildServer)` and `serveStdio(buildServer)`, where `buildServer` returns a new server on every call. + - A handler that builds a new server and a new stateless transport for each request. + - One server and one transport per session (a transport with a `sessionIdGenerator`). + - Connecting a server again after `close()`. + - `Client`. + + What fails now, how it shows, and what to change: + - One server object with a new stateless transport per request (`const server = new McpServer(...)` outside the handler, `await server.connect(transport)` inside it): the second HTTP request the process receives fails, and so does every later one. `connect()` rejects with an `SdkError` of code `ALREADY_CONNECTED`. If the handler closes the transport when the response ends, requests that arrive one after the other still work and a request that overlaps another one fails. Change: move `new McpServer(...)` and its registrations into the handler. + - One stateless transport for every request (a transport built once with `sessionIdGenerator: undefined`): the second HTTP request fails. `WebStandardStreamableHTTPServerTransport.handleRequest()` rejects with `Stateless transport cannot be reused across requests. Create a new transport per request.`, and `NodeStreamableHTTPServerTransport.handleRequest()` answers `500`. Change: build the server and the transport inside the handler and connect them there. + - `createMcpHandler(() => server)` with a server built once: a request that arrives after the previous response has been read to its end still works. A request that arrives while another one is being served is answered `500` with the JSON-RPC error `-32603` (`Internal server error`); the reason is reported only through the `onerror` option. Change: pass a function that builds the server, as in `createMcpHandler(buildServer)`. + - One server object for every session: the `initialize` request of the second session fails with `ALREADY_CONNECTED`. Change: build a server per session. + + What the caller sees when `connect()` or `handleRequest()` rejects depends on the host. Express 5, Fastify and Hono answer `500`. A plain `node:http` listener without its own error handling gets an unhandled rejection, which ends the process. + + The README examples of `@modelcontextprotocol/express`, `@modelcontextprotocol/fastify`, `@modelcontextprotocol/hono` and `@modelcontextprotocol/node`, and the handler examples in the JSDoc of `WebStandardStreamableHTTPServerTransport` and `NodeStreamableHTTPServerTransport`, now build a server and a transport per request. + +- [#2908](https://github.com/modelcontextprotocol/typescript-sdk/pull/2908) [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1) Thanks [@claude](https://github.com/apps/claude)! - The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. + +- Updated dependencies [[`5238fba`](https://github.com/modelcontextprotocol/typescript-sdk/commit/5238fba4424f82ec1ae9f6f458dd655ab322062d), [`4d94e7b`](https://github.com/modelcontextprotocol/typescript-sdk/commit/4d94e7b1ccf769d94a7bbba7789f1ee6c7dfdd8c), [`84804c2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/84804c22e45a662675a198f853b7f00063838a8d), [`e55f9ac`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e55f9ac1b1cae413599b499cbaa45c0378edba78), [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1), [`2237555`](https://github.com/modelcontextprotocol/typescript-sdk/commit/2237555ed036c3e80341c0f3c28684e9c3ff0728)]: + - @modelcontextprotocol/server@2.3.0 + ## 2.0.0 ### Patch Changes diff --git a/packages/middleware/fastify/package.json b/packages/middleware/fastify/package.json index 09ad7230dd..5da17a14f4 100644 --- a/packages/middleware/fastify/package.json +++ b/packages/middleware/fastify/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/fastify", "private": false, - "version": "2.0.0", + "version": "2.0.1", "description": "Fastify adapters for the Model Context Protocol TypeScript server SDK - Fastify middleware", "license": "Apache-2.0", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/middleware/hono/CHANGELOG.md b/packages/middleware/hono/CHANGELOG.md index d00c3ccc02..d7831dd06b 100644 --- a/packages/middleware/hono/CHANGELOG.md +++ b/packages/middleware/hono/CHANGELOG.md @@ -1,5 +1,33 @@ # @modelcontextprotocol/hono +## 2.0.2 + +### Patch Changes + +- [#2918](https://github.com/modelcontextprotocol/typescript-sdk/pull/2918) [`84804c2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/84804c22e45a662675a198f853b7f00063838a8d) Thanks [@claude](https://github.com/apps/claude)! - A `Server` or `McpServer` now serves one connection at a time, and a Streamable HTTP server transport without sessions (`sessionIdGenerator: undefined`) serves one request. An app that uses one server object, or one stateless transport, for every HTTP request fails on the second request after this upgrade. Build the server and the transport per request instead. + + What keeps working without a change: + - `createMcpHandler(buildServer)` and `serveStdio(buildServer)`, where `buildServer` returns a new server on every call. + - A handler that builds a new server and a new stateless transport for each request. + - One server and one transport per session (a transport with a `sessionIdGenerator`). + - Connecting a server again after `close()`. + - `Client`. + + What fails now, how it shows, and what to change: + - One server object with a new stateless transport per request (`const server = new McpServer(...)` outside the handler, `await server.connect(transport)` inside it): the second HTTP request the process receives fails, and so does every later one. `connect()` rejects with an `SdkError` of code `ALREADY_CONNECTED`. If the handler closes the transport when the response ends, requests that arrive one after the other still work and a request that overlaps another one fails. Change: move `new McpServer(...)` and its registrations into the handler. + - One stateless transport for every request (a transport built once with `sessionIdGenerator: undefined`): the second HTTP request fails. `WebStandardStreamableHTTPServerTransport.handleRequest()` rejects with `Stateless transport cannot be reused across requests. Create a new transport per request.`, and `NodeStreamableHTTPServerTransport.handleRequest()` answers `500`. Change: build the server and the transport inside the handler and connect them there. + - `createMcpHandler(() => server)` with a server built once: a request that arrives after the previous response has been read to its end still works. A request that arrives while another one is being served is answered `500` with the JSON-RPC error `-32603` (`Internal server error`); the reason is reported only through the `onerror` option. Change: pass a function that builds the server, as in `createMcpHandler(buildServer)`. + - One server object for every session: the `initialize` request of the second session fails with `ALREADY_CONNECTED`. Change: build a server per session. + + What the caller sees when `connect()` or `handleRequest()` rejects depends on the host. Express 5, Fastify and Hono answer `500`. A plain `node:http` listener without its own error handling gets an unhandled rejection, which ends the process. + + The README examples of `@modelcontextprotocol/express`, `@modelcontextprotocol/fastify`, `@modelcontextprotocol/hono` and `@modelcontextprotocol/node`, and the handler examples in the JSDoc of `WebStandardStreamableHTTPServerTransport` and `NodeStreamableHTTPServerTransport`, now build a server and a transport per request. + +- [#2908](https://github.com/modelcontextprotocol/typescript-sdk/pull/2908) [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1) Thanks [@claude](https://github.com/apps/claude)! - The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. + +- Updated dependencies [[`5238fba`](https://github.com/modelcontextprotocol/typescript-sdk/commit/5238fba4424f82ec1ae9f6f458dd655ab322062d), [`4d94e7b`](https://github.com/modelcontextprotocol/typescript-sdk/commit/4d94e7b1ccf769d94a7bbba7789f1ee6c7dfdd8c), [`84804c2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/84804c22e45a662675a198f853b7f00063838a8d), [`e55f9ac`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e55f9ac1b1cae413599b499cbaa45c0378edba78), [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1), [`2237555`](https://github.com/modelcontextprotocol/typescript-sdk/commit/2237555ed036c3e80341c0f3c28684e9c3ff0728)]: + - @modelcontextprotocol/server@2.3.0 + ## 2.0.1 ### Patch Changes diff --git a/packages/middleware/hono/package.json b/packages/middleware/hono/package.json index 89d52003b2..b06c2a00ca 100644 --- a/packages/middleware/hono/package.json +++ b/packages/middleware/hono/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/hono", "private": false, - "version": "2.0.1", + "version": "2.0.2", "description": "Hono adapters for the Model Context Protocol TypeScript server SDK - Hono middleware", "license": "Apache-2.0", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/middleware/node/CHANGELOG.md b/packages/middleware/node/CHANGELOG.md index ebd9186a7b..1d5c0e80de 100644 --- a/packages/middleware/node/CHANGELOG.md +++ b/packages/middleware/node/CHANGELOG.md @@ -1,5 +1,35 @@ # @modelcontextprotocol/node +## 2.1.1 + +### Patch Changes + +- [#2897](https://github.com/modelcontextprotocol/typescript-sdk/pull/2897) [`7f4c12a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7f4c12a6ae6b8f22411f7772c88036e1c8055423) Thanks [@claude](https://github.com/apps/claude)! - `hono` is now a regular dependency of `@modelcontextprotocol/node`, so installs with strict peer-dependency checking no longer fail on the `hono` peer that `@hono/node-server` requires. No runtime change. + +- [#2918](https://github.com/modelcontextprotocol/typescript-sdk/pull/2918) [`84804c2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/84804c22e45a662675a198f853b7f00063838a8d) Thanks [@claude](https://github.com/apps/claude)! - A `Server` or `McpServer` now serves one connection at a time, and a Streamable HTTP server transport without sessions (`sessionIdGenerator: undefined`) serves one request. An app that uses one server object, or one stateless transport, for every HTTP request fails on the second request after this upgrade. Build the server and the transport per request instead. + + What keeps working without a change: + - `createMcpHandler(buildServer)` and `serveStdio(buildServer)`, where `buildServer` returns a new server on every call. + - A handler that builds a new server and a new stateless transport for each request. + - One server and one transport per session (a transport with a `sessionIdGenerator`). + - Connecting a server again after `close()`. + - `Client`. + + What fails now, how it shows, and what to change: + - One server object with a new stateless transport per request (`const server = new McpServer(...)` outside the handler, `await server.connect(transport)` inside it): the second HTTP request the process receives fails, and so does every later one. `connect()` rejects with an `SdkError` of code `ALREADY_CONNECTED`. If the handler closes the transport when the response ends, requests that arrive one after the other still work and a request that overlaps another one fails. Change: move `new McpServer(...)` and its registrations into the handler. + - One stateless transport for every request (a transport built once with `sessionIdGenerator: undefined`): the second HTTP request fails. `WebStandardStreamableHTTPServerTransport.handleRequest()` rejects with `Stateless transport cannot be reused across requests. Create a new transport per request.`, and `NodeStreamableHTTPServerTransport.handleRequest()` answers `500`. Change: build the server and the transport inside the handler and connect them there. + - `createMcpHandler(() => server)` with a server built once: a request that arrives after the previous response has been read to its end still works. A request that arrives while another one is being served is answered `500` with the JSON-RPC error `-32603` (`Internal server error`); the reason is reported only through the `onerror` option. Change: pass a function that builds the server, as in `createMcpHandler(buildServer)`. + - One server object for every session: the `initialize` request of the second session fails with `ALREADY_CONNECTED`. Change: build a server per session. + + What the caller sees when `connect()` or `handleRequest()` rejects depends on the host. Express 5, Fastify and Hono answer `500`. A plain `node:http` listener without its own error handling gets an unhandled rejection, which ends the process. + + The README examples of `@modelcontextprotocol/express`, `@modelcontextprotocol/fastify`, `@modelcontextprotocol/hono` and `@modelcontextprotocol/node`, and the handler examples in the JSDoc of `WebStandardStreamableHTTPServerTransport` and `NodeStreamableHTTPServerTransport`, now build a server and a transport per request. + +- [#2908](https://github.com/modelcontextprotocol/typescript-sdk/pull/2908) [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1) Thanks [@claude](https://github.com/apps/claude)! - The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. + +- Updated dependencies [[`5238fba`](https://github.com/modelcontextprotocol/typescript-sdk/commit/5238fba4424f82ec1ae9f6f458dd655ab322062d), [`4d94e7b`](https://github.com/modelcontextprotocol/typescript-sdk/commit/4d94e7b1ccf769d94a7bbba7789f1ee6c7dfdd8c), [`84804c2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/84804c22e45a662675a198f853b7f00063838a8d), [`e55f9ac`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e55f9ac1b1cae413599b499cbaa45c0378edba78), [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1), [`2237555`](https://github.com/modelcontextprotocol/typescript-sdk/commit/2237555ed036c3e80341c0f3c28684e9c3ff0728)]: + - @modelcontextprotocol/server@2.3.0 + ## 2.1.0 ### Minor Changes diff --git a/packages/middleware/node/package.json b/packages/middleware/node/package.json index 25ef2cabdb..48dafc4d20 100644 --- a/packages/middleware/node/package.json +++ b/packages/middleware/node/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/node", - "version": "2.1.0", + "version": "2.1.1", "description": "Model Context Protocol implementation for TypeScript - Node.js middleware", "license": "Apache-2.0", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/server-legacy/CHANGELOG.md b/packages/server-legacy/CHANGELOG.md index 84aeffc0b0..ae8a63bf41 100644 --- a/packages/server-legacy/CHANGELOG.md +++ b/packages/server-legacy/CHANGELOG.md @@ -1,5 +1,14 @@ # @modelcontextprotocol/server-legacy +## 2.3.0 + +### Patch Changes + +- [#2908](https://github.com/modelcontextprotocol/typescript-sdk/pull/2908) [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1) Thanks [@claude](https://github.com/apps/claude)! - The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. + +- Updated dependencies [[`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1)]: + - @modelcontextprotocol/core@2.3.0 + ## 2.2.0 ### Patch Changes diff --git a/packages/server-legacy/package.json b/packages/server-legacy/package.json index 4ee45161c2..554565368b 100644 --- a/packages/server-legacy/package.json +++ b/packages/server-legacy/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/server-legacy", "private": false, - "version": "2.2.0", + "version": "2.3.0", "description": "Frozen v1 SSE transport and OAuth Authorization Server helpers for the Model Context Protocol TypeScript SDK. Deprecated; use StreamableHTTP and a dedicated OAuth server in production.", "deprecated": "This package is a frozen copy of v1's SSE transport and OAuth Authorization Server helpers for migration purposes only. Use StreamableHTTP from @modelcontextprotocol/server and a dedicated OAuth server in production. Will not receive new features.", "license": "Apache-2.0", diff --git a/packages/server/CHANGELOG.md b/packages/server/CHANGELOG.md index 8ea1932a19..8ae937d4c6 100644 --- a/packages/server/CHANGELOG.md +++ b/packages/server/CHANGELOG.md @@ -1,5 +1,43 @@ # @modelcontextprotocol/server +## 2.3.0 + +### Minor Changes + +- [#2918](https://github.com/modelcontextprotocol/typescript-sdk/pull/2918) [`84804c2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/84804c22e45a662675a198f853b7f00063838a8d) Thanks [@claude](https://github.com/apps/claude)! - A `Server` or `McpServer` now serves one connection at a time, and a Streamable HTTP server transport without sessions (`sessionIdGenerator: undefined`) serves one request. An app that uses one server object, or one stateless transport, for every HTTP request fails on the second request after this upgrade. Build the server and the transport per request instead. + + What keeps working without a change: + - `createMcpHandler(buildServer)` and `serveStdio(buildServer)`, where `buildServer` returns a new server on every call. + - A handler that builds a new server and a new stateless transport for each request. + - One server and one transport per session (a transport with a `sessionIdGenerator`). + - Connecting a server again after `close()`. + - `Client`. + + What fails now, how it shows, and what to change: + - One server object with a new stateless transport per request (`const server = new McpServer(...)` outside the handler, `await server.connect(transport)` inside it): the second HTTP request the process receives fails, and so does every later one. `connect()` rejects with an `SdkError` of code `ALREADY_CONNECTED`. If the handler closes the transport when the response ends, requests that arrive one after the other still work and a request that overlaps another one fails. Change: move `new McpServer(...)` and its registrations into the handler. + - One stateless transport for every request (a transport built once with `sessionIdGenerator: undefined`): the second HTTP request fails. `WebStandardStreamableHTTPServerTransport.handleRequest()` rejects with `Stateless transport cannot be reused across requests. Create a new transport per request.`, and `NodeStreamableHTTPServerTransport.handleRequest()` answers `500`. Change: build the server and the transport inside the handler and connect them there. + - `createMcpHandler(() => server)` with a server built once: a request that arrives after the previous response has been read to its end still works. A request that arrives while another one is being served is answered `500` with the JSON-RPC error `-32603` (`Internal server error`); the reason is reported only through the `onerror` option. Change: pass a function that builds the server, as in `createMcpHandler(buildServer)`. + - One server object for every session: the `initialize` request of the second session fails with `ALREADY_CONNECTED`. Change: build a server per session. + + What the caller sees when `connect()` or `handleRequest()` rejects depends on the host. Express 5, Fastify and Hono answer `500`. A plain `node:http` listener without its own error handling gets an unhandled rejection, which ends the process. + + The README examples of `@modelcontextprotocol/express`, `@modelcontextprotocol/fastify`, `@modelcontextprotocol/hono` and `@modelcontextprotocol/node`, and the handler examples in the JSDoc of `WebStandardStreamableHTTPServerTransport` and `NodeStreamableHTTPServerTransport`, now build a server and a transport per request. + +- [#2907](https://github.com/modelcontextprotocol/typescript-sdk/pull/2907) [`e55f9ac`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e55f9ac1b1cae413599b499cbaa45c0378edba78) Thanks [@claude](https://github.com/apps/claude)! - `allowedOrigins` and `validateOriginHeader` accept lowercase entries of the form `://*`, such as `moz-extension://*` or `chrome-extension://*`, which admit every origin of that scheme. This lets a server admit MCP clients that run as a browser extension when the extension ID cannot be listed, as on Firefox, where it differs on every install. `http://*` and `https://*` are not honoured, and the defaults are unchanged. + +### Patch Changes + +- [#2599](https://github.com/modelcontextprotocol/typescript-sdk/pull/2599) [`5238fba`](https://github.com/modelcontextprotocol/typescript-sdk/commit/5238fba4424f82ec1ae9f6f458dd655ab322062d) Thanks [@freya0926](https://github.com/freya0926)! - A server can now serve, and a client can now call, `tasks/get` and `tasks/cancel` of the Tasks extension (SEP-2663) on a 2026-07-28 connection, when the handler is registered and the request is sent with an explicit schema. Every other method that a protocol revision removed is still refused. If one server factory serves both eras and such a handler is meant for 2025-era clients only, register it only when `ctx.era === 'legacy'`. + +- [#2889](https://github.com/modelcontextprotocol/typescript-sdk/pull/2889) [`4d94e7b`](https://github.com/modelcontextprotocol/typescript-sdk/commit/4d94e7b1ccf769d94a7bbba7789f1ee6c7dfdd8c) Thanks [@claude](https://github.com/apps/claude)! - `registerTool` no longer converts tool schemas up front, so a server built per request stops converting every tool on every request. The warning about an invalid `x-mcp-header` declaration now appears each time tools are listed, not when the tool is registered. + +- [#2908](https://github.com/modelcontextprotocol/typescript-sdk/pull/2908) [`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1) Thanks [@claude](https://github.com/apps/claude)! - The `license` field of the package manifests is now `Apache-2.0`; the `LICENSE` file shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. + +- [#2841](https://github.com/modelcontextprotocol/typescript-sdk/pull/2841) [`2237555`](https://github.com/modelcontextprotocol/typescript-sdk/commit/2237555ed036c3e80341c0f3c28684e9c3ff0728) Thanks [@sharziki](https://github.com/sharziki)! - `McpServer.registerPrompt()` now types the callback correctly when no `argsSchema` is given: its one parameter is the server context. Before, reading `ctx.mcpReq` there was a type error although it worked at runtime. Prompts registered with an `argsSchema` are unchanged. + +- Updated dependencies [[`633dd3e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/633dd3e12bff6869c932c4a526341622320912b1)]: + - @modelcontextprotocol/core@2.3.0 + ## 2.2.0 ### Patch Changes diff --git a/packages/server/package.json b/packages/server/package.json index 84f2d331a7..806417873d 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/server", - "version": "2.2.0", + "version": "2.3.0", "description": "Model Context Protocol implementation for TypeScript - Server package", "license": "Apache-2.0", "author": "Anthropic, PBC (https://anthropic.com)",