LangGraph 系列 5 和 6 已经介绍了本地 Tool、Function Calling 与工具调用循环。Python 函数、Runnable 和 BaseTool 都可以交给 Agent 使用,但这些工具通常和应用代码放在同一个项目中。另一个应用想复用工具时,需要重新复制代码、安装依赖并处理参数格式。
从本文开始进入独立的 MCP 系列,讨论如何把工具、资源和提示词变成可以被不同语言、进程和 Agent 客户端复用的标准能力。
MCP 解决的是能力标准化和跨应用复用问题。服务端按照统一协议公开工具、资源和提示词,支持 MCP 的客户端就能发现并调用这些能力,而不需要理解服务端使用 Python、Java 还是其他语言实现。
1. MCP 是什么
MCP 的全称是 Model Context Protocol,即模型上下文协议。它定义了 AI 应用与外部能力之间的通信方式。
MCP 不是模型,也不是 Agent 框架。它不负责决定什么时候调用工具,也不负责生成最终回答。它负责描述和传输能力,让客户端能够完成下面这些操作:
- 发现服务端提供了哪些 Tool。
- 读取服务端公开的 Resource。
- 获取服务端维护的 Prompt。
- 按统一 Schema 传入参数并得到结果。
- 在初始化阶段协商双方支持的能力。
协议只规定通信规则,不限制实现语言。因此,Python Agent 可以调用 Java MCP Server,桌面应用也可以调用同一个网络 MCP Server。
2. MCP 与本地 Tool、Function Calling、HTTP API 的区别
这几个概念经常同时出现,但职责不同。
本地 Tool 是应用进程中的可调用函数。Function Calling 是模型生成结构化工具请求的能力。普通 HTTP API 是服务之间约定的网络接口。MCP 则在 JSON-RPC 基础上统一了能力发现、调用、通知、生命周期和传输方式。
一次完整调用可能同时使用它们:
用户问题
→ 模型通过 Function Calling 选择工具
→ Agent 调用 MCP Client
→ MCP Client 调用远端 MCP Tool
→ Tool 结果返回 Agent
→ 模型生成最终回答
所以 MCP 不取代 Function Calling。模型仍然需要产生工具调用请求,只是工具可能来自独立 MCP Server。
3. Host、Client 和 Server
MCP 使用 Host、Client、Server 三层架构。
下图中的蓝色虚线框表示同一个 Host 进程。Host 在内部创建多个 Client 实例,每个 Client 只维护与一个 Server 的独立会话。

Client 与 Server 之间传输的是双向 JSON-RPC 消息,不是单向函数调用。Host 负责跨 Server 编排,Server 之间没有直接通信通道。
3.1 Host
Host 是用户直接使用的 AI 应用,例如 IDE、桌面助手或 Agent 应用。它负责:
- 创建和管理 MCP Client。
- 控制哪些 Server 可以连接。
- 管理授权、用户同意和安全策略。
- 把 MCP 返回的能力交给模型或 Agent。
- 决定哪些上下文可以发送给服务端。
3.2 Client
Client 由 Host 创建,负责与某一个 Server 建立连接、协商能力和收发协议消息。
一个 Client 在一个会话中对应一个 Server。Host 如果连接三个 Server,通常会维护三个彼此隔离的 Client 连接。这样,一个 Server 不能直接查看另一个 Server 的通信内容。
3.3 Server
Server 提供具体能力。它可以是客户端临时启动的本地子进程,也可以是独立运行的网络服务。
Server 只应该获得完成当前调用所需的信息。它不会因为接入 MCP 就自动看见完整聊天记录,也不能直接访问其他 MCP Server。跨服务编排仍由 Host 或 Agent 负责。
4. MCP 基于 JSON-RPC
MCP 使用 JSON-RPC 2.0 编码消息。常见消息分为请求、响应、通知和错误。
一个请求包含方法、参数和请求 ID:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
响应使用相同 ID 与请求配对:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": []
}
}
通知没有 id,发送方不等待对应响应。错误响应则包含错误代码和说明。
业务代码通常不需要手写这些 JSON。MCP SDK 会完成编码、请求 ID 管理和结果转换,但理解底层结构有助于排查初始化失败、方法不存在和参数不匹配。
5. MCP 连接的生命周期
一次 MCP 会话不是连接成功后立即调用 Tool,而是经过明确的初始化过程。

主要阶段如下:
- Client 发送 initialize,声明协议版本和自身能力。
- Server 返回支持的协议版本、Server 信息和能力。
- Client 发送 notifications/initialized 初始化完成通知。
- 双方进入正常通信,可以列出或调用能力。
- 使用底层传输关闭连接;有状态 HTTP Session 还可以通过 DELETE 请求显式终止。
能力协商很重要。Server 只有声明支持 Tools,Client 才能按照协议使用工具相关方法;Resources、Prompts、Sampling 等能力也遵循相同原则。
MCP 没有定义专用的关闭协议消息。stdio 通过关闭输入流并结束 Server 子进程完成关闭,HTTP 则关闭相关连接。每个请求还应该设置超时;超时后停止等待,并在适用时发送取消通知,避免连接长期占用资源。
6. Server 提供的三种核心能力
6.1 Tools
Tool 表示可以执行的操作,例如计算、查询数据库或读取业务系统。Tool 包含名称、说明和参数 Schema,通常由模型或 Agent 决定是否调用。
Tool 可能产生副作用。删除文件、发送消息或修改数据库之前,Host 应该进行权限控制或用户确认。
6.2 Resources
Resource 表示可以读取的数据,例如配置说明、文件内容或固定知识。它通过 URI 标识,例如:
guide://mcp
Resource 更接近“读取什么”,Tool 更接近“执行什么”。具体由客户端决定怎样把 Resource 放入模型上下文。
6.3 Prompts
Prompt 是服务端公开的可复用提示词模板。客户端可以列出 Prompt,并传入参数获得消息内容。
Prompt 不会自动执行模型,也不是系统提示词的唯一来源。它只是 MCP Server 提供的一种可发现能力。
7. Client 侧能力
协议还定义了 Roots、Sampling 和 Elicitation 等 Client 能力。
- Roots:客户端向 Server 声明允许访问的文件系统根目录。
- Sampling:Server 请求 Host 使用模型生成内容,最终控制权仍在 Host。
- Elicitation:Server 请求用户补充信息或确认操作。
本文只明确这些能力的位置,不编写实现。它们也不是每个 MCP Client 和 Server 都必须支持的功能,是否可用取决于初始化阶段的能力协商。
8. stdio 传输
stdio 使用标准输入和标准输出传输 JSON-RPC 消息。
它的真实进程关系是:Client 启动一个独立 MCP Server 子进程,然后通过子进程的 stdin 和 stdout 通信。两者不是同一个进程。
Host 进程
└── MCP Client
└── 启动 MCP Server 子进程
├── stdin 接收 JSON-RPC
├── stdout 返回 JSON-RPC
└── stderr 输出日志
stdio 适合本机桌面应用、命令行工具和单用户场景。Client 负责 Server 子进程的启动和关闭,不需要提前监听端口。
使用 stdio 时有一条非常重要的规则:Server 不能向 stdout 输出普通日志,因为任何非 MCP 消息都会破坏协议流。日志应该写到 stderr。
每条 JSON-RPC 消息使用换行符分隔,消息本身不能包含未转义的换行。Client 写入 Server stdin 的内容也必须是有效 MCP 消息。
9. Streamable HTTP 传输
Streamable HTTP 适合独立运行和网络访问。Server 必须提供单一 MCP 端点,例如:
http://127.0.0.1:18100/mcp
Client 发送的每一条 JSON-RPC 消息都使用一次新的 HTTP POST 请求。POST 请求需要同时声明能够接收 application/json 和 text/event-stream;Server 可以直接返回一个 JSON 对象,也可以通过 SSE 返回多个消息。
Client 还可以尝试使用 GET 建立服务端到客户端的 SSE 流。如果 Server 不提供这种独立 SSE 流,应返回 405 Method Not Allowed,不能把 GET 描述成所有实现都必须提供的流式能力。
这意味着 Streamable HTTP 可以使用 SSE,但它不等于旧 HTTP+SSE 传输,也不是 WebSocket。
如果 Server 创建了有状态会话,可以在初始化响应中返回 MCP-Session-Id。后续请求需要携带该 Header。HTTP 请求还应携带协商后的 MCP-Protocol-Version。
下图只比较协议定义的两种标准传输。它们承载相同的 JSON-RPC 和生命周期,差别在于进程关系、消息边界、连接方式和会话管理。

10. 旧 HTTP+SSE 为什么仍然存在
旧 HTTP+SSE 是 MCP 2024-11-05 版本中的传输方式。它通常使用一个 SSE 端点接收服务端消息,再通过另一个 POST 端点发送客户端消息。
Streamable HTTP 已经取代它,网络新项目应该优先使用单一 /mcp 端点。旧 SSE 仍有意义,因为已有客户端和服务端需要兼容。后面的 FastMCP 实战会真实运行一次旧 SSE,但不会把它作为主路径。
11. 本地 MCP Server 也需要安全边界
本机服务并不等于天然安全。Streamable HTTP 规范明确要求关注以下问题:
- 本地服务优先绑定 127.0.0.1,不要无意暴露到全部网卡。
- 校验 Origin,降低 DNS Rebinding 风险。
- 网络服务应该增加认证和授权。
- Host 只向 Server 提供最少必要上下文。
- 调用有副作用的 Tool 前进行确认和审计。
- 不把第三方 MCP 返回的文本直接当作可信指令执行。
本系列的本地服务只用于学习测试。公网部署、OAuth 和细粒度权限会单独处理。
12. 常见误区
12.1 MCP Server 就是 Agent
不是。Server 提供能力,Agent 负责选择能力、组织调用并生成回答。
12.2 使用 MCP 后不需要模型 Function Calling
不是。Agent 把 MCP Tool 转换成模型可理解的工具 Schema,模型仍需要生成工具调用请求。
12.3 SSE 就是 WebSocket
不是。SSE 是基于 HTTP 的单向事件流。Streamable HTTP 可以结合 POST、GET 和 SSE 完成双向协议通信,但底层不是 WebSocket。
12.4 stdio Server 和 Client 在同一个进程
不是。Client 启动独立 Server 子进程,再通过标准流通信。
12.5 MCP Server 可以读取全部对话
不是。Host 决定向某个 Server 发送什么内容,Server 不应该自动获得完整对话或其他 Server 的上下文。
13. 总结
MCP 的价值不只是“远程调用一个函数”,而是为 AI 应用定义统一的能力发现、参数描述、生命周期和传输规则。
| 概念 | 主要职责 | 需要注意的边界 |
|---|---|---|
| Host | 管理 Client、模型、权限和用户交互 | 决定向 Server 发送哪些上下文 |
| Client | 维护与单个 Server 的会话 | 一个 Client 连接一个 Server |
| Server | 提供 Tool、Resource、Prompt | 不自动获得全部对话 |
| Tool | 执行操作 | 可能有副作用,需要权限控制 |
| Resource | 公开可读取数据 | 是否放入模型上下文由客户端决定 |
| Prompt | 提供可复用提示词 | 不会自动调用模型 |
| stdio | 本地子进程通信 | stdout 只能输出 MCP 消息 |
| Streamable HTTP | 网络 MCP 主路径 | 需要 Origin、认证和会话安全 |
| 旧 HTTP+SSE | 兼容旧客户端和服务端 | 不作为新项目首选 |