为什么大模型需要 MCP?一篇讲透 Agent 工具的 USB-C 接口
📮 本系列首发于公众号「Go2AI之路」,MCP 系列聚合目录。上一个系列「AI 模拟面试教练」见 系列目录。
上一系列,我们用 Function Calling 加大模型造了一个能出题、会追问、自动打分的 AI 面试教练。做到第八篇你会发现一个尴尬的事实:Agent 的能力越强,手上挂的工具越多——查数据库、读简历、发飞书消息,每接一个工具,就要在代码里手写一遍「工具声明 JSON + 调用分发 + 结果回填」。
三家模型厂商三种格式,五个桌面应用五种配置。工具明明一样,对接却要重来。
MCP(Model Context Protocol)就是来终结这种重复的。这一篇讲清楚它解决什么问题、协议本质是什么,下一篇我们用 Go 手写一个最小 MCP Server——你会发现它远没有听起来高深。
一、Function Calling 治好了「模型不会调工具」,却留下三个痛点
先公平地说:Function Calling 本身是个伟大的发明。它让模型学会在对话中「举手」:我要调用 query_interview_history,参数是 {"limit": 5}。
但把它放进真实工程,三个痛点会反复出现:
格式私有化。 工具清单用 JSON Schema 描述,可「模型举手」的报文格式各家自定。你在 OpenAI 适配层写好的工具调用循环,换个国产兼容端点就要回归测试一遍——我们给 DeepSeek 做降级处理时深有体会。
工具无法被发现。 Function Calling 的工具列表是你在代码里硬编码的。换一个宿主(桌面 Agent、IDE 插件、聊天软件),同一批工具要重新注册一遍。工具没有「插上就能用」的标准插座。
上下文接入无协议。 工具调用结果怎么回填对话、资源(文件、数据库记录)怎么暴露给模型,全靠各宿主自己发明轮子,行为不可预期。
一句话总结:Function Calling 解决了「单次怎么调」,没解决「工具怎么标准化地生产、发现和接入」。
二、MCP 是什么:给工具世界定一个 USB-C 接口
MCP 是 Anthropic 于 2024 年 11 月开源的开放协议,用一句话概括:它规定了「宿主应用 ↔ 模型 ↔ 工具/数据源」之间的通信标准,让任何工具只要实现一次 MCP,就能被所有支持 MCP 的宿主(Claude Desktop、Cursor、各类 Agent 框架,以及我们自己写的程序)直接调用。
类比最直观:
| 标准化之前 | 标准化之后 | |
|---|---|---|
| 手机充电 | 每家一根专用线 | USB-C,一线通吃 |
| 模型调工具 | 每个宿主手写对接 | MCP,一次实现处处可用 |
| 本质 | N×M 对接 | N+M 对接 |
架构上是经典的三方角色:
- Host(宿主):用户真正打开的应用,比如 IDE、聊天窗口;
- Client:宿主内嵌的协议客户端,一个 server 对应一个 client 连接;
- Server:暴露能力的进程/服务,标准实现里它就是个读 stdin、写 stdout 的普通程序。
注意最后这点:一个 MCP Server 本质上就是个黑白字符进出的进程。这就是下一篇我们能用纯 Go、零依赖手写出来的原因。
三、握手实测:四条 JSON 看懂协议本质
空讲不如抓包。我们把下一篇要写的最小 server 提前跑起来,用管道模拟宿主发消息——完整的面试 handshake 长这样(真实输出,未删减字段):
第 1 条:initialize——互相报名字
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"fake-host","version":"0.0.1"}}}
{"jsonrpc":"2.0","id":1,"result":{"capabilities":{},"protocolVersion":"2025-06-18","serverInfo":{"name":"minimal-mcp-server","version":"0.1.0"}}}
第 2 条:notifications/initialized——没有 id 的通知
{"jsonrpc":"2.0","method":"notifications/initialized"}
这条消息服务端必须处理、绝不能回复——JSON-RPC 里凡是没有 id 的就是通知,回复了反而会让宿主对不上账。这个细节是手写实现最容易踩的坑,我们下一篇的代码里专门用注释标了出来。
第 3 条:tools/list——声明「我会干什么」
{"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"echo","description":"回显输入的文本……","inputSchema":{"type":"object","properties":{"text":{"type":"string"}},"required":["text"]}}]}}
宿主拿到这份清单后,会原样转述给大模型。也就是说:模型的「工具视野」= server 在 tools/list 里声明的东西。安全边界天然清晰——没声明的,模型根本看不见。
第 4 条:tools/call——模型决定后的实际调用
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"echo","arguments":{"text":"你好,MCP!"}}}
{"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"你好,MCP!"}]}}
看明白了吗?MCP 不神秘,就是带约定的 JSON-RPC 2.0:一行一个 JSON,stdin 进、stdout 出,错误码沿用 -32601(方法不存在)、-32602(参数错误)这些标准编号。如果你写过 LSP(语言服务器协议)的对接,会有强烈的既视感——两者几乎是同一个设计哲学在不同领域的落地。
四、收藏向:MCP 三件套对照表
MCP 的能力不止工具。官方把 server 能暴露的东西分为三类,一张表记牢:
| 能力 | 方法前缀 | 干什么用 | 类比 |
|---|---|---|---|
| Tools | tools/* |
模型可调用的动作(查询、发送、计算) | 函数 |
| Resources | resources/* |
暴露给模型读的数据(文件、记录、日志) | 只读数据库视图 |
| Prompts | prompts/* |
预置的提示词模板,供用户/模型选用 | 代码片段 snippet |
三者权限模型也不同:Tools 是「模型主动调」,Resources 偏向「用户或模型按需读」,Prompts 则是「人先从菜单里挑」。判断某个能力该做成哪一类,就看触发它的是模型、用户还是两者皆可。
五、Go 开发者现在能做什么
协议是语言无关的,官方提供了多种语言的 SDK,Go 生态里也有社区实现。但我们的路线和上一系列一致:先抛开 SDK 手写一遍,理解本质,再用轮子。
下一篇《不写一行 SDK,200 行 Go 手写 MCP Server 全解析》会带你在 200 行以内实现一个完整可跑的 server:握手、通知处理、工具声明、工具调用,外加端到端测试。之后我们会把面试教练的 SQLite 历史库包装成 MCP 服务,让任何支持 MCP 的 Agent 都能直接查询面试报告——两个系列在此交汇。
工具的 USB-C 时代才刚刚开始,现在上车,正是时候。
相关阅读:MCP 系列聚合目录 · 第二篇:200 行 Go 手写 MCP Server
版本说明
- MCP 协议版本:2025-06-18(2026-11-12 核对自 modelcontextprotocol.io:该版现为 Older Stable,当前最新规范为 2026-07-28,已移除初始化握手并改为无会话协议;本文的握手与 stdio 流程适用于 2025-06-18 / 2025-11-25 修订版及仍支持版本协商的宿主。规范地址:modelcontextprotocol.io/specification)
本文系 AI 辅助生成,内容已经人工核对,如有错误欢迎评论区留言指正。
- 《Go 程序设计语言》(Go 语言圣经,机械工业出版社) —— Go 官方团队出品,公认入门第一书
- 《Go 语言实战》(异步图书,人民邮电出版社) —— 实战导向,面试前巩固工程手感
- 《Go 语言编程之旅:一起用 Go 做项目》(博文视点,电子工业出版社) —— 项目驱动入门,从零写出完整应用
- Keychron K1Max 矮轴机械键盘(Mac/Win 双系统,QMK/VIA 开源改键) —— 轻薄矮轴 + 开源固件,程序员桌面常客
- 罗技 MX Master 3S 无线鼠标(Flow 跨屏,静音电磁滚轮) —— 人体工学设计,写代码一整天手不酸
以上链接含京东联盟推广代码;通过链接购买本站可能获得少量佣金,不影响你的购买价格。
每周更新 Go + AI 应用开发实战:AI 面试官完整项目、MCP、Agent 工程化,完整源码随文章首发。
微信扫码,或搜索「Go2AI之路」关注,第一时间获取系列更新与源码,不再错过任何一篇。