---
name: TypeScript SDK
slug: mcp-typescript-sdk
type: github
source_url: https://github.com/modelcontextprotocol/typescript-sdk
organization: Model Context Protocol
organization_slug: modelcontextprotocol
total_releases: 10
latest_version: v2.4.0
latest_date: 2026-10-23
last_updated: 2026-10-24
tracking_since: 2026-07-27
canonical: https://releases.sh/modelcontextprotocol/mcp-typescript-sdk
organization_url: https://releases.sh/modelcontextprotocol
---

<Release version="v2.4.0" date="October 23, 2026" published="2026-10-23T18:32:25.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/v2.4.0">
## 2.4.0

| Package | Version |
|---|---|
| `@modelcontextprotocol/client` | 2.4.0 |
| `@modelcontextprotocol/server` | 2.4.0 |
| `@modelcontextprotocol/core` | 2.4.0 |
| `@modelcontextprotocol/server-legacy` | 2.4.0 |
| `@modelcontextprotocol/codemod` | 2.4.0 |
| `@modelcontextprotocol/node` | 2.1.2 |
| `@modelcontextprotocol/express`, `hono`, `fastify` | unchanged |

## Upgrade notes

- **`x-mcp-header` on a `number` parameter is rejected**, as the 2026-07-28 spec requires: the client does not list such a tool, and the server answers a call to it with `-32020`. Use `z.int()` or remove the annotation. (#2762, #2960)
- **`outputSchema` from `z.object(...).meta({ id })`.** On a 2025-11-25 connection the result is no longer wrapped in `{ result }`: read `structuredContent`, not `structuredContent.result`. (#3081)
- **The bundled Ajv validator uses fast-uri 3.1.8.** It rejects a `$id` or `$ref` with an invalid URI scheme, such as `my_tool:output`. (#3083)

## New

- **Skills over MCP (SEP-2640).** A server publishes a folder of skills with `loadSkills(folder)` and `skills.attach(server)`; a client lists, reads and verifies them with `SkillsClient`. It works on 2025-11-25 and 2026-07-28. `attach` is experimental and may change in a minor release. (#3047, #3080)
- **Opt-in `scope` on token refresh.** Implement `scopeForRefresh(tokens)` on your `OAuthClientProvider` for an authorization server that rejects a refresh without `scope` (Microsoft Entra ID, `AADSTS90009`). The default request does not change. (#3085)
- `ServerEvent` takes optional `params`, so a gateway can forward change notifications with their `_meta`. (#3057)
- The v1 to v2 upgrade guide is also an installable agent skill. (#2968)

## Fixes

- `update({ title })` on a resource or resource template shows up in list responses. (#3005)
- A `Server` connected to a per-request transport at a modern revision binds that revision instead of answering `-32022`. (#3057)
- `createMcpHandler` sends `Allow: POST` on every `405`. (#3002)
- `@modelcontextprotocol/node` accepts `@hono/node-server` 1.x or 2.x; a new install resolves 2.x. (#3084)
</Release>

<Release version="1.32.2" date="October 23, 2026" published="2026-10-23T18:06:24.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/1.32.2">
## What's Changed
* fix: add explicit | undefined to Transport optional properties (v1.x backport of #1766) by @kishormorol in https://github.com/modelcontextprotocol/typescript-sdk/pull/2814
* [v1.x] fix: allow registering after connect() when the capability was declared by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2958
* chore: bump version to 1.32.2 by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/3089

## New Contributors
* @kishormorol made their first contribution in https://github.com/modelcontextprotocol/typescript-sdk/pull/2814

**Full Changelog**: https://github.com/modelcontextprotocol/typescript-sdk/compare/1.32.1...1.32.2
</Release>

<Release version="v2.3.1" date="October 5, 2026" published="2026-10-05T11:54:56.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/v2.3.1">
## 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

- `requireBearerAuth` in `@modelcontextprotocol/server-legacy` takes the optional `expectedResource` that `@modelcontextprotocol/server` 2.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/server` and `@modelcontextprotocol/client` now open with one note that links the documentation, the migration guide and the issue form. (#2955)
</Release>

<Release version="1.32.1" date="October 5, 2026" published="2026-10-05T11:42:59.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/1.32.1">
## What's Changed
* [v1.x] docs: state the principles in CLAUDE.md by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2939
* [v1.x] docs: point the README at v2 and say what v1.x supports by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2942
* chore: bump version to 1.32.1 by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2954


**Full Changelog**: https://github.com/modelcontextprotocol/typescript-sdk/compare/1.32.0...1.32.1
</Release>

<Release version="v2.3.0" date="October 2, 2026" published="2026-10-02T17:55:03.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/v2.3.0">
## 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 the `McpServer` and the transport inside the request handler (or in the `createMcpHandler` factory) 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.** `maxToolInputElements` on `McpServer` limits the number of array elements and object members in a tool call's arguments. `expectedResource` on `requireBearerAuth` / `verifyBearerToken` accepts only tokens issued for this server (the token's audience); with Express, upgrade `@modelcontextprotocol/express` together with `@modelcontextprotocol/server`. (#2926, #2929)
- **`prompts/get` without `arguments` is validated as `{}`**, as `tools/call` already is. A top-level `.optional()` or `.default(...)` on a prompt's `argsSchema` no longer sees `undefined`. (#2107)
- **The client requires `eventsource-parser` 3.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

- `validateOriginHeader` and the `allowedOrigins` option of the Express, Fastify and Hono app helpers accept `<scheme>://*` entries such as `moz-extension://*`, so a server can admit MCP clients that run as a browser extension. (#2907)
- `tasks/get` and `tasks/cancel` of 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/get` without `arguments` no longer fails when every argument of the prompt is optional. (#2107)
- `SSEClientTransport` refreshes once after a 401 on connect instead of retrying without limit. (#2905, #2934)
- `registerTool` no longer converts tool schemas up front, so a server built per request stops converting every tool on every request. (#2889)
- `hono` is a regular dependency of `@modelcontextprotocol/node`, so installs with strict peer-dependency checking no longer fail. (#2897)
- A `server/discover` probe answered with an unusable 2xx reply now says so instead of reading like a network failure. (#2903)
- `McpServer.registerPrompt()` types the callback correctly when no `argsSchema` is given. (#2841)
- The `license` field of the package manifests is `Apache-2.0`. (#2908)
</Release>

<Release version="1.32.0" date="October 2, 2026" published="2026-10-02T17:28:24.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/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'` on `StreamableHTTPClientTransport` or `SSEClientTransport`. In browsers, a redirected request fails unless that option is set.
- **New options, both off unless you set them:** `maxToolInputElements` on `McpServer` limits the number of array elements and object members in a tool call's arguments. `expectedResource` on `requireBearerAuth` accepts 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 https://github.com/modelcontextprotocol/typescript-sdk/pull/2902
* docs: point SECURITY.md at GitHub Security Advisories (v1.x) by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2910
* [v1.x] examples: close idle sessions and cap the session map by @maxisbey in https://github.com/modelcontextprotocol/typescript-sdk/pull/2914
* [v1.x] fix(tasks): keep tasks of the in-memory task store within the session that created them by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2925
* [v1.x] feat(server): add maxToolInputElements option to limit the number of elements in tool-call arguments by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2927
* [v1.x] fix(server): accept tools/call and prompts/get requests that omit arguments by @raashish1601 in https://github.com/modelcontextprotocol/typescript-sdk/pull/2045
* [v1.x] feat(auth): add expectedResource to requireBearerAuth by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2930
* [v1.x] test(e2e): cover tools/call and prompts/get without arguments by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2931
* chore: bump version to 1.32.0 by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2935

## New Contributors
* @raashish1601 made their first contribution in https://github.com/modelcontextprotocol/typescript-sdk/pull/2045

**Full Changelog**: https://github.com/modelcontextprotocol/typescript-sdk/compare/1.31.0...1.32.0
</Release>

<Release version="v2.2.0" date="September 28, 2026" published="2026-09-28T19:24:07.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/v2.2.0">
## 2.2.0

| Package | Version |
|---|---|
| `@modelcontextprotocol/client` | 2.2.0 |
| `@modelcontextprotocol/server` | 2.2.0 |
| `@modelcontextprotocol/core` | 2.2.0 |
| `@modelcontextprotocol/server-legacy` | 2.2.0 |
| `@modelcontextprotocol/codemod` | 2.2.0 |
| `@modelcontextprotocol/node`, `express`, `hono`, `fastify` | unchanged |

## Upgrade notes

- **Pass `expectedIssuer` to the machine-to-machine OAuth providers.** Constructing `ClientCredentialsProvider`, `PrivateKeyJwtProvider`, `StaticPrivateKeyJwtProvider` or `CrossAppAccessProvider` without it is deprecated and logs a warning. Set it to the `issuer` of the authorization server the credentials were registered with. (#2887)
- **`fetchToken()` checks which authorization server the client information belongs to.** It throws `AuthorizationServerMismatchError` before sending anything when the provider's client information is bound to a different authorization server. (#2887)
- **List calls return the whole list.** `listTools()`, `listPrompts()`, `listResources()` and `listResourceTemplates()` called without a cursor now follow `nextCursor` until the server stops sending one. `listMaxPages` still caps the walk. (#2886)

## Fixes

- CommonJS TypeScript projects type-check again: the `jose` types used by the DPoP API are inlined into the declaration files (regression in 2.1.0). (#2883)
- `Client.listen()` no longer lets a rejection escape as a process-level unhandled rejection, and no longer hangs when a send never settles. (#2642)
- `_meta` is preserved on `input_required` results. (#2862)
- Hostnames ending in `.localhost` count as loopback for OAuth token endpoints, so host-based multi-tenant local setups work. (#2597)
- `OAuthTokensSchema` and `OAuthClientInformationSchema` accept the optional `issuer` field, so a provider that reads its storage back through them keeps it. (#2887)
- `createMcpHandler` no longer overflows the stack when the factory returns the same server instance for more than one request. Returning a fresh instance per request is still required. (#2778)
- `createMcpHandler` ends a `subscriptions/listen` stream right after the acknowledgement when it honored none of the requested notification types. (#2651)
- Sending a notification on a closed connection no longer produces a briefly unhandled promise rejection. (#2885)
- The `v1-to-v2` codemod keeps a file's leading comment block and directives above the rewritten imports. (#2582)
- Corrected citations in the JSDoc for OAuth token endpoints and for the `registerClient` deprecation notice. (#2768, #2729)

## Thanks

@maxisbey, @web-abin, @SyedTashfin, @arimu1, @axits-lab, @vjymisal0 and @sushantkumar23.

## Per-package changelogs

[client](https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/%40modelcontextprotocol%2Fclient%402.2.0) · [server](https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/%40modelcontextprotocol%2Fserver%402.2.0) · [core](https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/%40modelcontextprotocol%2Fcore%402.2.0) · [server-legacy](https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/%40modelcontextprotocol%2Fserver-legacy%402.2.0) · [codemod](https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/%40modelcontextprotocol%2Fcodemod%402.2.0)
</Release>

<Release version="1.31.0" date="September 28, 2026" published="2026-09-28T18:52:02.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/1.31.0">
## Upgrade notes
- Stored OAuth tokens and client information now include an `issuer` field. Storage that rejects unknown fields needs to allow it.
- Pass `expectedIssuer` when constructing `ClientCredentialsProvider`, `PrivateKeyJwtProvider` or `StaticPrivateKeyJwtProvider`. Constructing them without it is deprecated.

## What's Changed
* [v1.x] Bind stored OAuth credentials to the authorization server that issued them by @maxisbey in https://github.com/modelcontextprotocol/typescript-sdk/pull/2888
* chore: bump version to 1.31.0 by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2890


**Full Changelog**: https://github.com/modelcontextprotocol/typescript-sdk/compare/1.30.1...1.31.0
</Release>

<Release version="1.30.1" date="September 23, 2026" published="2026-09-23T15:59:38.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/1.30.1">
## What's Changed
* [v1.x] fix(server): read HTTP request bodies with a size limit and bound JSON-RPC batch length by @maxisbey in https://github.com/modelcontextprotocol/typescript-sdk/pull/2717
* fix(auth): preserve resource URI without trailing slash (#1968) by @MukundaKatta in https://github.com/modelcontextprotocol/typescript-sdk/pull/1972
* chore: bump version to 1.30.1 by @claude[bot] in https://github.com/modelcontextprotocol/typescript-sdk/pull/2848

## New Contributors
* @MukundaKatta made their first contribution in https://github.com/modelcontextprotocol/typescript-sdk/pull/1972

**Full Changelog**: https://github.com/modelcontextprotocol/typescript-sdk/compare/1.30.0...1.30.1
</Release>

<Release version="1.30.0" date="July 27, 2026" published="2026-07-27T17:54:36.000Z" url="https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/1.30.0">
## What's Changed
* fix(server): prioritize zod issues and format them by @mozmo15 in https://github.com/modelcontextprotocol/typescript-sdk/pull/1503
* chore(ci): switch publish to OIDC trusted publishing by @felixweinberger in https://github.com/modelcontextprotocol/typescript-sdk/pull/1839
* Add end-to-end test suite by @felixweinberger in https://github.com/modelcontextprotocol/typescript-sdk/pull/2167
* v1 stdio buffer limit by @KKonstantinov in https://github.com/modelcontextprotocol/typescript-sdk/pull/2239
* fix: support Zod 3.25 method literals by @mattzcarey in https://github.com/modelcontextprotocol/typescript-sdk/pull/2368
* Validate Content-Type by parsed media type instead of substring match (v1.x) by @felixweinberger in https://github.com/modelcontextprotocol/typescript-sdk/pull/2444
* fix: send SSE keep-alive comment frames from Streamable HTTP server transport (v1.x) by @mattzcarey in https://github.com/modelcontextprotocol/typescript-sdk/pull/2538
* fix(deps): widen @hono/node-server past GHSA-frvp-7c67-39w9 by @arimu1 in https://github.com/modelcontextprotocol/typescript-sdk/pull/2549
* Fix SSE keep-alive timer lifecycle in Streamable HTTP server transport (v1.x) by @felixweinberger in https://github.com/modelcontextprotocol/typescript-sdk/pull/2547
* chore: bump version to 1.30.0 by @felixweinberger in https://github.com/modelcontextprotocol/typescript-sdk/pull/2563

## New Contributors
* @mozmo15 made their first contribution in https://github.com/modelcontextprotocol/typescript-sdk/pull/1503
* @arimu1 made their first contribution in https://github.com/modelcontextprotocol/typescript-sdk/pull/2549

**Full Changelog**: https://github.com/modelcontextprotocol/typescript-sdk/compare/v1.29.0...1.30.0
</Release>
