Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ada352f
codemod iterations
KKonstantinov Jun 23, 2026
f915e5b
Merge branch 'main' of github.com:modelcontextprotocol/typescript-sdk…
KKonstantinov Jun 23, 2026
ab4b658
fix(codemod): match extensionless SDK subpath import specifiers
KKonstantinov Jun 23, 2026
7097be9
add canonical zod schema exports from @modelcontextprotocol/sdk-share…
KKonstantinov Jun 24, 2026
c65285a
fix(codemod): infer client/server project type from v1 source
KKonstantinov Jun 24, 2026
7d5aac3
feat(codemod): map task request/notification schemas to method strings
KKonstantinov Jun 24, 2026
5a74b53
Merge branch 'main' into feature/codemod-iterations-3
KKonstantinov Jun 24, 2026
5ffdb38
fixes
KKonstantinov Jun 24, 2026
10a4549
clean up
KKonstantinov Jun 25, 2026
c2e70af
fix(codemod): split aliased imports per-symbol, drop undefined schema…
KKonstantinov Jun 25, 2026
4a15488
fixes
KKonstantinov Jun 25, 2026
ac39021
fixes
KKonstantinov Jun 25, 2026
6d56a49
readme fix
KKonstantinov Jun 25, 2026
3f198f5
fixes
KKonstantinov Jun 25, 2026
065e142
fix(codemod): bound detectFormatter walk at /Users/kkonstantinov for …
KKonstantinov Jun 25, 2026
62871a9
merge, fixes
KKonstantinov Jun 25, 2026
faab4bc
fixes
KKonstantinov Jun 25, 2026
b452a80
core -> core-internal, sdk-shared -> core
KKonstantinov Jun 25, 2026
3c69fe8
core -> core-internal, sdk-shared -> core
KKonstantinov Jun 25, 2026
7a94d1a
Merge branch 'main' of github.com:modelcontextprotocol/typescript-sdk…
KKonstantinov Jun 25, 2026
5621119
docs fix
KKonstantinov Jun 25, 2026
51bf8bc
fixes
KKonstantinov Jun 25, 2026
3d7f4de
docs+lint: document public core package; drop stale core token from m…
KKonstantinov Jun 25, 2026
0918528
docs+chore: fix stale rename prose in core; drop never-needed sdk-sha…
KKonstantinov Jun 25, 2026
68b2120
fix(codemod): route destructured .then() dynamic-import param; fix st…
KKonstantinov Jun 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/add-sdk-shared-package.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/sdk-shared': minor
---

Add `@modelcontextprotocol/sdk-shared`: the public home for the MCP specification and OAuth/OpenID Zod schemas. It bundles the SDK's internal schema definitions and re-exports only the `*Schema` values, so consumers can validate protocol payloads (`<TypeName>Schema.parse(value)` / `.safeParse(value)`) without depending on a package's internal barrel. Alongside the spec schemas it also re-exports the auth schemas v1 exposed from `@modelcontextprotocol/sdk/shared/auth.js` (e.g. `OAuthTokensSchema`, `OAuthMetadataSchema`, `IdJagTokenExchangeResponseSchema`). Spec types, error classes, enums, and guards continue to live on `@modelcontextprotocol/server` and `@modelcontextprotocol/client`.
5 changes: 5 additions & 0 deletions .changeset/codemod-infer-project-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/codemod': patch
---

Infer client/server project type from source for v1 projects. A project being migrated still declares the single v1 `@modelcontextprotocol/sdk` dependency, so detecting the project type from `package.json` came back "unknown" and every file importing only shared protocol symbols defaulted to `@modelcontextprotocol/server` with an action-required warning. The codemod now scans the source for quoted `@modelcontextprotocol/sdk/client/…` and `…/server/…` import specifiers to infer the type (both → "both", one → that side, neither → "unknown"), routing shared symbols to the installed package and replacing the spurious warnings with at most an info note for genuinely ambiguous "both" projects.
5 changes: 5 additions & 0 deletions .changeset/codemod-sdk-shared-routing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/codemod': minor
---

Route v1 `@modelcontextprotocol/sdk/types.js` schema imports to the new `@modelcontextprotocol/sdk-shared` package. The `*Schema` Zod constants now migrate as a behavior-preserving import-path swap — `<Name>Schema.parse(value)` / `.safeParse(value)` keep working — while spec types, error classes, enums, and guards continue to resolve to `@modelcontextprotocol/client` / `@modelcontextprotocol/server` by context. A single `import { CallToolResult, CallToolResultSchema } from '.../types.js'` is split accordingly. The v1 OAuth/OpenID `*Schema` constants imported from `@modelcontextprotocol/sdk/shared/auth.js` are routed to `sdk-shared` the same way (their auth TYPES keep resolving to `client` / `server`). The previous `specSchemaAccess` transform (which rewrote `.parse()` into `specTypeSchemas.X['~standard'].validate(...)`) is removed.
5 changes: 5 additions & 0 deletions .changeset/codemod-task-handler-methods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/codemod': patch
---

Map the task request/notification schemas to their v2 method strings in the handler-registration transform. `setRequestHandler(GetTaskRequestSchema, …)`, `setNotificationHandler(TaskStatusNotificationSchema, …)`, and the other task handlers (`tasks/get`, `tasks/result`, `tasks/list`, `tasks/cancel`, `notifications/tasks/status`) now rewrite to the v2 two-argument method-string form instead of falling through to the generic "use the 3-argument form" manual-migration diagnostic.
6 changes: 6 additions & 0 deletions .changeset/idjag-spec-type-export.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@modelcontextprotocol/client': minor
'@modelcontextprotocol/server': minor
---

Add the v2 `IdJagTokenExchangeResponse` type to the public API and register its schema as an MCP spec type. `IdJagTokenExchangeResponse` is now exported from `@modelcontextprotocol/client` and `@modelcontextprotocol/server`, `'IdJagTokenExchangeResponse'` joins the `SpecTypeName` union, and `isSpecType.IdJagTokenExchangeResponse(value)` / `specTypeSchemas.IdJagTokenExchangeResponse` validate it by name — matching how the OAuth/OpenID auth schemas are already exposed. The Zod schema itself, `IdJagTokenExchangeResponseSchema`, is available from `@modelcontextprotocol/sdk-shared`.
1 change: 1 addition & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@modelcontextprotocol/node": "2.0.0-alpha.0",
"@modelcontextprotocol/server": "2.0.0-alpha.0",
"@modelcontextprotocol/server-legacy": "2.0.0-alpha.0",
"@modelcontextprotocol/sdk-shared": "2.0.0-alpha.0",
"@modelcontextprotocol/codemod": "2.0.0-alpha.0",
"@modelcontextprotocol/test-conformance": "2.0.0-alpha.0",
"@modelcontextprotocol/test-helpers": "2.0.0-alpha.0",
Expand Down
10 changes: 5 additions & 5 deletions docs/migration-SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ Replace all `@modelcontextprotocol/sdk/...` imports using this table.

| v1 import path | v2 package |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@modelcontextprotocol/sdk/types.js` | `@modelcontextprotocol/client` or `@modelcontextprotocol/server` |
| `@modelcontextprotocol/sdk/types.js` | Types / error classes / enums / guards → `@modelcontextprotocol/client` or `@modelcontextprotocol/server`; Zod `*Schema` constants → `@modelcontextprotocol/sdk-shared` |
| `@modelcontextprotocol/sdk/shared/protocol.js` | `@modelcontextprotocol/client` or `@modelcontextprotocol/server` |
| `@modelcontextprotocol/sdk/shared/transport.js` | `@modelcontextprotocol/client` or `@modelcontextprotocol/server` |
| `@modelcontextprotocol/sdk/shared/uriTemplate.js` | `@modelcontextprotocol/client` or `@modelcontextprotocol/server` |
| `@modelcontextprotocol/sdk/shared/auth.js` | `@modelcontextprotocol/client` or `@modelcontextprotocol/server` |
| `@modelcontextprotocol/sdk/shared/auth.js` | Types / classes → `@modelcontextprotocol/client` or `@modelcontextprotocol/server`; OAuth/OpenID Zod `*Schema` constants (e.g. `OAuthTokensSchema`, `OAuthMetadataSchema`) → `@modelcontextprotocol/sdk-shared` |
| `@modelcontextprotocol/sdk/shared/stdio.js` | `@modelcontextprotocol/client` or `@modelcontextprotocol/server` (`ReadBuffer`, `serializeMessage`, `deserializeMessage` are in the root barrel; the `./stdio` subpath only has the transport class) |

Notes:
Expand Down Expand Up @@ -98,8 +98,7 @@ Notes:
| `StreamableHTTPError` | REMOVED (use `SdkHttpError` with `SdkErrorCode.ClientHttp*`) |
| `WebSocketClientTransport` | REMOVED (use `StreamableHTTPClientTransport` or `StdioClientTransport`) |

All other **type** symbols from `@modelcontextprotocol/sdk/types.js` retain their original names. **Zod schemas** (e.g., `CallToolResultSchema`, `ListToolsResultSchema`) are no longer part of the public API — they are internal to the SDK. For runtime validation, use
`isSpecType.TypeName(value)` (e.g., `isSpecType.CallToolResult(v)`) or `specTypeSchemas.TypeName` for the `StandardSchemaV1Sync` validator object. The keys are typed as `SpecTypeName`, a literal union of all spec type names.
All other **type** symbols from `@modelcontextprotocol/sdk/types.js` retain their original names — import them from `@modelcontextprotocol/client` or `@modelcontextprotocol/server`. The **Zod schemas** (e.g., `CallToolResultSchema`, `ListToolsResultSchema`) move to `@modelcontextprotocol/sdk-shared`; `<Name>Schema.parse(value)` / `.safeParse(value)` keep working unchanged (the codemod rewrites the import path). To validate **without** depending on Zod, use `isSpecType.TypeName(value)` (e.g., `isSpecType.CallToolResult(v)`) or `specTypeSchemas.TypeName` (a `StandardSchemaV1Sync` validator) from `@modelcontextprotocol/client` / `@modelcontextprotocol/server`; the keys are typed as `SpecTypeName`, a literal union of all spec type names.

### Error class changes

Expand Down Expand Up @@ -558,4 +557,5 @@ Validator behavior:
8. If using server SSE transport, migrate to Streamable HTTP
9. If using server auth from the SDK: RS helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`, `OAuthTokenVerifier`) → `@modelcontextprotocol/express`; AS helpers → `@modelcontextprotocol/server-legacy/auth` (deprecated); migrate AS to external IdP/OAuth library
10. If relying on `listTools()`/`listPrompts()`/etc. throwing on missing capabilities, set `enforceStrictCapabilities: true`
11. Verify: build with `tsc` / run tests
11. Format the changed files with the project's formatter (`prettier --write`, `eslint --fix`, or `biome format --write`) — edits are not reformatted automatically, and the wrapped schemas (step 5) and rewritten `setRequestHandler` method strings (section 9) frequently need it to satisfy lint
12. Verify: build with `tsc` / run tests
26 changes: 19 additions & 7 deletions docs/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ This guide covers the breaking changes introduced in v2 of the MCP TypeScript SD
Version 2 of the MCP TypeScript SDK introduces several breaking changes to improve modularity, reduce dependency bloat, and provide a cleaner API surface. The biggest change is the split from a single `@modelcontextprotocol/sdk` package into separate `@modelcontextprotocol/core`,
`@modelcontextprotocol/client`, and `@modelcontextprotocol/server` packages.

> **Formatting:** The `@modelcontextprotocol/codemod` package automates most of the mechanical changes below, but it rewrites your code's AST without reformatting it — wrapped schemas and generated handler method strings may not match your project's style. After migrating (with the codemod or by hand), run your formatter on the changed files — for example `prettier --write`, `eslint --fix`, or `biome format --write` — and review the diff.

## Breaking Changes

### Package split (monorepo)
Expand Down Expand Up @@ -514,29 +516,39 @@ The return type is now inferred from the method name via `ResultTypeMap`. For ex

For **custom (non-spec)** methods, keep the result-schema argument — see [Sending custom-method requests](#sending-custom-method-requests). Only drop the schema when calling a spec method.

If you were using `CallToolResultSchema` (or any `*Schema` constant) for **runtime validation** (not just in `request()`/`callTool()` calls), use `isSpecType` or `specTypeSchemas`:
If you were using `CallToolResultSchema` (or any `*Schema` constant) for **runtime validation** (not just in `request()`/`callTool()` calls), import the schema from `@modelcontextprotocol/sdk-shared`. Your `.parse()` / `.safeParse()` calls keep working unchanged — only the import path changes:

```typescript
// v1: runtime validation with Zod schema
// v1
import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
if (CallToolResultSchema.safeParse(value).success) {
/* ... */
}

// v2: keyed type predicate
// v2 — same code, new import path
import { CallToolResultSchema } from '@modelcontextprotocol/sdk-shared';
if (CallToolResultSchema.safeParse(value).success) {
/* ... */
}
```

`@modelcontextprotocol/sdk-shared` is the canonical home for the Zod schema constants — both the spec schemas and the OAuth/OpenID schemas (e.g. `OAuthTokensSchema`, `OAuthMetadataSchema`) that v1 exported from `@modelcontextprotocol/sdk/shared/auth.js`. `@modelcontextprotocol/server` and `@modelcontextprotocol/client` keep a Zod-free public surface (they export the corresponding TypeScript types, e.g. `OAuthTokens`), so the raw `*Schema` constants live in `sdk-shared`. (The codemod rewrites these imports for you.)

If you'd rather **not** depend on Zod, `@modelcontextprotocol/client` and `@modelcontextprotocol/server` also expose Zod-free validators keyed by `SpecTypeName` — a literal union of every named spec type, so you get autocomplete and a compile error on typos:

```typescript
import { isSpecType } from '@modelcontextprotocol/client';
if (isSpecType.CallToolResult(value)) {
/* ... */
}
const blocks = mixed.filter(isSpecType.ContentBlock);

// v2: or get the StandardSchemaV1Sync validator object directly
// or the StandardSchemaV1Sync validator object directly
import { specTypeSchemas } from '@modelcontextprotocol/client';
const result = specTypeSchemas.CallToolResult['~standard'].validate(value);
```

`isSpecType` and `specTypeSchemas` are keyed by `SpecTypeName` — a literal union of every named type in the MCP spec — so you get autocomplete and a compile error on typos. `specTypeSchemas.X` is a `StandardSchemaV1Sync<In, Out>` — `validate()` returns the result synchronously,
so you can access `.issues` / `.value` without `await`. It composes with any Standard-Schema-aware library. The pre-existing `isCallToolResult(value)` guard still works.
`specTypeSchemas.X` is a `StandardSchemaV1Sync<In, Out>` — `validate()` returns the result synchronously, so you can access `.issues` / `.value` without `await`. It composes with any Standard-Schema-aware library. The pre-existing `isCallToolResult(value)` guard still works.

### Client list methods return empty results for missing capabilities

Expand Down Expand Up @@ -582,7 +594,7 @@ The following deprecated type aliases have been removed from `@modelcontextproto
| `IsomorphicHeaders` | Use Web Standard `Headers` |
| `AuthInfo` (from `server/auth/types.js`) | `AuthInfo` (now re-exported by `@modelcontextprotocol/client` and `@modelcontextprotocol/server`) |

All other types and schemas exported from `@modelcontextprotocol/sdk/types.js` retain their original names — import them from `@modelcontextprotocol/client` or `@modelcontextprotocol/server`.
All other symbols exported from `@modelcontextprotocol/sdk/types.js` retain their original names. Import the **types**, error classes, enums, and guards from `@modelcontextprotocol/client` or `@modelcontextprotocol/server`, and the **Zod schemas** (the `*Schema` constants) from `@modelcontextprotocol/sdk-shared`.

> **Note on `isJSONRPCResponse`:** v1's `isJSONRPCResponse` was a deprecated alias that only checked for _result_ responses (it was equivalent to `isJSONRPCResultResponse`). v2 removes the deprecated alias and introduces a **new** `isJSONRPCResponse` with corrected semantics — it
> checks for _any_ response (either result or error). If you are migrating v1 code that used `isJSONRPCResponse`, rename it to `isJSONRPCResultResponse` to preserve the original behavior. Use the new `isJSONRPCResponse` only when you want to match both result and error responses.
Expand Down
36 changes: 5 additions & 31 deletions packages/codemod/batch-test/repos.json
Original file line number Diff line number Diff line change
@@ -1,40 +1,14 @@
[
{
"repo": "modelcontextprotocol/servers",
"repo": "firebase/firebase-tools",
"ref": "main",
"packages": [
{
"dir": "src/everything",
"sourceDir": ".",
"dir": ".",
"sourceDir": "src/mcp",
"checks": {
"typecheck": "npx tsc --noEmit",
"build": "npm run build",
"test": "npm run test",
"lint": "npm run prettier:check"
}
}
]
},
{
"repo": "modelcontextprotocol/inspector",
"ref": "main",
"packages": [
{
"dir": "client",
"sourceDir": "src",
"checks": {
"typecheck": "npx tsc --noEmit",
"build": "npm run build",
"test": "npm run test",
"lint": "npm run lint"
}
},
{
"dir": "server",
"sourceDir": "src",
"checks": {
"typecheck": "npx tsc --noEmit",
"build": "npm run build",
"typecheck": "npx tsc -p tsconfig.compile.json",
"build": null,
"test": null,
"lint": null
}
Expand Down
3 changes: 1 addition & 2 deletions packages/codemod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@
"scripts": {
"typecheck": "tsgo -p tsconfig.json --noEmit",
"generate:versions": "tsx scripts/generateVersions.ts",
"generate:spec-schemas": "tsx scripts/generateSpecSchemaMap.ts",
"prebuild": "pnpm run generate:versions && pnpm run generate:spec-schemas",
"prebuild": "pnpm run generate:versions",
"build": "tsdown",
"build:watch": "tsdown --watch",
"prepack": "pnpm run build",
Expand Down
39 changes: 0 additions & 39 deletions packages/codemod/scripts/generateSpecSchemaMap.ts

This file was deleted.

3 changes: 2 additions & 1 deletion packages/codemod/scripts/generateVersions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const PACKAGE_DIRS: Record<string, string> = {
'@modelcontextprotocol/server': 'server',
'@modelcontextprotocol/node': 'middleware/node',
'@modelcontextprotocol/express': 'middleware/express',
'@modelcontextprotocol/server-legacy': 'server-legacy'
'@modelcontextprotocol/server-legacy': 'server-legacy',
'@modelcontextprotocol/sdk-shared': 'sdk-shared'
};

const versions: Record<string, string> = {};
Expand Down
Loading
Loading