Repository navigation
Releases: modelcontextprotocol/typescript-sdk
Release list
2.3.1
| Package | Version |
|---|---|
@modelcontextprotocol/client |
2.3.1 |
@modelcontextprotocol/server |
2.3.1 |
@modelcontextprotocol/core |
2.3.1 |
@modelcontextprotocol/server-legacy |
2.3.1 |
@modelcontextprotocol/codemod |
2.3.1 |
@modelcontextprotocol/node, express, hono, fastify |
unchanged |
Changes
requireBearerAuthin@modelcontextprotocol/server-legacytakes the optionalexpectedResourcethat@modelcontextprotocol/server2.3.0 added: it accepts only tokens issued for this server (the token's audience). Off unless you set it. (#2952)- The npm pages of
@modelcontextprotocol/serverand@modelcontextprotocol/clientnow open with one note that links the documentation, the migration guide and the issue form. (#2955)
1.32.1
@modelcontextprotocol/[email protected]
Patch Changes
- Updated dependencies []:
- @modelcontextprotocol/[email protected]
@modelcontextprotocol/[email protected]
Patch Changes
-
#2952
5a18673Thanks @claude! -requireBearerAuthin@modelcontextprotocol/server-legacytakes the optionalexpectedResourcethat@modelcontextprotocol/server2.3.0 and@modelcontextprotocol/sdk1.32.0 added: the resource the token must be issued for (its audience), usually the server's URL. When it is set, a token is accepted only if the verifier reports that value inAuthInfo.resource; the two are compared as strings, ignoring a fragment and one trailing slash. A token reported for another value, or for none, is answered401 invalid_tokenwith the usualWWW-Authenticatechallenge. When it is not set, nothing changes. The package stays frozen otherwise; this option is added so that itsrequireBearerAuthmatches the 1.x middleware it is a copy of. -
Updated dependencies []:
- @modelcontextprotocol/[email protected]
@modelcontextprotocol/[email protected]
@modelcontextprotocol/[email protected]
@modelcontextprotocol/[email protected]
@modelcontextprotocol/[email protected]
@modelcontextprotocol/[email protected]
Patch Changes
- Updated dependencies []:
- @modelcontextprotocol/[email protected]
2.3.0
| Package | Version |
|---|---|
@modelcontextprotocol/client |
2.3.0 |
@modelcontextprotocol/server |
2.3.0 |
@modelcontextprotocol/core |
2.3.0 |
@modelcontextprotocol/server-legacy |
2.3.0 |
@modelcontextprotocol/codemod |
2.3.0 |
@modelcontextprotocol/node |
2.1.1 |
@modelcontextprotocol/express, hono |
2.0.2 |
@modelcontextprotocol/fastify |
2.0.1 |
Upgrade notes
- One server per request.
Server.connect()now rejects while the instance is already connected, and a stateless Streamable HTTP transport handles one request. Create theMcpServerand the transport inside the request handler (or in thecreateMcpHandlerfactory) instead of sharing one instance across requests. Creating a server is cheap since #2889. (#2918) - Redirects stay on the same origin. The HTTP client transports now follow a redirect only when it stays on the same origin (same scheme, host and port; http to https on the same host is allowed). A deployment whose endpoint redirects to another host or port either configures the final URL or sets
redirectPolicy: 'follow'on the transport. In browsers, a redirected request fails unless that option is set. (#2901) - New options, both off unless you set them.
maxToolInputElementsonMcpServerlimits the number of array elements and object members in a tool call's arguments.expectedResourceonrequireBearerAuth/verifyBearerTokenaccepts only tokens issued for this server (the token's audience); with Express, upgrade@modelcontextprotocol/expresstogether with@modelcontextprotocol/server. (#2926, #2929) prompts/getwithoutargumentsis validated as{}, astools/callalready is. A top-level.optional()or.default(...)on a prompt'sargsSchemano longer seesundefined. (#2107)- The client requires
eventsource-parser3.0.8 or later. It cuts the time and memory needed to receive a large message sent as a single SSE event: in our test a 100 MB tool result went from about a minute and 1.7 GB of peak memory to under a second and about 0.5 GB. (#2846)
New
validateOriginHeaderand theallowedOriginsoption of the Express, Fastify and Hono app helpers accept<scheme>://*entries such asmoz-extension://*, so a server can admit MCP clients that run as a browser extension. (#2907)tasks/getandtasks/cancelof the Tasks extension can be served and called on a 2026-07-28 connection. (#2599)
Fixes
- A large message received as a single SSE event over Streamable HTTP is fast again: a 50 MB tool result that took about 13 seconds arrives in under a second. (#2846)
prompts/getwithoutargumentsno longer fails when every argument of the prompt is optional. (#2107)SSEClientTransportrefreshes once after a 401 on connect instead of retrying without limit. (#2905, #2934)registerToolno longer converts tool schemas up front, so a server built per request stops converting every tool on every request. (#2889)honois a regular dependency of@modelcontextprotocol/node, so installs with strict peer-dependency checking no longer fail. (#2897)- A
server/discoverprobe answered with an unusable 2xx reply now says so instead of reading like a network failure. (#2903) McpServer.registerPrompt()types the callback correctly when noargsSchemais given. (#2841)- The
licensefield of the package manifests isApache-2.0. (#2908)
1.32.0
Upgrade notes
- Redirects: the HTTP client transports now follow a redirect only when it stays on the same origin (same scheme, host and port; http to https on the same host is allowed). A deployment whose endpoint redirects to another host or port either configures the final URL or sets
redirectPolicy: 'follow'onStreamableHTTPClientTransportorSSEClientTransport. In browsers, a redirected request fails unless that option is set. - New options, both off unless you set them:
maxToolInputElementsonMcpServerlimits the number of array elements and object members in a tool call's arguments.expectedResourceonrequireBearerAuthaccepts only tokens issued for this server (the token's audience).
What's Changed
- [v1.x] fix(client): follow redirects only within the endpoint's origin by @claude[bot] in #2902
- docs: point SECURITY.md at GitHub Security Advisories (v1.x) by @claude[bot] in #2910
- [v1.x] examples: close idle sessions and cap the session map by @maxisbey in #2914
- [v1.x] fix(tasks): keep tasks of the in-memory task store within the session that created them by @claude[bot] in #2925
- [v1.x] feat(server): add maxToolInputElements option to limit the number of elements in tool-call arguments by @claude[bot] in #2927
- [v1.x] fix(server): accept tools/call and prompts/get requests that omit arguments by @raashish1601 in #2045
- [v1.x] feat(auth): add expectedResource to requireBearerAuth by @claude[bot] in #2930
- [v1.x] test(e2e): cover tools/call and prompts/get without arguments by @claude[bot] in #2931
- chore: bump version to 1.32.0 by @claude[bot] in #2935
New Contributors
- @raashish1601 made their first contribution in #2045
Full Changelog: 1.31.0...1.32.0
@modelcontextprotocol/[email protected]
Minor Changes
-
#2929
40f8f4eThanks @claude! -requireBearerAuthandverifyBearerTokentake a new optionalexpectedResource, which makes them accept only tokens issued for this resource (the token's audience). Set it to the value your authorization server puts into tokens meant for this server, usually the server's URL. When it is set, a token is accepted only if the verifier reports that value inAuthInfo.resource; the two are compared as strings, ignoring a fragment and one trailing slash. A token reported for another value, or for none, is answered401 invalid_tokenwith the usualWWW-Authenticatechallenge. When it is not set, nothing changes. To use it, passexpectedResourceand haveverifyAccessTokenfillAuthInfo.resource, for example from theaudclaim. The option is declared on a new exported type,VerifyBearerTokenOptions, which extendsBearerAuthOptions;BearerAuthOptionsitself is unchanged. The ExpressrequireBearerAuthpasses the option through. With Express,@modelcontextprotocol/expresshas to be upgraded to this release as well: 2.0.1 does not pass the option on, so nothing is compared. Its options type does not have the option, so TypeScript reports anexpectedResourcewritten in a call to the 2.0.1requireBearerAuthas an error. -
#2926
6d8dbc6Thanks @claude! -McpServernow accepts amaxToolInputElementsoption that limits the number of elements in tool-call arguments: the largest combined number of array elements and object members a singletools/callargumentspayload may contain. It is off by default, so behavior is unchanged unless you set it. When it is set and a call exceeds it, that call is answered with anisError: truetool result that names the limit, before the input schema runs, and the server keeps serving. Set it above the largest arguments your tools legitimately accept;maxRequestBodySizeremains the primary limit on request size. The value must be a number of at least 1, orInfinityfor no limit; any other value is rejected at construction. The options type is exported asMcpServerOptions. -
#2918
84804c2Thanks @claude! - AServerorMcpServernow 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)andserveStdio(buildServer), wherebuildServerreturns 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 anSdkErrorof codeALREADY_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: movenew 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 withStateless transport cannot be reused across requests. Create a new transport per request., andNodeStreamableHTTPServerTransport.handleRequest()answers500. 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 answered500with the JSON-RPC error-32603(Internal server error); the reason is reported only through theonerroroption. Change: pass a function that builds the server, as increateMcpHandler(buildServer).- One server object for every session: the
initializerequest of the second session fails withALREADY_CONNECTED. Change: build a server per session.
What the caller sees when
connect()orhandleRequest()rejects depends on the host. Express 5, Fastify and Hono answer500. A plainnode:httplistener without its own error handling gets an unhandled rejection, which ends the process.The README examples of
@modelcontextprotocol/express,@modelcontextprotocol/fastify,@modelcontextprotocol/honoand@modelcontextprotocol/node, and the handler examples in the JSDoc ofWebStandardStreamableHTTPServerTransportandNodeStreamableHTTPServerTransport, now build a server and a transport per request. -
#2907
e55f9acThanks @claude! -allowedOriginsandvalidateOriginHeaderaccept lowercase entries of the form<scheme>://*, such asmoz-extension://*orchrome-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://*andhttps://*are not honoured, and the defaults are unchanged.
Patch Changes
-
#2599
5238fbaThanks @freya0926! - A server can now serve, and a client can now call,tasks/getandtasks/cancelof 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 whenctx.era === 'legacy'. -
#2107
2fc49eaThanks @pragnyanramtha! -prompts/getwithoutargumentsno longer fails with "Invalid arguments" when every argument of the prompt is optional. A missingargumentsis now validated as{}, as it already is fortools/call, so a top-level.optional()or.default(...)onargsSchemano longer seesundefined. -
#2889
4d94e7bThanks @claude! -registerToolno longer converts tool schemas up front, so a server built per request stops converting every tool on every request. The warning about an invalidx-mcp-headerdeclaration now appears each time tools are listed, not when the tool is registered. -
#2908
633dd3eThanks @claude! - Thelicensefield of the package manifests is nowApache-2.0; theLICENSEfile shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. -
#2841
2237555Thanks @sharziki! -McpServer.registerPrompt()now types the callback correctly when noargsSchemais given: its one parameter is the server context. Before, readingctx.mcpReqthere was a type error although it worked at runtime. Prompts registered with anargsSchemaare unchanged. -
Updated dependencies [
633dd3e]:- @modelcontextprotocol/[email protected]