Header now adapts cleanly across widths instead of wrapping or clipping:
- LeftSection/RightSection are symmetric (`flex: 1, miw: 0, wrap: nowrap`),
so the natural-width CenterSection sits visually centered between them.
Server name truncates with ellipsis when the left slice is too narrow.
- Below `md` (992px) the SegmentedControl swaps for a Select dropdown so
the tab labels never have to shrink or wrap.
- Below `sm` (768px) the "Disconnect" button collapses to an MdLinkOff
ActionIcon (with `aria-label` + `title` for the tooltip).
- Below `lg` (1200px) ServerStatusIndicator hides its text label and shows
only the colored dot (full label still available as a tooltip on hover),
freeing space so the Disconnect button stops getting truncated at typical
desktop widths.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
InspectorView replaces the prior pair (ConnectedView/UnconnectedView wrapping
children) with a single state-machine view. Holds activeServer, connectionStatus,
initializeResult, latencyMs, activeTab, and availableTabs internally; renders
the appropriate screen based on activeTab; switches the header between connected
and unconnected modes.
Screen data (servers, tools, prompts, resources, resourceTemplates, subscriptions,
logs, tasks, progressByTaskId, history) flows in via props so stories can populate
the entire view with fixtures. Demo data lives in stories, not in the view.
Stories include one server per transport (stdio, sse, streamable-http) so the
TransportBadge / descriptor variants are all visible.
Reorders ViewHeader.stories tabs to match the new ALL_TABS sequence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
Use args + useArgs pattern so onSettingsChange and onClose fire
through Storybook's args system. Every form interaction now logs
to the Actions panel with the full updated settings object.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace onOAuthChange(field, value) with onOAuthChange(oauth) where
oauth is { clientId, clientSecret, scopes }. Each keystroke now
reports the full OAuth state, not just the single field that changed.
This lets the consumer see the complete picture on every change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use Storybook's useArgs hook from storybook/preview-api to update
args from within the render function. This wires fn() callbacks to
the Actions panel AND updates the UI state through Storybook's args
system. All form interactions (add/remove/edit headers/metadata,
accordion open/close, connection mode, timeouts, OAuth) now both
update the UI and log to the Actions panel.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Storybook config has no addon-actions/addon-essentials, so fn()
calls never produce visible output. The stories are fully interactive
via useState — add/remove/edit headers, metadata, timeouts, OAuth,
and connection mode all work visually in the UI.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each handler now both updates local state (so the UI reacts) and
calls a Storybook fn() spy (so the Actions panel logs every
callback with its arguments).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace fn() stubs with useState handlers so add/remove/edit for
headers, metadata, connection mode, timeouts, and OAuth all work
interactively in Storybook. The InteractiveForm wrapper manages
settings state the same way ServerSettingsModal does.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wrap modal stories in AppShell to provide a page background behind
the modal overlay. Add fullscreen layout parameter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Revert ServerSettingsForm to a controlled component with
expandedSections/onExpandedSectionsChange props. The form is a
dumb component — accordion state belongs to its container.
Create ServerSettingsModal group that manages:
- Accordion expand/collapse state with ListToggle expand-all button
- Add/remove/edit header pairs
- Add/remove/edit metadata pairs
- Connection mode, timeout, and OAuth changes
- All changes flow through a single onSettingsChange callback
Update ServerSettingsForm stories with useState render functions
so accordion sections are interactive.
Update UnconnectedView WithSettingsModal story to use the new
ServerSettingsModal component.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move expandedSections/onExpandedSectionsChange from props to internal
useState. The accordion open/close is local display logic, not parent
state. Add optional defaultExpandedSections prop for initial state.
Simplify UnconnectedView WithSettingsModal story — no longer needs
external state management for accordion sections.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix getCapabilityEntries to iterate fixed key sets so unsupported
capabilities render red X (was only showing present/supported ones)
- Merge duplicate @mantine/core import in ViewHeader
- Move ConnectionState from ServerCard to core/mcp/types.ts
- Narrow onConnectionModeChange to "proxy" | "direct" instead of string
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ServerCard: Replace flat scalar props (name, version, transport, status,
error) with grouped objects (config: MCPServerConfig, info?: Implementation,
connection: ConnectionState). Remove auto-connect useEffect — dumb
components must not self-dispatch side effects. Derive transport and
command/url from config.
ServerInfoContent: Replace flat props with initializeResult: InitializeResult
and clientCapabilities: ClientCapabilities from MCP SDK. Derive capability
lists by iterating the ServerCapabilities record.
ServerSettingsForm: Collapse flat setting props (connectionMode, headers,
metadata, timeouts, oauth*) into settings: InspectorServerSettings. Add
InspectorServerSettings type to core/mcp/types.ts.
ImportServerJsonPanel: Replace scattered scalar props (jsonContent,
selectedPackageIndex, serverName) with draft: InspectorServerJsonDraft.
ViewHeader: Replace serverName: string with serverInfo: Implementation.
Use ConnectionStatus from core types.
ConnectedView: Update to pass serverInfo: Implementation instead of
serverName. Use ConnectionStatus type.
Update all stories for ServerCard, ServerInfoContent, ServerSettingsForm,
ImportServerJsonPanel, ViewHeader, ServerListScreen, ConnectedView, and
UnconnectedView.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove unused clientExperimental prop from ExperimentalFeaturesPanel
- Restore readable display of server capabilities by extracting
description and methods fields when present instead of raw JSON
- Extract RootDraft type alias to avoid repeated inline type
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
RootsTable: Replace local RootEntry with SDK Root type; consolidate
newRootName/newRootPath into newRootDraft object; rename Path→URI label.
SchemaForm: Replace local JsonSchema with shared JsonSchemaType from
utils/jsonUtils; update consumers (ElicitationFormPanel,
InlineElicitationRequest) to import from shared location.
ExperimentalFeaturesPanel: Replace array-based ExperimentalCapability
with ServerCapabilities['experimental'] freeform record; replace
responseJson string with JSONRPCResponse | JSONRPCErrorResponse; rename
requestJson→requestDraft; use Date for RequestHistoryItem.timestamp;
rename KeyValuePair→HeaderPair; add error badge for error responses.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Tighten ElicitationFormPanel story fixtures from
satisfies ElicitRequest["params"] to satisfies ElicitRequestFormParams
- Show model preferences container when modelPreferences exists even
without hints, so costPriority/speedPriority/intelligencePriority
are visible independently
- Fix stop reason ordering to match SDK enum: endTurn, stopSequence,
maxTokens
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add three new stories showing sampling/elicitation flows overlaid
on the ToolsScreen via Mantine Modal:
- WithSamplingModal: SamplingRequestPanel in a modal during tool execution
- WithElicitationModal: ElicitationFormPanel in a modal during tool execution
- WithPendingRequests: PendingClientRequests with inline sampling and
elicitation cards in a modal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Filter undefined model hint names in SamplingRequestPanel, matching
the pattern already used in InlineSamplingRequest
- Narrow ElicitationFormPanel to accept ElicitRequestFormParams instead
of the full ElicitRequest['params'] union; removes the 'requestedSchema
in request' guard and renders the schema unconditionally
- Add isUrlMode type guard in InlineElicitationRequest to properly
narrow the URL variant; eliminates the 'as { url: string }' cast
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ad hoc local types with SDK schema types across the Sampling
and Elicitation group components.
- SamplingRequestPanel: accept `request: CreateMessageRequestParams` +
`draftResult: CreateMessageResult` instead of 16 flat props; derive
messages, model preferences, and parameters from the request object;
drop `tools`/`toolChoice` (not in MCP 2025-11-25 CreateMessageRequest)
- InlineSamplingRequest: accept `request: CreateMessageRequestParams`;
derive messagePreview and modelHints from the request
- ElicitationFormPanel: accept `request: ElicitRequest['params']` +
`serverName`; pass requestedSchema directly to SchemaForm
- ElicitationUrlPanel: rename `elicitationId` to `requestId`
- InlineElicitationRequest: accept `request: ElicitRequest['params']`;
discriminate form vs URL mode on request shape instead of `mode` prop
- PendingClientRequests: unchanged (children-based wrapper)
- Delete local `SamplingTool` type
- Update all stories with real SDK type fixtures
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract duplicated extractMethod into shared historyUtils.ts
- Include response content in search (was accidentally dropped)
- Show Parameters instead of raw Request in expanded view; gate on
params existing so parameterless requests don't show empty block
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ad hoc flat props with MessageEntry from core/mcp/types.ts
across the History group components and HistoryScreen.
- HistoryEntry: accept `entry: MessageEntry` instead of flat props
(timestamp, method, target, status, durationMs, parameters, response);
derive method/target/status from embedded JSON-RPC objects; fix
Collapse animation by removing outer {isExpanded && ...} wrapper;
drop childEntries (not part of MessageEntry)
- HistoryControls: type onMethodFilterChange as (string | undefined)
- HistoryListPanel: accept `MessageEntry[]` + `pinnedIds: Set<string>`
instead of separate entries/pinnedEntries arrays with pre-bound
callbacks; pass onReplay/onTogglePin by entry ID
- HistoryScreen: accept `MessageEntry[]` + `pinnedIds` + ID-based
callbacks; collapse two-array model into single list with pinned
overlay
- Delete local HistoryEntryProps data shape, HistoryChildEntry type
- Update all stories with real JSON-RPC MessageEntry fixtures
- Update ConnectedView HistoryActive story
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix Collapse animation: remove outer {isExpanded && ...} wrapper so
Mantine's Collapse component drives the mount/unmount animation
- Show statusMessage for all tasks, not just active ones, so failed/
cancelled tasks display their error reason without expanding
- Remove redundant "Status" detail row — the TaskStatusBadge in the
header already communicates status
- Fix ttl guard: change !== null to != null to correctly handle the
SDK's optional (undefined) field
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When progress notification data is available for an active task, show
the ProgressDisplay (which includes its own message). Fall back to
the Task's statusMessage only when no progress data is present.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Progress notifications arrive separately from the Task object, so the
parent provides a map of progress data keyed by taskId. TaskListPanel
and TasksScreen accept an optional progressByTaskId prop and pass the
matching entry to each TaskCard.
Updated Mixed story and ConnectedView TasksActive story to demonstrate
the progress bar on the active "working" task.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Progress notifications (notifications/progress) are sent separately
from the Task object per the MCP spec. Add an optional progress prop
typed as Pick<ProgressNotification['params'], 'progress' | 'total' |
'message'> so the parent can pass progress data when available.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ad hoc TaskCardProps data shape with SDK Task type across the
Tasks group components and TasksScreen.
- TaskCard: accept `task: Task` instead of flat props (taskId, status,
method, target, progress, etc.); derive all display fields from the
SDK Task object (taskId, status, ttl, createdAt, lastUpdatedAt,
statusMessage); remove fields not present on SDK Task (method, target,
progress as number, error, completedAt, elapsed)
- TaskControls: type statusFilter as `TaskStatus | undefined`; add
runtime validation guard on Select onChange
- TaskListPanel: accept `Task[]` instead of `TaskCardProps[]`; pass
`onCancel(taskId)` through to each TaskCard; use `task.taskId` as key
- TasksScreen: accept `Task[]` + `onCancel(taskId)` callback; type
internal statusFilter state as `TaskStatus | undefined`
- Delete re-export of `TaskStatus` from TaskCard (import directly from
SDK where needed)
- Update all stories with real SDK `Task` fixtures
- Update ConnectedView TasksActive story
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Validate the Select value against LOG_LEVELS before casting to
LoggingLevel, ensuring the compiler isn't silently bypassed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace string-typed log levels with SDK LoggingLevel across the Logs
group components and LoggingScreen.
- LogControls: type currentLevel, visibleLevels, and all handlers with
LoggingLevel instead of string; type LOG_LEVELS array and LEVEL_COLORS
record with LoggingLevel
- LogStreamPanel: type visibleLevels as Record<LoggingLevel, boolean>
instead of Record<string, boolean>
- LoggingScreen: type currentLevel, onSetLevel, visibleLevels state,
and toggle handlers with LoggingLevel; extract NO_LEVELS_VISIBLE as
a module-level constant
- Stories already used LoggingLevel literals; updated type annotations
to use Record<LoggingLevel, boolean>
- No ConnectedView story changes needed (already passes valid
LoggingLevel values)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hoist previewUri() to a const in ResourceTemplatePanel to avoid
duplicate computation
- Include resource.title in subscriptions search filter for consistency
with resources and templates filters
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix template-expanded URIs not rendering: construct synthetic Resource
from readState.uri when the URI is absent from the resources list
- Fix non-image blob content rendering raw base64: show placeholder
message; also handle audio blobs properly
- Hide mimeType display when multiple content items to avoid confusion
- Rename ResourceControls selectedTemplate → selectedTemplateUri for
consistency with selectedUri and selectedResourceUri
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ad hoc local types with MCP SDK schema types across the Resources
group components and ResourcesScreen, per the v2 UX interfaces plan.
- ResourceListItem: accept `resource: Resource | ResourceTemplate` instead
of flat `name`/`uri`; render `title ?? name`; delete local
`ResourceAnnotations` type
- ResourceControls: accept `Resource[]`, `ResourceTemplate[]`,
`InspectorResourceSubscription[]` + `selectedUri`/`selectedTemplate`
instead of `ResourceItem[]`/`TemplateListItem[]`/`SubscriptionItem[]`;
no-op on re-selecting
- ResourcePreviewPanel: accept `resource: Resource` +
`contents: (TextResourceContents | BlobResourceContents)[]` instead of
flat `content: string`; use SDK `Annotations` (audience as Role[]);
`lastUpdated` as `Date` not `string`
- ResourceTemplatePanel: accept `template: ResourceTemplate` instead of
flat props; use SDK `Annotations`
- ResourceSubscribedItem: accept `subscription: InspectorResourceSubscription`
instead of flat `name`/`lastUpdated`; `lastUpdated` as `Date`
- ResourcesScreen: accept `Resource[]`, `ResourceTemplate[]`,
`InspectorResourceSubscription[]` + `selectedResourceUri`/
`selectedTemplateUri` + `ReadResourceState`; derive selections via
`find()`; add loading/error states
- Delete local `ResourceItem`, `TemplateListItem`, `SubscriptionItem`,
`SelectedResource`, `SelectedTemplate`, `ResourceAnnotations` types
- Update all stories with real SDK fixtures
- Update ConnectedView ResourcesActive story
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show a loader when GetPromptState status is "pending" and a red alert
when status is "error". Add Loading and WithError stories.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ad hoc local types with MCP SDK schema types across the Prompts
group components and PromptsScreen, per the v2 UX interfaces plan.
- PromptListItem: accept `prompt: Prompt` instead of flat `name`/`description`;
render `title ?? name` as primary label
- PromptControls: accept `Prompt[]` + `selectedName` instead of `PromptItem[]`;
no-op on clicking already-selected prompt; search includes title field
- PromptArgumentsForm: accept `prompt: Prompt` instead of flat props;
read `prompt.arguments` directly; display `title ?? name` as heading
- PromptMessagesDisplay: narrow type from `(PromptMessage | SamplingMessage)[]`
to `PromptMessage[]` per spec
- PromptsScreen: accept `Prompt[]` + `selectedPromptName` + `GetPromptState`;
derive selected prompt via `prompts.find()`; own `argumentValues` state
locally; reset arguments on tool switch
- Delete local `PromptItem`, `SelectedPrompt`, `PromptArgument` types
- Update all stories with real SDK `Prompt` fixtures
- Update ConnectedView PromptsActive story
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of a separate alert banner and content below, render error
content directly inside a titled Alert with "Tool Error" heading.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show a red alert banner when CallToolResult.isError is true, giving
a visual distinction between successful and failed tool executions.
Add ErrorResult story to demonstrate the error state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix hasAnyAnnotation checking annotations.title which is never rendered
- Reset formValues when switching tools via onSelectTool handler
- Extract ToolProgress type from ToolDetailPanel, reuse in ToolsScreen
- Fix contradictory readOnlyHint + destructiveHint in story fixture
- Replace listMaxHeight function with LIST_MAX_HEIGHT constant
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>