modelcontextprotocol/typescript-sdk/mcp-typescript-sdk-upgrade-to-v2
- community
Checking that the SKILL.md file is still in the repository.
Upgrades TypeScript code from v1 of the MCP TypeScript SDK (`@modelcontextprotocol/sdk`) to v2 (`@modelcontextprotocol/client`, `/server`, `/core` and the middleware packages): runs the official codemod, then works through what it cannot rewrite. Use whenever a project depends on `@modelcontextprotocol/sdk` and the user wants to migrate, upgrade, port or bump it to v2, or is fixing v1-to-v2 breakage such as missing `McpError`, `RequestHandlerExtra` or `*Schema` exports, `@mcp-codemod-error` markers, or changed auth, error, transport or handler behavior, even if they do not say "migration".
Install
npx vskill@latest install modelcontextprotocol/typescript-sdk/mcp-typescript-sdk-upgrade-to-v2SKILL.md
Upgrading from v1.x to v2
This guide covers upgrading from @modelcontextprotocol/sdk (v1.x) to the v2 packages. It is written for shell-capable agents and humans alike: run the codemod first, then work through the manual sections for what the codemod can't rewrite.
If you are already on v2 and want to adopt the 2026-07-28 protocol revision, see support-2026-07-28.md instead.
TL;DR — quick path
- Prerequisites. Node.js 20+. v2 is ESM-first but ships a CommonJS build too, so
both import and require('@modelcontextprotocol/…') resolve natively.
- Run the codemod.
``bash npx @modelcontextprotocol/codemod@latest v1-to-v2 . ` Run it at the **package root** (.), not ./src — it also rewrites package.json, and real projects import the SDK from test/, scripts/`, and fixtures too.
- Grep for markers. Anything the codemod recognized but could not safely rewrite is
marked in place: ``bash grep -rn '@mcp-codemod-error' . ``
- Type-check.
tsc --noEmit(or your build). Remaining errors map to the
manual sections below.
- Format. The codemod rewrites the AST without reformatting — run your formatter on
the changed files (prettier --write / eslint --fix / biome format --write); the codemod prints the exact command after it runs.
- Run your tests.
- Decide whether to serve the 2026-07-28 revision. The upgrade alone does not: a server
that still calls server.connect(new StdioServerTransport()) or hands requests to a *StreamableHTTPServerTransport serves 2025-era clients only, and a client pinned to 2026-07-28 cannot connect to it. To serve both, move the entry point to serveStdio(() => createServer()) or createMcpHandler(() => createServer()). A server that uses HTTP sessions keeps its transport for 2025-era clients and routes to it with isLegacyRequest, in front of createMcpHandler(factory, { legacy: 'reject' }). createMcpHandler checks no Host or Origin header, so a server that set enableDnsRebindingProtection mounts host and origin validation in front of it; see Serving the 2026-07-28 revision.
Migrating a large codebase gradually instead of in one pass? See Migrating in stages (large codebases).
<!-- #endregion intro -->
<!-- #region codemod -->
What the codemod handles
The codemod (`@modelcontextprotocol/codemod`) mechanically applies every rename whose mapping is fixed. The mappings are the source of truth — they live in the codemod package and are not reproduced here:
| Mapping | Source file | |
|---|---|---|
@modelcontextprotocol/sdk/... import paths → v2 packages | `mappings/importMap.ts` | |
Symbol renames (McpError → ProtocolError, JSONRPCError → JSONRPCErrorResponse, …) | `mappings/symbolMap.ts` | |
setRequestHandler(Schema, …) → setRequestHandler('method/string', …) | `mappings/schemaToMethodMap.ts` | |
extra.* → ctx.mcpReq.* / ctx.http?.* property remap | `mappings/contextPropertyMap.ts` |
In addition the codemod:
- Updates
package.jsondependencies (@modelcontextprotocol/sdk→ the v2 packages
your imports actually use).
- Rewrites
.tool()/.prompt()/.resource()toregisterTool/registerPrompt
/ registerResource and wraps inputSchema / outputSchema / argsSchema / uriSchema raw Zod shapes with z.object(), adding import { z } from 'zod' when the file has no z binding.
- Drops the result-schema argument from
client.request()/client.callTool()for
spec methods.
- Routes the spec Zod
*Schemaconstants imported fromsdk/types.jsto
@modelcontextprotocol/core (mixed imports are split; .parse() / .safeParse() calls are left untouched). Task-handler schema constants (GetTaskRequestSchema etc.) used as setRequestHandler args are not rewritten — the experimental tasks feature was removed (SEP-2663), so each such registration is marked with an action-required diagnostic instead (see Experimental tasks interception removed).
- Renames
ErrorCode→ProtocolErrorCodeand routes the local-only members
(RequestTimeout, ConnectionClosed) to SdkErrorCode — rewriting an all-SDK condition's instanceof ProtocolError guard to SdkError, and marking guards that mix the two enums.
- Renames every
StreamableHTTPErrorreference toSdkHttpErrorand adds the import
(constructor calls are marked for review — argument shape changed).
- Replaces
IsomorphicHeaderswith the Web StandardHeaderstype and drops the
import (a warning notes Headers uses .get()/.set(), not bracket access).
- Rewrites
SchemaInput<T>→StandardSchemaWithJSON.InferInput<T>. - Renames
RequestHandlerExtra→ServerContext/ClientContextand theextra
parameter to ctx.
- Rewrites
vi.mock/jest.mockand dynamicimport()paths. - Renames the
ResourceTemplatetype imported from@modelcontextprotocol/sdk/types.js
to ResourceTemplateType (the spec wire type). The ResourceTemplate URI-template helper class from server/mcp.js keeps its name and is not renamed.
- Drops
@modelcontextprotocol/sdk/server/zod-compat.jsimports. - Inverts optional completable nesting —
completable(schema.optional(), cb)becomes
completable(schema, cb).optional() (see Standard Schema objects); shapes it cannot invert get an @mcp-codemod-error marker.
- Rewrites
Protocol/mergeCapabilitiesimports fromshared/protocol.jsto the
client or server package root, like the module's other symbols.
What the codemod does NOT handle
Each of these maps to a manual section below. The codemod marks every site it recognized but could not safely rewrite with an @mcp-codemod-error comment.
- Node 20 / ESM — pre-flight, not a code rewrite. → Packaging & runtime
- Header-read `.get()` rewrite —
IsomorphicHeadersis renamed toHeaders
and extra.requestInfo?.headers[…] is remapped to ctx.http?.req?.headers[…], but converting that bracket access to .get() is manual. (Headers you _pass in_ via requestInit.headers need no rewrite — plain objects remain valid.) → HTTP & headers
- `ctx.mcpReq.send()` schema-arg drop — the codemod drops the schema arg from
client.request() / client.callTool() but leaves nested ctx.mcpReq.send() calls alone. → Low-level protocol
- OAuth error-class consolidation —
instanceof InvalidGrantError→OAuthError+
OAuthErrorCode is a judgment rewrite. → Auth
- `SdkErrorCode` branch selection — the codemod renames
StreamableHTTPError→
SdkHttpError; deciding which SdkErrorCode branch a given catch should match is judgment. → Errors
- Namespace schema access —
import * as t from '…/types.js'+
t.CallToolResultSchema.parse(…) can't be split per-symbol; the codemod flags it action-required — re-import the schema from @modelcontextprotocol/core by hand. → Types & schemas
- Import-less (injected) SDK surfaces — the codemod is import-driven: a file that
receives the SDK surface as a parameter (dependency injection, factory seams) and has no SDK import is never rewritten, and the v1 idioms there fail at runtime, not compile time — e.g. the v1 schema-first setRequestHandler(Schema, …) form throws a TypeError at registration. Grep such seams for v1 API tokens beyond import statements (setRequestHandler(, ErrorCode., extra.) and apply the handler-registration and Errors sections by hand. → Low-level protocol
- Behavioral adaptation — list auto-aggregation, capability empties, lazy validator
compilation, output-schema validation rules. → Behavioral changes
Manual changes (what the codemod does not handle)
<!-- #endregion codemod -->
Each subsystem has its own reference file. Open the one that matches the type error, runtime failure or @mcp-codemod-error marker in front of you; most migrations need only a few of them.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/mcp-typescript-sdk-upgrade-to-v2/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/modelcontextprotocol/typescript-sdk/mcp-typescript-sdk-upgrade-to-v2)