Skip to main content
Model Context Protocol (MCP) 允许服务器公开可由语言模型调用的工具。工具使模型能够与外部系统交互,例如查询数据库、调用 API 或执行计算。每个工具都由名称唯一标识,并包含描述其 schema 的元数据。

用户交互模型

MCP 中的工具被设计为模型控制,这意味着语言模型可以基于其对上下文和用户提示的理解,自动发现并调用工具。 不过,实现可以自由地通过任何适合自身需求的界面模式公开工具;协议本身并不强制规定任何特定的用户交互模型。
出于信任与安全及安全性考虑,SHOULD 始终让人类参与流程,并能够拒绝工具调用。应用 SHOULD
  • 提供清楚说明哪些工具会暴露给 AI 模型的 UI
  • 在工具被调用时插入清晰的视觉指示
  • 针对操作向用户展示确认提示,确保人类参与流程

能力

支持工具的服务器 MUST 声明 tools 能力:
listChanged 表示服务器是否会在可用工具列表变化时发出通知。 声明 tools 能力的服务器 MUST 响应 tools/list 请求,并返回当前对请求客户端可用的一组工具。该集合 MAY 为空,也 MAY 随时间变化(见列表变化通知),但 MUST NOT 因连接不同或连接上其他请求的副作用而变化。该集合 MAY 随请求中提供的授权而变化,例如只返回调用方已授予 scope 允许的工具,因为凭据是逐请求输入,而不是连接状态。 服务器 SHOULD 以确定性顺序返回工具(即,当底层工具集合未变化时,请求之间保持相同顺序)。确定性顺序使客户端能够可靠地缓存工具列表,并在工具被纳入模型上下文时提高 LLM 提示缓存命中率。

协议消息

列出工具

为了发现可用工具,客户端会发送 tools/list 请求。此操作支持分页缓存 请求:
响应:

调用工具

为了调用工具,客户端会发送 tools/call 请求: 请求:
响应:

需要输入的工具结果

服务器 MAYInputRequiredResult 响应 tools/call,表示在完成工具调用前需要额外输入。这遵循多轮往返请求机制。 使用输入响应重试请求时,客户端会在请求参数中包含 inputResponses,并在服务器提供时包含 requestState 需要输入的响应:
带输入响应重试:
请注意,初始请求与重试之间的 JSON-RPC id MUST 不同。

列表变化通知

当可用工具列表变化时,已声明 listChanged 能力的服务器 SHOULD 向已打开 subscriptions/listen 流且设置了 toolsListChanged: true 的客户端发送通知:

消息流

数据类型

Tool

工具定义包括:
  • name:工具的唯一标识符
  • title:用于显示的可选人类可读工具名称。
  • description:对功能的人类可读描述
  • icons:用于在用户界面中显示的可选图标数组
  • inputSchema:定义预期参数的 JSON Schema
    • 遵循 JSON Schema 使用指南
    • 如果不存在 $schema 字段,则默认为 2020-12
    • MUST 是有效的 JSON Schema 对象(不是 null
    • 对于没有参数的工具,请使用以下有效方式之一:
      • { "type": "object", "additionalProperties": false } - 推荐:明确只接受空对象
      • { "type": "object" } - 接受任何对象(包括带有属性的对象)
    • 属性 MAY 包含 x-mcp-header annotation,用于将参数值公开为 HTTP 标头
  • outputSchema:定义预期输出结构的可选 JSON Schema
  • annotations:描述工具行为的可选属性
出于信任与安全及安全性考虑,除非工具 annotations 来自受信任服务器,否则客户端 MUST 将其视为不可信。

工具名称

  • 工具名称长度 SHOULD 在 1 到 128 个字符之间(含边界)。
  • 工具名称 SHOULD 被视为区分大小写。
  • SHOULD 仅允许以下字符:ASCII 大写和小写字母(A-Z、a-z)、数字(0-9)、下划线(_)、连字符(-)和点(.)
  • 工具名称 SHOULD NOT 包含空格、逗号或其他特殊字符。
  • 工具名称 SHOULD 在服务器内唯一。
  • 有效工具名称示例:
    • getUser
    • DATA_EXPORT_v2
    • admin.tools.list
工具名称唯一性限定在单个服务器内。聚合多个服务器工具的客户端或代理 MAY 遇到命名冲突(例如,两个服务器各自公开一个 search 工具),并且 SHOULD 实现消歧策略,例如为工具名称添加服务器标识符前缀。服务器 name(来自 serverInfo)不保证在服务器之间唯一,因此 SHOULD NOT 依赖它来消歧。

x-mcp-header

x-mcp-header 扩展属性允许服务器在使用 Streamable HTTP 传输时,指定特定工具参数镜像到 HTTP 标头中。这使网络中间件(负载均衡器、代理、WAF)无需解析请求正文,就能基于参数值路由和处理请求。 x-mcp-header 属性直接放置在要镜像的属性的 JSON Schema 中。它的值指定结果 Mcp-Param-{name} HTTP 标头的名称部分。 x-mcp-header 值的约束:
  • MUST NOT 为空
  • MUST 匹配 HTTP field-name token 语法(1*tcharRFC 9110 Section 5.1
  • MUST NOT 包含控制字符,包括回车(CR,\r)或换行(LF,\n
  • inputSchema 中的所有 x-mcp-header 值之间,MUST 以大小写不敏感方式保持唯一
  • MUST 仅应用于具有原始类型(integer、string、boolean)的参数。不允许用于类型为 number 的参数。Integer 值 MUST 位于使用 IEEE754 双精度浮点数表示的整数安全范围内(−253+1 到 253−1)
  • MAY 应用于 inputSchema 中任意嵌套深度的属性,而不仅限于顶层属性
使用 Streamable HTTP 传输的客户端 MUST 拒绝任何 x-mcp-header 值违反这些约束的工具定义。拒绝意味着客户端 MUSTtools/list 的结果中排除无效工具。客户端在拒绝工具定义时 SHOULD 记录警告,并包含工具名称和拒绝原因。这确保单个格式错误的工具定义不会阻止其他有效工具被使用。使用其他传输(例如 stdio)的客户端 MAY 完全忽略 x-mcp-header annotations。 x-mcp-header 的工具定义示例:
在此示例中,当工具以 "region": "us-west1" 被调用时,客户端会向 HTTP 请求添加标头 Mcp-Param-Region: us-west1
服务器开发者 SHOULD NOT 使用 x-mcp-header 标记敏感参数(密码、API key、token、PII),因为标头值对网络中间件可见。

Tool Result

工具结果可以包含结构化内容或非结构化内容。 非结构化内容会在结果的 content 字段中返回,并且可以包含多个不同类型的内容项:
所有内容类型(文本、图像、音频、资源链接和嵌入式资源)都支持可选的 annotations,用于提供受众、优先级和修改时间等元数据。这与资源和提示使用的 annotation 格式相同。

文本内容

图像内容

音频内容

资源链接

工具 MAY 返回指向资源的链接,以提供额外上下文或数据。在这种情况下,工具会返回一个可由客户端订阅或获取的 URI:
资源链接支持与常规资源相同的资源 annotations,以帮助客户端理解如何使用它们。
工具返回的资源链接不保证会出现在 resources/list 请求的结果中。

嵌入式资源

资源 MAY 使用合适的 URI scheme 以内嵌方式提供额外上下文或数据。使用嵌入式资源的服务器 SHOULD 实现 resources 能力:
嵌入式资源支持与常规资源相同的资源 annotations,以帮助客户端理解如何使用它们。

Structured Content

结构化内容会作为 JSON 值在结果的 structuredContent 字段中返回。这可以是任何 JSON 值(对象、数组、字符串、数字、布尔值或 null),并且在定义了工具的 outputSchema 时符合该 schema。 为了向后兼容,返回结构化内容的工具 SHOULD 同时在 TextContent 块中返回序列化后的 JSON。

输出 Schema

工具也可以提供输出 schema,用于验证结构化结果。如果提供了输出 schema:
  • 服务器 MUST 提供符合此 schema 的结构化结果。
  • 客户端 SHOULD 根据此 schema 验证结构化结果。
带输出 schema 的工具示例:
此工具的有效响应示例:
带数组输出 schema 的工具示例:
带数组输出的工具的有效响应示例:
提供输出 schema 有助于客户端和 LLM 通过以下方式理解并正确处理结构化工具输出:
  • 启用对响应的严格 schema 验证
  • 提供类型信息,以便更好地与编程语言集成
  • 指导客户端和 LLM 正确解析和使用返回的数据
  • 支持更好的文档和开发者体验

Schema 示例

使用默认 2020-12 schema 的工具:

使用显式 draft-07 schema 的工具:

无参数工具:

有状态工具

本节是关于工具设计的非规范性指导。协议没有状态句柄的概念;从线上传输视角看,句柄只是工具结果中的普通字符串,也是后续工具调用的普通参数。
MCP 没有协议级 session,因此服务器不能依赖隐式的逐连接状态来关联一个工具调用和下一个工具调用。需要跨调用维护状态的服务器(购物车、打开的浏览器上下文、数据库事务等)应通过创建工具返回显式句柄,并在后续调用中接受该句柄作为参数。 例如,管理购物车的服务器可能会公开:
模型负责继续携带 basket_id;服务器将购物车内容存储在该键下,并在每次调用时查找。 设计句柄时,服务器应考虑:
  • Authorization。 对于已认证服务器,句柄是名称而不是能力。服务器应在每次调用时根据句柄验证调用方授权。对于未认证服务器,句柄必然是 bearer token,因此应以足够熵生成(例如 UUIDv4)并设置有界生命周期。
  • Opacity。 编码内部结构的句柄会诱使解析或猜测;不透明标识符不会。
  • Lifetime。 由于句柄的生命周期超过任何单个连接,服务器的保留策略应在创建工具的描述中说明(例如,“baskets expire after 24 hours of inactivity”),以便模型在决定创建状态时能够看到。
  • Expiry errors。 针对已过期或未知句柄的调用应返回说明该情况的工具执行错误,以便模型可以通过创建新句柄来恢复。

错误处理

工具使用两种错误报告机制:
  1. 协议错误 表示请求结构本身存在问题,模型通常不太可能修复: 它们以标准 JSON-RPC 错误形式返回:
  2. 工具执行错误 包含可操作反馈,语言模型可用其自我修正并使用调整后的参数重试:
    • API 失败
    • 输入验证错误(例如日期格式错误、值超出范围)
    • 业务逻辑错误
    它们在工具结果中以 isError: true 报告:
客户端 MAY 将协议错误提供给语言模型,但这类错误不太可能成功恢复。客户端 SHOULD 将工具执行错误提供给语言模型,以支持自我修正。

安全注意事项

  1. 服务器 MUST
    • 验证所有工具输入
    • 实现适当的访问控制
    • 对工具调用进行速率限制
    • 清理工具输出
  2. 客户端 SHOULD
    • 对敏感操作提示用户确认
    • 在调用服务器前向用户显示工具输入,以避免恶意或意外的数据外泄
    • 在传递给 LLM 前验证工具结果
    • 根据 inputSchemaoutputSchema 验证工具输入与输出时,遵循 $ref 解析要求
    • 为工具调用实现超时
    • 出于审计目的记录工具使用情况