MCP Apps 与 MCP-UI 协议深度解析
1. 引言
随着大型语言模型(LLM)在各个领域的广泛应用,如何让 AI 模型与外部工具和服务进行高效交互成为了一个关键问题。Anthropic 于 2024 年 11 月推出的 Model Context Protocol(MCP)为解决这一问题提供了标准化方案[1]。然而,传统的 MCP 工具只能返回文本或结构化数据,无法满足用户对丰富交互体验的需求。
MCP Apps 和 MCP-UI 协议应运而生,它们通过在 MCP 基础上扩展 UI 能力,使得工具能够返回交互式的 HTML 界面,从而在对话中直接渲染数据可视化、表单、仪表板等丰富的用户界面。本文将深入解析这两个协议的核心概念、技术细节和实际应用。
2. MCP 协议基础回顾
在深入探讨 MCP Apps 和 MCP-UI 之前,我们先简要回顾 MCP 的核心架构。
MCP 基于 JSON-RPC 2.0 协议,定义了三种主要角色[2]:
- Host(宿主):发起连接的 LLM 应用程序,如 Claude Desktop、VS Code 等
- Client(客户端):宿主应用中的连接器,负责与服务器通信
- Server(服务器):提供上下文和能力的服务
MCP 服务器可以向客户端提供以下功能:
- Resources(资源):上下文和数据,供用户或 AI 模型使用
- Prompts(提示):模板化的消息和工作流
- Tools(工具):供 AI 模型执行的函数
3. MCP Apps 协议详解
3.1 什么是 MCP Apps
MCP Apps 是 MCP 的第一个官方扩展,于 2026 年 1 月正式发布[3]。它允许 MCP 工具返回交互式的 HTML 界面,这些界面直接在对话中渲染,用户可以直接与之交互,而无需离开当前对话上下文。
3.2 核心工作原理
MCP Apps 的架构依赖于两个关键的 MCP 原语:
- 带有 UI 元数据的工具:工具在定义中包含
_meta.ui.resourceUri字段,指向 UI 资源 - UI 资源:通过
ui://协议提供的服务器端资源,包含打包的 HTML/JavaScript
MCP Apps 的工作流程可以用以下时序图表示:
// 工具定义示例
{
name: "visualize_data",
description: "将数据可视化为交互式图表",
inputSchema: { /* ... */ },
_meta: {
ui: {
resourceUri: "ui://charts/interactive"
}
}
}3.3 通信协议
MCP Apps 使用基于 postMessage 的 JSON-RPC 协议进行宿主与 UI 之间的通信[4]。
宿主到 UI 的通信(通知)
| 通知类型 | 描述 |
|---|---|
ui/notifications/tool-input | 完整的工具参数 |
ui/notifications/tool-input-partial | 流式传输的部分参数 |
ui/notifications/tool-result | 工具执行结果 |
ui/notifications/host-context-changed | 主题、语言环境、视口变化 |
ui/notifications/size-changed | 宿主通知尺寸约束 |
ui/notifications/tool-cancelled | 工具执行被取消 |
UI 到宿主的通信(请求)
| 方法 | 描述 |
|---|---|
tools/call | 调用另一个 MCP 工具 |
ui/message | 发送后续消息到对话 |
ui/open-link | 在新标签页中打开 URL |
notifications/message | 向宿主记录日志消息 |
ui/notifications/size-changed | 请求小部件调整大小 |
3.4 App API
开发者可以使用 @modelcontextprotocol/ext-apps 包来构建 MCP Apps,该包提供了 App 类用于 UI 到宿主的通信:
import { App } from "@modelcontextprotocol/ext-apps";
const app = new App();
await app.connect();
// 接收来自宿主的工具结果
app.ontoolresult = (result) => {
renderChart(result.data);
};
// 从 UI 调用服务器工具
const response = await app.callServerTool({
name: "fetch_details",
arguments: { id: "123" },
});
// 更新模型上下文
await app.updateModelContext({
content: [{ type: "text", text: "用户选择了选项 B" }],
});3.5 安全模型
MCP Apps 通过多层安全机制确保 UI 代码的安全执行[5]:
- Iframe 沙箱化:所有 UI 内容在受限的 iframe 中运行
- 预声明模板:宿主可以在渲染前审查 HTML 内容
- 可审计消息:所有 UI 到宿主的通信都通过可记录的 JSON-RPC
- 用户同意:宿主可以要求对 UI 发起的工具调用进行明确批准
4. MCP-UI 协议详解
4.1 MCP-UI 的历史与现状
MCP-UI 是由 Ido Salomon 和 Liad Yosef 创建的开源项目,它率先探索了通过 MCP 提供交互式 UI 的概念[6]。MCP-UI 的工作直接影响了 MCP Apps 规范的制定。
目前,MCP-UI 已经被标准化到 MCP Apps 中,其 SDK 实现了 MCP Apps 规范,同时作为社区增强功能的试验场[7]。
4.2 SDK 包
MCP-UI 提供了多个语言的 SDK 实现:
@mcp-ui/server(TypeScript):创建 UI 资源对象@mcp-ui/client(TypeScript):渲染工具 UI 的 React 组件mcp_ui_server(Ruby):创建 UI 资源的辅助方法mcp-ui-server(Python):创建 UI 资源的辅助方法
4.3 UIResource 格式
UI 内容的基础数据格式是 UIResource 对象[8]:
interface UIResource {
type: 'resource';
resource: {
uri: string; // ui://component/id
mimeType: 'text/html;profile=mcp-app'; // MCP Apps 标准
text?: string; // 内联 HTML 内容
blob?: string; // Base64 编码的内容
};
}关键字段说明:
uri:使用ui://协议的唯一标识符(例如:ui://my-tool/widget-01)mimeType:text/html;profile=mcp-app——MCP Apps 标准的 MIME 类型text或blob:实际内容,可以是纯文本或 Base64 编码
4.4 URI 方案
MCP-UI 使用特定的 URI 方案来标识 UI 资源:
ui://<component-name>/<instance-id>- 用途:所有 UI 资源
- 内容:
text或blob包含 HTML 内容 - 客户端动作:在沙箱化 iframe 中渲染
4.5 内容编码
MCP-UI 支持两种内容编码方式:
text:简单的直接字符串,适用于较小、不太复杂的内容blob:Base64 编码的字符串- 优点:能稳健处理特殊字符,更适合大型负载,确保 JSON 传输过程中的完整性
- 缺点:需要在客户端进行 Base64 解码,略微增加负载大小
4.6 外部 URL 处理
当使用 createUIResource 并设置 content.type: 'externalUrl' 时,不同 SDK 的行为有所不同:
- TypeScript SDK:在服务器端获取 URL 的 HTML 内容,注入
<base>标签以便相对路径正确解析,验证 URL(仅限 http/https,阻止私有/localhost 地址) - Python 和 Ruby SDK:直接将 URL 字符串存储为资源内容,由宿主客户端负责获取和渲染
5. MCP Apps 与 MCP-UI 的关系
MCP Apps 和 MCP-UI 之间存在密切的关系:
- MCP-UI 是先驱:MCP-UI 最早探索了通过 MCP 提供交互式 UI 的概念
- MCP Apps 是标准:MCP Apps 将 MCP-UI 的模式标准化为官方扩展
- MCP-UI 是实现:MCP-UI SDK 现在实现了 MCP Apps 规范
- MCP-UI 是试验场:MCP-UI 继续作为社区增强功能的试验场
对于已经使用 MCP-UI 的开发者,迁移到官方扩展是直接的,但也可以继续使用 MCP-UI,因为它的 SDK 支持 MCP Apps 模式。
6. 使用场景
MCP Apps 在以下场景中表现出色[9]:
6.1 数据探索
销售分析工具返回交互式仪表板。用户可以按地区筛选、深入查看特定账户、导出报告,而无需离开对话。
6.2 配置向导
部署工具呈现包含依赖字段的表单。选择"生产环境"会显示额外的安全选项;选择"暂存环境"会显示不同的默认值。
6.3 文档审查
合同分析工具以内联方式显示 PDF 并高亮显示条款。用户点击批准或标记部分内容,模型实时看到他们的决定。
6.4 实时监控
服务器健康工具显示实时更新的指标。无需重新运行工具即可查看当前状态。
7. 客户端支持
MCP Apps 目前已在多个主流客户端中得到支持[10]:
- Claude:支持 Web 和桌面体验
- Goose:Block 公司开发的 AI 助手
- Visual Studio Code:通过 GitHub Copilot 集成
- ChatGPT:OpenAI 的 AI 助手
- Postman:API 开发工具
- MCPJam:MCP 开发工具
这意味着开发者可以构建一个交互式体验,在所有广泛使用的客户端中运行,而无需编写任何客户端特定的代码。
8. 开发入门
8.1 环境设置
要开始构建 MCP Apps,可以使用官方 SDK:
npm install @modelcontextprotocol/ext-apps
npm install @mcp-ui/server
npm install @mcp-ui/client8.2 创建简单的 MCP App
以下是一个简单的示例,展示如何创建带有交互式 UI 的 MCP 工具:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { registerAppTool, registerAppResource } from '@modelcontextprotocol/ext-apps/server';
import { createUIResource } from '@mcp-ui/server';
import { z } from 'zod';
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
// 创建 UI 资源
const widgetUI = createUIResource({
uri: 'ui://my-server/widget',
content: {
type: 'rawHtml',
htmlString: `
<h1>交互式小部件</h1>
<button onclick="handleClick()">点击我</button>
<script>
function handleClick() {
window.parent.postMessage({
type: 'tool',
payload: { toolName: 'process_click', params: {} }
}, '*');
}
</script>
`
},
encoding: 'text',
});
// 注册资源处理器
registerAppResource(server, 'widget_ui', widgetUI.resource.uri, {}, async () => ({
contents: [widgetUI.resource]
}));
// 注册带有 _meta.ui.resourceUri 的工具
registerAppTool(server, 'show_widget', {
description: '显示交互式小部件',
inputSchema: { query: z.string() },
_meta: { ui: { resourceUri: widgetUI.resource.uri } }
}, async ({ query }) => {
return { content: [{ type: 'text', text: `查询: ${query}` }] };
});8.3 客户端渲染
在客户端使用 AppRenderer 组件渲染工具 UI:
import { AppRenderer } from '@mcp-ui/client';
function ToolUI({ client, toolName, toolInput, toolResult }) {
return (
<AppRenderer
client={client}
toolName={toolName}
sandbox={{ url: sandboxUrl }}
toolInput={toolInput}
toolResult={toolResult}
onOpenLink={async ({ url }) => {
// 验证 URL 方案后再打开
if (url.startsWith('https://') || url.startsWith('http://')) {
window.open(url);
}
}}
onMessage={async (params) => console.log('消息:', params)}
/>
);
}9. 总结与展望
MCP Apps 和 MCP-UI 协议为 AI 工具提供了强大的 UI 能力,使得 AI 助手不再局限于文本交互,而是能够提供丰富的可视化、表单、仪表板等交互式界面。这不仅提升了用户体验,也为 AI 应用的开发开辟了新的可能性。
随着更多客户端支持 MCP Apps,以及社区不断贡献新的组件和模式,我们可以预见 AI 交互将变得更加直观、高效和人性化。开发者现在就可以开始构建 MCP Apps,为用户提供前所未有的 AI 交互体验。
参考文献
Anthropic. "Introducing the Model Context Protocol." (2024-11-25). https://www.anthropic.com/news/model-context-protocol ↩︎
Model Context Protocol. "Specification." (2025-06-18). https://modelcontextprotocol.io/specification/2025-06-18 ↩︎
MCP Core Maintainers. "MCP Apps - Bringing UI Capabilities To MCP Clients." (2026-01-26). https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/ ↩︎
MCP-UI. "Protocol Details." (2025). https://mcpui.dev/guide/protocol-details ↩︎
Model Context Protocol. "MCP Apps." (2026). https://modelcontextprotocol.io/extensions/apps/overview ↩︎
MCP-UI. "Introduction." (2025). https://mcpui.dev/guide/introduction ↩︎
MCP-UI. "MCP-UI is now standardized into MCP Apps!" (2026). https://mcpui.dev ↩︎
MCP-UI. "Protocol Details - UIResource Wire Format." (2025). https://mcpui.dev/guide/protocol-details ↩︎
MCP Core Maintainers. "MCP Apps - Bringing UI Capabilities To MCP Clients." (2026-01-26). https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/ ↩︎
Model Context Protocol. "MCP Apps - Client Support." (2026). https://modelcontextprotocol.io/extensions/apps/overview ↩︎