在 ChatKit 对话中把 MCP 工具调用结果渲染为可交互的内联应用。
_meta.ui.resourceUri 声明 UI 资源,ChatKit 就会把该资源渲染为对话中的内联 iframe,并通过标准 MCP Apps JSON-RPC bridge 与 Xpert 后端通信。
适合使用 MCP Apps 的场景包括图表、仪表盘、地图、表单、媒体浏览器、下钻分析等需要交互的工具结果。如果只是静态结构化卡片,优先使用 ChatKit Widgets。如果是工作台页面、集成配置页或长期存在的平台页面,继续使用 Xpert extension view。
Xpert 支持的能力
Xpert MCP Apps Host 支持:- 通过
_meta.ui.resourceUri发现工具 UI 元数据 - ChatKit
McpApp消息组件 ui://MCP resource,MIME 类型为text/html;profile=mcp-app- JSON-RPC bridge 方法,包括
ui/initialize、ui/notifications/tool-input、ui/notifications/tool-result、tools/call、resources/read、ui/open-link、ui/message、ui/update-model-context、ui/request-display-mode、ui/notifications/size-changed - 通过
_meta.ui.visibility = ['app']暴露 app-only 工具 - 从 MCP App resource metadata 读取
_meta.ui.csp、_meta.ui.permissions、domain、prefersBorder - 短生命周期 app instance,并支持刷新历史消息后用安全元数据恢复
- 通过 Xpert plugin 安装的 plugin-managed MCP server
window.openai API。为了保持跨 host 兼容,MCP App 应优先使用标准 bridge。
架构
聊天历史只保存安全元数据,例如appInstanceId、resourceUri、toolName、toolsetId、serverName,以及受大小限制的初始工具输入/结果快照。原始 HTML 不写入对话历史。页面刷新后,如果内存中的 app instance 已经过期,后端可以根据这些元数据重新连接 Toolset 并恢复 instance。
历史回放和初始工具结果
MCP App 首次渲染时需要收到触发工具调用的tool-input 和 tool-result。Xpert + ChatKit 的读取顺序是:
- 优先使用 live app instance:只要内存中的 app instance 仍有效,resource 响应会直接返回 live instance 中保存的完整初始
toolResult。 - live instance 不存在时 revive:刷新历史、Agent Toolset 已关闭或后端进程重启后,MCP Apps Host 会重新连接 Toolset,读取
ui://resource,并创建新的 app instance。 - 最后使用聊天历史中的小型快照:如果消息中保存了受控大小的初始
toolResult,ChatKit 会用它回放ui/notifications/tool-result;如果没有可用结果,则只发送ui/notifications/tool-input,不会伪造空结果。
128KB 的标准 CallToolResult 会内联保存;超过阈值时,消息只保存 toolResultSize 和 toolResultTruncated: true。阈值可通过后端环境变量调整:
运行时元数据约定
ChatKit 不直接理解任意 MCP server 的实现细节,而是依赖 Xpert 后端保留从当前 Toolset 中发现的 MCP App 元数据。 运行时,当 Xpert 看到_meta.ui.resourceUri,并且 resource URI 使用 ui:// scheme 时,该 MCP 工具就具备 App 能力。工具 _meta.ui 只应该承载 resourceUri 和 visibility。CSP、浏览器权限、domain、prefersBorder 等资源安全与呈现元数据应放在 MCP App resource 的 _meta.ui 上;Xpert 会优先读取 resources/read content item metadata,并在缺失时使用 resources/list metadata 作为 fallback。
visibility 控制谁可以调用工具:
常见设计是:一个 model-visible 工具负责打开 MCP App,另有一个或多个 app-only 工具供 iframe 交互使用。
Xpert 会把非 model-visible 的工具从 LLM 工具列表中过滤掉。MCP Apps Host 也会拒绝 iframe 调用不可见于 app 或在 Toolset 中被禁用的工具。
插件侧 metadata 和工具注册示例请参考 MCP Tools 和 MCP Apps。
Resource 要求
MCP App resource 必须返回带 MCP App profile 的 HTML,MIME 类型为text/html;profile=mcp-app。注册 resource 是 MCP server 的职责;校验和 sandbox 则由 host 负责。
resource 也可以在 _meta.ui 中声明展示 metadata:title、description 和 icon。title 与 description 可以是字符串,也可以是 Xpert 风格的 I18nObject;icon 使用共享的 IconDefinition 结构。ChatKit 只把这些安全描述符写入消息历史,并根据当前 ChatKit 语言解析文本,在 MCP App 消息头部渲染 icon/title/description。
安全默认值是严格的:
- 初始 App HTML 只接受
ui://resource - 原始 HTML 在渲染时读取,不写入聊天历史
- CSP 默认 deny-by-default,只允许 resource
_meta.ui.csp中声明的域名 - camera、microphone、geolocation、clipboard-write 默认拒绝,只有 resource
_meta.ui.permissions显式请求时才会通过 iframeallow放行 - iframe 内通过
resources/read读取的资源限定在同一个 MCP server 内,拒绝http://、https://、javascript://、data://、blob://等浏览器或脚本 scheme - resource
domain当前不会创建 dedicated origin;v1 中视为 host 暂不支持的 metadata - iframe 的所有工具调用都经过 Xpert 后端,并执行租户、组织、工作区、Toolset、工具启用状态等校验
主题变量
ChatKit 会在 MCP App HTML 写入 iframe 之前,向<head> 注入一段宿主主题样式。变量名使用通用 --mcp-app-* 前缀,其他 MCP Apps host 也可以复用同一契约:
--mcp-app-* 公共变量,而不是依赖 ChatKit 内部 CSS class 或私有 token。当前 host 提供:
推荐 App 样式:
--mcp-app-color-chart-* 是 host 提供的图表色提示,不保证一定适合具体业务图表。如果 host 主题的图表 token 偏灰或仅用于弱化 UI,MCP App 可以定义自己的语义数据色板,例如 --sales-chart-revenue、--sales-chart-margin、--risk-chart-high,同时继续使用 --mcp-app-* 控制背景、文本、边框、字体和圆角。
ui/initialize 的 hostContext.theme 仍返回 light / dark 字符串;同一份变量也会出现在 hostContext.themeCssVariables 中,供 App 初始化图表主题或生成 canvas 配色。
ChatKit 也会通过 hostContext.locale、hostContext.language 和 hostContext.direction 传递当前 UI 语言。在 iframe 文档运行前,ChatKit 会把同样的值写入 App HTML 的 lang 与 dir 属性。MCP App 应在自己的前端资源中使用这些字段完成标签、数字/日期格式、图表标题和校验消息的本地化。
Bridge 方法
iframe 内部通过postMessage 发送 JSON-RPC 消息。App 应先初始化并读取 host 能力。初始化请求需要包含 App 信息、能力和协议版本:
McpUiInitializeResult:
CallToolResult 形状的工具结果:
编写和打包
在 Xpert 中推荐用 plugin-managed MCP server 交付 MCP App。插件负责 MCP server 入口、工具元数据、ui:// resource、app-only 工具和安装策略;ChatKit 只负责托管工具调用产生的 app instance。
插件侧实现流程、manifest schema、包结构和本地测试清单请参考 MCP Tools 和 MCP Apps。
与其他 Xpert UI 能力的关系
MCP Apps 是 Xpert 的 UI 扩展点之一:
不要把任意 HTML 塞进 widget renderer,也不要让 middleware 承担 resource host 的职责。MCP Apps 应走 MCP resource 和 bridge 流程;extension view 仍然走 Xpert view manifest 以及平台 data/action provider。
启用和运维
生产环境需要显式启用:appInstanceToken,ChatKit 在 resource 和 RPC 请求中带上它。生产环境中,如果签名 token 缺失、过期,或与 tenant、workspace、Toolset、server、tool、resource URI 不匹配,revive、tools/call、resources/read 都会被拒绝。
本地非生产环境默认启用 MCP Apps,并兼容没有 appInstanceToken 的旧消息。插件构建、安装、受控 stdio runtime 和运行副本检查请参考 MCP Tools 和 MCP Apps。