convert-mcp-sdk-v1-to-v2
Use if porting an MCP TypeScript server from @modelcontextprotocol/sdk v1.x to the v2 SDK.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Use if porting an MCP TypeScript server from @modelcontextprotocol/sdk v1.x to the v2 SDK.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | convert-mcp-sdk-v1-to-v2 |
| description | Use if porting an MCP TypeScript server from @modelcontextprotocol/sdk v1.x to the v2 SDK. |
Port an existing MCP TypeScript server from @modelcontextprotocol/sdk v1.x (single package) to the v2 split-package SDK: @modelcontextprotocol/server, /client, /node, /express, /hono. The v2 surface changes are package split, extra → ctx handler-context mapping, Zod v3→v4 with raw-shape removal, McpError → ProtocolError, method-string request-handler keys, framework adapter packages, and OAuth-router removal.
v2 is currently a pre-release alpha. Latest published: 2.0.0-alpha.2 (verified on npm, 2026-05-09). Most production servers should stay on @modelcontextprotocol/sdk@^1.x and use this skill to plan, test, and stage the migration — not to flip a production switch.
Trigger on actual migration intent applied to an existing v1 codebase. Italicized phrases below are concrete tells:
@modelcontextprotocol/sdk/server/mcp.js imports with @modelcontextprotocol/server"extra.signal/extra.authInfo and I need the v2 equivalent"inputSchema: { name: z.string() } raw shapes to v2", "upgrade Zod v3 to v4 in MCP tools"mcpAuthRouter / requireBearerAuth / OAuthServerProvider"StreamableHTTPServerTransport for NodeStreamableHTTPServerTransport"McpError/ErrorCode → ProtocolError/ProtocolErrorCode rename"setRequestHandler(CallToolRequestSchema, ...) → method-string keys"package.json contains @modelcontextprotocol/sdk (the v1 single package).build-mcp-server-sdk-v1.build-mcp-server-sdk-v2.build-mcp-server-sdk-v1.build-mcp-server-sdk-v2.mcp-use wrapper (not the official SDK) → use build-mcp-use-server.McpServer classes from two packages do not interoperate; types silently diverge and instanceof checks break at runtime.@modelcontextprotocol/server@2.0.0-alpha.2). ^ ranges across alphas surface breaking changes mid-migration. Always use --save-exact (or pnpm/yarn equivalents).extra → ctx) and schemas (ZodRawShape → z.object) together for any tool you touch. Half-migrated handlers are the single biggest source of runtime errors.mcpAuthRouter, requireBearerAuth, OAuthServerProvider) is removed from v2. If @modelcontextprotocol/server-auth-legacy is published for the target alpha, use it as a transition; otherwise stay on v1 or move auth to the HTTP layer (Bearer middleware, Passport, jose) and forward identity via req.auth."type": "module" to package.json. v2 is ESM-only — CommonJS dual-publish is unsupported.The most-used renames at a glance. Detailed per-area guides linked below.
| Area | v1 | v2 |
|---|---|---|
| Server class import | @modelcontextprotocol/sdk/server/mcp.js | @modelcontextprotocol/server |
| Stdio transport | @modelcontextprotocol/sdk/server/stdio.js | @modelcontextprotocol/server |
| HTTP transport | StreamableHTTPServerTransport from …/server/streamableHttp.js | NodeStreamableHTTPServerTransport from @modelcontextprotocol/node |
| SSE transport | SSEServerTransport | removed (clients must move to Streamable HTTP first) |
| Express adapter | createMcpExpressApp from SDK subpath | createMcpExpressApp from @modelcontextprotocol/express |
| Hono adapter | (none) | createMcpHonoApp from @modelcontextprotocol/hono |
| Client | @modelcontextprotocol/sdk/client/index.js | @modelcontextprotocol/client |
| Errors | McpError / ErrorCode from …/types.js | ProtocolError / ProtocolErrorCode from @modelcontextprotocol/server |
| Request-handler key | setRequestHandler(CallToolRequestSchema, …) | setRequestHandler("tools/call", …) |
| Zod | import { z } from "zod" (v3) | import * as z from "zod/v4" |
| Tool input schema | inputSchema: { name: z.string() } raw shape | inputSchema: z.object({ name: z.string() }) full schema |
| Handler signature | (args, extra) => … | (args, ctx) => … |
| Auth router | mcpAuthRouter, requireBearerAuth, OAuthServerProvider | removed (HTTP-layer auth or transition package) |
| v1 | v2 |
|---|---|
extra.signal | ctx.mcpReq.signal |
extra.requestId | ctx.mcpReq.id |
extra.sendNotification(n) | ctx.mcpReq.notify(n) |
extra.sendRequest(r, s) | ctx.mcpReq.send(r, s) |
extra.authInfo | ctx.http?.authInfo |
extra.requestInfo | ctx.http?.req |
extra.closeSSEStream?.() | ctx.http?.closeSSE?.() |
extra.sessionId | ctx.sessionId (top-level, unchanged) |
ctx.http? is nullable — stdio transport leaves it undefined. Any code that assumed extra.authInfo was always defined needs an explicit branch.
Read package.json, tsconfig.json, and every file under src/. Record:
@modelcontextprotocol/sdk/* import path (subpath exports are the migration unit).extra.* field accessed in handlers.z.object().McpError(ErrorCode.X, …) call site and the codes used.setRequestHandler(SomeRequestSchema, …) call.createMcpExpressApp, requireBearerAuth, mcpAuthRouter, custom middleware that depends on the SDK.For a deterministic first pass, run bash scripts/check-v2-feasibility.sh <project-dir> from this skill directory and read scripts/check-v2-feasibility.md. Use the report to focus the manual inventory; do not treat it as a substitute for reading the code.
| Strategy | When | Effort | Trade-off |
|---|---|---|---|
| Full rewrite | Small server (≤200 LOC tools, ≤2 transports, no OAuth router) | Hours | Cleanest end state, full v2 API access |
| Meta-package shim | Medium server, many subpath imports, target alpha publishes the shim | Hours | Keeps v1 import paths working under v2; defer rewrites tool-by-tool |
| HTTP-layer auth transition | Production OAuth server using mcpAuthRouter | Days | Replace SDK OAuth with app/framework middleware in a separate auth migration |
| Stay on v1 | OAuth-heavy, large, or alpha-allergic | Zero | No code change; revisit when v2 reaches stable |
Read references/guides/migration-strategy.md before committing. Record the choice in the change description.
Per references/guides/package-and-imports.md. Smallest unit: one import line at a time.
For direct-package migrations, preview the mechanical import portion with bash scripts/migrate-imports.sh <project-dir> and read scripts/migrate-imports.md. Rerun with --write only after reviewing the dry-run. Do not use it for schema, ctx, auth-router, request-handler-key, or transport-lifecycle rewrites — those need hand edits.
Per references/guides/schema-and-errors.md.
import { z } from "zod" → import * as z from "zod/v4"{ name: z.string() } → full schema z.object({ name: z.string() }). v2 rejects raw shapes outright.zod-to-json-schema — v2 emits JSON Schema 2020-12 natively via z.toJSONSchema().Per references/guides/handler-context-mapping.md. Use the mapping table above. No-args tool handler: (extra) => … becomes (ctx) => … — same shape, renamed.
Per references/guides/schema-and-errors.md. McpError / ErrorCode → ProtocolError / ProtocolErrorCode. setRequestHandler(CallToolRequestSchema, …) → setRequestHandler("tools/call", …).
Per references/guides/auth-replacements.md.
mcpAuthRouter and the target alpha publishes @modelcontextprotocol/server-auth-legacy, keep the v1 router through that transition package; otherwise stay on v1 until auth can move out of the SDK.authInfo via req.auth. The Express adapter passes req.auth through to ctx.http?.authInfo automatically.better-auth MCP plugin currently targets v1 import paths and is flagged for deprecation — do not adopt it new.Per references/guides/transports-and-adapters.md. Use the surface map table above. Hono is new in v2 via @modelcontextprotocol/hono (the official SDK package, not the unrelated community @hono/mcp package).
Per references/patterns/validation-and-rollback.md.
"type": "module" to package.json. Bump engines to Node 20+.npx @anthropic-ai/mcp-inspector for browser/manual coverage.test-by-mcpc-cli for headless CLI smoke/regression checks when mcpc is available.// v1
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "my-server", version: "1.0.0" });
server.registerTool("greet", {
inputSchema: { name: z.string() }, // raw shape
}, async ({ name }, extra) => { // (args, extra)
await extra.sendNotification({ method: "...", params: {} });
return { content: [{ type: "text", text: `Hi ${name}` }] };
});
await server.connect(new StdioServerTransport());
// v2
import { McpServer, StdioServerTransport } from "@modelcontextprotocol/server";
import * as z from "zod/v4";
const server = new McpServer({ name: "my-server", version: "1.0.0" });
server.registerTool("greet", {
inputSchema: z.object({ name: z.string() }), // full schema
}, async ({ name }, ctx) => { // (args, ctx)
await ctx.mcpReq.notify({ method: "...", params: {} });
return { content: [{ type: "text" as const, text: `Hi ${name}` }] };
});
await server.connect(new StdioServerTransport());
^ ranges — alphas can publish breaking changes between any two patches.ctx.http? as nullable everywhere — stdio leaves it undefined.@modelcontextprotocol/sdk and @modelcontextprotocol/server in the same compiled bundle without the meta-package shim — TypeScript accepts duplicate types but instanceof checks and class identity break at runtime.req.auth propagates without explicitly wiring HTTP-layer auth middleware — v2 has no server-side OAuth router.package-lock.json until v2 has been stable in production for at least one full release cycle.npm install v2 packages without --save-exact.better-auth MCP plugin as a new dependency in a v2 migration — flagged for deprecation, currently targets v1 import paths.When a port finishes, report:
ctx rewritestest-by-mcpc-cli, real client, staging/canaryAfter the port lands, hand off to build-mcp-server-sdk-v2 for ongoing v2 maintenance.
Use the smallest set relevant to the migration step.
| Reference | When to read |
|---|---|
references/guides/migration-strategy.md | Choosing between full rewrite, meta-package shim, HTTP-layer auth transition, "stay on v1" |
| Reference | When to read |
|---|---|
references/guides/package-and-imports.md | Package split table, import-by-import rewriter, meta-package shim usage |
references/guides/schema-and-errors.md | Zod v3→v4, raw shapes, JSON Schema dialect, error class rename, request-handler key strings |
references/guides/handler-context-mapping.md | Full extra → ctx field mapping, no-args handlers, http nullability, new ctx-only methods |
references/guides/transports-and-adapters.md | Transport renames, Express/Hono adapters, DNS rebinding, hostHeaderValidation |
references/guides/auth-replacements.md | OAuth-router replacement, custom Bearer/Passport/jose patterns, why not better-auth |
| Reference | When to read |
|---|---|
references/patterns/validation-and-rollback.md | Migration test plan, dual-version coexistence, rollback playbook, alpha-pinning |
Source-verified against the v1.x branch (latest stable: @modelcontextprotocol/sdk@^1.x) and the v2 alpha packages (@modelcontextprotocol/server@2.0.0-alpha.2, /client@2.0.0-alpha.2, /node@2.0.0-alpha.2, /express@2.0.0-alpha.2, /hono@2.0.0-alpha.2). npm verification on 2026-05-09 found no published @modelcontextprotocol/core, @modelcontextprotocol/sdk@2.0.0-alpha.2, or @modelcontextprotocol/server-auth-legacy; re-check the v2 changelog and npm package availability before each migration sprint.
Use if driving agent-browser for webpage interaction, screenshots, @ref snapshots, tabs, UI verification, CDP attach, Steel Browser, or cloud providers (Browser Use, Browserbase, Browserless, Kernel).
Use if verifying claimed-done work or auditing session/plan/branch completion with evidence.
Use if creating, redesigning, or merging a Claude skill, with research before writing SKILL.md.
Use skill if you are running repeatable Codex reviews across lenses or branches, optionally verifying and fixing confirmed findings in isolated worktrees.
Use if running deep multi-file research over 5+ entities or a market — wave-dispatched corpus.
Use if finishing a project — review and merge every branch/worktree into main, retire dead branches.