为什么不直接构建 Web 应用?
你当然可以构建一个独立 Web 应用,然后把链接发给用户。不过,MCP Apps 提供了独立页面难以匹配的关键优势:- 保留上下文。 应用位于对话内部。用户不需要切换标签页、丢失当前位置,也不必回想哪个聊天线程里有那个仪表盘。UI 就在触发它的讨论旁边。
- 双向数据流。 应用可以调用 MCP 服务器上的任何工具,主机也可以把最新结果推送给应用。独立 Web 应用需要自己的 API、认证和状态管理;MCP Apps 通过现有 MCP 模式获得这些能力。
- 集成主机能力。 应用可以将动作委托给主机,由主机调用用户已经连接的能力和工具(需用户同意)。这样每个应用不必自行实现和维护直接集成(例如邮件提供商),而是可以请求一个结果(例如“安排这个会议”),再由主机通过用户现有连接能力完成路由。
- 安全保证。 MCP Apps 运行在由主机控制的沙箱 iframe 中。它们不能访问父页面、窃取 cookies,也不能逃逸容器。这意味着主机可以安全渲染第三方应用,而不必完全信任服务器作者。
MCP Apps 如何工作
传统 MCP 工具会返回文本、图片、资源或结构化数据,并由主机作为对话的一部分展示。MCP Apps 扩展了这种模式,允许工具在其描述中声明一个交互式 UI 引用,并由主机就地渲染。 核心模式组合了两个 MCP 原语:一个在描述中声明 UI 资源的工具,以及一个将数据渲染成交互式 HTML 界面的 UI 资源。 当大型语言模型(LLM)决定调用支持 MCP Apps 的工具时,会发生以下过程:-
UI 预加载:工具描述包含
_meta.ui.resourceUri字段,指向一个ui://资源。主机可以在工具被调用前预加载该资源,从而支持将工具输入流式传给应用等能力。 -
资源获取:主机从服务器获取 UI 资源。该资源包含一个 HTML 页面,为了简化通常会打包 JavaScript 和 CSS。应用也可以从
_meta.ui.csp指定的源加载外部脚本和资源。 -
沙箱渲染:Web 主机通常会在对话中的沙箱 iframe 内渲染 HTML。沙箱会限制应用对父页面的访问,以确保安全。资源的
_meta.ui对象可以包含permissions来请求额外能力(例如麦克风、摄像头),也可以包含csp来控制应用可从哪些外部源加载资源。 -
双向通信:应用和主机通过 JSON-RPC 协议通信,这个协议形成了 MCP 的一种专用方言。一些请求和通知与核心 MCP 协议共享(例如
tools/call),一些类似(例如ui/initialize),大多数则是带ui/方法名前缀的新方法。应用可以请求工具调用、发送消息、更新模型上下文,并从主机接收数据。
何时使用 MCP Apps
当使用场景涉及以下需求时,MCP Apps 很适合: 探索复杂数据。 用户问“按地区显示销售额”。文本响应可能只能列数字,而 MCP App 可以渲染交互式地图,让用户点击地区下钻、悬停查看详情,并在指标间切换,而且不需要额外提示。 配置大量选项。 设置部署可能涉及几十个相互依赖的选择。相比来回对话(“哪个地区?”“什么实例规格?”“启用自动扩缩容吗?”),MCP App 可以展示一个表单,让用户一次看到所有选项,并带有校验和默认值。 查看富媒体。 当用户要求审阅 PDF、查看 3D 模型或预览生成图片时,文本描述不够。MCP App 可以把实际查看器(平移、缩放、旋转)直接嵌入对话中。 实时监控。 显示实时指标、日志或系统状态的仪表盘需要持续更新。MCP App 可以维护持久连接,并在数据变化时更新显示,而不需要用户反复询问“现在状态如何?” 多步骤工作流。 审批报销、审查代码变更或分诊议题,都需要逐项检查。MCP App 可以提供导航控件、操作按钮,以及跨交互保持的状态。安全模型
MCP Apps 运行在沙箱 iframe 中,与主机应用强隔离。沙箱会阻止应用访问父窗口的 DOM、读取主机的 cookies 或 local storage、导航父页面,或在父上下文中执行脚本。 应用与主机之间的所有通信都通过 postMessage API。主机控制应用可以访问哪些能力。例如,主机可能限制应用可调用哪些工具,或禁用sendOpenLink 能力。
沙箱设计目标是防止应用逃逸并访问主机或用户数据。
框架支持
MCP Apps 使用自己的 MCP 方言,与核心协议一样基于 JSON-RPC。有些消息与常规 MCP 共享(例如tools/call),另一些则是应用专用消息(例如 ui/initialize)。传输使用 postMessage,而不是 stdio 或 HTTP。由于这些都是标准 Web 原语,你可以使用任意框架,也可以不用框架。
@modelcontextprotocol/ext-apps 中的 App 类只是便利封装,并不是必需项。如果你想避免依赖,或需要更细粒度控制,也可以直接实现 postMessage 协议。
示例目录 包含 React、Vue、Svelte、Preact、Solid 和原生 JavaScript 的入门模板。这些模板展示了各框架体系中的推荐模式,但它们只是示例而不是要求。你可以选择最适合自己场景的方案。
客户端支持
MCP Apps 是核心 MCP 规范的扩展。不同客户端的主机支持情况不同。
-
使用框架:
@mcp-ui/client包提供 React 组件,用于在主机应用中渲染 MCP Apps 视图并与其交互。用法详情见 MCP-UI 文档。 - 基于 AppBridge 构建:SDK 包含 App Bridge 模块,用于处理在沙箱 iframe 中渲染应用、消息传递、工具调用代理和安全策略执行。basic-host 示例 展示了如何集成它。
示例
ext-apps 仓库 包含可直接运行的示例,用于展示不同使用场景:- 3D 和可视化: map-server (CesiumJS 地球仪), threejs-server (Three.js 场景), shadertoy-server (着色器效果)
- 数据探索: cohort-heatmap-server, customer-segmentation-server, wiki-explorer-server
- 业务应用: scenario-modeler-server, budget-allocator-server
- 媒体: pdf-server, video-resource-server, sheet-music-server, say-server (文本转语音)
- 工具类: qr-server, system-monitor-server, transcript-server (语音转文本)
- 入门模板: React, Vue, Svelte, Preact, Solid, 原生 JavaScript