Closed
Description
Context
The AppRenderer is the heaviest piece of the Apps tab — it owns the iframe and the AppBridge lifecycle from @modelcontextprotocol/ext-apps. To keep the screen layer "dumb", the wiring layer (Phase 3) constructs the bridge from the active MCP Client and pushes input/result/cancellation through an imperative ref rather than via prop drilling.
See Apps Screen feature spec and storybook component plan entry 2.5b.
Legacy v1 reference: AppRenderer.tsx.
Scope
AppRenderer
- Path:
clients/web/src/components/elements/AppRenderer/(orgroups/if it ends up composing other parts). - Props:
sandboxPath: string— URL/path of the sandbox proxy iframe.tool: Tool— selected app tool (used for resource URI lookup).bridgeFactory: (iframe: HTMLIFrameElement) => AppBridge— wiring layer constructs the bridge using a real MCPClient.onError?: (err: Error) => void— error notifications.
- Imperative ref (
AppRendererHandle):sendToolInput(args: Record<string, unknown>): Promise<void>sendToolResult(result: CallToolResult): Promise<void>sendToolCancelled(reason: string): Promise<void>teardown(): Promise<void>
- Owns the iframe element and
AppBridgehandle; no Mantine controls beyond a positioningBox. - On unmount: invokes
bridge.teardownResource(...)then disconnects the transport.
Stories
- Loading (iframe mounting), Loaded (with mock bridge factory), Error, Maximized.
- Mock the bridge factory in stories so Storybook does not need a real MCP client.
Acceptance criteria
- Real MCP types only (
Tool,CallToolResult,Implementation) — no v1.5 wrappers. - Bridge construction is delegated entirely to
bridgeFactoryso the renderer is testable in Storybook with mocks. - No store access; no business logic — only iframe + bridge proxy.
- Tests pass and coverage is ≥ 90%.
- Cleans up the bridge on unmount (no leaked
MessagePortlisteners).
Dependencies
- Blocked by: Apps tab — add @modelcontextprotocol/ext-apps dep and isAppTool helper in core.
- Can run in parallel with:
AppListItem/AppDetailPanelissue.
Branch / Base
- Base:
v2/main - Label:
v2
Metadata
Metadata
Assignees
Labels
v2Issues and PRs for v2Issues and PRs for v2
Activity
feat(apps): AppRenderer with imperative ref (#1262) (#1282)