Phase 0 foundations for component interfaces refactor
Stands up the type-only prerequisites for the v2 UX component
interfaces refactor per specification/v2_ux_interfaces_plan.md.
Phase 0.1 — MCP SDK dependency:
- Add @modelcontextprotocol/sdk ^1.29.0 and zod ^4.3.6 to both the
root package.json and clients/web/package.json so component files
can import Tool / Prompt / Resource / Task / LoggingLevel / etc.
directly from the SDK.
Phase 0.2 — Inspector wrapper-types module:
- Create core/mcp/types.ts mirroring the type-only subset of v1.5's
core/mcp/types.ts: MCPServerConfig (discriminated union), ServerType,
MCPConfig, ConnectionStatus, StderrLogEntry, MessageEntry (Date
timestamps, not ISO strings), FetchRequestEntry(+Base), ServerState,
and the *Invocation types. Adds v2-only wrappers
InspectorResourceSubscription and InspectorServerJsonDraft.
- Add core/mcp/taskNotificationSchemas.ts for the Inspector-owned
notifications/tasks/list_changed signal (not in the SDK).
- Add core/mcp/elicitationCreateMessage.ts re-exporting ElicitRequest
and ElicitResult plus an InspectorPendingElicitation interface for
typing the pending-queue.
- Add core/json/jsonUtils.ts for the shared JsonValue / JsonObject
types used inside core/mcp/types.ts.
- Copy v1.5's clients/web/src/utils/jsonUtils.ts (JsonSchemaType) and
schemaUtils.ts (AJV-backed validators) verbatim so SchemaForm can
switch off its local JsonSchema type.
- Copy v1.5's clients/web/src/lib/types/customHeaders.ts verbatim for
ServerSettingsForm and the experimental panel.
- Add clients/web/src/types/navigation.ts with InspectorTab (UI-routing
concept, lives with the web client rather than in core/).
- Wire tsconfig.app.json + vite.config.ts with the @inspector/core/*
path alias so component files can import from core/ without
relative-path hell.
Phase 0.3 — Vet (likely) hedges in v2_ux_interfaces.md:
- Follow-up sweep on commit 2ef257da. Replaces the remaining
useMcpClient references with useInspectorClient, ties pending
elicitation / sampling callbacks to the in-InspectorClient queue
rather than a non-existent useElicitation / useSampling hook,
corrects Task references to the SDK type (not an InspectorTask
wrapper), corrects log hook wiring to useMessageLog, and strikes
all remaining v2-only hooks with explicit "no v1.5 analog"
annotations. grep "likely" specification/v2_ux_interfaces.md now
returns zero results.
Phase 0.4 — Local-redeclaration inventory:
- specification/v2_ux_interfaces_phase_0_4_inventory.md enumerates
every ad hoc local type (JsonSchema, LogLevel, TaskStatus,
PromptItem, ResourceItem, ToolListItemProps, RootEntry, KeyValuePair,
inline ConnectionStatus / transport unions) that will be replaced
in Phases 1–4, including the file it lives in, every site that
re-imports it, and the SDK / wrapper type that replaces it. Intended
for the Phase 0 PR description and as a running checklist during
the refactor.
Build state: npm run build / lint / format:check all pass in
clients/web.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6abbe4eb1f
commit
8edff4ea77
4 changed files with 3192 additions and 82 deletions
13
core/json/jsonUtils.ts
Normal file
13
core/json/jsonUtils.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* JSON value type used across the inspector project
|
||||
*/
|
||||
export type JsonValue =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| undefined
|
||||
| JsonValue[]
|
||||
| { [key: string]: JsonValue };
|
||||
|
||||
export type JsonObject = { [key: string]: JsonValue };
|
||||
19
core/mcp/elicitationCreateMessage.ts
Normal file
19
core/mcp/elicitationCreateMessage.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import type {
|
||||
ElicitRequest,
|
||||
ElicitResult,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
|
||||
export type { ElicitRequest, ElicitResult };
|
||||
|
||||
/**
|
||||
* Shape of a pending elicitation request tracked by the Inspector client.
|
||||
* v1.5 implements this as a class with a resolver/reject closure; v2 will
|
||||
* materialize the runtime when the core hook layer lands. For now we keep the
|
||||
* interface so screens/groups can type the pending-elicitation queue.
|
||||
*/
|
||||
export interface InspectorPendingElicitation {
|
||||
id: string;
|
||||
timestamp: Date;
|
||||
request: ElicitRequest;
|
||||
taskId?: string;
|
||||
}
|
||||
23
core/mcp/taskNotificationSchemas.ts
Normal file
23
core/mcp/taskNotificationSchemas.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Notification schema for notifications/tasks/list_changed (server → client).
|
||||
*
|
||||
* The SDK exports list_changed schemas for resources, prompts, tools, and roots, and
|
||||
* TaskStatusNotificationSchema for notifications/tasks/status, but no schema for
|
||||
* notifications/tasks/list_changed. Mainline (v1) does not register a schema for it
|
||||
* either: they use client.fallbackNotificationHandler so any unmatched notification
|
||||
* (including tasks/list_changed) is passed to onNotification, and App branches on
|
||||
* notification.method === "notifications/tasks/list_changed". We register specific
|
||||
* handlers only (no fallback), so we define this schema to handle the notification.
|
||||
*
|
||||
* List-changed notifications have no defined params (they are signals to refetch);
|
||||
* the SDK uses params: NotificationsParamsSchema.optional() for other list_changed
|
||||
* types (which is private, so we can't import it). We accept optional params only
|
||||
* so the notification parses; we do not use any params in the handler.
|
||||
*/
|
||||
import { NotificationSchema } from "@modelcontextprotocol/sdk/types.js";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
export const TasksListChangedNotificationSchema = NotificationSchema.extend({
|
||||
method: z.literal("notifications/tasks/list_changed"),
|
||||
params: z.record(z.string(), z.unknown()).optional(),
|
||||
});
|
||||
184
core/mcp/types.ts
Normal file
184
core/mcp/types.ts
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
import type {
|
||||
CallToolResult,
|
||||
GetPromptResult,
|
||||
Implementation,
|
||||
JSONRPCErrorResponse,
|
||||
JSONRPCNotification,
|
||||
JSONRPCRequest,
|
||||
JSONRPCResultResponse,
|
||||
Prompt,
|
||||
ReadResourceResult,
|
||||
Resource,
|
||||
ServerCapabilities,
|
||||
Tool,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
import type { JsonValue } from "../json/jsonUtils.js";
|
||||
|
||||
// Stdio transport config
|
||||
export interface StdioServerConfig {
|
||||
type?: "stdio";
|
||||
command: string;
|
||||
args?: string[];
|
||||
env?: Record<string, string>;
|
||||
cwd?: string;
|
||||
}
|
||||
|
||||
// SSE transport config
|
||||
export interface SseServerConfig {
|
||||
type: "sse";
|
||||
url: string;
|
||||
headers?: Record<string, string>;
|
||||
eventSourceInit?: Record<string, unknown>;
|
||||
requestInit?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
// StreamableHTTP transport config
|
||||
export interface StreamableHttpServerConfig {
|
||||
type: "streamable-http";
|
||||
url: string;
|
||||
headers?: Record<string, string>;
|
||||
requestInit?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export type MCPServerConfig =
|
||||
| StdioServerConfig
|
||||
| SseServerConfig
|
||||
| StreamableHttpServerConfig;
|
||||
|
||||
export type ServerType = "stdio" | "sse" | "streamable-http";
|
||||
|
||||
export interface MCPConfig {
|
||||
mcpServers: Record<string, MCPServerConfig>;
|
||||
}
|
||||
|
||||
export type ConnectionStatus =
|
||||
| "disconnected"
|
||||
| "connecting"
|
||||
| "connected"
|
||||
| "error";
|
||||
|
||||
export interface StderrLogEntry {
|
||||
timestamp: Date;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface MessageEntry {
|
||||
id: string;
|
||||
timestamp: Date;
|
||||
direction: "request" | "response" | "notification";
|
||||
message:
|
||||
| JSONRPCRequest
|
||||
| JSONRPCNotification
|
||||
| JSONRPCResultResponse
|
||||
| JSONRPCErrorResponse;
|
||||
response?: JSONRPCResultResponse | JSONRPCErrorResponse;
|
||||
duration?: number; // Time between request and response in ms
|
||||
}
|
||||
|
||||
export type FetchRequestCategory = "auth" | "transport";
|
||||
|
||||
export interface FetchRequestEntry {
|
||||
id: string;
|
||||
timestamp: Date;
|
||||
method: string;
|
||||
url: string;
|
||||
requestHeaders: Record<string, string>;
|
||||
requestBody?: string;
|
||||
responseStatus?: number;
|
||||
responseStatusText?: string;
|
||||
responseHeaders?: Record<string, string>;
|
||||
responseBody?: string;
|
||||
duration?: number; // Time between request and response in ms
|
||||
error?: string;
|
||||
/** Distinguishes OAuth/auth fetches from MCP transport fetches */
|
||||
category: FetchRequestCategory;
|
||||
}
|
||||
|
||||
/** Entry shape from createFetchTracker before category is added by the caller */
|
||||
export type FetchRequestEntryBase = Omit<FetchRequestEntry, "category">;
|
||||
|
||||
export interface ServerState {
|
||||
status: ConnectionStatus;
|
||||
error: string | null;
|
||||
capabilities?: ServerCapabilities;
|
||||
serverInfo?: Implementation;
|
||||
instructions?: string;
|
||||
resources: Resource[];
|
||||
prompts: Prompt[];
|
||||
tools: Tool[];
|
||||
stderrLogs: StderrLogEntry[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a complete resource read invocation, including request parameters,
|
||||
* response, and metadata.
|
||||
*/
|
||||
export interface ResourceReadInvocation {
|
||||
result: ReadResourceResult;
|
||||
timestamp: Date;
|
||||
uri: string;
|
||||
metadata?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a complete resource template read invocation, including request parameters,
|
||||
* response, and metadata.
|
||||
*/
|
||||
export interface ResourceTemplateReadInvocation {
|
||||
uriTemplate: string;
|
||||
expandedUri: string;
|
||||
result: ReadResourceResult;
|
||||
timestamp: Date;
|
||||
params: Record<string, string>;
|
||||
metadata?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a complete prompt get invocation, including request parameters,
|
||||
* response, and metadata.
|
||||
*/
|
||||
export interface PromptGetInvocation {
|
||||
result: GetPromptResult;
|
||||
timestamp: Date;
|
||||
name: string;
|
||||
params?: Record<string, string>;
|
||||
metadata?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a complete tool call invocation, including request parameters,
|
||||
* response, and metadata.
|
||||
*/
|
||||
export interface ToolCallInvocation {
|
||||
toolName: string;
|
||||
params: Record<string, JsonValue>;
|
||||
result: CallToolResult | null;
|
||||
timestamp: Date;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
metadata?: Record<string, string>;
|
||||
}
|
||||
|
||||
// v2-only wrapper types (no v1.5 equivalent)
|
||||
|
||||
/**
|
||||
* Resource subscription wrapper used by the Resources screen to track
|
||||
* subscribed resources and the time of the last update notification.
|
||||
*/
|
||||
export interface InspectorResourceSubscription {
|
||||
resource: Resource;
|
||||
lastUpdated?: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draft state for importing a server from registry JSON. Owned by the
|
||||
* ImportServerJsonPanel wiring layer. `parsed` is typed `unknown` until the
|
||||
* registry schema type is added in a follow-up.
|
||||
*/
|
||||
export interface InspectorServerJsonDraft {
|
||||
rawText: string;
|
||||
parsed?: unknown;
|
||||
selectedPackageIndex?: number;
|
||||
envOverrides: Record<string, string>;
|
||||
nameOverride?: string;
|
||||
}
|
||||
Loading…
Reference in a new issue