不改一行代码接入外部工具:claude-code-from-scratch MCP协议集成完全指南
【免费下载链接】claude-code-from-scratchBuild your own Claude Code from scratch. 🔍 Claude Code 开源了 50 万行代码,读不动?用 ~5000 行 TypeScript / Python 从零复现核心架构,11 章分步教程带你理解 coding agent 精髓项目地址: https://gitcode.com/gh_mirrors/cl/claude-code-from-scratch
MCP 协议是 Anthropic 推出的开放标准,让 AI 助手可以即插即用地连接外部工具。开源教程项目claude-code-from-scratch用约 5000 行 TypeScript / Python 代码从零复现了 Claude Code 的核心架构,其中第 12 章专门拆解了MCP 集成:只需在配置文件里声明一个服务器地址,Agent 就能自动发现并调用外部工具——数据库、Slack、GitHub 统统可以接进来,全程不动一行 Agent 源码。
上图可以这样理解:Agent 是中心的行星,MCP 服务器像卫星一样围绕它接入,工具通过标准轨道(JSON-RPC)与中心通信。
为什么需要 MCP 协议:工具不再写死
在没接 MCP 之前,Agent 的工具全部写死在 src/tools.ts 里——想加一个新工具,就得改源码、重新编译、重新部署。这对一个要长期使用的编码助手来说非常不灵活。
MCP(Model Context Protocol)解决了这个问题:把"工具"从代码里搬出来,变成一个独立运行的服务器进程。Agent 负责"问它有什么工具、替用户调用",服务器负责"干活"。两者之间只靠标准协议通信,谁升级都不影响谁。
🎯 核心思路一句话:spawn 子进程 → JSON-RPC 握手 → 发现工具 → 前缀注册 → 透明路由。
MCP 客户端的五步工作流程
读完 docs/12-mcp.md 你会发现,整个 MCP 客户端的实现短得惊人——TypeScript 演示版只有约 43 行。它的工作流程分五步:
| 步骤 | 动作 | 对应协议方法 |
|---|---|---|
| 1️⃣ 启动 | 用子进程启动 MCP 服务器,接管 stdin/stdout | — |
| 2️⃣ 握手 | 交换协议版本与能力,确认双方就绪 | initialize+notifications/initialized |
| 3️⃣ 发现 | 询问服务器提供哪些工具及其参数格式 | tools/list |
| 4️⃣ 注册 | 给工具名加上mcp__服务器名__前缀,并入工具表 | — |
| 5️⃣ 路由 | 模型调用工具时,按前缀转发回对应服务器 | tools/call |
关键点在于传输方式:所有通信都走子进程的标准输入输出(stdio),每行一个 JSON-RPC 2.0 消息。不需要开端口、不需要管 URL、不需要心跳检测——进程一退出,连接自然终结,天然零配置。
完整的生产级实现见 src/mcp.ts(约 277 行,补上了配置加载、多服务器管理、超时和错误处理),Python 版对应 python/mini_claude/mcp_client.py。
一分钟上手:跑通 MCP 集成 Demo
每个代码章都配了一条命令即可运行的演示,MCP 这章也不例外,而且不需要 API key(本地 mock 模型驱动):
git clone https://gitcode.com/gh_mirrors/cl/claude-code-from-scratch cd claude-code-from-scratch npm install && npm run build node steps/run.mjs 12运行时会看到模型调用了来自外部 MCP 服务器的add工具:
$ node steps/run.mjs 12 you: Use the add tool to compute 17 + 25. → mcp__demo__add({"a":17,"b":25}) 17 + 25 = 42.这个42不是模型编的,而是真的有一个独立子进程算出来再传回的。提供这个add工具的示例服务器就在 steps/mcp-demo-server.mjs 里,不足 40 行,值得通读一遍——它演示了 MCP 服务器端需要应答的全部消息。
几个实用参数:
--diff:只看第 12 章比上一章多写的代码,学习增量最快--py:切换 Python 版实现--live:读取.env里的 key,连真实模型用自己的 prompt 试
接入自己的工具服务器:配置怎么写
想接真实的外部工具,只需在配置文件里声明服务器。支持三个位置,合并后同名服务器"后读覆盖先读":
| 配置文件 | 作用域 |
|---|---|
~/.claude/settings.json | 用户级,所有项目生效 |
.claude/settings.json(项目内) | 项目级 |
.mcp.json(项目根目录) | MCP 专用,格式相同 |
配置格式长这样:
{ "mcpServers": { "filesystem": { "command": "npx", "args": ["@modelcontextprotocol/server-filesystem", "/tmp"] }, "github": { "command": "npx", "args": ["@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "ghp_xxx" } } } }保存后无需改任何代码,Agent 在首次对话时会自动连接这些服务器并把它们的工具并入工具表。
三段式命名规范:一个名字解决两个问题
所有 MCP 工具注册时都会被改写成mcp__服务器名__工具名的三段式格式,例如filesystem服务器的read_file变成mcp__filesystem__read_file。
这个看似简单的命名约定同时解决两个问题:
- 防冲突:不同服务器可以有同名工具,前缀隔离后互不干扰
- 免映射表路由:Agent 看到调用名,拆出中间一段就知道该转发给哪个服务器,一行
if判断 + 一行转发搞定
对 Agent 循环来说,MCP 工具和内置工具完全没区别——都是名字 + 参数 schema + 执行函数。模型甚至不知道自己调的是"外部"工具。
关键设计决策:为什么这么做
docs/12-mcp.md 里专门讨论了几个值得新手学习的设计选择:
❓ 为什么用 stdio 而不是 HTTP?零端口管理、进程生命周期自动绑定到父进程,子进程退出时所有挂起请求自动失败,不存在连接泄漏。HTTP 方案要处理端口冲突、进程发现、心跳检测,复杂度高一个数量级。
❓ 为什么连接设 15 秒超时?MCP 服务器常用npx启动,首次运行要下载 npm 包(一般 3-8 秒)。15 秒足够覆盖,又不至于让用户干等。超时后静默跳过该服务器,其他工具照常工作。
❓ 为什么"懒连接"?Agent 启动时不连,首次真正需要时才连。用户只是问一句"这个函数什么意思"时,零 MCP 开销。
❓ 为什么不用官方 SDK?直接用原始 JSON-RPC 写,整个通信逻辑约 60 行,零依赖。教学项目更重要的是让你看到协议本身的每一层细节。
与真实 Claude Code 的 MCP 实现对比
| 维度 | Claude Code | mini-claude 教程版 |
|---|---|---|
| 传输协议 | stdio + SSE | 仅 stdio(覆盖 95% 场景) |
| 客户端 | SDK 内置封装 | 原始 JSON-RPC,无依赖 |
| 工具发现 | 支持运行时动态刷新 | 一次性发现 |
| 配置来源 | 多源 + 企业策略下发 | settings.json + .mcp.json |
| 错误处理 | 重试 + 降级 | 静默跳过失败服务器 |
| 连接时机 | 首次对话懒加载 | 首次对话懒加载 |
教程版有意做了简化,但核心机制(stdio 握手、三段式命名、懒加载、透明路由)与真实 Claude Code 完全一致——这正是"读不动 50 万行代码"时用 5000 行学架构的价值。
小结
- MCP 协议 = AI 助手接入外部工具的标准插座,配置即接入,不改一行 Agent 代码
- 五步流程:spawn → 握手 → 发现 → 前缀注册 → 透明路由
node steps/run.mjs 12一条命令即可无 API key 跑通完整演示- 想深挖细节,直接读 docs/12-mcp.md 对照 src/mcp.ts 源码
💬 扫码加入「AI Agent 工坊」交流群,和其他读者一起讨论 coding agent 与 MCP 实践。
【免费下载链接】claude-code-from-scratchBuild your own Claude Code from scratch. 🔍 Claude Code 开源了 50 万行代码,读不动?用 ~5000 行 TypeScript / Python 从零复现核心架构,11 章分步教程带你理解 coding agent 精髓项目地址: https://gitcode.com/gh_mirrors/cl/claude-code-from-scratch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考