ARTICLE · 1001911
MCP 是什么?让 AI 连接工具之前,先看懂这条协议

你让 AI 总结一篇文章,它张口就来;再问一句“帮我查一下项目里本周还没关闭的问题?”,它却回答:我没有访问权限。
这不是模型突然变笨了。它不知道你的仓库地址,没有 GitHub token,也没有一条可以抵达 GitHub 的连接。要回答这个问题,AI 应用需要把外部能力接进来,再把结果交回模型。
MCP(Model Context Protocol)约定的,正是这条连接该如何发生。

问题不在于模型不愿意回答,而在于它没有通往外部系统的连接。
01 一次调用,先找到三方
MCP 不是“模型直接连数据库”。一次调用至少经过三个角色:
01 · HOST
AI 应用本身,例如 Claude Desktop 或你写的 AI 应用。它接收问题,协调模型和连接。
02 · CLIENT
Host 创建的协议连接器。一个 Client 维护与一个 Server 的连接,负责发送 MCP 请求。
03 · SERVER
能力提供者。它读取文件、查询数据库或调用 GitHub API,再把结果按 MCP 格式返回。

Host 接收问题,Client 维护连接,Server 提供能力。
模型可以提出“我要调用 search_issues”,但真正发出请求的是 Client,真正接触 GitHub 的是 Server。
02 它们靠什么互相听懂?
Host、Client 和 Server 不会互相发送一段“随便写的文字”,而是交换遵循 JSON-RPC 2.0 的 JSON 消息。可以把它想成一张快递单:

一张“快递单”至少要写清楚做什么、带什么参数,以及如何对应回复。
method写“要做什么”; params写“需要哪些参数”; id让请求和回复能够一一对应。
Client 先用 tools/list 询问“你有哪些工具?”
● ● ●{ "jsonrpc": "2.0", "method": "tools/list", "id": 1}Server 返回工具描述和输入规则,Host 再把它们提供给模型(下面截取其中一个工具描述):
● ● ●{ "name": "search_issues", "description": "查找仓库 issue", "inputSchema": { "type": "object", "properties": { "repository": { "type": "string" }, "state": { "type": "string" }, "created_after": { "type": "string" } }, "required": ["repository", "state", "created_after"] }}模型选好工具后,Client 再发出真正的调用(日期以 2026-08-24 为示例):
● ● ●{ "jsonrpc": "2.0", "method": "tools/call", "id": 2, "params": { "name": "search_issues", "arguments": { "repository": "your-project", "state": "open", "created_after": "2026-08-24" } }}Server 处理后,用同一个 id 返回 JSON-RPC 响应;SDK 再把其中的 result 映射成 CallToolResult。双方遵守同一份消息格式,和 Server 使用哪种语言无关。

先发现工具,再按输入规则填参数,最后发起调用。
03 把“查问题”走一遍
用户输入:帮我查一下项目里本周还没关闭的问题。
Host 让 Client 先获取 tools/list,再把工具清单和用户问题提供给模型,模型选出search_issues。Client 发送 tools/call,传入项目名、状态和时间范围。Server 使用自身配置的凭证(如果目标系统需要),调用问题管理系统,把列表整理成 CallToolResult。Host 把结果放回模型上下文,模型再用自然语言回答。

同一个问题经过模型、Client、Server 和外部系统,最后回到模型上下文。
在这个 GitHub 示例里,访问凭证由 Server 侧管理,不需要放进模型消息;结果中是否包含敏感数据,取决于 Server 的返回内容。
04 用 TypeScript 看懂 Client
用官方 Everything Server 做练习。下面的三行调用,正好对应“连接、发现、调用”;完整 import 和 transport 初始化放在仓库示例中。

Server 提供工具,Client 通过三个 SDK 方法完成连接、发现和调用。
● ● ●npx -y @modelcontextprotocol/server-everything● ● ●await client.connect(transport);const { tools } = await client.listTools();const result = await client.callTool({ name: "echo", arguments: { message: "Hello MCP" },});connect 完成握手,listTools 获取工具描述,callTool 发出实际调用。把这些方法和 Server 的注册代码对照起来,就能看到协议如何落到 SDK。
什么时候值得用 MCP?

工具就在应用进程内,Function Calling 往往够用;能力在远端或由独立团队维护,MCP 更合适。
如果工具就在自己的应用进程里,模型用 Function Calling 产出函数名和参数,再交给内部工具或 Skill 执行,通常已经够用。MCP 更适合下面几种情况:
能力在远端:要连接 GitHub、数据库或 SaaS,而不是当前进程里的函数; 由第三方或独立团队维护:Server 可以单独升级,不必跟着每个 Host 一起发布; 需要长期常驻:Server 自己管理凭证、缓存、限流和审计,多个客户端可以复用; 工具需要动态发现:Host 通过 tools/list获取最新能力,而不是把工具清单写死。
所以 MCP 不是 Function Calling 的替代品:模型仍然可以用 Function Calling 做选择,MCP 可以把选择跨进程或跨网络送到真正提供能力的 Server。
回到最初的问题
AI 能查到 issue,不是模型越过了权限边界,而是 Host、Client 和 Server 按 MCP 把一次调用接了起来。MCP 统一连接方式,授权、确认和审计仍由业务系统负责。
下一次,继续拆一条技术链路

扫码关注,获取后续文章与代码实验