Preface¶
MCP Apps allow MCP tool results to carry ui:// HTML resources, which are rendered by the client into an interactive interface. To implement this in DeepSeek Harness (DSH), a full suite of components is required: the protocol Host, the sandbox renderer, and the display mode manager.
In comparison to existing approaches: DSH’s Web build comes with an inline-only renderer, covering only the inline surface. Below is an introduction to openma-ai/dsh-mcp-apps: it packs the MCP Apps Host and Web renderer into a standard Cordis plugin, filling in this layer of capability.
What is it¶
openma-ai/dsh-mcp-apps (npm package name @openma/dsh-mcp-apps, current version 0.1.1, MIT license) provides MCP Apps support for DeepSeek Harness, packaged as a standard Cordis plugin. The implementation is based on the official @modelcontextprotocol/ext-apps AppBridge and PostMessageTransport.
The project consists of three packages:
@openma/dsh-mcp-apps: A installable, nestable bundle kernel that manages the lifecycles of the Host and Web child rows;@openma/dsh-mcp-apps-host: An internal runtime package providing thectx.mcpAppsservice registry;@openma/dsh-mcp-apps-web: An internal runtime package, the Web renderer that runs App HTML within a dual-iframe sandbox.
Core Capabilities¶
Reusing the Same MCP Connection¶
After installing the bundle, two independent child rows are added: the Host service sharing the existing MCP connection, and the Web renderer running App HTML in a dual-iframe sandbox. The MCP server connection remains as an independent plugin row. DSH’s mcp-client automatically contributes the connection upon detecting the optional ctx.mcpApps service, for example:
- name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: weather
transport: stdio
command: weather-mcp-server
With this configuration, tools, resources, prompts, model-side execution, and AppBridge calls share the same MCP SDK Client, including its authentication and reconnection generation; this project does not open a second connection.
Restricted Browser Remote Boundary¶
Cross-browser Remote boundary calls are limited to two types: callTool and readResource; the latter only accepts ui:// URIs. Host-side plugins can call listResources, listPrompts, and getPrompt within the process, and these results are not injected into the model context.
Renderer Claim Conditions¶
The Web renderer only claims Tool results that meet the following conditions:
- presentation card is
mcp-app; - resource URI is
ui://; - MIME type is exactly
text/html;profile=mcp-app; - result is a valid MCP Tool result passing schema validation.
Other results do not participate in the tool.call.takeover chain and proceed with the standard tool view and generic fallback.
One Session, Three Surfaces¶
An AppBridge session can move between three surfaces: inline, fullscreen (right panel), and restricted Picture-in-Picture, without needing to remount the iframe. The Host display mode control in the bottom-left corner only appears after the App declares it via appCapabilities.availableDisplayModes.
Sandbox Boundaries¶
- App HTML does not run inside the DSH document but is loaded into a dual-iframe sandbox;
- CSP is installed before App code and only accepts verified HTTP(S)/WS(S) domain sources;
- External navigation is only allowed for HTTP(S) URLs and opens in a new tab;
- Inline height requests are limited to 96–720 px;
- Internal document navigation immediately cuts off Host-to-App forwarding.
Installation and Enablement¶
- Install the bundle:
dsh plugin --profile web add @openma/dsh-mcp-apps
When installing from a local checkout, install dependencies first, then add the root directory:
npm install
dsh plugin --profile web add .
If the current profile is confirmed to contain the official Host, you can also install just the renderer; this is the minimal equivalent solution:
dsh plugin --profile web add ./packages/web
- The bundle patch mounts a kernel, under which there are two child rows:
mcp-apps-hostandmcp-apps-web:
- id: mcp-apps-bundle
name: '@openma/dsh-mcp-apps'
- Installing the full bundle is also safe on a DSH combination that already provides
ctx.mcpAppsand generates theremote.mcpAppsnamespace: the fallback Host row becomes a no-op, and the Web renderer directly reuses the existing Remote.
Typical Usage: Verifying Surface Switching¶
The repository comes with an example stdio MCP server. Build and start it:
npm run build:example:display-modes
node examples/display-modes/server.mjs
Its display_modes tool opens ui://dsh/display-modes. Increment the counter in the interface and switch between the three surfaces sequentially to verify that the App session remains alive after moving between surfaces.
Scenarios and Considerations¶
- To use MCP Apps directly in DSH’s Web profile, install this package. If the goal is to use external Agent Plugins (including their respective MCP Apps) like Codex, Claude Code, Pi in DSH, just install
@openma/dsh-agents-plugins-bridge, which already includes MCP Apps; do not install both bundles into the same profile. - The Host package is UI-independent. The full HTML/AppBridge path is currently only implemented in the Web package; TUI can independently install the Host and provide its own renderer (e.g., text fallback or “open in browser”), and terminal clients should not execute arbitrary App HTML inline.
- The Web renderer targets the current DSH Web build’s
tool.call.takeoverchain. When combined with DSH 0.1.0-rc.7, priority -110 makes it claim MCP App results before the built-in inline-only renderer with priority -100. - Downloads, App-to-chat messages, and sampling are not yet enabled.
- Development or build requires Node.js 20 or later.
- Plugins run with the permissions of the current dsh process. It is recommended to check the repository source code and license (this project is MIT) before installation to ensure it meets your security requirements.
Closing¶
To summarize: dsh-mcp-apps integrates the MCP Apps protocol Host and sandbox rendering into DSH using two Cordis plugin rows, reusing existing MCP connections, supporting three surfaces (inline, fullscreen, and Picture-in-Picture), and narrowing the browser security boundary to callTool and readResource for ui://. See https://www.skillhub.cn/plugins/openma-ai/dsh-mcp-apps (independent site, no official affiliation with DeepSeek) for the community directory page, and https://github.com/openma-ai/dsh-mcp-apps for source code and documentation.