协会地址:上海市长宁区古北路620号图书馆楼309-313室
Anthropic 构建 MCP 应用程序的经验总结
来源: Agentic AI Foundation (AAIF)
作者: Agentic AI Foundation
发布时间: 2026/5/8 00:46:14
原文链接: https://aaif.io/blog/anthropics-lessons-from-building-mcp-apps/
深入解析 Olivier Chafik 与 Anton Pidkuiko 在 MCP Dev Summit North America 2026 上的演讲
Anthropic 公司的工程师 Olivier Chafik 和 Anton Pidkuiko 向我们展示了 MCP Apps(MCP 应用)的工作原理、常见故障点以及在生产环境中行之有效的模式。
MCP Apps(MCP 应用)之所以存在,是因为在聊天中直接显示数据效率低下。以“今天纽约天气如何?”这样一个简单请求为例。当用户提出请求时,模型从工具获取 JSON 数据,将其转换为文本,然后逐 token 发送回来。用户看到的是一大段格式化文本。
而使用 MCP Apps(MCP 应用),工具响应中包含一个指向 HTML 资源的引用。宿主直接渲染该资源。用户获得的是一个交互式小部件。模型无需再逐字叙述输出结果。
这减少了 token 消耗,降低了延迟,并带来了更好的体验。Anton 现场演示了一个 PDF 查看器,用户可以在同一个聊天窗口内填写字段、盖章文档、添加签名,无需重新加载页面。

数据流:数据去向及其重要性
理解服务器、应用和模型之间的数据流,决定了你的 MCP 应用表现如何,以及它在何处悄然出错。
工具结果包含三个不同的字段,每个字段有不同的去向:
content流向模型。保持简洁。当你的应用渲染输出时,模型不需要完整的叙述——只需知道显示了什么即可。structuredContent是应用可读取的类型化数据。模型可能看到也可能看不到。如果同时存在content,则structuredContent对模型隐藏。这适用于让应用以结构化方式消费的数据。_meta仅流向应用,模型永远看不到。这是存放内部 ID、预取数据、视图 UUID 或任何纯操作性内容的正确位置。
每个字段只有一个去向,混用它们会产生难以发现的错误。
身份验证与访问:直接获取与工具调用
应用获取数据的方式取决于是否需要身份验证。无需身份验证时,直接获取;需要时,使用工具调用。
如果你的应用不需要认证,它的行为就像一个标准的 Web 应用。你可以直接 fetch、使用 WebSocket、加载外部脚本。你确实需要声明将连接哪些域名,并且如果你的 API 有严格的 CORS 规则,你希望应用从一个稳定的域名提供服务——规范支持这一点。
如果你的应用需要身份验证,最好直接处理:不要试图通过工具结果传递令牌。令牌会过期。用户加载三周前的聊天记录时,会遇到状态损坏的问题。相反,任何需要身份验证的操作都应使用工具调用。这样可以复用宿主现有的身份验证基础设施,避免令牌过期问题。
该规范还支持仅应用可见的工具(app-visible-only tools),即模型永远看不到的工具。这些工具适用于你希望由应用处理、而不暴露额外工具以免混淆模型的内部操作。
保持模型信息同步
应用和模型需要保持同步。MCP 应用(MCP Apps)有一个名为 updateModelContext 的原语来处理这个问题。你的应用可以向模型推送文本或图像(页面截图、当前状态、选择上下文),这些内容会在下一次用户交互时才会发送。你可以在一次会话中调用它上千次,只有最后一次版本会被采纳。
例如,PDF 查看器就是这样工作的。每当用户翻页或更新选择时,它都会向模型上下文推送截图和当前页码。如果用户连续翻看 100 页而不输入任何内容,则不会消耗令牌。当他们输入时,模型拥有准确的上下文。
对于希望模型确切知道用户正在查看什么的情况,这种模式比试图在文本中编码状态更可靠。
流式传输以降低延迟
大型工具调用参数(有时多达 10,000 个 token 或更多)可能成为真正的延迟瓶颈。该规范现在支持部分输入流式传输,让应用能够在完整工具结果就绪之前开始渲染。
在实践中,一旦主机看到工具名称,它就可以获取资源并启动应用。应用在部分输入到达时接收它们,并可以显示进度指示器或逐步开始渲染。完整的输入和工具结果稍后到达。这是由主机管理的可选功能,但对于输出量大的 AI 密集型应用来说,这是一项有意义的性能改进。
Anton 展示了一个流式传输示例:时间序列图表在数据到达时逐步渲染,而不是用户等待完整响应后才看到任何内容。
状态持久化:两种模式
状态持久化尚未纳入核心规范,但目前有两种模式可用。
第一种是服务器端存储。你在服务器上实现 get 和 set 工具,以视图的唯一 ID 作为键。设置起来更复杂,但能保证跨机器和会话正常工作。
第二种是本地存储。MCP 应用是 Web 应用,可以使用本地存储。实现起来更简单,但可靠性较低:客户端可能会清除它,并且无法跨设备工作。对于非关键状态,这是一个合理的选择。
为多主机构建:握手完成工作
许多团队已经拥有 MCP 服务器,并希望在不破坏非 UI 客户端的情况下添加 UI。解决方案是在初始化时进行能力检测。在 MCP 握手过程中,你可以检查客户端是否支持 MCP Apps。如果不支持,则隐藏应用特定的工具;如果支持,则将其暴露出来。
同样的逻辑也适用于应用内部。应用与宿主之间存在第二次握手,协议中的每一项能力都是可选的。目标是实现优雅降级——即使某些功能不可用,你的应用也应在不同宿主上合理运行。
如何将 MCP Apps 无缝融入用户体验
MCP Apps 不应显得格格不入。宿主在初始化时向应用传递上下文,包括界面是浅色模式还是深色模式、CSS 变量,以及可能遮挡屏幕部分的 UI 元素信息。
演讲中的一些实用提示:
- 在内联模式下避免垂直滚动
- 在移动设备上使用捏合手势切换到全屏
- 如果通过截图更新模型上下文,请使用防抖处理。目标是让应用感觉像是宿主的一部分,而不是从另一个上下文插入进来的东西。
即将到来的规范变更如何影响 MCP Apps
即将有两项重要的规范变更值得关注。视图本地工具(View-local tools) 将允许应用声明自己的工具,而无需通过服务器路由,从而实现更简洁的架构并减少状态依赖。此外,主机(host) 将能够直接将数据推送到视图,从而消除某些应用目前用于接收模型更新的轮询模式。
MCP 应用(MCP Apps)正在加速发展,围绕它的社区也非常活跃。加入讨论,提交 Issue,并学习构建交互式 MCP 用户体验——因为这正是人们所期待的。
如果你正在构建或计划构建 MCP 应用,那么这场完整的演讲值得一看。AAIF 开源仓库 提供了跨多个框架的实用示例。
加入 AAIF Discord 的讨论,并探索 MCP GitHub 仓库 开始构建。







