Refactor ServerCard stack to use id-based callbacks
Distinguishes server `id` (the unique map key in MCPConfig.mcpServers)
from `name` (display label) so containers can dispatch by id without
relying on display strings. ServerCard, ConnectionToggle, ServerListScreen,
and supporting stories all updated.
- ServerCard: add `id` prop; all action callbacks now `(id: string) => void`
- ConnectionToggle: collapse `onConnect`/`onDisconnect` into single `onToggle`
- ServerListScreen: lift `activeServer` to a prop; combine `onSetActive` +
`onToggleConnection` into a single `onToggleConnection(id)` callback
- Stories: use UUIDs for server ids so callbacks visibly carry ids, not names
Removes the "Direct"/"Via Proxy" connection mode concept, which is no
longer planned. ServerSettingsForm drops the section, ServerCard drops
the badge, InspectorServerSettings drops the field.
Removes the "Test Client Features" dropdown from ServerCard along with
its four handlers; that surface will live elsewhere.
TransportBadge now collapses `sse` and `streamable-http` into a single
"HTTP" label; ServerCard adds a grey transport descriptor next to the
badge ("Standard I/O", "SSE (Server Sent Events) [deprecated]",
"Streamable HTTP"). The version badge moves from the header row to sit
beside the transport badge.
ServerCard header no longer wraps; long server names truncate with
ellipsis.
Specification docs (`v2_scope.md`, `v2_screenshots.md`,
`v2_ux_interfaces.md`, `v2_ux_storybook.md`) updated to match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
29ce55290f
commit
1149288ea6
4 changed files with 196 additions and 326 deletions
|
|
@ -49,10 +49,6 @@
|
|||
* SSE
|
||||
* SHTTP
|
||||
|
||||
## Connection Type
|
||||
* Direct
|
||||
* Via Proxy
|
||||
|
||||
## Logging Level Control
|
||||
* Present and synchronized when connecting to server with logging capability
|
||||
|
||||
|
|
|
|||
|
|
@ -81,11 +81,6 @@ Request history with replay and pin functionality.
|
|||
|
||||
## Client Feature Handlers
|
||||
|
||||
### Test Client Features Dropdown
|
||||
Menu for testing client capabilities (Sampling, Elicitation, Roots).
|
||||
|
||||

|
||||
|
||||
### Sampling Panel
|
||||
Handler for `sampling/createMessage` requests with mock response input.
|
||||
|
||||
|
|
|
|||
|
|
@ -128,9 +128,9 @@ For each component, the plan records:
|
|||
- **Purpose** — Large on/off switch that connects or disconnects a configured server.
|
||||
- **Current props** — `checked: boolean`; `loading: boolean`; `disabled: boolean`; `onChange: (checked: boolean) => void`.
|
||||
- **MCP schema touch points** — None — purely presentational, but `checked`/`loading` are derived from `ConnectionStatus` application state (not MCP schema).
|
||||
- **Target props** — `status: ConnectionStatus` (core-owned enum: `"disconnected" | "connecting" | "connected" | "failed"`); `disabled?: boolean`; `onConnect: () => void`; `onDisconnect: () => void`.
|
||||
- **Callbacks → core hook** — `onConnect`, `onDisconnect` → `useConnection` (v1.5 `useConnection` exposes `connect`/`disconnect`).
|
||||
- **Internal refactors** — Derive `checked`/`loading` from `status` internally; split the single `onChange` into explicit `onConnect`/`onDisconnect` so the wiring layer can pass hook callbacks directly without a boolean adapter.
|
||||
- **Target props** — `status: ConnectionStatus` (core-owned enum: `"disconnected" | "connecting" | "connected" | "error"`); `disabled?: boolean`; `onToggle: () => void`.
|
||||
- **Callbacks → core hook** — `onToggle` → wiring layer reads the current `connection.status` for the owning server and dispatches `useConnection`'s `connect` or `disconnect` (v1.5 `useConnection` exposes both).
|
||||
- **Internal refactors** — Derive `checked`/`loading` from `status` internally; collapse `onChange(boolean)` to a single `onToggle()` — the wiring layer already has the connection state and decides connect vs disconnect, so a boolean from the toggle adds no information.
|
||||
|
||||
### ContentViewer
|
||||
|
||||
|
|
@ -238,9 +238,9 @@ For each component, the plan records:
|
|||
- **Purpose** — Toggle button to subscribe/unsubscribe from a single MCP resource.
|
||||
- **Current props** — `subscribed: boolean`; `onToggle: () => void`.
|
||||
- **MCP schema touch points** — `SubscribeRequest.params.uri` and `UnsubscribeRequest.params.uri` — but the URI is held by the parent row; the button itself only needs the current subscription boolean.
|
||||
- **Target props** — `subscribed: boolean`; `onSubscribe: () => void`; `onUnsubscribe: () => void` (split for parity with `ConnectionToggle`). Alternatively keep a single `onToggle` if the wiring layer prefers that.
|
||||
- **Callbacks → core hook** — `onSubscribe` / `onUnsubscribe` → `useInspectorClient` (wraps `client.subscribeResource` / `client.unsubscribeResource`); `subscribed` derived from a core-owned subscription set.
|
||||
- **Internal refactors** — Optional split of `onToggle` into the two explicit callbacks; otherwise none.
|
||||
- **Target props** — `subscribed: boolean`; `onToggle: () => void`. (`ConnectionToggle` settled on the same single-callback shape; the wiring layer reads `subscribed` and dispatches subscribe vs unsubscribe.)
|
||||
- **Callbacks → core hook** — `onToggle` → wiring layer dispatches `useInspectorClient`'s `client.subscribeResource` or `client.unsubscribeResource` based on the current `subscribed` value; `subscribed` derived from a core-owned subscription set.
|
||||
- **Internal refactors** — None.
|
||||
|
||||
### TaskStatusBadge
|
||||
|
||||
|
|
@ -528,10 +528,10 @@ For each component, the plan records:
|
|||
|
||||
- **Location**: `groups/ServerCard/`
|
||||
- **Purpose**: Card for a configured server with status, transport, connection toggle, actions, and test-client-features menu.
|
||||
- **Current props**: `name`, `version?`, `transport`, `connectionMode`, `command`, `status`, `retryCount?`, `error?`, `canTestClientFeatures`, `activeServer?`, many handlers.
|
||||
- **MCP schema touch points**: `Implementation` (server `name`, `version`) from `InitializeResult.serverInfo`. Transport/command/mode/status are Inspector-core-owned (connection lifecycle).
|
||||
- **Target props**: `config: InspectorServerConfig`, `info?: Implementation`, `connection: InspectorConnectionState` (`status`, `retryCount`, `error`), `canTestClientFeatures`, `activeServer?`, handlers unchanged.
|
||||
- **Callbacks → core hook**: `onToggleConnection`/`onSetActiveServer` from `useConnection`; `onEdit`/`onClone`/`onRemove` from `useServers`; test handlers from `useSampling`/`useElicitation`/`useRoots`.
|
||||
- **Current props**: `id`, `name`, `version?`, `transport`, `command`, `status`, `retryCount?`, `error?`, `activeServer?`, action handlers. (The grey transport descriptor next to the `TransportBadge` is derived from `config.type` — "Standard I/O", "SSE (Server Sent Events) [deprecated]", or "Streamable HTTP" — not a separate `connectionMode` prop. The "Test Client Features" dropdown was removed; sampling/elicitation/roots simulators live elsewhere.)
|
||||
- **MCP schema touch points**: `Implementation` (server `name`, `version`) from `InitializeResult.serverInfo`. Transport/command/status are Inspector-core-owned (connection lifecycle).
|
||||
- **Target props**: `id: string` (the `MCPConfig.mcpServers` map key), `name: string` (display label), `config: InspectorServerConfig`, `info?: Implementation`, `connection: InspectorConnectionState` (`status`, `retryCount`, `error`), `activeServer?` (read-only — set by the wiring layer), action handlers all keyed by `id`.
|
||||
- **Callbacks → core hook**: `onToggleConnection(id)` from `useConnection` — the wiring layer reads the current `connection.status` for that id and dispatches connect or disconnect (no separate `onSetActiveServer`; active state is owned by the wiring layer); `onEdit`/`onClone`/`onRemove` from `useServers`.
|
||||
- **Internal refactors**: Replace flat scalar props with grouped objects; **move the auto-connect `useEffect` out** — dumb components must not self-dispatch side effects.
|
||||
|
||||
### ServerInfoContent
|
||||
|
|
@ -557,8 +557,8 @@ For each component, the plan records:
|
|||
### ServerSettingsForm
|
||||
|
||||
- **Location**: `groups/ServerSettingsForm/`
|
||||
- **Purpose**: Per-server settings — connection mode, headers, metadata, timeouts, OAuth.
|
||||
- **Current props**: `connectionMode`, `headers`, `metadata`, `connectionTimeout`, `requestTimeout`, `oauthClient*`, many handlers.
|
||||
- **Purpose**: Per-server settings — headers, metadata, timeouts, OAuth. (The connection-mode "Via Proxy"/"Direct" toggle was removed; the inspector picks the right transport from `MCPServerConfig.type`.)
|
||||
- **Current props**: `headers`, `metadata`, `connectionTimeout`, `requestTimeout`, `oauthClient*`, many handlers.
|
||||
- **MCP schema touch points**: `Request._meta` passthrough is the only schema-level tie-in; the rest is Inspector-core-owned.
|
||||
- **Target props**: `settings: InspectorServerSettings`, `onSettingsChange(settings)` (or keep granular setters).
|
||||
- **Callbacks → core hook**: `useServers` (v2-only — no v1.5 analog).
|
||||
|
|
@ -761,13 +761,13 @@ themselves — every callback passed down must originate in a core hook.
|
|||
- **Current props**: `servers: ServerCardProps[]`, `onAddManually`, `onImportConfig`, `onImportServerJson`.
|
||||
- **MCP schema touch points**: `Implementation` (server `name`/`version`), `ServerCapabilities`, `InitializeResult` — identity and capability surface reported on initialize. Transport config (`command`, `args`, `env`, `url`, `headers`) is **not** MCP schema; it is Inspector core app state.
|
||||
- **Target props**:
|
||||
- `servers: ServerEntry[]` where `ServerEntry = { id: string; config: ServerTransportConfig; connection: { status: 'disconnected' | 'connecting' | 'connected' | 'error'; error?: string; initializeResult?: InitializeResult } }`.
|
||||
- `activeServerId?: string` — may be lifted to core if it drives routing; currently screen-local.
|
||||
- `onAddManually`, `onImportConfig`, `onImportServerJson`, `onConnect(id)`, `onDisconnect(id)`, `onSetActiveServer(id)`, `onEditServer(id)`, `onRemoveServer(id)`.
|
||||
- `servers: ServerEntry[]` where `ServerEntry = { id: string; name: string; config: ServerTransportConfig; connection: { status: 'disconnected' | 'connecting' | 'connected' | 'error'; error?: string; initializeResult?: InitializeResult } }`.
|
||||
- `activeServer?: string` — pass-through from the wiring layer; drives card dimming. **Not** local screen state.
|
||||
- `onAddManually`, `onImportConfig`, `onImportServerJson`, `onToggleConnection(id)`, `onEditServer(id)`, `onRemoveServer(id)` — the toggle is consolidated; the wiring layer reads current connection state for that id and decides whether to connect or disconnect.
|
||||
- **Callbacks → core hook**: `useServers` (v2-only — no v1.5 analog) owns the persisted config list; `useConnection` (v1.5, `core/react/useConnection.ts`) owns per-server transport lifecycle and exposes `connectionStatus`, `serverCapabilities`, `connect`, `disconnect`. `ServerListScreen` composes both via a parent view.
|
||||
- **Internal refactors**:
|
||||
- Stop flattening each server into a loose `ServerCardProps`; pass `ServerEntry` and let `ServerCard` read `config` / `connection` fields.
|
||||
- `activeServer` state may migrate to `useServers` once it gates which screen renders; until then, keep `useState` local.
|
||||
- `activeServer` is a prop, not local screen state — the wiring layer tracks which server is connected and passes the id down. `compact` toggle stays as local `useState`.
|
||||
|
||||
<!-- /AGENT:SCREENS -->
|
||||
|
||||
|
|
|
|||
|
|
@ -283,12 +283,10 @@ Server connection card with status, transport, command, and action buttons.
|
|||
| `name` | `string` | Server name |
|
||||
| `version` | `string?` | Server version |
|
||||
| `transport` | `'stdio' \| 'http'` | Transport type |
|
||||
| `connectionMode` | `string` | "Via Proxy" or "Direct" |
|
||||
| `command` | `string` | Command or URL |
|
||||
| `status` | `'connected' \| 'connecting' \| 'disconnected' \| 'failed'` | Connection state |
|
||||
| `retryCount` | `number?` | Failed retry count |
|
||||
| `error` | `{ message: string; details?: string }?` | Error info |
|
||||
| `canTestClientFeatures` | `boolean` | Show "Test Client Features" dropdown |
|
||||
| `onToggleConnection` | `(connect: boolean) => void` | Connect/disconnect |
|
||||
| `onCopyCommand` | `() => void` | Copy command |
|
||||
| `onServerInfo` | `() => void` | View server info |
|
||||
|
|
@ -296,14 +294,10 @@ Server connection card with status, transport, command, and action buttons.
|
|||
| `onEdit` | `() => void` | Edit server |
|
||||
| `onClone` | `() => void` | Clone server |
|
||||
| `onRemove` | `() => void` | Remove server |
|
||||
| `onTestSampling` | `() => void` | Test sampling |
|
||||
| `onTestElicitationForm` | `() => void` | Test elicitation (form) |
|
||||
| `onTestElicitationUrl` | `() => void` | Test elicitation (URL) |
|
||||
| `onConfigureRoots` | `() => void` | Configure roots |
|
||||
|
||||
**Mantine:** `Card` with `Card.Section` dividers. Uses StatusIndicator, TransportBadge, ConnectionToggle, CopyButton, InlineError elements. `Menu` for "Test Client Features" dropdown.
|
||||
**Mantine:** `Card` with `Card.Section` dividers. Uses StatusIndicator, TransportBadge, ConnectionToggle, CopyButton, InlineError elements.
|
||||
|
||||
**Stories:** Connected, Disconnected, Connecting, Failed, FailedWithError, WithClientFeatures, HttpDirect, LongCommand
|
||||
**Stories:** Connected, Disconnected, Connecting, Failed, FailedWithError, HttpDirect, LongCommand
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -679,11 +673,10 @@ Server metadata, capabilities, and instructions display (modal body content).
|
|||
|
||||
### 2.20 ServerSettingsForm
|
||||
|
||||
Server settings form with connection mode, headers, metadata, timeouts, and OAuth.
|
||||
Server settings form with headers, metadata, timeouts, and OAuth.
|
||||
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `connectionMode` | `'proxy' \| 'direct'` | Connection mode |
|
||||
| `headers` | `Array<{ key: string; value: string }>` | Custom headers |
|
||||
| `metadata` | `Array<{ key: string; value: string }>` | Request metadata |
|
||||
| `connectionTimeout` | `number` | Connection timeout ms |
|
||||
|
|
|
|||
Loading…
Reference in a new issue