前言¶
MCP Apps 允许 MCP 工具结果附带 ui:// 的 HTML 资源,由客户端渲染成可交互界面。要在 DeepSeek Harness(DSH)里跑通它,需要协议 Host、沙箱渲染器和显示模式管理这一整套组件。
对比已有做法:DSH 的 Web 构建自带一个 inline-only 渲染器,只覆盖行内一种表面。下面介绍 openma-ai/dsh-mcp-apps:它把 MCP Apps Host 与 Web 渲染器打包成普通 Cordis 插件,补上这一层能力。
这是什么¶
openma-ai/dsh-mcp-apps(npm 包名 @openma/dsh-mcp-apps,当前版本 0.1.1,MIT 许可)为 DeepSeek Harness 提供 MCP Apps 支持,以普通 Cordis 插件形式打包。实现基于官方 @modelcontextprotocol/ext-apps 的 AppBridge 与 PostMessageTransport。
项目由三个包组成:
@openma/dsh-mcp-apps:可安装、可嵌套的 bundle kernel,管理 Host 与 Web 两个子行的生命周期;@openma/dsh-mcp-apps-host:内部运行时包,提供ctx.mcpApps服务注册表;@openma/dsh-mcp-apps-web:内部运行时包,在双 iframe 沙箱中运行 App HTML 的 Web 渲染器。
核心能力¶
复用同一条 MCP 连接¶
安装 bundle 后新增两个独立子行:共享既有 MCP 连接的 Host 服务,以及在双 iframe 沙箱中运行 App HTML 的 Web 渲染器。MCP 服务器连接保持为独立插件行,DSH 的 mcp-client 检测到可选的 ctx.mcpApps 服务后自动贡献连接,例如:
- name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: weather
transport: stdio
command: weather-mcp-server
这样配置后,工具、资源、prompts、模型侧执行与 AppBridge 调用共用同一个 MCP SDK Client,包括它的认证与重连 generation;这个项目不会开第二条连接。
受限的浏览器 Remote 边界¶
跨浏览器 Remote 边界的调用只有两种:callTool 与 readResource,后者只接受 ui:// URI。Host 侧插件可以在进程内调用 listResources、listPrompts、getPrompt,且这些结果不会注入模型上下文。
渲染器的认领条件¶
Web 渲染器只认领同时满足以下条件的 Tool 结果:
- presentation card 为
mcp-app; - 资源 URI 是
ui://; - MIME 类型精确为
text/html;profile=mcp-app; - 结果是通过 schema 校验的合法 MCP Tool 结果。
其余结果不参与 tool.call.takeover 链,继续走普通的工具视图与通用 fallback。
一个会话,三种表面¶
一个 AppBridge 会话可以在 inline、fullscreen(右侧面板)与受限画中画三种表面之间移动,无需重挂载 iframe。左下角的 Host 显示模式控件,只在 App 通过 appCapabilities.availableDisplayModes 声明后才会出现。
沙箱边界¶
- App HTML 不在 DSH 文档内运行,而是加载进双 iframe 沙箱;
- CSP 先于 App 代码安装,仅接受经过校验的 HTTP(S)/WS(S) 域来源;
- 外部导航仅允许 HTTP(S) URL,且在新标签页打开;
- inline 高度请求限制在 96–720 px;
- 内部文档一旦发生导航,立即切断 Host-to-App 转发。
安装与启用¶
1、安装 bundle:
dsh plugin --profile web add @openma/dsh-mcp-apps
从本地检出安装时,先装依赖,再添加根目录:
npm install
dsh plugin --profile web add .
若当前 profile 已确认包含官方 Host,也可以只装渲染器,这是最小等价方案:
dsh plugin --profile web add ./packages/web
2、bundle patch 会挂载一个 kernel,其下拥有 mcp-apps-host 与 mcp-apps-web 两个子行:
- id: mcp-apps-bundle
name: '@openma/dsh-mcp-apps'
3、在已经提供 ctx.mcpApps 与生成 remote.mcpApps 命名空间的 DSH 组合上,安装完整 bundle 也是安全的:fallback Host 行会变成 no-op,Web 渲染器直接复用既有 Remote。
典型用法:验证三种表面切换¶
仓库自带一个示例 stdio MCP 服务器。构建并启动:
npm run build:example:display-modes
node examples/display-modes/server.mjs
它的 display_modes 工具会打开 ui://dsh/display-modes。在界面里递增计数器并依次切换三种表面,可以验证 App 会话在表面之间移动后依然保持存活。
适用场景与注意事项¶
- 想在 DSH 的 Web profile 里直接使用 MCP Apps,安装本包即可。如果目标是在 DSH 里使用 Codex、Claude Code、Pi 等外部 Agent Plugins(包含它们各自的 MCP Apps),只需安装
@openma/dsh-agents-plugins-bridge,它已自带 MCP Apps;不要把两个 bundle 装进同一个 profile。 - Host 包与 UI 无关。完整的 HTML/AppBridge 路径目前只有 Web 包实现;TUI 可以独立安装 Host 并自行提供渲染器(例如文本 fallback 或「在浏览器中打开」),终端客户端不应在行内执行任意 App HTML。
- Web 渲染器针对当前 DSH Web 构建的
tool.call.takeover链。与 DSH 0.1.0-rc.7 组合时,priority -110 使它先于 priority -100 的内置 inline-only 渲染器认领 MCP App 结果。 - Downloads、App-to-chat messages、sampling 尚未启用。
- 开发或构建需要 Node.js 20 或更新版本。
- 插件以当前 dsh 进程的权限运行。安装前建议检查仓库源码与许可证(本项目为 MIT),确认符合自己的安全要求。
结尾¶
回顾一下:dsh-mcp-apps 用两个 Cordis 插件行把 MCP Apps 的协议 Host 与沙箱渲染接进 DSH,复用既有 MCP 连接,支持 inline、fullscreen、画中画三种表面,并把浏览器安全边界收敛到 callTool 与 ui:// 的 readResource。社区目录页见 https://www.skillhub.cn/plugins/openma-ai/dsh-mcp-apps(独立站点,与 DeepSeek 无官方从属关系),源码与文档见 https://github.com/openma-ai/dsh-mcp-apps。