You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Title: Interactive MCP Apps rendered inside the Playground chat Goal: When a tool result or resource includes MCP Apps UI content (per SEP-1865), the React Playground renders it as a sandboxed iframe inline in the conversation, with bidirectional JSON-RPC to the gateway. This turns Playground from a text/markdown chat into a host capable of displaying dashboards, charts, configuration wizards, and other interactive UIs returned by MCP servers. Why now: SEP-1865 reached stable on 2026-01-26 and is already supported by Claude (web + desktop), VS Code Insiders, Goose, and Postman. Adding host support in Playground gives ContextForge users a first-class way to consume rich tool output — including the obvious near-term win of metrics/observability tools returning real charts instead of text tables.
🧑🏻💻 User Story 1 — Inline rendering of an MCP App
As a: Playground user calling a tool that returns an MCP App (e.g. a metrics dashboard) I want: the app to render inline in the assistant's turn, sandboxed and themed So that: I can see and interact with rich tool output without leaving the chat
✅ Acceptance Criteria
Scenario: Tool returns MCP App contentGiven a tool result contains UI content tagged with the io.modelcontextprotocol/ui extension
When the assistant turn renders
Then the content is mounted in a sandboxed iframe inline in the message
And the iframe inherits the Playground theme (light/dark) via the documented theming hook
And CSP enforces the SEP-1865 sandbox restrictions
Scenario: App reads model contextGiven a rendered MCP App calls ui/get-model-context
Then it receives the current conversation context per spec
🧑🏻💻 User Story 2 — Bidirectional communication
As a: MCP App author I want: my app to call tools, post chat messages, and update model context from inside the iframe So that: my dashboard can fetch fresh data, drive the conversation, and behave like a first-class participant
✅ Acceptance Criteria
Scenario: App invokes a toolGiven a rendered MCP App calls tools/call via the host bridge
Then the Playground forwards the call through the gateway with the session's auth
And the response is returned to the app
Scenario: App posts a chat messageGiven a rendered MCP App calls ui/message
Then the message appears in the conversation as if the user had typed it
Scenario: App updates model contextGiven a rendered MCP App calls ui/update-model-context
Then subsequent assistant turns see the updated context
🧑🏻💻 User Story 3 — Safety and fallback
As a: gateway operator I want: untrusted MCP App content to be confined and gracefully degraded when unsupported So that: a third-party MCP server can't pivot through Playground into the rest of the UI
✅ Acceptance Criteria
Scenario: CSP and sandbox enforcementGiven an MCP App attempts to break out of its iframe sandbox or violate CSP
Then the attempt is blocked and logged
Scenario: Unsupported display modeGiven a tool result includes UI content the Playground cannot render
Then a fallback card is shown with the resource link and MIME type
Scenario: Feature flag offGiven MCP Apps host support is disabled by config
Then UI content is shown as a non-interactive fallback only
Server-side ingestion, federation, and proxying of MCP Apps from upstream MCP servers.
Tool-UI association metadata in the registry.
Non-Playground hosts (e.g. surfacing the same content elsewhere in the admin UI).
🔗 MCP Standards Check
Implements SEP-1865 (io.modelcontextprotocol/ui) on the host/client side.
No breaking changes to existing MCP-compliant integrations — content without the extension renders as today.
🔄 Alternatives Considered
Ad-hoc inline rendering of HTML/SVG from tool results. Rejected: no security model, no bidirectional comms, no theming contract, no standards alignment.
Chart-only convention (e.g. Vega-Lite JSON via a known MIME). Useful as a narrow path for the metrics use case, but not a substitute for MCP Apps. Could ship alongside as a lower-cost interim.
🧭 Type of Feature
Relationship to other issues
io.modelcontextprotocol/ui).🧭 Epic
Title: Interactive MCP Apps rendered inside the Playground chat
Goal: When a tool result or resource includes MCP Apps UI content (per SEP-1865), the React Playground renders it as a sandboxed iframe inline in the conversation, with bidirectional JSON-RPC to the gateway. This turns Playground from a text/markdown chat into a host capable of displaying dashboards, charts, configuration wizards, and other interactive UIs returned by MCP servers.
Why now: SEP-1865 reached stable on 2026-01-26 and is already supported by Claude (web + desktop), VS Code Insiders, Goose, and Postman. Adding host support in Playground gives ContextForge users a first-class way to consume rich tool output — including the obvious near-term win of metrics/observability tools returning real charts instead of text tables.
🧑🏻💻 User Story 1 — Inline rendering of an MCP App
As a: Playground user calling a tool that returns an MCP App (e.g. a metrics dashboard)
I want: the app to render inline in the assistant's turn, sandboxed and themed
So that: I can see and interact with rich tool output without leaving the chat
✅ Acceptance Criteria
🧑🏻💻 User Story 2 — Bidirectional communication
As a: MCP App author
I want: my app to call tools, post chat messages, and update model context from inside the iframe
So that: my dashboard can fetch fresh data, drive the conversation, and behave like a first-class participant
✅ Acceptance Criteria
🧑🏻💻 User Story 3 — Safety and fallback
As a: gateway operator
I want: untrusted MCP App content to be confined and gracefully degraded when unsupported
So that: a third-party MCP server can't pivot through Playground into the rest of the UI
✅ Acceptance Criteria
📐 Design Sketch
flowchart LR Tool[MCP Tool result<br/>w/ io.modelcontextprotocol/ui content] --> GW[ContextForge Gateway] GW --> Chat[/llmchat session/] Chat --> PG[React Playground] PG --> IF[Sandboxed iframe<br/>MCP App] IF -- ui/message, ui/update-model-context,<br/>tools/call via host bridge --> PG PG -- forwarded JSON-RPC --> GWScope
In scope:
/llmchat/chat.ui/get-model-context,ui/update-model-context,ui/message, and forwardedtools/call.Out of scope (covered by #2527):
🔗 MCP Standards Check
io.modelcontextprotocol/ui) on the host/client side.🔄 Alternatives Considered
📓 Additional Context
@modelcontextprotocol/ext-apps