build-mcp-sdk
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBuild MCP SDK
构建MCP SDK
Build and maintain MCP servers using v1.x (single package, Zod-based, protocol version 2025-11-25). Covers , , , , transports, OAuth 2.1, sessions, and deployment.
@modelcontextprotocol/sdkMcpServerregisterToolregisterResourceregisterPromptWhen to use a different skill instead:
- Imports from (split packages) → use
@modelcontextprotocol/serverbuild-mcp-sdk-v2 - Handlers use instead of flat
ctx.mcpReq→ useextrabuild-mcp-sdk-v2 - Uses the wrapper library → use
mcp-usebuild-mcp-use-server - Auditing/optimizing an existing server → use
optimize-mcp-server
How to detect v1: (single package) in . Handlers use with , , at the top level.
@modelcontextprotocol/sdkpackage.json(args, extra)extra.sendNotificationextra.authInfoextra.signalCore rules:
- Always use — the
McpServerclass is deprecated for direct useServer - Always use /
registerTool/registerResource— positionalregisterPrompt/tool()/resource()overloads are deprecatedprompt() - Always use for input/output schemas — the SDK converts them to JSON Schema 2020-12 automatically
zod - Always use for HTTP —
StreamableHTTPServerTransportis deprecatedSSEServerTransport - Access only for sampling, elicitation, resource subscriptions, or custom protocol extensions
server.server - Tool names SHOULD be 1-128 chars using letters, digits, underscore, hyphen, dot
- Input validation errors SHOULD be returned as tool execution errors () not protocol errors — enables LLM self-correction
isError: true
使用 v1.x构建和维护MCP服务器(单包、基于Zod、协议版本2025-11-25)。内容覆盖、、、、传输层、OAuth 2.1、会话和部署。
@modelcontextprotocol/sdkMcpServerregisterToolregisterResourceregisterPrompt何时应使用其他skill:
- 从(拆分包)导入 → 使用
@modelcontextprotocol/serverbuild-mcp-sdk-v2 - 处理程序使用而非扁平结构的
ctx.mcpReq→ 使用extrabuild-mcp-sdk-v2 - 使用封装库 → 使用
mcp-usebuild-mcp-use-server - 审计/优化现有服务器 → 使用
optimize-mcp-server
如何识别v1版本: 中存在(单包)。处理程序使用的参数形式,顶层包含、、等属性。
package.json@modelcontextprotocol/sdk(args, extra)extra.sendNotificationextra.authInfoextra.signal核心规则:
- 始终使用—— 直接使用
McpServer类已被弃用Server - 始终使用/
registerTool/registerResource—— 位置参数形式的registerPrompt/tool()/resource()重载已被弃用prompt() - 始终使用定义输入/输出schema —— SDK会自动将其转换为JSON Schema 2020-12
zod - HTTP场景始终使用——
StreamableHTTPServerTransport已被弃用SSEServerTransport - 仅在采样、启发式交互、资源订阅或自定义协议扩展时才访问
server.server - 工具名称应为1-128个字符,仅使用字母、数字、下划线、连字符、点
- 输入验证错误应作为工具执行错误返回()而非协议错误 —— 便于LLM自我修正
isError: true
Workflow
工作流
1 — Detect what exists
1 — 检测现有内容
Run and in the project directory. Look for:
tree -L 3ls package.json tsconfig.json- in
@modelcontextprotocol/sdkdependencies → existing MCP serverpackage.json - in dependencies → wrong skill, redirect to
mcp-usebuild-mcp-use-server - or
.mcp.jsonkey inmcp→ MCP client config, not server codepackage.json - with tool/resource handler files → existing implementation to extend
src/
Summarize: existing server (go to Step 2A) or new server (go to Step 2B).
在项目目录下运行和,查找以下内容:
tree -L 3ls package.json tsconfig.json- 依赖中存在
package.json→ 现有MCP服务器@modelcontextprotocol/sdk - 依赖中存在→ 选错了skill,请跳转至
mcp-usebuild-mcp-use-server - 存在或
.mcp.json中有package.json字段 → MCP客户端配置,不是服务端代码mcp - 目录下有工具/资源处理程序文件 → 可扩展的现有实现
src/
判断结果:现有服务器(进入步骤2A)或新服务器(进入步骤2B)。
2A — Audit an existing SDK server
2A — 审计现有SDK服务器
When an MCP server already exists, do not rebuild. Read the implementation and assess:
- Which API style is used? If deprecated /
tool(), migrate toresource()/registerToolregisterResource - Are Zod schemas defined for all tool inputs? If raw JSON Schema objects, convert to Zod
- Is the transport current? If , migrate to
SSEServerTransportStreamableHTTPServerTransport - Are tool annotations set? Add ,
readOnlyHint,destructiveHint,idempotentHintwhere missingopenWorldHint - Does the server validate header for HTTP transport? Add
OriginorcreateMcpExpressApp()hostHeaderValidation - Does the server declare capabilities correctly during initialization? Check ,
tools,resources,promptslogging
Then proceed to the user's requested changes (add tools, fix bugs, add auth, etc.).
当已有MCP服务器时,不要完全重构。阅读实现并评估:
- 使用的是哪种API风格?如果是已弃用的/
tool(),请迁移到resource()/registerToolregisterResource - 所有工具输入都定义了Zod schema吗?如果是原始JSON Schema对象,请转换为Zod格式
- 传输层是当前版本吗?如果是,请迁移到
SSEServerTransportStreamableHTTPServerTransport - 工具注解是否已设置?补充缺失的、
readOnlyHint、destructiveHint、idempotentHintopenWorldHint - 服务器是否对HTTP传输的头做了校验?添加
Origin或createMcpExpressApp()hostHeaderValidation - 服务器初始化时是否正确声明了能力?检查、
tools、resources、prompts配置logging
然后继续处理用户请求的改动(添加工具、修复bug、添加认证等)。
2B — Scope a new server
2B — 定义新服务器的范围
Ask or infer from context:
- What does the server wrap? (API, database, file system, CLI tool, etc.)
- Transport? stdio for local CLI integration, Streamable HTTP for remote/multi-client
- Auth needed? Bearer token, OAuth 2.1, or none (local stdio)
- Tools, resources, or prompts? Most servers need tools; resources for data access; prompts for reusable templates
- Client features needed? Sampling (LLM completions), elicitation (user input), roots (filesystem access)
询问或从上下文推断:
- 服务器封装的是什么?(API、数据库、文件系统、CLI工具等)
- 使用什么传输层? 本地CLI集成用stdio,远程/多客户端场景用Streamable HTTP
- 需要认证吗? Bearer令牌、OAuth 2.1或无需认证(本地stdio场景)
- 需要工具、资源还是提示词? 大多数服务器需要工具;数据访问场景用资源;可复用模板用提示词
- 需要哪些客户端功能? 采样(LLM补全)、启发式交互(用户输入)、根目录访问(文件系统权限)
3 — Choose the implementation branch
3 — 选择实现分支
| Scenario | Action |
|---|---|
| New stdio server | Scaffold from quick-start template → |
| New HTTP server (stateful) | Scaffold with session management → |
| New HTTP server (stateless) | Scaffold without sessions → |
| Add tools to existing server | Read |
| Add resources | Read |
| Add authentication | Read |
| Add sampling or elicitation | Read |
| Deploy to production | Read |
| Understand the MCP protocol | Read |
| 场景 | 操作 |
|---|---|
| 新stdio服务器 | 基于快速入门模板脚手架搭建 → |
| 新HTTP服务器(有状态) | 带会话管理的脚手架 → |
| 新HTTP服务器(无状态) | 不带会话的脚手架 → |
| 给现有服务器添加工具 | 阅读 |
| 添加资源 | 阅读 |
| 添加认证 | 阅读 |
| 添加采样或启发式交互 | 阅读 |
| 部署到生产环境 | 阅读 |
| 了解MCP协议 | 阅读 |
4 — Preflight setup
4 — 前期准备
Before writing server code, confirm:
- Node.js 18+ installed (required for )
globalThis.crypto - — both are required
npm install @modelcontextprotocol/sdk zod - TypeScript 5+ with or
"moduleResolution": "node16"in tsconfig"nodenext" - If HTTP transport: (Express 5 recommended)
npm install express
编写服务器代码前,确认:
- 已安装Node.js 18+(依赖此版本)
globalThis.crypto - 执行—— 两者都是必需依赖
npm install @modelcontextprotocol/sdk zod - TypeScript 5+,tsconfig中配置或
"moduleResolution": "node16""nodenext" - 如果用HTTP传输:(推荐Express 5)
npm install express
5 — Build or extend the server
5 — 构建或扩展服务器
Default implementation sequence:
- Create instance with name, version, and optional description/icons
McpServer - Define Zod schemas for each tool's input (and output if is needed)
structuredContent - Register tools with — input schema, annotations, async handler
server.registerTool() - Register resources with if the server exposes data
server.registerResource() - Register prompts with if the server provides templates
server.registerPrompt() - Create transport and connect:
await server.connect(transport) - Handle graceful shutdown with
process.on('SIGINT', ...)
Refer to for complete working examples.
references/examples/server-recipes.md默认实现顺序:
- 创建实例,配置名称、版本,可选描述/图标
McpServer - 为每个工具的输入定义Zod schema(如果需要则还要定义输出schema)
structuredContent - 使用注册工具 —— 配置输入schema、注解、异步处理程序
server.registerTool() - 如果服务器暴露数据,使用注册资源
server.registerResource() - 如果服务器提供模板,使用注册提示词
server.registerPrompt() - 创建传输层并连接:
await server.connect(transport) - 用处理优雅关闭
process.on('SIGINT', ...)
完整可运行示例请参考。
references/examples/server-recipes.md6 — Validate
6 — 验证
- stdio: Test with or pipe JSON-RPC messages directly
npx @anthropic-ai/mcp-inspector - HTTP: Start the server, then test with or the MCP Inspector
curl - Tool schemas: Verify Zod validation catches bad input (pass invalid args, confirm error response)
- Annotations: Check that /
readOnlyHintare accurate for each tooldestructiveHint - Capabilities: Verify the server declares the correct capabilities during initialization
- stdio: 使用测试,或直接传输JSON-RPC消息测试
npx @anthropic-ai/mcp-inspector - HTTP: 启动服务器,然后用或MCP Inspector测试
curl - 工具schema: 验证Zod校验可以捕获错误输入(传入无效参数,确认返回错误响应)
- 注解: 检查每个工具的/
readOnlyHint配置是否准确destructiveHint - 能力: 验证服务器初始化时声明的能力正确
Quick start — minimal stdio server
快速入门 —— 最简stdio服务器
typescript
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" },
{ instructions: "A helpful server" }
);
server.registerTool("greet", {
description: "Greet a user by name",
inputSchema: { name: z.string().describe("The user's name") },
annotations: { readOnlyHint: true, destructiveHint: false },
}, async ({ name }) => ({
content: [{ type: "text", text: `Hello, ${name}!` }],
}));
const transport = new StdioServerTransport();
await server.connect(transport);typescript
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" },
{ instructions: "A helpful server" }
);
server.registerTool("greet", {
description: "Greet a user by name",
inputSchema: { name: z.string().describe("The user's name") },
annotations: { readOnlyHint: true, destructiveHint: false },
}, async ({ name }) => ({
content: [{ type: "text", text: `Hello, ${name}!` }],
}));
const transport = new StdioServerTransport();
await server.connect(transport);Core API summary
核心API摘要
McpServer
McpServer
typescript
new McpServer(
{ name: string, version: string, description?: string, icons?: Icon[] },
{ capabilities?: ServerCapabilities, instructions?: string }
)
server.connect(transport: Transport): Promise<void>
server.close(): Promise<void>
server.registerTool(name, config, handler): RegisteredTool
server.registerResource(name, uri | template, config, handler): RegisteredResource
server.registerPrompt(name, config, handler): RegisteredPrompt
server.sendToolListChanged(): void
server.sendResourceListChanged(): void
server.sendPromptListChanged(): void
server.sendLoggingMessage(params): Promise<void>typescript
new McpServer(
{ name: string, version: string, description?: string, icons?: Icon[] },
{ capabilities?: ServerCapabilities, instructions?: string }
)
server.connect(transport: Transport): Promise<void>
server.close(): Promise<void>
server.registerTool(name, config, handler): RegisteredTool
server.registerResource(name, uri | template, config, handler): RegisteredResource
server.registerPrompt(name, config, handler): RegisteredPrompt
server.sendToolListChanged(): void
server.sendResourceListChanged(): void
server.sendPromptListChanged(): void
server.sendLoggingMessage(params): Promise<void>registerTool config
registerTool配置
typescript
{
title?: string, // Human-readable display name
description?: string, // LLM reads this to decide when to call the tool
inputSchema?: ZodRawShape | ZodSchema,
outputSchema?: ZodRawShape | ZodSchema, // Enables structuredContent validation
annotations?: {
readOnlyHint?: boolean, // Does not modify state
destructiveHint?: boolean, // May delete/modify data
idempotentHint?: boolean, // Repeated calls safe
openWorldHint?: boolean, // Interacts with external services
},
icons?: Icon[], // Visual identifier (2025-11-25)
}typescript
{
title?: string, // 人类可读的展示名称
description?: string, // LLM通过这个描述判断何时调用工具
inputSchema?: ZodRawShape | ZodSchema,
outputSchema?: ZodRawShape | ZodSchema, // 启用structuredContent校验
annotations?: {
readOnlyHint?: boolean, // 不修改状态
destructiveHint?: boolean, // 可能删除/修改数据
idempotentHint?: boolean, // 重复调用是安全的
openWorldHint?: boolean, // 与外部服务交互
},
icons?: Icon[], // 视觉标识(2025-11-25版本新增)
}CallToolResult
CallToolResult
typescript
{
content: Array<
| { type: "text", text: string }
| { type: "image", data: string, mimeType: string }
| { type: "audio", data: string, mimeType: string }
| { type: "resource", resource: { uri: string, text?: string, blob?: string } }
| { type: "resource_link", uri: string, name?: string, description?: string }
>,
structuredContent?: Record<string, unknown>,
isError?: boolean,
}typescript
{
content: Array<
| { type: "text", text: string }
| { type: "image", data: string, mimeType: string }
| { type: "audio", data: string, mimeType: string }
| { type: "resource", resource: { uri: string, text?: string, blob?: string } }
| { type: "resource_link", uri: string, name?: string, description?: string }
>,
structuredContent?: Record<string, unknown>,
isError?: boolean,
}RequestHandlerExtra (v1.x)
RequestHandlerExtra (v1.x)
Every handler receives as the last argument:
extratypescript
{
signal: AbortSignal, // For cooperative cancellation
authInfo?: AuthInfo, // From OAuth middleware
sessionId?: string, // Current session ID
requestId: RequestId, // JSON-RPC request ID
requestInfo?: RequestInfo, // Original HTTP request metadata
_meta?: RequestMeta, // Protocol-level metadata
sendNotification: (notification) => Promise<void>,
sendRequest: (request, schema, options?) => Promise<Result>,
}Note: In v2 alpha, this becomes with a restructured API. See .
ServerContextreferences/guides/v2-migration.md每个处理程序最后一个参数都是:
extratypescript
{
signal: AbortSignal, // 用于协作式取消
authInfo?: AuthInfo, // 来自OAuth中间件
sessionId?: string, // 当前会话ID
requestId: RequestId, // JSON-RPC请求ID
requestInfo?: RequestInfo, // 原始HTTP请求元数据
_meta?: RequestMeta, // 协议级元数据
sendNotification: (notification) => Promise<void>,
sendRequest: (request, schema, options?) => Promise<Result>,
}注意:在v2 alpha版本中,这部分变成了,API结构有调整。参见。
ServerContextreferences/guides/v2-migration.mdError handling
错误处理
typescript
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
// Hard protocol errors (tool not found, bad params):
throw new McpError(ErrorCode.InvalidParams, "Missing required field: query");
// Soft tool errors (API failures the LLM can handle):
return { content: [{ type: "text", text: "Error: rate limit exceeded" }], isError: true };Per spec: input validation errors SHOULD use (tool execution errors) rather than protocol errors — this enables model self-correction.
isError: truetypescript
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
// 严重协议错误(工具不存在、参数错误):
throw new McpError(ErrorCode.InvalidParams, "Missing required field: query");
// 可由LLM处理的轻度工具错误(API调用失败):
return { content: [{ type: "text", text: "Error: rate limit exceeded" }], isError: true };根据协议规范:输入验证错误应使用(工具执行错误)而非协议错误 —— 这可以让模型实现自我修正。
isError: trueDecision rules
决策规则
- Prefer (
ZodRawShape) for simple inputs — use full{ name: z.string() }only for transforms, refinements, or discriminated unionsz.object() - Prefer soft errors over thrown
isError: truefor recoverable failures — LLMs handle soft errors betterMcpError - Prefer stdio for local-only servers — zero infrastructure, single client
- Prefer Streamable HTTP for remote or multi-client servers
- Prefer stateful HTTP (with ) when the server needs progress notifications, resumability, or multi-turn context
sessionIdGenerator - Prefer stateless HTTP () for simple request-response tools
sessionIdGenerator: undefined - Set on every tool — LLMs use them to decide execution safety; treat annotations as untrusted unless from a trusted server
annotations - Use (the underlying
server.server) only whenServerlacks the method you needMcpServer - Use when the tool must return validated structured data alongside text content
outputSchema - Tool names: use format (e.g.
service_action_resource), 1-128 charactersgithub_search_repos
- 简单输入优先使用(
ZodRawShape)—— 仅在需要转换、校验优化或可辨识联合时才使用完整的{ name: z.string() }z.object() - 可恢复故障优先使用软错误,而非抛出
isError: true—— LLM对软错误的处理效果更好McpError - 仅本地使用的服务器优先使用stdio —— 无需基础设施,仅支持单客户端
- 远程或多客户端服务器优先使用Streamable HTTP
- 当服务器需要进度通知、可恢复性或多轮上下文时,优先使用有状态HTTP(带)
sessionIdGenerator - 简单请求-响应工具优先使用无状态HTTP()
sessionIdGenerator: undefined - 每个工具都要设置—— LLM用它来判断执行安全性;除非来自可信服务器,否则将注解视为不可信内容
annotations - 仅当缺少你需要的方法时,才使用
McpServer(底层server.server实例)Server - 当工具需要返回经过校验的结构化数据和文本内容时,使用
outputSchema - 工具命名:使用格式(例如
service_action_resource),长度1-128字符github_search_repos
Guardrails
护栏规则
- Never use the deprecated ,
tool(), orresource()positional-argument methodsprompt() - Never use the deprecated in new servers
SSEServerTransport - Never use the deprecated class directly — always go through
ServerMcpServer - Never expose internal error details to clients — return user-friendly error messages
- Never skip schemas for tool inputs — unvalidated input is a security risk
zod - Never hardcode secrets — use environment variables for API keys and tokens
- Never omit graceful shutdown handling for HTTP servers
- Never run HTTP servers on localhost without DNS rebinding protection (or
createMcpExpressApp()middleware)hostHeaderValidation - Never use — for parameterless tools, omit
inputSchema: nullentirelyinputSchema - Servers MUST validate header on HTTP transport to prevent DNS rebinding; respond with 403 for invalid origins
Origin
- 永远不要使用已弃用的、
tool()或resource()位置参数方法prompt() - 新服务器永远不要使用已弃用的
SSEServerTransport - 永远不要直接使用已弃用的类 —— 始终通过
Server使用McpServer - 永远不要向客户端暴露内部错误详情 —— 返回用户友好的错误信息
- 永远不要省略工具输入的schema —— 未校验的输入存在安全风险
zod - 永远不要硬编码密钥 —— API密钥和令牌使用环境变量存储
- 永远不要省略HTTP服务器的优雅关闭处理
- 永远不要在localhost上运行没有DNS重绑定保护的HTTP服务器(使用或
createMcpExpressApp()中间件)hostHeaderValidation - 永远不要使用—— 无参数工具直接省略
inputSchema: null即可inputSchema - 服务器必须对HTTP传输的头做校验,防止DNS重绑定;无效origin返回403
Origin
Reference routing
参考文档导航
Use the smallest relevant set for the branch of work.
针对你当前的工作分支,使用最相关的最小参考集。
Start here
入门参考
| Reference | When to read |
|---|---|
| Scaffolding a new server from scratch |
| Registering tools, defining Zod schemas, handling tool results |
| Choosing and configuring stdio, Streamable HTTP, or SSE (legacy) |
| 参考文档 | 阅读时机 |
|---|---|
| 从零搭建新服务器脚手架 |
| 注册工具、定义Zod schema、处理工具返回结果 |
| 选择和配置stdio、Streamable HTTP或SSE(遗留)传输层 |
Server capabilities
服务器能力参考
| Reference | When to read |
|---|---|
| Adding resources (static/template URI) or prompts |
| Adding OAuth 2.1, bearer tokens, or custom auth |
| Building MCP clients — connecting, calling tools, reading resources, auth, sampling |
| Managing sessions, sampling, elicitation, resumability, graceful shutdown |
| Durable long-running tool operations — registerToolTask, InMemoryTaskStore, callToolStream |
| Understanding protocol lifecycle, capabilities, message format, security requirements |
| Planning for v2 alpha migration — package split, Standard Schema, ServerContext, framework adapters |
| 参考文档 | 阅读时机 |
|---|---|
| 添加资源(静态/模板URI)或提示词 |
| 添加OAuth 2.1、Bearer令牌或自定义认证 |
| 构建MCP客户端 —— 连接、调用工具、读取资源、认证、采样 |
| 管理会话、采样、启发式交互、可恢复性、优雅关闭 |
| 持久化长时间运行的工具操作 —— registerToolTask、InMemoryTaskStore、callToolStream |
| 了解协议生命周期、能力、消息格式、安全要求 |
| 规划v2 alpha版本迁移 —— 包拆分、标准Schema、ServerContext、框架适配器 |
Build and ship
构建和发布参考
| Reference | When to read |
|---|---|
| Copy-paste working server examples for common patterns |
| Deploying to production (Docker, serverless, cloud) |
| Logging, error handling, rate limiting, monitoring |
| Common mistakes and how to fix them |
| 参考文档 | 阅读时机 |
|---|---|
| 复制常用场景的可运行服务器示例 |
| 部署到生产环境(Docker、Serverless、云服务) |
| 日志、错误处理、限流、监控 |
| 常见错误和修复方案 |
Specification Enhancement Proposals (SEPs)
规范增强提案(SEP)
| Reference | When to read |
|---|---|
| Understanding what SEPs exist and their developer impact |
| Implementing OAuth flows, enterprise auth, URL elicitation, client security |
| Tool naming rules, icons, validation errors, sampling with tools, tasks, tracing |
| JSON Schema dialect, SSE polling, extensions framework, elicitation improvements, MCP Apps |
| Accepted SEPs not yet Final — upcoming breaking changes to prepare for |
| 参考文档 | 阅读时机 |
|---|---|
| 了解现有SEP及其对开发者的影响 |
| 实现OAuth流程、企业认证、URL启发式交互、客户端安全 |
| 工具命名规则、图标、校验错误、工具采样、任务、链路追踪 |
| JSON Schema方言、SSE轮询、扩展框架、启发式交互优化、MCP应用 |
| 已接受但尚未最终落地的SEP —— 即将到来的破坏性变更提前准备 |
Why migrate to v2?
为什么要迁移到v2?
v2 ( + ) shipped in early 2026. Key benefits over v1:
@modelcontextprotocol/server@modelcontextprotocol/client- Structured handler context — ,
ctx.mcpReq.log(),ctx.mcpReq.elicitInput()replace manualctx.mcpReq.requestSampling()callsextra.sendRequest() - Framework adapters — and
createMcpExpressApp()from dedicated packages instead of manual wiringcreateMcpHonoApp() - Standard Schema support — use Zod v4, Valibot, or ArkType for tool schemas (not locked to Zod)
- JSON Schema 2020-12 by default — v1 defaults to Draft-7 via ; v2 uses native
zod-to-json-schemaz.toJSONSchema() - Better auth — client middleware system (,
withOAuth,withLogging), grant-agnosticapplyMiddlewares, discovery cachingprepareTokenRequest() - Smaller bundles — split packages mean you only install what you use
- ESM-only — cleaner module resolution, no CJS baggage
Community adoption is still early (Q1 2026 release). Most production servers remain on v1.x. See for the full source-verified migration guide, or use for new v2 projects.
references/guides/v2-migration.mdbuild-mcp-sdk-v2v2( + )于2026年初发布。相比v1的核心优势:
@modelcontextprotocol/server@modelcontextprotocol/client- 结构化处理上下文 —— 、
ctx.mcpReq.log()、ctx.mcpReq.elicitInput()替代手动的ctx.mcpReq.requestSampling()调用extra.sendRequest() - 框架适配器 —— 来自专用包的和
createMcpExpressApp(),无需手动配置createMcpHonoApp() - 标准Schema支持 —— 工具schema支持Zod v4、Valibot或ArkType(不绑定Zod)
- 默认使用JSON Schema 2020-12 —— v1通过默认使用Draft-7;v2使用原生
zod-to-json-schemaz.toJSONSchema() - 更好的认证能力 —— 客户端中间件系统(、
withOAuth、withLogging)、授权无关的applyMiddlewares、发现缓存prepareTokenRequest() - 更小的包体积 —— 拆分包意味着你只需要安装用到的部分
- 仅支持ESM —— 更简洁的模块解析,没有CJS遗留问题
目前社区采用率还比较低(2026年Q1发布),大多数生产服务器仍然使用v1.x版本。完整的经过源码验证的迁移指南参见,新的v2项目可以使用。
references/guides/v2-migration.mdbuild-mcp-sdk-v2Compatibility note
兼容性说明
This skill targets v1.x (stable, branch). Source-verified against the TypeScript SDK repository.
@modelcontextprotocol/sdkv1.xKey 2025-11-25 spec additions: icons for tools/resources/prompts, tool name guidance (SEP-986), URL-mode elicitation (SEP-1036), tool calling in sampling (SEP-1577), experimental tasks (SEP-1686), JSON Schema 2020-12 as default dialect (SEP-1613), extensions framework (SEP-2133).
本skill针对 v1.x(稳定版,分支),已对照TypeScript SDK仓库源码验证。
@modelcontextprotocol/sdkv1.x2025-11-25版本协议核心新增内容:工具/资源/提示词图标、工具命名规范(SEP-986)、URL模式启发式交互(SEP-1036)、采样中的工具调用(SEP-1577)、实验性任务(SEP-1686)、默认使用JSON Schema 2020-12方言(SEP-1613)、扩展框架(SEP-2133)。