ui:// MCP-Apps cards
Parent: capabilities
Per-tool interactive cards in the chat, delivered as MCP-Apps ui:// resources, rendered in a sandboxed iframe talking to the host via postMessage. All per-tool cards are migrated — ask_visitor, corpus_search/list, summarize, the calendar tools, and even calendar_book (via the booker plugin's own ui:// card); the backend serves them through the tool's _meta.ui_resource.
The handshake
(The wire also carries mcp-ui:tool / mcp-ui:tool-result — a card calling back into a tool — and mcp-ui:state-set / mcp-ui:state-ack for card state; app/src/components/page/McpAppCard.tsx + its hook.)
Class view — the frontend dispatch
Precision: CardKind is only 'dump' | 'none' — the ui:// path is not a kind: when the tool result carries _meta.ui_resource, uiHtmlForTool → McpAppCard renders it regardless, and cardKindFor only decides the fallback for the rest.
The one remaining exception: the generic dump
NON_SANDBOX_CARDS (app/src/components/page/ToolCallCards.tsx) has shrunk to a single entry: the generic dump card used for skill_* / ext_* tool results (a debug-style text rendering). Everything else is a sandboxed ui:// card.
Proposed (🚧 — still unbuilt as of 2026-09-07: mcpplugin.Manifest has no renderer field)
Replace even that residue with a manifest-declared renderer field (renderer: ui | dump) — consistent with the Origin/manifest philosophy of mcp-capability-plugins: each capability declares its rendering, no hardcoded list at all.