Skip to content

Commit 51b0238

Browse files
docs: reframe migration guide around 'most servers: just bump' path; add Prerequisites, transitive-v1-deps, spec-param warning
1 parent 4fbcfcd commit 51b0238

3 files changed

Lines changed: 99 additions & 2 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@modelcontextprotocol/core': patch
3+
'@modelcontextprotocol/client': patch
4+
'@modelcontextprotocol/server': patch
5+
---
6+
7+
Reframe the v1→v2 migration guide around the "most servers: just bump `@modelcontextprotocol/sdk` to ^2" path. Adds a TL;DR section, a Prerequisites section (zod ^4.2.0, `moduleResolution`, bun cache), transitive-v1-dependency guidance, and a warning against extending spec-method params with custom fields.

docs/migration-SKILL.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
---
22
name: migrate-v1-to-v2
3-
description: Migrate MCP TypeScript SDK code from v1 (@modelcontextprotocol/sdk) to v2 (@modelcontextprotocol/core, /client, /server). Use when a user asks to migrate, upgrade, or port their MCP TypeScript code from v1 to v2.
3+
description: Migrate MCP TypeScript SDK code from v1 (@modelcontextprotocol/sdk) to v2 (@modelcontextprotocol/sdk@^2, or the split /client and /server packages). Use when a user asks to migrate, upgrade, or port their MCP TypeScript code from v1 to v2.
44
---
55

66
# MCP TypeScript SDK: v1 → v2 Migration
77

8-
Apply these changes in order: dependencies → imports → API calls → type aliases.
8+
**Shortest path for most servers:** bump `@modelcontextprotocol/sdk` to `^2.0.0` and stop. v1 import paths and APIs continue to work as `@deprecated` aliases (IDE strikethrough, no runtime warnings) that forward to the new implementation. If the user only wants to "get on v2", do that, run the build, and
9+
report any IDE-flagged `@deprecated` usages as optional follow-ups.
10+
11+
Apply the rest of this guide when the user wants a **full migration** to the new split packages with no `@deprecated` usages. Order: environment → dependencies → imports → API calls → type aliases.
912

1013
## 1. Environment
1114

1215
- Node.js 20+ required (v18 dropped)
1316
- ESM only (CJS dropped). If the project uses `require()`, convert to `import`/`export` or use dynamic `import()`.
17+
- TypeScript `moduleResolution` must be `bundler`, `nodenext`, or `node16` (legacy `node`/`node10` cannot resolve the v2 `exports` map; fails with TS2307).
18+
- If using Zod, must be `zod@^4.2.0` (older versions lack `~standard.jsonSchema`; passes typecheck but **crashes at runtime** on `tools/list`).
1419

1520
## 2. Dependencies
1621

docs/migration.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,78 @@
22

33
This guide covers the breaking changes introduced in v2 of the MCP TypeScript SDK and how to update your code.
44

5+
> **Note:** This guide describes the v2.0.0 release as a whole. The compatibility shims it references land across the [v2-bc PR series](https://github.com/modelcontextprotocol/typescript-sdk/pulls?q=is%3Apr+label%3Av2-bc); on any individual PR's branch some referenced symbols may not yet exist.
6+
7+
## TL;DR — most servers just bump the version
8+
9+
For **most MCP servers**, upgrading to v2 is a one-line change:
10+
11+
```diff
12+
- "@modelcontextprotocol/sdk": "^1.0.0"
13+
+ "@modelcontextprotocol/sdk": "^2.0.0"
14+
```
15+
16+
In v2, `@modelcontextprotocol/sdk` is a meta-package that re-exports the new split packages at the v1 import paths. v1 APIs (deep-import paths like `@modelcontextprotocol/sdk/server/mcp.js`, variadic `server.tool()`, `McpError`, `RequestHandlerExtra`, etc.) continue to work as
17+
**`@deprecated` aliases** — your IDE will show strikethrough and a hover note pointing at the new API, but there are no runtime warnings. You can ship on v2 immediately and migrate the deprecated usages at your own pace.
18+
19+
Read on if you want to:
20+
21+
- Migrate to the new split packages (`@modelcontextprotocol/server`, `@modelcontextprotocol/client`) for smaller bundles
22+
- Adopt the new API surface (no `@deprecated` strikethrough)
23+
- Understand a specific breaking change
24+
25+
> **Clients and frameworks** (host applications, custom transports, proxies) typically need a few more changes than servers — see the [Custom methods](#setrequesthandler-and-setnotificationhandler-use-method-strings), [Error hierarchy](#error-hierarchy-refactoring), and [Server auth](#server-auth-split) sections.
26+
27+
## Prerequisites
28+
29+
Before upgrading, check these three environment requirements. They are the most common source of confusing errors during migration.
30+
31+
### Zod must be `^4.2.0`
32+
33+
If you use Zod for tool/prompt schemas, you must be on **`zod@^4.2.0` or later**, and import from the `zod` (or `zod/v4`) entry point.
34+
35+
Older Zod versions (3.x, or 4.0.0–4.1.x) do **not** implement the `~standard.jsonSchema` property the SDK uses to render `inputSchema` for `tools/list`. This passes type-checking but **crashes at runtime** when a client calls `tools/list`.
36+
37+
```jsonc
38+
// package.json
39+
"dependencies": {
40+
"zod": "^4.2.0"
41+
}
42+
```
43+
44+
```typescript
45+
// Either of these works on zod@^4.2.0:
46+
import * as z from 'zod';
47+
import * as z from 'zod/v4';
48+
49+
// This does NOT work (zod 3.x has no Standard Schema support):
50+
import * as z from 'zod/v3';
51+
```
52+
53+
### TypeScript `moduleResolution` must be `bundler`, `nodenext`, or `node16`
54+
55+
v2 packages ship ESM-only with an `exports` map and no top-level `main`/`types` fields. TypeScript's legacy `"moduleResolution": "node"` (or `"node10"`) cannot resolve them and fails with `TS2307: Cannot find module '@modelcontextprotocol/server'`.
56+
57+
Update your `tsconfig.json`:
58+
59+
```jsonc
60+
{
61+
"compilerOptions": {
62+
"moduleResolution": "bundler" // or "nodenext" / "node16"
63+
}
64+
}
65+
```
66+
67+
> We deliberately do **not** ship `main`/`types` fallback fields — testing showed it suppresses TypeScript's helpful "consider updating moduleResolution" diagnostic and replaces it with dozens of misleading transitive errors.
68+
69+
### Testing locally with bun: clear the cache
70+
71+
If you are testing a local v2 build via `file:` tarballs, note that **bun caches `file:` dependencies by filename** and ignores content changes. Re-packing the SDK without bumping the version installs a stale tarball.
72+
73+
```bash
74+
bun pm cache rm && bun install --force
75+
```
76+
577
## Overview
678

779
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`,
@@ -396,6 +468,9 @@ server.setRequestHandler('acme/search', { params: SearchParams, result: SearchRe
396468

397469
The handler receives the parsed `params` directly (not the full request envelope). `_meta` is stripped before validation and is available as `ctx.mcpReq._meta`. Supplying `result` types the handler's return value; omit it to return any `Result`.
398470

471+
> **Warning:** Do **not** add custom fields to a _spec_ method's params (e.g., adding `{ tabId, image }` to `'notifications/message'`). v2 validates incoming spec messages against the spec schema, so unknown fields are stripped before your handler sees them. Use a vendor-prefixed
472+
> method name instead.
473+
399474
For `setNotificationHandler`, the 3-arg handler is `(params, notification) => void`. The raw notification is the second argument, so `_meta` is recoverable via `notification.params?._meta`.
400475

401476
#### Sending custom-method requests
@@ -512,6 +587,16 @@ const result = await specTypeSchemas.CallToolResult['~standard'].validate(value)
512587

513588
`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 `StandardSchemaV1<In, Out>`, which composes with any Standard-Schema-aware library. The pre-existing `isCallToolResult(value)` guard still works.
514589

590+
### Transitive dependencies still on v1
591+
592+
If a package you depend on (e.g., a shared MCP utilities library or framework adapter) still vends types from `@modelcontextprotocol/sdk@^1`, you will see structural type errors where v1 and v2 types meet (`Server` is not assignable to `Server`, `Transport` not assignable to
593+
`Transport`).
594+
595+
There is no SDK-side fix for this. Either:
596+
597+
- Upgrade the transitive dependency to v2 first, or
598+
- Add a type assertion (`as unknown as Transport`) at the boundary until it is upgraded.
599+
515600
### Client list methods return empty results for missing capabilities
516601

517602
`Client.listPrompts()`, `listResources()`, `listResourceTemplates()`, and `listTools()` now return empty results when the server didn't advertise the corresponding capability, instead of sending the request. This respects the MCP spec's capability negotiation.

0 commit comments

Comments
 (0)