夜航船 NightShip · 返回主页 · 博客

MCP v1→v2迁移实战:7.6万个项目要搬家的前留档

2026-10-17 · 林一舟

上个月写MCP入门文的时候,我提了一句"官方TypeScript SDK周下载5100万"。当时没展开说的一件事:SDK已经换代了。

2026年7月27日,MCP TypeScript SDK发布了v2稳定版。不是加个版本号的常规升级——包名换了。你项目里那行 @modelcontextprotocol/sdk,对应的不再是最新的东西。

更关键的是官方给的维护窗口:v1.x只维护到v2发布后6个月,也就是2027年1月底。我去npm上数了一下,还挂在v1上的依赖项目有76,000多个。这些项目都要在窗口内搬家,而中文社区里讲"怎么迁"的文章,我写这篇时基本搜不到。

所以这篇就把我们自己项目(一个双传输的MCP server模板)从v1迁到v2的完整过程记下来。全程半小时以内,其中二十分钟在等npm install。

先判断:你要不要迁

三种情况:

  1. 用了官方TS SDK写server/client → 要迁,本文就是给你的
  2. 只是配置使用别人的MCP server(改Claude/Cursor配置文件那种)→ 不用动,协议本身没变,客户端配置原样能用
  3. 用其他语言SDK(Python等) → 不受这次TS SDK换包影响,跟各自语言SDK的版本线走

包名对照表(迁移的核心就这张表)

v2把一个大包拆成了按需引入的几个包:

v1(@modelcontextprotocol/sdk) v2
sdk/server/mcp.js 的 McpServer @modelcontextprotocol/server
sdk/server/stdio.js 的 StdioServerTransport @modelcontextprotocol/server/stdio
sdk/server/streamableHttp.js 的 StreamableHTTPServerTransport @modelcontextprotocol/node 的 NodeStreamableHTTPServerTransport
sdk/inMemory.js(写测试用) @modelcontextprotocol/client
sdk/client/index.js 的 Client @modelcontextprotocol/client

注意最后一行常被忽略:写集成测试时用 InMemoryTransport.createLinkedPair() 的,v2里Server侧的InMemory并进了server包,Client和配对传输从 @modelcontextprotocol/client 拿。

用express/fastify/hono的,v2提供了对应的适配层,Node原生req/res场景就是 @modelcontextprotocol/node。

三步迁移

第一步,官方自动迁移工具(v2一起发布的,很多文章还没提到):

# 在项目根目录执行
npx @modelcontextprotocol/codemod@latest v1-to-v2 .

它会处理:import路径改写、.tool()改registerTool、裸schema对象包上z.object()、package.json依赖替换(移除旧包、加上v2三包)。我们项目15处改动、9个文件,它一次跑完全部正确。

第二步,手工点一:zod必须升到4.2+。

npm i zod@^4.2

这是整个迁移里最阴的坑,值得单独一段。zod停在3.x的项目:npm install正常、server能启动、看起来一切安好——直到第一次 tools/list 才报错。因为v2走Standard Schema标准做schema转换,zod 3.x的主入口没有对应的导出。codemod会在输出里警告你,但如果你跳过警告直接跑测试之外的验证路径,就会以为迁移完成了。

第三步,手工点二:全量验证,别只看启动。

npm install
npm run typecheck
npm test        # 如果你有基于InMemoryTransport的真协议测试,这时候会说话

注册写法的变化(codemod会替你改,但你要看得懂改了什么):

// v1:位置参数 + 裸对象schema
server.tool("get_time", "获取时间", { timeZone: z.string().optional() }, handler);

// v2:配置对象 + schema必须 z.object() 包裹
server.registerTool("get_time", {
  description: "获取时间",
  inputSchema: z.object({ timeZone: z.string().optional() }),
}, handler);

registerResource / registerPrompt 同理。v1的 .resource()、.prompt() 糖方法在v2不保证可用,别留着。

验证别只跑到typecheck

我们的迁移验证链是:typecheck零错误 → 9个基于InMemoryTransport的真协议测试全绿 → build → 起真实HTTP服务打一次 initialize 握手。

握手那里还有个小插曲值得记:POST上去先收到一个400,Client must accept both application/json and text/event-stream。这不是迁移失败,恰恰是v2传输层在按规范校验请求头——请求补上 Accept: application/json, text/event-stream 就通了。看到这个报错说明你的HTTP传输是活的。

无状态成为一等公民

2026-07-28规范的关键词是无状态、可缓存、可路由。落到开发习惯上就一条:别把业务状态挂在MCP会话上。server实例不再绑定会话之后,水平扩展、网关缓存、CDN这些都是白拿的。会话模式还需要的话(比如长连接场景),传输层的 sessionIdGenerator 那套构造参数没变,有状态模式照旧能开。

迁移检查清单

写在最后

这次换代对生态是好事:包按需拆分、schema走标准、无状态原生支持——都是冲着"企业可以放心上生产"去的。对开发者来说,麻烦就这一个季度:2027年1月底前搬完。早上车的项目,后面就只剩享受了。

如果你不想自己动手迁,或者要开个新项目想直接站在v2线上:我们把自己的双传输模板(stdio + Streamable HTTP、鉴权、真协议测试、CI/CD全套)迁到了v2,淘宝搜「夜航船NightShip」可以找到,配套的《MCP开发速查手册》v1.1第11节就是本文的完整版速查表。

夜航船 NightShip · 白天泊岸,夜里出航

我是林一舟,「夜航船 NightShip」——一个只在夜里发布产品的独立开发者。这篇是夜航手记的原创文章。

🛠 免费工具:MCP 配置生成器 · JSON 转 Schema · MCP 端点测试器

📖 完整《MCP 开发速查手册》(v2 基线 + 迁移速查):淘宝搜「夜航船NightShip」,海外 Gumroad