模型上下文协议(Model Context Protocol, MCP)
MCP 是一个开放协议,用于规范 AI 应用连接到工具、数据和外部系统的方式。本页是 MCP 架构、消息与代码示例的完整参考。
MCP 简介
可以把 MCP 比作用于 AI 的 USB-C 接口:正如 USB-C 为连接不同设备提供了统一的物理接口, MCP 为将语言模型连接到各种数据源和工具提供了统一的软件接口。在 MCP 出现之前,AI 助手与外部系统之间的每一次集成 都需要单独编写、无法复用。MCP 打破了这种模式:任何按照 MCP 规范编写的服务器,都可以被任何支持 MCP 的宿主应用使用。
架构:Host、Client 与 Server
MCP 的架构由三个独立的角色组成:
- Host — 用户直接使用的应用程序(例如 AI 助手或 IDE)。Host 负责管理权限并协调多个连接。
- Client — 存在于 Host 内部,与恰好一个 Server 维持一对一的有状态连接。
- Server — 你所构建的应用程序;它通过 Resources、Tools 和 Prompts 将自己的数据和能力暴露给 Host。
一个 Host 可以同时连接多个不同的 Server(例如一个用于库存,一个用于 CRM),这些连接彼此完全独立、互不干扰。
MCP 服务器的三大核心要素
Resources(资源)
Server 暴露给 Host 的数据——例如一份文档、一条数据库记录或一个配置文件。每个 Resource 都由一个唯一的 URI 标识, 通常是应用程序控制的(application-controlled),即由宿主应用决定何时读取它(类似于一次 GET 请求)。
Tools(工具)
语言模型可以自行决定是否执行的函数(模型控制,model-controlled)——例如
check_inventory() 或 book_appointment()。每个 Tool 都有名称、描述,以及用于输入输出的 JSON Schema。
模型根据这段描述来决定何时使用该 Tool,因此描述的准确性至关重要。
Prompts(提示词)
预先制作、可复用的模板,通常是用户控制的(user-controlled)——由用户有意识地选择使用(例如作为界面中的快捷指令)。 Prompts 有助于将与你的 Server 进行最优交互的方式标准化。
Sampling 与 Roots(进阶功能)
除了三大核心要素之外,MCP 还提供两项进阶能力:Sampling 允许 Server 反过来请求 Host 的语言模型生成文本; Roots 则定义了 Server 被允许访问的文件系统边界。
传输层(Transports)
| 传输方式 | 使用场景 | 说明 |
|---|---|---|
stdio | 本地服务器 | 通过进程的标准输入/输出进行通信;最简单的方式,适合 Server 与用户运行在同一台设备上的情况。 |
| 基于 HTTP(Streamable HTTP) | 远程服务器 | 通过 HTTP 通信,适合以独立远程服务形式运行、且需要身份验证的 Server。 |
连接生命周期
所有 MCP 消息都遵循 JSON-RPC 2.0 格式(三种消息类型:request、response 和 notification)。 一个典型的连接会经历以下周期:
- initialize — Client 向 Server 声明自己的协议版本和能力
- Server 回应自己的协议版本和能力
- Client 发送一条 initialized 通知以最终确定连接
- 开始正常操作:
tools/list、tools/call、resources/list、resources/read、prompts/list、prompts/get - 最后,连接被干净地关闭
快速上手:构建一个简单的服务器
以下示例使用官方 Python 包构建一个带有一个简单 Tool 的 MCP 服务器:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Store Inventory")
@mcp.tool()
def check_inventory(sku: str) -> dict:
"""按 SKU 检查产品库存"""
# 在这里连接到你真实的数据库
return {"sku": sku, "in_stock": True, "quantity": 12}
if __name__ == "__main__":
mcp.run()
仅需这几行代码,任何兼容 MCP 的 Host 就能发现这个工具,并在合适的时机调用它——无需任何额外的集成代码。
身份验证与安全
在 stdio 传输方式下,安全边界就是操作系统的进程边界。但对于基于 HTTP 的远程 Server,以下几点至关重要:
- 使用标准的身份验证机制(例如 OAuth 2.1)来验证 Client 的身份
- 为每个 Tool 定义所需的最小权限;切勿构建一个拥有数据库完全访问权限的"万能" Tool
- 记录所有 Tool 调用日志,以便在出现异常行为时可追溯
- 在面向公众的 Server 上实施速率限制(Rate Limiting)
官方 SDK
主要语言均提供官方 SDK,包括用于 Python 的 mcp 包,以及用于 TypeScript/JavaScript 的
@modelcontextprotocol/sdk。针对其他语言的非官方、社区驱动的 SDK 也在逐步开发中。建议始终从最新版本的官方 SDK 开始。
最佳实践
- 保持工具小而专一 — 一个 Tool,一个明确的任务
- 撰写精确的描述 — 模型是根据描述而非名称来决定是否使用某个 Tool 的
- 返回结构化输出 — 使用结构固定的 JSON,而非难以预测的自由文本
- 清晰地报告错误 — 提供模型能够理解的错误信息,而不仅仅是状态码
- 谨慎地进行版本管理 — 对 Tool 的结构性更改要谨慎并做好文档记录
常见问题
MCP 会取代 REST API 吗?
并非如此。MCP 是构建在你现有逻辑之上的标准层;在一个工具(Tool)的背后,调用的通常仍是你现有的 API 或数据库。
MCP 只适用于 Anthropic 的模型吗?
不是。MCP 是一个开放标准,旨在与任何支持其实现的模型或宿主应用程序兼容。
OpenCommerce 中 MCP 与 UCP 有什么区别?
MCP 用于安全、受控地访问你的内部数据;UCP 则是为任何智能体都可使用的通用商业交易(搜索、购物车、支付)而设计的。