Phase 2: Refactor Server/Settings/ViewShell cluster to MCP SDK types
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>
This commit is contained in:
parent
c25a092ed1
commit
771a67ee20
2 changed files with 562 additions and 539 deletions
|
|
@ -1,7 +1,16 @@
|
|||
import type { InspectorServerSettings } from "@inspector/core/mcp/types.js";
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { fn } from "storybook/test";
|
||||
import { ServerSettingsForm } from "./ServerSettingsForm";
|
||||
|
||||
const defaultSettings: InspectorServerSettings = {
|
||||
connectionMode: "proxy",
|
||||
headers: [],
|
||||
metadata: [],
|
||||
connectionTimeout: 30000,
|
||||
requestTimeout: 60000,
|
||||
};
|
||||
|
||||
const meta: Meta<typeof ServerSettingsForm> = {
|
||||
title: "Groups/ServerSettingsForm",
|
||||
component: ServerSettingsForm,
|
||||
|
|
@ -25,55 +34,51 @@ type Story = StoryObj<typeof ServerSettingsForm>;
|
|||
|
||||
export const DefaultSettings: Story = {
|
||||
args: {
|
||||
connectionMode: "proxy",
|
||||
headers: [],
|
||||
metadata: [],
|
||||
connectionTimeout: 30000,
|
||||
requestTimeout: 60000,
|
||||
settings: defaultSettings,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithHeaders: Story = {
|
||||
args: {
|
||||
connectionMode: "proxy",
|
||||
headers: [
|
||||
{ key: "Authorization", value: "Bearer token-abc-123" },
|
||||
{ key: "X-Custom-Header", value: "custom-value" },
|
||||
],
|
||||
metadata: [],
|
||||
connectionTimeout: 30000,
|
||||
requestTimeout: 60000,
|
||||
settings: {
|
||||
...defaultSettings,
|
||||
headers: [
|
||||
{ key: "Authorization", value: "Bearer token-abc-123" },
|
||||
{ key: "X-Custom-Header", value: "custom-value" },
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const WithOAuth: Story = {
|
||||
args: {
|
||||
connectionMode: "direct",
|
||||
headers: [],
|
||||
metadata: [],
|
||||
connectionTimeout: 30000,
|
||||
requestTimeout: 60000,
|
||||
oauthClientId: "my-client-id",
|
||||
oauthClientSecret: "super-secret-value",
|
||||
oauthScopes: "read write admin",
|
||||
settings: {
|
||||
...defaultSettings,
|
||||
connectionMode: "direct",
|
||||
oauthClientId: "my-client-id",
|
||||
oauthClientSecret: "super-secret-value",
|
||||
oauthScopes: "read write admin",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const AllConfigured: Story = {
|
||||
args: {
|
||||
connectionMode: "proxy",
|
||||
headers: [
|
||||
{ key: "Authorization", value: "Bearer token-abc-123" },
|
||||
{ key: "X-Request-Id", value: "req-456" },
|
||||
],
|
||||
metadata: [
|
||||
{ key: "userId", value: "user-789" },
|
||||
{ key: "sessionId", value: "session-012" },
|
||||
],
|
||||
connectionTimeout: 15000,
|
||||
requestTimeout: 45000,
|
||||
oauthClientId: "my-client-id",
|
||||
oauthClientSecret: "super-secret-value",
|
||||
oauthScopes: "read write",
|
||||
settings: {
|
||||
connectionMode: "proxy",
|
||||
headers: [
|
||||
{ key: "Authorization", value: "Bearer token-abc-123" },
|
||||
{ key: "X-Request-Id", value: "req-456" },
|
||||
],
|
||||
metadata: [
|
||||
{ key: "userId", value: "user-789" },
|
||||
{ key: "sessionId", value: "session-012" },
|
||||
],
|
||||
connectionTimeout: 15000,
|
||||
requestTimeout: 45000,
|
||||
oauthClientId: "my-client-id",
|
||||
oauthClientSecret: "super-secret-value",
|
||||
oauthScopes: "read write",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@ import {
|
|||
Text,
|
||||
TextInput,
|
||||
} from "@mantine/core";
|
||||
|
||||
export interface KeyValuePair {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
import type { InspectorServerSettings } from "@inspector/core/mcp/types.js";
|
||||
|
||||
export type ServerSettingsSection =
|
||||
| "connectionMode"
|
||||
|
|
@ -23,14 +19,7 @@ export type ServerSettingsSection =
|
|||
| "oauth";
|
||||
|
||||
export interface ServerSettingsFormProps {
|
||||
connectionMode: "proxy" | "direct";
|
||||
headers: KeyValuePair[];
|
||||
metadata: KeyValuePair[];
|
||||
connectionTimeout: number;
|
||||
requestTimeout: number;
|
||||
oauthClientId?: string;
|
||||
oauthClientSecret?: string;
|
||||
oauthScopes?: string;
|
||||
settings: InspectorServerSettings;
|
||||
expandedSections: ServerSettingsSection[];
|
||||
onExpandedSectionsChange: (sections: ServerSettingsSection[]) => void;
|
||||
onConnectionModeChange: (mode: string) => void;
|
||||
|
|
@ -75,7 +64,7 @@ function KeyValueRows({
|
|||
onChange,
|
||||
onRemove,
|
||||
}: {
|
||||
items: KeyValuePair[];
|
||||
items: { key: string; value: string }[];
|
||||
onChange: (index: number, key: string, value: string) => void;
|
||||
onRemove: (index: number) => void;
|
||||
}) {
|
||||
|
|
@ -105,14 +94,7 @@ function KeyValueRows({
|
|||
}
|
||||
|
||||
export function ServerSettingsForm({
|
||||
connectionMode,
|
||||
headers,
|
||||
metadata,
|
||||
connectionTimeout,
|
||||
requestTimeout,
|
||||
oauthClientId,
|
||||
oauthClientSecret,
|
||||
oauthScopes,
|
||||
settings,
|
||||
expandedSections,
|
||||
onExpandedSectionsChange,
|
||||
onConnectionModeChange,
|
||||
|
|
@ -145,12 +127,12 @@ export function ServerSettingsForm({
|
|||
<Accordion.Panel>
|
||||
<Select
|
||||
data={CONNECTION_MODE_OPTIONS}
|
||||
value={connectionMode}
|
||||
value={settings.connectionMode}
|
||||
onChange={(value) => {
|
||||
if (value) onConnectionModeChange(value);
|
||||
}}
|
||||
description={
|
||||
connectionMode === "proxy"
|
||||
settings.connectionMode === "proxy"
|
||||
? "Route through inspector proxy (required for STDIO)"
|
||||
: undefined
|
||||
}
|
||||
|
|
@ -168,11 +150,11 @@ export function ServerSettingsForm({
|
|||
</HintText>
|
||||
<AddButton onClick={onAddHeader}>+ Add Header</AddButton>
|
||||
</Group>
|
||||
{headers.length === 0 ? (
|
||||
{settings.headers.length === 0 ? (
|
||||
<EmptyHint>No custom headers configured</EmptyHint>
|
||||
) : (
|
||||
<KeyValueRows
|
||||
items={headers}
|
||||
items={settings.headers}
|
||||
onChange={onHeaderChange}
|
||||
onRemove={onRemoveHeader}
|
||||
/>
|
||||
|
|
@ -191,11 +173,11 @@ export function ServerSettingsForm({
|
|||
</HintText>
|
||||
<AddButton onClick={onAddMetadata}>+ Add Metadata</AddButton>
|
||||
</Group>
|
||||
{metadata.length === 0 ? (
|
||||
{settings.metadata.length === 0 ? (
|
||||
<EmptyHint>No request metadata configured</EmptyHint>
|
||||
) : (
|
||||
<KeyValueRows
|
||||
items={metadata}
|
||||
items={settings.metadata}
|
||||
onChange={onMetadataChange}
|
||||
onRemove={onRemoveMetadata}
|
||||
/>
|
||||
|
|
@ -211,13 +193,13 @@ export function ServerSettingsForm({
|
|||
<NumberInput
|
||||
label="Connection Timeout"
|
||||
suffix=" ms"
|
||||
value={connectionTimeout}
|
||||
value={settings.connectionTimeout}
|
||||
onChange={handleTimeoutChange("connectionTimeout")}
|
||||
/>
|
||||
<NumberInput
|
||||
label="Request Timeout"
|
||||
suffix=" ms"
|
||||
value={requestTimeout}
|
||||
value={settings.requestTimeout}
|
||||
onChange={handleTimeoutChange("requestTimeout")}
|
||||
/>
|
||||
</Group>
|
||||
|
|
@ -234,12 +216,12 @@ export function ServerSettingsForm({
|
|||
</HintText>
|
||||
<TextInput
|
||||
label="Client ID"
|
||||
value={oauthClientId ?? ""}
|
||||
value={settings.oauthClientId ?? ""}
|
||||
onChange={(e) => onOAuthChange("clientId", e.currentTarget.value)}
|
||||
/>
|
||||
<TextInput
|
||||
label="Client Secret"
|
||||
value={oauthClientSecret ?? ""}
|
||||
value={settings.oauthClientSecret ?? ""}
|
||||
type="password"
|
||||
onChange={(e) =>
|
||||
onOAuthChange("clientSecret", e.currentTarget.value)
|
||||
|
|
@ -247,7 +229,7 @@ export function ServerSettingsForm({
|
|||
/>
|
||||
<TextInput
|
||||
label="Scopes"
|
||||
value={oauthScopes ?? ""}
|
||||
value={settings.oauthScopes ?? ""}
|
||||
onChange={(e) => onOAuthChange("scopes", e.currentTarget.value)}
|
||||
/>
|
||||
</Stack>
|
||||
|
|
|
|||
Loading…
Reference in a new issue