从零构建自己的 MCP Server:2026年 Model Context Protocol 实战指南
💡 工具推荐:开发 MCP Server 时,用 Evergreen Tools 的 JSON格式化工具 校验 mcpServers 配置、正则表达式测试工具 调试 slugify 逻辑、Base64编解码 处理鉴权头,都是 Server 开发的好帮手!
MCP(Model Context Protocol)在 2026 年已经成为 AI 代理连接外部工具的「USB-C 接口」。Anthropic 把它开源后,OpenAI、Google、Microsoft 相继原生支持,Claude、Cursor、Windsurf 等宿主全部兼容。本文用一个真实可运行的例子,从零构建你自己的 MCP Server——理解架构、写第一个工具、注册给宿主、处理错误。全文代码可直接运行。
从 N x M 到 N + M:一个协议连接所有工具
一、MCP 到底解决了什么问题
MCP 之前,每个模型 x 每个工具都需要一条自定义连接器——Claude 连 Slack、连 GitHub、连 Jira,各写一套(代码示例1 的 N x M 问题)。MCP 之后,模型宿主(Claude、Cursor 等)统一说 MCP 协议,工具方只需暴露一个 MCP Server。连接数从 N x M 降到 N + M。2026 年主流模型和 IDE 全部原生支持,意味着你写一个 Server,所有宿主都能调用。
# The N x M problem MCP solves
# Before MCP: every model x every tool = custom connector
models = ["Claude", "GPT", "Gemini"]
tools = ["Slack", "GitHub", "Jira", "Notion"]
connectors_before_mcp = len(models) * len(tools) # 12 custom integrations
# After MCP: model hosts speak one protocol, tools expose one server
# models -> MCP host -> MCP protocol -> MCP servers
connectors_after_mcp = len(models) + len(tools) # 7 total二、最小可运行的 Server:30 行搞定
用官方 TypeScript SDK 写一个 MCP Server 只需要 30 行(代码示例2):创建 McpServer、用 server.tool() 注册工具、连接 StdioServerTransport。示例中的 word_count 工具接收一段文本,返回单词数——麻雀虽小,五脏俱全:输入 schema、异步处理、标准化输出。跑起来后,任何 MCP 兼容宿主都能直接调用。
# Minimal MCP server with the official TypeScript SDK
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({
name: "evergreen-utils",
version: "1.0.0",
});
server.tool(
"word_count",
{ text: "string" },
async ({ text }) => ({
content: [{ type: "text", text: String(text.trim().split(/\s+/).length) }],
}),
);
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("MCP server ready on stdio");三、把 Server 注册给宿主
写完 Server 只是第一步,还要让宿主知道去哪找它。代码示例3 展示了三种主流宿主的注册方式:Claude Desktop/Code 写在 ~/.claude.json 的 mcpServers 字段,Cursor 写在 ~/.cursor/mcp.json,Windsurf 写在 ~/.codeium/windsurf/mcp_config.json。结构完全一致:command(启动命令)、args(参数)、env(环境变量)。注册后重启宿主即可发现新工具。
# Register your server so Claude / Cursor / Windsurf can find it
# ~/.claude.json (Claude Desktop / Code)
{
"mcpServers": {
"evergreen-utils": {
"command": "node",
"args": ["/path/to/server.mjs"],
"env": {}
}
}
}
# Cursor: ~/.cursor/mcp.json (same shape)
# Windsurf: ~/.codeium/windsurf/mcp_config.json (same shape)四、生产级 Server 的四个要点
第一,输入校验:MCP 的 schema 只做基础类型检查,业务规则要自己在 handler 里校验,非法输入返回 isError: true(代码示例4)。第二,日志走 stderr:MCP 的 stdio 传输用 stdout 传协议数据,调试日志必须打到 stderr,否则会污染协议流。第三,幂等设计:代理可能重试调用,工具应该是幂等的。第四,超时与限流:给外部 API 调用加超时,避免代理卡死。
# Robust handler: validate input, fail loudly, log for debugging
server.tool(
"slugify",
{ title: "string", max_len: "number?" },
async ({ title, max_len = 60 }) => {
if (!title || title.length === 0) {
return { content: [{ type: "text", text: "ERROR: title is required" }],
isError: true };
}
const slug = title.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "")
.slice(0, max_len);
console.error("[slugify]", { input: title, output: slug }); // debug log on stderr
return { content: [{ type: "text", text: slug }] };
},
);五、常见坑与排查
最常见的坑有三个:一是 stdout 被 console.log 污染,导致宿主「连接失败」——所有调试输出改用 console.error;二是注册路径写错,宿主找不到 Server——检查 JSON 语法和绝对路径;三是工具名冲突,两个 Server 暴露同名工具时宿主行为不确定——用命名空间前缀(如 evergreen_*)规避。排查时先单独运行 Server 看 stderr 日志,再用宿主自带的 MCP 调试面板验证。
六、2026 年的下一步:从工具到 Agent 生态
MCP 在 2026 年的进化方向是:从「集成标准」走向「运行时」——MCP Apps 打包格式、Agent-to-Agent 传输扩展、Linux 基金会的治理。对你来说,现在动手构建第一个 MCP Server 正是时候:它不仅是技术练习,更是进入下一代 AI 工具生态的入场券。先跑通本文的最小例子,再逐步加上鉴权、缓存、观测,你的工具就会成为 AI 代理能力版图的一部分。
进入下一代 AI 工具生态的入场券
📌 常见问题 FAQ
MCP 是什么?
Model Context Protocol,Anthropic 开源的开放协议,统一 AI 模型与外部工具/数据源的连接方式。2026 年 OpenAI、Google、Microsoft 及主流 IDE 均已原生支持。
MCP 解决了什么问题?
解决了 N x M 集成问题:每个模型 x 每个工具都要写自定义连接器。MCP 之后模型宿主统一说一种协议,工具只需暴露一个 MCP Server。
写一个 MCP Server 需要多少代码?
用官方 SDK 约 30 行即可运行:创建 McpServer、server.tool() 注册工具、连接 StdioServerTransport。
如何让 Claude、Cursor 使用我的 MCP Server?
在宿主配置文件的 mcpServers 字段注册:Claude 用 ~/.claude.json,Cursor 用 ~/.cursor/mcp.json,Windsurf 用 ~/.codeium/windsurf/mcp_config.json,结构都是 command/args/env。
MCP Server 最常见的坑是什么?
stdout 被 console.log 污染导致协议流损坏(调试日志必须走 stderr)、注册路径写错、工具名冲突。排查时先单独运行 Server 看 stderr 日志。