agentsclimarketplace

Convert mcp sdk v1 to v2

Skill yigitkonur/skills-by-yigitkonur/skills/convert-mcp-sdk-v1-to-v2

Use if porting an MCP TypeScript server from @modelcontextprotocol/sdk v1.x to the v2 SDK.From its SKILL.md

Install
npx -y skills add yigitkonur/skills-by-yigitkonur --skill convert-mcp-sdk-v1-to-v2

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 11 stars11 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

15.4 KB, as published. Nobody here has run it

Convert MCP Server (SDK v1 → v2)

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.

When to use this skill

Trigger on actual migration intent applied to an existing v1 codebase. Italicized phrases below are concrete tells:

  • "port my MCP server to v2", "upgrade @modelcontextprotocol/sdk to the new split packages"
  • "replace @modelcontextprotocol/sdk/server/mcp.js imports with @modelcontextprotocol/server"
  • "my handlers use extra.signal/extra.authInfo and I need the v2 equivalent"
  • "convert inputSchema: { name: z.string() } raw shapes to v2", "upgrade Zod v3 to v4 in MCP tools"
  • "replace mcpAuthRouter / requireBearerAuth / OAuthServerProvider"
  • "swap StreamableHTTPServerTransport for NodeStreamableHTTPServerTransport"
  • "McpError/ErrorCode → ProtocolError/ProtocolErrorCode rename"
  • "setRequestHandler(CallToolRequestSchema, ...) → method-string keys"

Detection signals (all should be true)

  • package.json contains @modelcontextprotocol/sdk (the v1 single package).
  • The user states intent to migrate, upgrade, port, or convert — not just maintain v1.
  • There is existing handler/transport/auth code to transform — not a greenfield build.

Do NOT use this skill for

  • New v1 server (no existing code) → use build-mcp-server-sdk-v1.
  • New v2 server (greenfield on v2 alpha) → use build-mcp-server-sdk-v2.
  • Maintaining or bug-fixing a v1 server with no migration intent → use build-mcp-server-sdk-v1.
  • Already on v2 and just need to extend it → use build-mcp-server-sdk-v2.
  • Using the mcp-use wrapper (not the official SDK) → use build-mcp-use-server.

Core rules — load-bearing

  • Pick a strategy before touching files. Full rewrite, meta-package shim (only if the target alpha actually publishes one), HTTP-layer auth transition, or stay on v1. Verify package availability on npm before committing.
  • Never mix v1 and v2 packages in the same module graph except deliberately during a staged migration. Two McpServer classes from two packages do not interoperate; types silently diverge and instanceof checks break at runtime.
  • Pin to exact alpha versions (@modelcontextprotocol/[email protected]). ^ ranges across alphas surface breaking changes mid-migration. Always use --save-exact (or pnpm/yarn equivalents).
  • Migrate handler context (extra → ctx) and schemas (ZodRawShape → z.object) together for any tool you touch. Half-migrated handlers are the single biggest source of runtime errors.
  • Replace OAuth deliberately. Server-side OAuth (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.
  • Upgrade Node to 20+ and add "type": "module" to package.json. v2 is ESM-only — CommonJS dual-publish is unsupported.
  • Keep a working v1 branch alive until v2 graduates from alpha. v2 is a delivery target; v1 is the running production until then.

v1 → v2 surface map

The most-used renames at a glance. Detailed per-area guides linked below.

Areav1v2
Server class import@modelcontextprotocol/sdk/server/mcp.js@modelcontextprotocol/server
Stdio transport@modelcontextprotocol/sdk/server/stdio.js@modelcontextprotocol/server
HTTP transportStreamableHTTPServerTransport from …/server/streamableHttp.jsNodeStreamableHTTPServerTransport from @modelcontextprotocol/node
SSE transportSSEServerTransportremoved (clients must move to Streamable HTTP first)
Express adaptercreateMcpExpressApp from SDK subpathcreateMcpExpressApp from @modelcontextprotocol/express
Hono adapter(none)createMcpHonoApp from @modelcontextprotocol/hono
Client@modelcontextprotocol/sdk/client/index.js@modelcontextprotocol/client
ErrorsMcpError / ErrorCode from …/types.jsProtocolError / ProtocolErrorCode from @modelcontextprotocol/server
Request-handler keysetRequestHandler(CallToolRequestSchema, …)setRequestHandler("tools/call", …)
Zodimport { z } from "zod" (v3)import * as z from "zod/v4"
Tool input schemainputSchema: { name: z.string() } raw shapeinputSchema: z.object({ name: z.string() }) full schema
Handler signature(args, extra) => …(args, ctx) => …
Auth routermcpAuthRouter, requireBearerAuth, OAuthServerProviderremoved (HTTP-layer auth or transition package)

extra → ctx (most-frequent moves)

v1v2
extra.signalctx.mcpReq.signal
extra.requestIdctx.mcpReq.id
extra.sendNotification(n)ctx.mcpReq.notify(n)
extra.sendRequest(r, s)ctx.mcpReq.send(r, s)
extra.authInfoctx.http?.authInfo
extra.requestInfoctx.http?.req
extra.closeSSEStream?.()ctx.http?.closeSSE?.()
extra.sessionIdctx.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.

Workflow

1 — Inventory the v1 server

Read package.json, tsconfig.json, and every file under src/. Record:

  • Every @modelcontextprotocol/sdk/* import path (subpath exports are the migration unit).
  • Every extra.* field accessed in handlers.
  • Every transport class instantiated.
  • Every Zod schema shape: raw-object shorthand vs full z.object().
  • Every McpError(ErrorCode.X, …) call site and the codes used.
  • Every setRequestHandler(SomeRequestSchema, …) call.
  • Every framework wiring point: 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.

2 — Choose the migration strategy

StrategyWhenEffortTrade-off
Full rewriteSmall server (≤200 LOC tools, ≤2 transports, no OAuth router)HoursCleanest end state, full v2 API access
Meta-package shimMedium server, many subpath imports, target alpha publishes the shimHoursKeeps v1 import paths working under v2; defer rewrites tool-by-tool
HTTP-layer auth transitionProduction OAuth server using mcpAuthRouterDaysReplace SDK OAuth with app/framework middleware in a separate auth migration
Stay on v1OAuth-heavy, large, or alpha-allergicZeroNo code change; revisit when v2 reaches stable

Read references/guides/migration-strategy.md before committing. Record the choice in the change description.

3 — Rewrite packages and imports

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.

4 — Rewrite schemas

Per references/guides/schema-and-errors.md.

  • import { z } from "zod" → import * as z from "zod/v4"
  • Raw shape { name: z.string() } → full schema z.object({ name: z.string() }). v2 rejects raw shapes outright.
  • Drop zod-to-json-schema — v2 emits JSON Schema 2020-12 natively via z.toJSONSchema().

5 — Rewrite handlers (extra → ctx)

Per references/guides/handler-context-mapping.md. Use the mapping table above. No-args tool handler: (extra) => … becomes (ctx) => … — same shape, renamed.

6 — Rewrite errors and request-handler keys

Per references/guides/schema-and-errors.md. McpError / ErrorCode → ProtocolError / ProtocolErrorCode. setRequestHandler(CallToolRequestSchema, …) → setRequestHandler("tools/call", …).

7 — Replace auth

Per references/guides/auth-replacements.md.

  • If using 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.
  • If integrating fresh: do auth at the HTTP layer (Express/Hono middleware) and forward identity into authInfo via req.auth. The Express adapter passes req.auth through to ctx.http?.authInfo automatically.
  • The better-auth MCP plugin currently targets v1 import paths and is flagged for deprecation — do not adopt it new.

8 — Replace transports and adapters

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

9 — Validate and stage rollout

Per references/patterns/validation-and-rollback.md.

  • Add "type": "module" to package.json. Bump engines to Node 20+.
  • Run type-check first, then the existing unit/integration test suite.
  • Smoke-test with npx @anthropic-ai/mcp-inspector for browser/manual coverage.
  • Use test-by-mcpc-cli for headless CLI smoke/regression checks when mcpc is available.
  • Connect at least one real MCP client before production rollout.
  • Stage in a non-prod environment for at least one week before flipping production traffic.
  • Keep the v1 branch deployable until v2 reaches stable — alpha versions can break.

Quick diff — minimal hello-world before/after

// 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());

Decision rules

  • Prefer the meta-package shim only when the target alpha actually publishes it; otherwise direct packages or stay on v1.
  • Prefer separating auth migration from the SDK port — auth is high-stakes; only use a verified transition package.
  • Prefer pinned alpha versions over ^ ranges — alphas can publish breaking changes between any two patches.
  • Prefer migrating one handler end-to-end (imports + schema + ctx + errors) over one concern across all handlers — bounds the test surface per PR.
  • Treat ctx.http? as nullable everywhere — stdio leaves it undefined.

Guardrails

  • Never run an alpha SDK in production before staging it in a non-prod environment with realistic traffic for at least one week.
  • Never mix @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.
  • Never assume req.auth propagates without explicitly wiring HTTP-layer auth middleware — v2 has no server-side OAuth router.
  • Never delete the v1 branch or package-lock.json until v2 has been stable in production for at least one full release cycle.
  • Never npm install v2 packages without --save-exact.
  • Never adopt the better-auth MCP plugin as a new dependency in a v2 migration — flagged for deprecation, currently targets v1 import paths.

Output contract

When a port finishes, report:

  • migration strategy chosen and why
  • package/version changes, exact alpha pins, and whether the meta-package shim remains
  • handlers/tools migrated, especially schema and ctx rewrites
  • auth path chosen: stay on v1, verified transition package, HTTP-layer auth, or no auth
  • transports/adapters changed
  • validation rung reached: type-check, unit tests, Inspector, test-by-mcpc-cli, real client, staging/canary
  • rollback status: v1 branch/image/lockfile preserved, or blocker if not verified
  • residual risks from v2 alpha status

After the port lands, hand off to build-mcp-server-sdk-v2 for ongoing v2 maintenance.

Reference routing

Use the smallest set relevant to the migration step.

Plan and decide

ReferenceWhen to read
references/guides/migration-strategy.mdChoosing between full rewrite, meta-package shim, HTTP-layer auth transition, "stay on v1"

Rewrite mechanics

ReferenceWhen to read
references/guides/package-and-imports.mdPackage split table, import-by-import rewriter, meta-package shim usage
references/guides/schema-and-errors.mdZod v3→v4, raw shapes, JSON Schema dialect, error class rename, request-handler key strings
references/guides/handler-context-mapping.mdFull extra → ctx field mapping, no-args handlers, http nullability, new ctx-only methods
references/guides/transports-and-adapters.mdTransport renames, Express/Hono adapters, DNS rebinding, hostHeaderValidation
references/guides/auth-replacements.mdOAuth-router replacement, custom Bearer/Passport/jose patterns, why not better-auth

Validate and ship

ReferenceWhen to read
references/patterns/validation-and-rollback.mdMigration test plan, dual-version coexistence, rollback playbook, alpha-pinning

Compatibility note

Source-verified against the v1.x branch (latest stable: @modelcontextprotocol/sdk@^1.x) and the v2 alpha packages (@modelcontextprotocol/[email protected], /[email protected], /[email protected], /[email protected], /[email protected]). npm verification on 2026-05-09 found no published @modelcontextprotocol/core, @modelcontextprotocol/[email protected], or @modelcontextprotocol/server-auth-legacy; re-check the v2 changelog and npm package availability before each migration sprint.

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.