modelcontextprotocol/typescript-sdk/mcp-typescript-sdk-upgrade-to-v2

Trust tier 3
  • community
Source check pending

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-v2

SKILL.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

  1. Prerequisites. Node.js 20+. v2 is ESM-first but ships a CommonJS build too, so

both import and require('@modelcontextprotocol/…') resolve natively.

  1. 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.

  1. Grep for markers. Anything the codemod recognized but could not safely rewrite is

marked in place: ``bash grep -rn '@mcp-codemod-error' . ``

  1. Type-check. tsc --noEmit (or your build). Remaining errors map to the

manual sections below.

  1. 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.

  1. Run your tests.
  2. 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:

MappingSource 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.json dependencies (@modelcontextprotocol/sdk → the v2 packages

your imports actually use).

  • Rewrites .tool() / .prompt() / .resource() to registerTool / 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 *Schema constants imported from sdk/types.js to

@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 → ProtocolErrorCode and 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 StreamableHTTPError reference to SdkHttpError and adds the import

(constructor calls are marked for review — argument shape changed).

  • Replaces IsomorphicHeaders with the Web Standard Headers type and drops the

import (a warning notes Headers uses .get()/.set(), not bracket access).

  • Rewrites SchemaInput<T> → StandardSchemaWithJSON.InferInput<T>.
  • Renames RequestHandlerExtra → ServerContext / ClientContext and the extra

parameter to ctx.

  • Rewrites vi.mock / jest.mock and dynamic import() paths.
  • Renames the ResourceTemplate type 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.js imports.
  • 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 / mergeCapabilities imports from shared/protocol.js to 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 — IsomorphicHeaders is renamed to Headers

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

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
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/modelcontextprotocol/typescript-sdk/mcp-typescript-sdk-upgrade-to-v2/badge)](https://verified-skill.com/skills/modelcontextprotocol/typescript-sdk/mcp-typescript-sdk-upgrade-to-v2)

Something wrong with this skill or its page? Tell us.