认识 MCP Apps:价值、概念、场景、与 Web Apps 的区别 深入 MCP Apps:Server + Host + View 的协同运作机制 体验 MCP Apps:从零构建你的第一个 MCP App MCP Apps 与 A2UI:设计思路、能力边界与适用选择
01
假设在你的 AI 助手客户端中新增一个功能:能够连接企业的 CRM 系统,统计上个季度的销售与订单数据。
单纯的 Markdown 表格或冗长文本,表现力十分有限 展示实时变化的“监控面板”或非文本媒体数据较为麻烦 探索性交互(如排序、点击查看详情)需要来回反复对话 多轮对话会造成上下文膨胀、污染与 token 消耗
MCP Server 中的工具可以声明关联的交互式 UI 资源 返回的交互式 UI 可内嵌渲染在客户端应用(如AI 对话)中
支持嵌入 UI 与客户端应用之间的双向通信
数据探索与可视化:如上文所述 — 销售分析工具返回一个交互式大屏。用户可以直接在 AI 生成的界面中按地区过滤、向下钻取客户详情,并导出报告,全程无需离开对话窗口。
在 ERP 里查订单和客户信息 切到 MES 看生产进度和排产情况 再打开 WMS 确认库存与出库状态 回到 OA 发起审批或催办流程
02
Server 也就是MCP Server,除了注册工具,现在还需要注册 UI 资源。这些 UI 资源就是打包好的 HTML 页面,描述了工具的“UI”。
Host 也就是 AI 客户端应用。它负责连接 MCP Server、发现工具、在 iframe 中渲染 UI,并充当 UI View 和 Server 之间的"中间人"。
View 运行在 Host 的 iframe 沙箱中的可交互 UI “小应用”。它接收工具数据,展示界面,响应用户操作。 它们之间的关系如图:
把拿到的 HTML 渲染注入一个 iframe,这就是View 创建一个 AppBridge 对象 — View 和 Server 之间的通信桥梁 等待 View 来完成“握手”动作(ui初始化)
content 会进入 AI 模型上下文的精简内容,比如"北京,25°C,晴"。 structuredContent 用来给 UI 用的富数据,比如用来提供查询切换的城市列表等。
向对话发送消息 — 比如用户在 UI 上做了个选择,View 可以把用户的选择发回聊天界面,AI 就知道了用户的意图。 更新模型上下文 — View 可以告诉 AI 当前 UI 的状态,比如"用户正在查看上海天气",AI 在后续回答中就可以参考这个上下文。
绝对安全隔离:浏览器提供的跨 iframe 通信标准,iframe 里的代码只能通过 postMessage 对外传话。 基于事件监听:一方通过 window.postMessage() 喊话,另一方通过监听 message 事件来收听。
03
create-mcp-app 从零脚手架一个完整的 MCP App 项目。 migrate-oai-app 将已有的 OpenAI Apps SDK 项目迁移到 MCP Apps SDK。 add-app-to-server 用来给已有的 MCP Server 增加交互式的 UI。 convert-web-app 将普通 Web App 转化成 MCP App,让其可以在 MCP Host 应用中呈现。
npx skills add modelcontextprotocol/ext-apps
Node.js 20+ TypeScript 5+(MCP Apps SDK 全程 TypeScript) 对 MCP 协议与开发有基本了解(可翻阅我们的文章)
@modelcontextprotocol/ext-apps
基础 SDK,供 View 端开发使用(运行在 iframe 内)。
@modelcontextprotocol/ext-apps/app-bridge
MCP Host 端 SDK,用于开发 Host 应用与 View 通信。
@modelcontextprotocol/ext-apps/server
MCP Server 端 SDK,用于注册带 UI 的工具。
@modelcontextprotocol/ext-apps/react(可选)
基础 SDK 的 React Hooks 封装;如果选择React 开发 view,可以用它。
basic-server-vanillajs(或 react/vue/svelte 等变体)脚手架,初始化项目。核心结构如下:@modelcontextprotocol/ext-apps、@modelcontextprotocol/sdk、vite + vite-plugin-singlefile(用来把UI 部分打包成一个自包含的 HTML 文件)。registerAppTool(
server,
"get-weather",
{
title: ...
description: ...
inputSchema: ...
_meta: { ui: { resourceUri: weatherResourceUri } },
},
async ({ city }) => {.........模拟返回天气数据.......
},
);registerAppResource(
server,
...
async () => {
const html = await fs.readFile(path.join(DIST_DIR, "weather-app.html"), "utf-8");
return {
contents: [
{ uri: weatherResourceUri, mimeType: RESOURCE_MIME_TYPE, text: html },
],
};
},
);import { App } from"@modelcontextprotocol/ext-apps";
...
const app = new App({ name: "Weather App", version: "1.0.0" });
// 注册工具结果达到:重新渲染 UI
app.ontoolresult = (result) => {
const data = parseResult(result);
if (data) {
currentCity = data.city;
renderWeather(data);
}
};
// 点击UI上的刷新按钮,更新天气数据
refreshBtn.addEventListener("click", () => {
fetchWeather(currentCity);
});
// 与Host连接、初始化、握手等
app.connect();先注册,后连接
npm run start
localhost:3001/mcp。# 在 ext-apps/examples/basic-host 目录下SERVERS='["http://localhost:3001/mcp"]' npm run dev
http://localhost:8080,就可以看到这个界面:一种是使用上面提到的 SDK中的 AppBridge 模块,用来在沙盒iframe渲染UI、消息传递、工具调用等。具体参考官方的例子 basic-host。 另一种是使用官方独立的 mcp-ui React组件库,具体参考: https://github.com/MCP-UI-Org/mcp-ui。
04
UI生成方式 A2UI 的 UI 由 AI 动态生成 JSON 来描述,属于“即时构建 UI”;而 MCP Apps 的 UI 则由开发者预先实现为完整网页。
换句话说,在 A2UI 中,AI 更像“设计师”,实时构建界面;而在 MCP Apps 中,开发者提供现成组件,AI 按需调用。
组件灵活性 MCP Apps 通过 iframe 几乎可以嵌入任意复杂的前端应用,支持高度自由的交互与渲染;A2UI 生成的 UI 则通常受限于预定义的白名单组件。
不过,正因为组件受限,A2UI 的安全边界相对更清晰;而 MCP Apps 虽然有沙盒 iframe 机制,但仍需对第三方前端代码进行一定程度的信任。
跨平台体验 A2UI 的最终渲染由各端原生框架完成;MCP Apps 则更偏向在浏览器环境中工作,通过 iframe 在 Web 界面中渲染。
如果你的 AI 应用需要运行在多种终端类型上,并希望 UI 风格与系统原生体验保持一致,A2UI 可能更合适。MCP Apps 目前主要应用于 Web 场景,未来也可能扩展到更多终端。
生态支持 MCP Apps 得到 Anthropic 与 OpenAI 的支持,并已在 Claude、ChatGPT 等主流 AI 客户端中落地。开发者社区也贡献了大量 SDK 与示例,整体门槛相对较低。
A2UI 当前主要应用于 Google 自身产品及部分开源项目中,后续生态扩展情况仍有待观察。
使用场景侧重 MCP Apps 更适合在对话式 Agent 应用中嵌入垂直应用开发者提供的交互能力,例如 SaaS 产品推出 MCP Apps 插件版。
而 A2UI 更像是在培养 AI 自身的前端生成能力:用户只需用自然语言描述需求,AI 即可动态生成一个可用的界面。
END
