Context
Compose the AppsScreen and wire it as a top-level tab in the connected layout. See Apps Screen feature spec and storybook component plan entry 3.2a.
Scope
AppsScreen
- Path:
clients/web/src/components/screens/AppsScreen/
- Two-panel layout (sidebar + dynamic right pane).
- Receives the already-filtered subset of tools that are MCP Apps. Filtering happens in the wiring layer using
isAppTool from core/mcp/apps.
- Props:
tools: Tool[] (apps only)
listChanged: boolean
sandboxPath: string
bridgeFactory: (iframe: HTMLIFrameElement) => AppBridge
rendererRef: Ref<AppRendererHandle>
onRefreshList: () => void
onSelectApp: (name: string) => void
onOpenApp: (name: string, args: Record<string, unknown>) => void
onCloseApp: () => void
- Right pane swaps between
AppDetailPanel (form state) and AppRenderer (running state) plus a header with "Back to Input" / Maximize / Close.
- Maximize hides the sidebar so the app gets full viewport width.
- Auto-launches the app when selected if the tool has no input fields.
- Search and "Refresh Apps" mirror
ToolControls.
InspectorView integration
- Add
"Apps" to ALL_TABS (placed right after "Tools").
- Add an
"apps" value to InspectorTab in clients/web/src/types/navigation.ts.
- Add a new
<ScreenStage active={activeTab === "Apps"}> block in InspectorView that mounts AppsScreen with stub noop callbacks (Phase 3 wiring will replace them with real useManagedTools / useConnection calls, matching the pattern for the other screens).
availableTabs derivation should expose the Apps tab whenever the server advertises tools capability (apps are tools, not a separate capability).
Stories
NoSelection, AppSelected, AppRunning, AppRunningMaximized, NoFieldsApp, WithListChanged, Empty.
Acceptance criteria
Dependencies
- Blocked by:
- Apps tab — add @modelcontextprotocol/ext-apps dep and isAppTool helper in core
- Apps tab — AppListItem and AppDetailPanel groups
- Apps tab — AppRenderer with imperative ref
Branch / Base
Context
Compose the AppsScreen and wire it as a top-level tab in the connected layout. See Apps Screen feature spec and storybook component plan entry 3.2a.
Scope
AppsScreenclients/web/src/components/screens/AppsScreen/isAppToolfromcore/mcp/apps.tools: Tool[](apps only)listChanged: booleansandboxPath: stringbridgeFactory: (iframe: HTMLIFrameElement) => AppBridgerendererRef: Ref<AppRendererHandle>onRefreshList: () => voidonSelectApp: (name: string) => voidonOpenApp: (name: string, args: Record<string, unknown>) => voidonCloseApp: () => voidAppDetailPanel(form state) andAppRenderer(running state) plus a header with "Back to Input" / Maximize / Close.ToolControls.InspectorViewintegration"Apps"toALL_TABS(placed right after"Tools")."apps"value toInspectorTabinclients/web/src/types/navigation.ts.<ScreenStage active={activeTab === "Apps"}>block inInspectorViewthat mountsAppsScreenwith stubnoopcallbacks (Phase 3 wiring will replace them with realuseManagedTools/useConnectioncalls, matching the pattern for the other screens).availableTabsderivation should expose the Apps tab whenever the server advertisestoolscapability (apps are tools, not a separate capability).Stories
NoSelection,AppSelected,AppRunning,AppRunningMaximized,NoFieldsApp,WithListChanged,Empty.Acceptance criteria
ToolsScreen(Mantine theme variants, no inline styles).Dependencies
Branch / Base
v2/mainv2