MCP Apps

MCP Apps

社区译文;来源: MCP 80041ab0

如需完整的 API 文档、高级模式和全部规范,请访问 MCP Apps 官方文档。

文本响应的表达能力终究有限。有时用户需要与数据交互,而不只是阅读数据。MCP Apps 允许服务器返回可直接在对话中呈现的交互式 HTML 界面,例如数据可视化、表单和仪表盘。

Excalidraw MCP App 在 Claude 对话中绘制时序图

为什么不直接构建 Web 应用?

你当然可以构建独立 Web 应用,再向用户发送链接。但与独立页面相比,MCP Apps 具有以下关键优势:

  • 保留上下文。 应用位于对话内。用户无需切换标签页、丢失当前位置,也不用回想仪表盘出现在哪个聊天线程中。UI 就在促成它的讨论旁边。
  • 双向数据流。 应用可以调用 MCP 服务器上的任何工具,宿主也可以把最新结果推送给应用。独立 Web 应用需要自行实现 API、身份验证和状态管理,而 MCP Apps 通过现有 MCP 模式获得这些能力。
  • 集成宿主能力。 应用可以把操作委托给宿主,由宿主调用用户已连接的能力和工具,但仍须获得用户同意。这样,每个应用不必分别实现并维护对电子邮件提供商等服务的直接集成,而可以请求一个结果(例如“安排这场会议”),再由宿主通过用户现有的已连接能力完成路由。
  • 安全保证。 MCP Apps 在宿主控制的沙箱 iframe 中运行,不能访问父页面、窃取 Cookie 或逃逸容器。因此,宿主无需完全信任服务器作者,也能安全呈现第三方应用。

如果你的使用场景不需要这些特性,普通 Web 应用可能更简单。但如果你希望与基于 LLM 的对话紧密集成,MCP Apps 会更合适。

MCP Apps 如何工作

传统 MCP 工具返回文本、图像、资源或结构化数据,由宿主将其显示为对话的一部分。MCP Apps 扩展了这一模式:工具可以在描述中声明对交互式 UI 的引用,再由宿主就地呈现该 UI。

其核心模式组合了两个 MCP 原语:一个在描述中声明 UI 资源的工具,以及一个把数据呈现为交互式 HTML 界面的 UI 资源。

当大语言模型(LLM)决定调用支持 MCP Apps 的工具时,会发生以下过程:

  1. 预加载 UI:工具描述包含 _meta.ui.resourceUri 字段,指向一个 ui:// 资源。宿主可以在工具实际调用前预加载该资源,从而支持将工具输入流式传给应用等功能。

  2. 获取资源:宿主从服务器获取 UI 资源。该资源包含一个 HTML 页面,通常会为简化部署而把 JavaScript 和 CSS 一并打包。应用也可以从 _meta.ui.csp 指定的来源加载外部脚本和资源。

  3. 沙箱渲染:Web 宿主通常在对话内的沙箱 iframe 中呈现 HTML。沙箱限制应用访问父页面,从而确保安全。资源的 _meta.ui 对象可以包含 permissions,用于请求麦克风、摄像头等额外能力,也可以包含 csp,用于控制应用可从哪些外部来源加载资源。

  4. 双向通信:应用和宿主通过一种形成独立 MCP 方言的 JSON-RPC 协议通信。部分请求和通知与核心 MCP 协议共用(例如 tools/call),部分请求与之相似(例如 ui/initialize),其余大多使用以 ui/ 开头的新方法名。应用可以请求工具调用、发送消息、更新模型上下文,并接收宿主数据。

  sequenceDiagram
    participant User
    participant Agent
    participant App as MCP App iframe
    participant Server as MCP Server

    User->>Agent: "show me analytics"
    Note over User,App: Interactive app rendered in chat
    Agent->>Server: tools/call
    Server-->>Agent: tool input/result
    Agent-->>App: tool result pushed to app
    User->>App: user interacts
    App->>Agent: tools/call request
    Agent->>Server: tools/call (forwarded)
    Server-->>Agent: fresh data
    Agent-->>App: fresh data
    Note over User,App: App updates with new data
    App-->>Agent: context update

应用与宿主保持隔离,但仍可通过安全的 postMessage 通道调用 MCP 工具。

何时使用 MCP Apps

MCP Apps 适合以下使用场景:

探索复杂数据。 用户提出“按地区显示销售额”。文本响应可以列出数字,而 MCP App 可以呈现交互式地图,让用户点击地区深入查看、悬停获取详情,并在不同指标之间切换,全程无需额外提示词。

配置大量选项。 设置一次部署可能涉及数十个相互依赖的选择。与其反复对话(“哪个区域?”“多大的实例?”“启用自动扩缩容吗?”),MCP App 可以提供一个表单,让用户一次看到所有选项以及校验规则和默认值。

查看富媒体。 当用户需要审阅 PDF、查看 3D 模型或预览生成的图像时,文本描述并不足够。MCP App 可以把实际查看器直接嵌入对话,并支持平移、缩放和旋转。

实时监控。 显示实时指标、日志或系统状态的仪表盘需要持续更新。MCP App 可以维持持久连接并更新显示,而不需要用户反复询问“现在状态如何?”。

多步骤工作流。 审批报销单、评审代码改动或分流问题,都需要逐项检查。MCP App 可以提供导航控件、操作按钮,以及跨交互保留的状态。

安全模型

MCP Apps 在沙箱 iframe 中运行,与宿主应用保持强隔离。沙箱阻止应用访问父窗口的 DOM、读取宿主的 Cookie 或本地存储、导航父页面,或在父上下文中执行脚本。

应用与宿主之间的所有通信都通过 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 规范的扩展。不同客户端的宿主支持情况并不相同。

目前,Claude、Claude Desktop、VS Code GitHub Copilot、Microsoft 365 Copilot、Goose、Postman、MCPJam 和 Archestra.AI 支持 MCP Apps。请查看客户端矩阵,了解各客户端对扩展的完整支持情况。

如果你正在构建 MCP 客户端并希望支持 MCP Apps,有两种选择:

  1. 使用框架:@mcp-ui/client 软件包提供 React 组件,用于在宿主应用中呈现 MCP Apps 视图并与之交互。使用详情请参阅 MCP-UI 文档。

  2. 基于 AppBridge 构建:SDK 包含 App Bridge 模块,负责在沙箱 iframe 中呈现应用、传递消息、代理工具调用和实施安全策略。basic-host 示例展示了如何集成它。

实现细节请参阅 API 文档。

示例

ext-apps 仓库包含可直接运行的示例,展示了不同使用场景:

要开始构建自己的 MCP App,请参阅构建指南。