docs(apps): specify the v2 Apps tab (#1265)
Adds the missing Apps tab to the v2 UX specification. Apps are the subset of tools whose `_meta.ui.resourceUri` advertises a UI resource (per `@modelcontextprotocol/ext-apps`). The screen mirrors the legacy v1 layout: a sidebar of apps and a right pane that toggles between an input form (before launch) and the embedded MCP App via `AppBridge`. - v2_ux.md: add `[Apps]` to the navigation tab list and a new "Apps Screen" subsection with both states (input form / running app). - v2_ux_features.md: full Apps Screen feature spec — ASCII diagrams, detection rule, presentational contract for `AppsScreen` / `AppRenderer` (imperative ref shape so the screen stays "dumb" and the wiring layer drives the bridge). - v2_screenshots.md: link the two reference PNGs from the legacy v1 client. - v2_ux_storybook.md: add `AppListItem` (2.3a), `AppDetailPanel` (2.5a), `AppRenderer` (2.5b), and `AppsScreen` (3.2a); update Build Order. Implementation work tracked on the v2 board: #1260–#1264. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5a2d24bac7
commit
bcb5b643ff
1 changed files with 315 additions and 19 deletions
|
|
@ -334,6 +334,24 @@ Single tool entry in the sidebar list with name and annotation badges.
|
|||
|
||||
---
|
||||
|
||||
### 2.3a AppListItem
|
||||
|
||||
Single MCP App entry in the sidebar list. Mirrors `ToolListItem` but renders the app's `tool.icons` (real MCP `Tool.icons`) when present and surfaces a chevron affordance.
|
||||
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `tool` | `Tool` | App tool (real MCP `Tool` type) |
|
||||
| `selected` | `boolean` | Whether this app is currently selected |
|
||||
| `onClick` | `() => void` | Selection callback |
|
||||
|
||||
**Mantine:** `UnstyledButton` with `Group` (Icon + label/description + ChevronRight). Reuses the same active-state background highlight pattern as `ToolListItem`.
|
||||
|
||||
**Stories:** Default, Selected, WithIcon, NoDescription, LongName
|
||||
|
||||
> Alternative: fold icon support into `ToolListItem` and reuse it on the Apps screen. Decide during implementation — see issue "Tool icon support on tool list items".
|
||||
|
||||
---
|
||||
|
||||
### 2.4 ToolDetailPanel
|
||||
|
||||
Tool name, description, annotations display, and generated parameter form.
|
||||
|
|
@ -373,6 +391,50 @@ Displays tool execution results with copy/clear actions.
|
|||
|
||||
---
|
||||
|
||||
### 2.5a AppDetailPanel
|
||||
|
||||
App name, description, optional icon, and generated `App Input` form. Mirrors `ToolDetailPanel` but the action button is **Open App** (no annotations, no progress display, no cancel — execution is delegated to the embedded app).
|
||||
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `tool` | `Tool` | App tool (real MCP `Tool` type) |
|
||||
| `formValues` | `Record<string, unknown>` | Current form values |
|
||||
| `isOpening` | `boolean` | Whether the app is currently being launched |
|
||||
| `onFormChange` | `(values: Record<string, unknown>) => void` | Form value change |
|
||||
| `onOpenApp` | `() => void` | Open App callback |
|
||||
|
||||
**Mantine:** `Stack` with icon + `Title` (`tool.title ?? tool.name`), description `Text`, SchemaForm (see 2.12), full-width `Button` with `IconPlayerPlay` for open. Disabled while `isOpening` or while the form has validation errors.
|
||||
|
||||
**Stories:** NoFields, SimpleStringParam, MultipleParams, WithIcon, Opening, ComplexSchema
|
||||
|
||||
---
|
||||
|
||||
### 2.5b AppRenderer
|
||||
|
||||
Embeds an MCP App in a sandboxed iframe and exposes an imperative ref so the wiring layer can drive the bridge. The component is a thin shell — it owns the iframe element and the `AppBridge` lifecycle but does **not** know about the active MCP `Client`. The wiring layer constructs the bridge (real MCP `Client` + `Implementation` + `McpUiHostCapabilities`) and passes it in via the `bridgeFactory` callback when the iframe mounts.
|
||||
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `sandboxPath` | `string` | URL/path of the sandbox proxy iframe |
|
||||
| `tool` | `Tool` | The selected app tool (for resource URI lookup) |
|
||||
| `bridgeFactory` | `(iframe: HTMLIFrameElement) => AppBridge` | Wiring layer creates the bridge from the active MCP client |
|
||||
| `onError` | `(err: Error) => void` | Error notification callback |
|
||||
|
||||
**Imperative ref (`AppRendererHandle`):**
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `sendToolInput(args)` | Push complete tool arguments to the app |
|
||||
| `sendToolResult(result)` | Push the `CallToolResult` from the server |
|
||||
| `sendToolCancelled(reason)` | Notify the app that execution was cancelled |
|
||||
| `teardown()` | Request graceful shutdown before unmounting |
|
||||
|
||||
**Mantine:** `Box` with `iframe` element. No Mantine controls — display logic only. The renderer treats the bridge handle and iframe element as runtime state, not props, but exposes the bridge actions through `useImperativeHandle`.
|
||||
|
||||
**Stories:** Loading, Loaded (with mock bridge), Error, Maximized
|
||||
|
||||
---
|
||||
|
||||
### 2.6 ResourceListItem
|
||||
|
||||
Single resource entry with name and annotation badges.
|
||||
|
|
@ -855,6 +917,28 @@ Three-panel layout: tool list, detail/form, and results.
|
|||
|
||||
---
|
||||
|
||||
### 3.2a AppsScreen
|
||||
|
||||
Two-panel layout: app list on the left, dynamic right pane that toggles between an input form (before launch) and the embedded `AppRenderer` (after launch). Receives the **already-filtered** subset of tools that are MCP Apps; filtering happens in the wiring layer via the shared `isAppTool` helper in `core/mcp/apps`.
|
||||
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `tools` | `Tool[]` | Apps (already filtered to those with `_meta.ui.resourceUri`) |
|
||||
| `listChanged` | `boolean` | List changed indicator |
|
||||
| `sandboxPath` | `string` | Sandbox proxy path passed through to `AppRenderer` |
|
||||
| `bridgeFactory` | `(iframe) => AppBridge` | Wiring layer creates the bridge from the active MCP client |
|
||||
| `rendererRef` | `Ref<AppRendererHandle>` | Imperative ref forwarded to the embedded `AppRenderer` |
|
||||
| `onRefreshList` | `() => void` | Refresh apps list |
|
||||
| `onSelectApp` | `(name: string) => void` | App selection callback |
|
||||
| `onOpenApp` | `(name: string, args: Record<string, unknown>) => void` | Open App callback (wiring runs `tools/call` and pushes result via the ref) |
|
||||
| `onCloseApp` | `() => void` | Close currently-open app |
|
||||
|
||||
**Mantine:** Two-column layout. Left: `Card` with ListChangedIndicator, search `TextInput`, AppListItem stack, "Refresh Apps" `Button`. Right: `Card` whose content swaps between AppDetailPanel (form state) and AppRenderer (running state) plus a "Back to Input" / Maximize / Close header. Maximize hides the sidebar by widening the right card to full width.
|
||||
|
||||
**Stories:** NoSelection, AppSelected, AppRunning, AppRunningMaximized, NoFieldsApp (auto-launches on select), WithListChanged, Empty (no apps available)
|
||||
|
||||
---
|
||||
|
||||
### 3.3 ResourcesScreen
|
||||
|
||||
Two-panel layout: resource list (with accordion sections) and content preview.
|
||||
|
|
@ -1022,7 +1106,8 @@ Depends on Phase 1 elements being complete.
|
|||
2. **ServerCard** (2.1) - Uses StatusIndicator, TransportBadge, ConnectionToggle, CopyButton, InlineError
|
||||
3. **AddServerMenu** (2.2)
|
||||
4. **ToolListItem** (2.3) - Uses AnnotationBadge
|
||||
5. **ResourceListItem** (2.6) - Uses AnnotationBadge
|
||||
5. **AppListItem** (2.3a) - Renders `tool.icons` (or fold into ToolListItem)
|
||||
6. **ResourceListItem** (2.6) - Uses AnnotationBadge
|
||||
6. **LogControls** (2.11)
|
||||
7. **ResultPanel** (2.5) - Uses ContentViewer, CopyButton
|
||||
8. **PromptMessagesDisplay** (2.10) - Uses MessageBubble
|
||||
|
|
@ -1033,17 +1118,19 @@ Depends on Phase 1 elements being complete.
|
|||
Depends on SchemaForm and Phase 2.
|
||||
|
||||
1. **ToolDetailPanel** (2.4) - Uses SchemaForm, AnnotationBadge, ProgressDisplay
|
||||
2. **ResourcePreviewPanel** (2.7) - Uses ContentViewer
|
||||
3. **ResourceTemplateInput** (2.8)
|
||||
4. **PromptArgumentsForm** (2.9)
|
||||
5. **TaskCard** (2.13) - Uses ProgressDisplay
|
||||
6. **HistoryEntry** (2.14)
|
||||
7. **SamplingRequestPanel** (2.15) - Uses MessageBubble
|
||||
8. **ElicitationFormPanel** (2.16) - Uses SchemaForm
|
||||
9. **ElicitationUrlPanel** (2.17)
|
||||
10. **ServerSettingsForm** (2.20)
|
||||
11. **ImportServerJsonPanel** (2.21)
|
||||
12. **ExperimentalFeaturesPanel** (2.22)
|
||||
2. **AppDetailPanel** (2.5a) - Uses SchemaForm
|
||||
3. **AppRenderer** (2.5b) - Imperative ref shell for embedded MCP App; depends on `@modelcontextprotocol/ext-apps`
|
||||
4. **ResourcePreviewPanel** (2.7) - Uses ContentViewer
|
||||
5. **ResourceTemplateInput** (2.8)
|
||||
6. **PromptArgumentsForm** (2.9)
|
||||
7. **TaskCard** (2.13) - Uses ProgressDisplay
|
||||
8. **HistoryEntry** (2.14)
|
||||
9. **SamplingRequestPanel** (2.15) - Uses MessageBubble
|
||||
10. **ElicitationFormPanel** (2.16) - Uses SchemaForm
|
||||
11. **ElicitationUrlPanel** (2.17)
|
||||
12. **ServerSettingsForm** (2.20)
|
||||
13. **ImportServerJsonPanel** (2.21)
|
||||
14. **ExperimentalFeaturesPanel** (2.22)
|
||||
|
||||
### Phase 4: Inline Handlers
|
||||
Depends on Phase 3 panels.
|
||||
|
|
@ -1057,11 +1144,12 @@ Depends on all groups.
|
|||
|
||||
1. **ServerListScreen** (3.1)
|
||||
2. **ToolsScreen** (3.2)
|
||||
3. **ResourcesScreen** (3.3)
|
||||
4. **PromptsScreen** (3.4)
|
||||
5. **LoggingScreen** (3.5)
|
||||
6. **TasksScreen** (3.6)
|
||||
7. **HistoryScreen** (3.7)
|
||||
3. **AppsScreen** (3.2a)
|
||||
4. **ResourcesScreen** (3.3)
|
||||
5. **PromptsScreen** (3.4)
|
||||
6. **LoggingScreen** (3.5)
|
||||
7. **TasksScreen** (3.6)
|
||||
8. **HistoryScreen** (3.7)
|
||||
|
||||
### Phase 6: Views
|
||||
Depends on screens.
|
||||
|
|
|
|||
Loading…
Reference in a new issue