MCP TypeScript SDK (V2) / @modelcontextprotocol/codemod
@modelcontextprotocol/codemod
Codemods for migrating MCP TypeScript SDK code between major versions.
Usage
npx @modelcontextprotocol/codemod@beta v1-to-v2 .
# or a single source file (manifest changes are reported, not applied)
npx @modelcontextprotocol/codemod@beta v1-to-v2 src/server.tsThe codemod rewrites TypeScript and JavaScript source files (.ts/.tsx/.mts/.cts/.js/.jsx/.mjs/.cjs) in place. Run it on a clean working tree so you can review the diff.
What v1-to-v2 covers
The mechanical rename mappings are the source of truth — see src/migrations/v1-to-v2/mappings/:
importMap.ts—@modelcontextprotocol/sdk/...import paths → v2 packagessymbolMap.ts— symbol renames (McpError→ProtocolError, …)schemaToMethodMap.ts—setRequestHandler(Schema, …)→setRequestHandler('method/string', …)contextPropertyMap.ts—extra.*→ctx.mcpReq.*/ctx.http?.*
Transforms in src/migrations/v1-to-v2/transforms/ also rewrite .tool() → registerTool (wrapping inputSchema / outputSchema / argsSchema / uriSchema raw shapes with z.object()), drop the result-schema argument from client.request() / client.callTool() for spec methods, route spec *Schema imports to @modelcontextprotocol/core, rename StreamableHTTPError → SdkHttpError / IsomorphicHeaders → Headers, rewrite SchemaInput<T> → StandardSchemaWithJSON.InferInput<T>, route ErrorCode.{RequestTimeout,ConnectionClosed} to SdkErrorCode (rewriting an all-SDK condition's instanceof ProtocolError guard to SdkError, and marking guards that mix the two enums), add import { z } from 'zod' when a wrap needs it, rewrite vi.mock / jest.mock / dynamic import() paths, invert optional completable nesting (completable(schema.optional(), cb) becomes completable(schema, cb).optional()), and drop Protocol / mergeCapabilities (no v2 export) with an action-required marker naming the replacement.
@mcp-codemod-error markers
When the codemod recognizes a v1 pattern but cannot safely rewrite it (ambiguous context, removed API with no mechanical replacement, signature change requiring judgment), it leaves the code unchanged and inserts a comment:
/* @mcp-codemod-error WebSocketClientTransport removed in v2. Use StreamableHTTPClientTransport or StdioClientTransport. */After running the codemod, find every site that needs attention:
grep -rn '@mcp-codemod-error' .What it does NOT cover
CJS→ESM / Node 20 pre-flight, header read rewrites (ctx.http?.req?.headers bracket access → .get(); sending plain-record headers keeps working), OAuth error-class consolidation (instanceof InvalidGrantError → OAuthError + OAuthErrorCode), per-scenario SdkErrorCode branch selection, ctx.mcpReq.send() schema-arg drop, and behavioral adaptation are manual — see the migration guide for what to do after the codemod runs.
The codemod handles the v1→v2 SDK surface upgrade only. Adopting the 2026-07-28 protocol revision (createMcpHandler, multi-round-trip requests, versionNegotiation) is architectural and not codemod-automatable — see docs/migration/support-2026-07-28.md.
Modules
- cli
- generated/versions
- index
- migrations
- migrations/v1-to-v2
- migrations/v1-to-v2/mappings/authSchemaNames
- migrations/v1-to-v2/mappings/contextPropertyMap
- migrations/v1-to-v2/mappings/importMap
- migrations/v1-to-v2/mappings/schemaRouting
- migrations/v1-to-v2/mappings/schemaToMethodMap
- migrations/v1-to-v2/mappings/specSchemaNames
- migrations/v1-to-v2/mappings/symbolMap
- migrations/v1-to-v2/transforms
- migrations/v1-to-v2/transforms/completableNesting
- migrations/v1-to-v2/transforms/contextTypes
- migrations/v1-to-v2/transforms/handlerRegistration
- migrations/v1-to-v2/transforms/importPaths
- migrations/v1-to-v2/transforms/mcpServerApi
- migrations/v1-to-v2/transforms/mockPaths
- migrations/v1-to-v2/transforms/removedApis
- migrations/v1-to-v2/transforms/schemaParamRemoval
- migrations/v1-to-v2/transforms/symbolRenames
- runner
- types
- utils/astUtils
- utils/detectFormatter
- utils/diagnostics
- utils/importUtils
- utils/packageJsonUpdater
- utils/projectAnalyzer