跳到主内容

MCP 工具结果怎么展示给用户:五类 content、annotations 与前端渲染的三层处理

100%
MCP 工具结果怎么展示给用户:五类 content、annotations 与前端渲染的三层处理

结论先说:MCP 工具返回的不只是一段字符串。按 2025-11-25 版规范,工具结果同时存在 content(非结构化内容,五类)和 structuredContent(结构化内容)两条通道,客户端必须把「传给模型的内容」和「展示给用户的内容」分开处理,否则图片、音频、资源引用会整块丢失或被误当成文本塞进上下文。

这是很多 MCP 客户端「工具明明返回了结果,界面上却什么都没有」的根因。问题不在服务端,在渲染层。

一、工具结果的两种形态

规范原文的表述是:工具结果可以包含结构化或非结构化内容。非结构化内容放在结果的 content 字段,是一个数组,可以包含多个不同类型的内容项;结构化内容作为 JSON 对象放在 structuredContent 字段。

为向后兼容,规范明确要求:返回结构化内容的工具SHOULD 同时把序列化后的 JSON 放进一个 TextContent 块里。也就是说,老客户端只读 content 也能拿到数据,新客户端则可以直接用 structuredContent 做类型和字段级处理。

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      { "type": "text", "text": "{\"temperature\": 22.5, \"conditions\": \"Partly cloudy\"}" }
    ],
    "structuredContent": {
      "temperature": 22.5,
      "conditions": "Partly cloudy",
      "humidity": 65
    }
  }
}

二、五类 content 逐个说

类型type 值关键字段渲染要点
文本texttext直接渲染,长文本需折叠
图片imagedata(base64)、 mimeType解码后内联展示,不要把 base64 塞进模型上下文
音频audiodata(base64)、 mimeType给播放器,模型侧只留一句描述
资源链接resource_linkuri 、 name 、 description 、 mimeType渲染成可点击条目,按需再拉取
嵌入资源resourceresource.uri / mimeType / text内容已内联,直接展示

resource_link 与 resource 不是一回事

这是最容易搞混的一对。两者 type 值不同,语义也不同:

  • resource_link 只给一个 URI,客户端可以后续订阅或拉取。规范特别提醒:工具返回的资源链接,不保证会出现在 resources/list 的结果里——别指望用列表接口兜底。
  • resource 是嵌入资源,内容已经内联在结果里(含 uri 、 mimeType 和 text)。规范要求:使用嵌入资源的服务器 SHOULD 实现 resources 能力。
// resource_link:只给引用
{ "type": "resource_link", "uri": "file:///project/src/main.rs",
  "name": "main.rs", "mimeType": "text/x-rust" }

// resource:内容已内联
{ "type": "resource", "resource": {
    "uri": "file:///project/src/main.rs",
    "mimeType": "text/x-rust",
    "text": "fn main() { println!(\"Hello world!\"); }" } }

三、 annotations:决定这块内容给谁看

所有内容类型都支持可选的 annotations,提供三类元数据:

  • audience:目标受众数组,如 ["user"] 或 ["user", "assistant"]。这是分流渲染的核心依据——只标 user 的内容,不该进模型上下文。
  • priority:优先级数值,如 0.9 、 0.7 。内容超出展示区域时,按它决定谁先被折叠。
  • lastModified:ISO 8601 时间戳,如 2025-05-03T14:30:00Z。用于判断缓存是否过期。
annotations 与 resources 、 prompts 使用的是同一套格式。如果服务端没给,客户端要有一套默认策略:文本默认进模型,二进制默认只给人看,否则多模态结果会被整块丢弃。

四、三层渲染处理


  1. 标准化:遍历 content 数组,按 type 分派到对应处理器;遇到不认识的 type 要保留原文并提示,不要静默丢弃——规范允许未来扩展类型。

  2. 分流:按 annotations.audience 决定是否进模型上下文;文本进上下文,图片/音频转为描述性一句话加资源句柄,避免 base64 直接撑爆上下文窗口。

  3. 降级:结构化内容优先读 structuredContent;它缺失时回退到 content 里的 JSON 文本块解析;都失败则展示原始文本,保证老服务器也能用。

五、 outputSchema:服务端的 MUST 与客户端的 SHOULD

工具可以在定义里提供 outputSchema(可选 JSON Schema,未指定 $schema 时默认 2020-12)。一旦提供,规范给出两条硬要求:

  • 服务端 MUST 提供符合该 schema 的结构化结果;
  • 客户端 SHOULD 依据该 schema 校验结构化结果。

它的四个作用是:启用严格的响应校验、为编程语言提供类型信息、指导客户端与模型正确解析返回数据、改善文档与开发体验。规范还特别澄清了一点:structuredContent 是服务器产生的结果数据,与模型的 structured outputs(受 schema 约束的生成)不是一回事,不要混用校验逻辑。

六、错误:isError 与协议错误要分开处理

工具用两种机制报错,客户端的处理策略完全不同:

机制位置适用场景客户端建议
协议错误JSON-RPC 的 error 字段未知工具、请求格式错误、服务器错误MAY 提供给模型,但恢复概率低
工具执行错误result 里 isError: trueAPI 失败、入参校验失败、业务逻辑错误SHOULD 提供给模型,便于自我纠正重试

区别在于:工具执行错误带的是可操作的反馈(比如「出发日期必须在未来,当前日期是 2025-08-08 」),模型拿到后能自行调整参数重试;协议错误说的是请求结构有问题,模型基本修不了。

七、落地清单

  • content 数组逐项处理,不要只取第一项——多内容项是常态。
  • base64 的 image / audio 不进模型上下文,只留资源句柄与一句描述。
  • resource_link 不要假设能通过 resources/list 找到,需要时可主动拉取。
  • 有 structuredContent 就优先用;同时兼容 content 里的 JSON 文本块。
  • 大结果集要分页或截断,可参考MCP 大数据量结果的分页与不透明游标设计。
  • 错误分支单独渲染,isError 的内容明确标为执行失败,不要和正常结果混排。
服务端作者需要注意的三条
一、返回结构化内容时,务必同时把序列化 JSON 放进 TextContent,否则老客户端拿不到数据。
二、输出图片音频时带上 mimeType,客户端才能正确解码。
三、工具契约(包括输出结构)一旦发布就要考虑兼容性,改动方式见 MCP 工具契约演进四步法。

客户端侧的完整实现流程,可参考用 Python 从零实现一个 MCP 客户端,其中对结果解析与结构化处理的环节讲得更细。


工具返回了图片,但界面上什么都没有,是什么原因
最常见是客户端只处理了 text 类型,把 image 、 audio 、 resource 等类型整块忽略。需要遍历 content 数组逐项分派,而不是只取第一个文本块。

structuredContent 和 content 里的 JSON 文本重复了,要不要都读
优先读 structuredContent,它有 schema 保障和类型信息;content 里的 JSON 文本是向后兼容用的兜底。两者不一致时以 structuredContent 为准并记录告警。

resource_link 和 resource 该怎么选
内容已经在手边、且体积可控时用 resource(嵌入);内容很大或需要客户端后续订阅变更时用 resource_link 。注意工具返回的资源链接不保证出现在 resources/list 里。

annotations 的 audience 有什么实际用途
用来分流:标了 user 的内容只展示给人看,不进模型上下文;标了 assistant 的则是给模型的补充信息。这是控制上下文膨胀的关键字段。

outputSchema 是必须的吗
不是。它是可选的,但一旦提供,服务端就必须返回符合它的结构化结果,客户端也应当校验。想让下游稳定解析,建议都给上。

这篇有帮助吗?
云上的幻象
云上的幻象查看主页

七彩云博客,分享 WordPress 建站实战与 AI 工具测评,覆盖服务器运维、站长工具、软件资源与电商运营干货,专注原创实用的主题插件、网站加速与安全优化教程。

997文章4评论

相关文章

评论 (0)

欢迎你,新朋友,感谢参与互动!文明发言,理性交流 · 首次评论将在审核后展示