Feature: Preview tool should support rendering MCP Apps (ext-apps)
Summary
The Claude Preview tool (preview_start / preview_screenshot) currently only supports localhost dev servers. It should also support rendering MCP Apps (text/html;profile=mcp-app resources) inline — the same way claude.ai web and Claude Desktop already do.
Context
MCP Apps are interactive HTML interfaces returned by MCP servers via structured_content + ui:// resources. They're already supported by Claude Desktop, claude.ai, VS Code Copilot, Cursor, ChatGPT, Goose, and others per the MCP client matrix.
When an MCP tool declares _meta.ui.resourceUri pointing to a ui:// resource, the host should:
- Fetch the HTML resource from the MCP server
- Render it in a sandboxed iframe
- Pass
structured_contentfrom tool results to the app via postMessage
Current behavior
- Claude Code CLI receives
structured_contentfrom MCP tools but ignores it — only theTextContentfallback is shown - The Preview tool can render localhost dev servers but has no integration with MCP App resources
- External links in previewed pages are blocked (expected), but there's no way to render MCP App HTML that communicates with its MCP server
Proposed behavior
When an MCP tool result includes structured_content and the tool has a ui.resourceUri, Claude Code should:
- Fetch the MCP App HTML resource via
ReadMcpResourceTool - Render it in the Preview panel (sandboxed iframe)
- Bridge
structured_contentto the app via the ext-apps postMessage protocol - Support bidirectional tool calls (app → MCP server) through the existing MCP connection
This would give Claude Code feature parity with Claude Desktop for MCP Apps rendering.
Workaround
Currently we work around this by:
- Creating a standalone HTML page that fetches data from a static JSON file
- Serving it via
python3 -m http.serverthrough the Preview tool - Manually piping MCP tool output into the JSON file
This loses all the benefits of MCP Apps (bidirectional data flow, live updates, tool calls from the app).
References
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗