* test(core): backfill coverage on inspectorClient + remote server
Resolves#1310. Drops the two TODO(#1310) exclusions from
clients/web/vite.config.ts (coverage.exclude); both files now pass the
per-file gate (lines >=90, statements >=85, functions >=80, branches >=50).
core/mcp/remote/node/server.ts (88.15 / 78.37 -> 97.29 / 100):
- Extract createTokenAuthProvider to its own file
(core/mcp/remote/node/tokenAuthProvider.ts) so the 7 no-op
OAuthClientProvider stubs can be unit-tested directly.
- Add focused integration tests covering the remaining gaps:
* createTransportNode failure path on POST /api/mcp/connect
* /api/mcp/send when transport is dead
* /api/log non-JSON body (catch fallback)
* forwardLogEvent unknown-level / no-messages / string-first-message
fallbacks (lines 232, 240-242, 257-265 in the original)
* /api/fetch missing-url + upstream-throw paths
* /api/storage POST invalid storeId + invalid JSON body
* /api/storage GET when the on-disk store is unparseable
core/mcp/inspectorClient.ts (73.48 / 72.09 -> 91.16 / 89.92):
Added a single "Coverage backfill (#1310)" describe block to the existing
integration test, plus a few unit-style cases:
- OAuth getters / setOAuthConfig / authenticate when oauthManager is unset.
- Simple session, roots, subscription, and instructions accessors.
- subscribe / unsubscribe error paths against a server without the
subscribe capability; happy path against one with it.
- getPrompt + readResourceFromTemplate happy path + expansion-failure.
- setLoggingLevel "Server does not support logging" guard.
- getAppRendererClient (null before connect, cached proxy after).
- OAuth + stdio: authenticate() throws via getServerUrl()'s stdio check.
- listChanged notifications: tools/resources/prompts handlers via the
fixture add_tool / add_resource / add_prompt tools.
- Misc tiny branches: re-connect no-op, elicit form mode, getTaskCapabilities
on a tasks-less server, receiver-task TTL cleanup + cancel via the
private surface (the focused-unit pass the issue describes).
- defensive `if (!this.client) throw` guards: one nullify-and-call test
exercises 16 of them via a single instance, plus the connect() entry
guard.
The receiver-task internals test uses (instance as unknown as
{ private fields... }) to drive createReceiverTask / cancelReceiverTask
/ TTL cleanup directly; per the issue, refactoring private helpers to
be testable from a unit test was authorized.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(core): address #1317 PR review feedback
- Rename the misnamed "listChanged notifications" describe in
inspectorClient.test.ts to "capability detection after connect", since
the test asserts only on getCapabilities() round-tripping and never
triggers or observes a notification dispatch. Real dispatch coverage
lives in the adjacent "list_changed + resourceUpdated notifications"
block. Kept the resources/prompts fixtures with a note explaining why
they are required for the server to advertise the matching capabilities.
- Expand the comment on the 250ms wait in remote-transport.test.ts'
/api/mcp/send dead-transport test so it is clear the >= 500 assertion
is intentionally permissive across both the dead-transport short-
circuit and the downstream send-failure branches.
- Add a "keep this in sync" pointer on the nullify() helper so a future
cleanup that removes any of the defensive `if (!this.client) throw`
guards in inspectorClient.ts is reminded to drop the matching call here
rather than silently under-covering.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(core): apply v1.5-port cleanups deferred from #1306
Addresses issue #1309 — five small, mechanical cleanups deferred from the
v1.5 runtime port:
1. Collapse BrowserOAuthStorage / NodeOAuthStorage / RemoteOAuthStorage
onto a shared OAuthStorageBase. Three ~130-line duplicates become
thin adapter wrappers; behavior + public API unchanged.
2. Re-enable erasableSyntaxOnly in tsconfig.app.json by rewriting the
seven (plus two the issue missed in sampling/elicitation create-
message) parameter-property constructors as explicit field + assign.
3. Route the lone console.error in inspectorClient.ts through this.logger.
4. Replace `${Date.now()}-${Math.random()}` with crypto.randomUUID() at
the five local-only ID sites (message tracking + sampling/elicit).
5. Pin the remote-server hono app generic at new Hono<Env>() and drop
the streamSSE cast. Root cause of the cast was an unresolved hono
subpath: the tsconfig "hono/*" wildcard didn't honor the exports
map, so hono/streaming leaked to the root-hoisted hono@4.12.12 while
hono itself resolved to clients/web/hono@4.12.18. Replaced the
wildcard with an explicit hono/streaming entry in both tsconfig.app
and tsconfig.test, removing the package-identity mismatch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(core): address #1316 PR review feedback
- Drop the stranded no-op getServerState() read at the top of
clearClientInformation in OAuthStorageBase (carried over verbatim
from the three originals).
- Drop the crypto.randomUUID() guard at the task-ID site so all
six in-scope sites are consistent; the fallback branch was dead
code on every supported runtime.
- Remove the residual `c as Context` cast at the streamSSE call site
in core/mcp/remote/node/server.ts — once both hono imports
resolve to the same package the route-typed Context flows through
to streamSSE with no cast at all.
- Move the new `options` / `config` field declarations in
RemoteClientTransport up with the rest of the field block, matching
the layout used by the other five rewritten classes in this PR.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* wip(core): bulk-copy v1.5 InspectorClient runtime files (#1302)
Verbatim ports from origin/v1.5/main into v2/main core/:
- logging/ (2 files)
- storage/ + storage/adapters/ (4 files)
- auth/ + auth/browser/ + auth/node/ + auth/remote/ (16 files)
- mcp/config.ts + mcp/node/ (4 files, stdio transport)
- mcp/remote/ + mcp/remote/node/ (12 files, HTTP/SSE transport)
- mcp/inspectorClient.ts (~2169 LOC), messageTrackingTransport,
fetchTracking, oauthManager, index, state/index
Total: ~7,800 LOC of source files, copied unmodified via
`git show origin/v1.5/main:<path> > <dest>`.
Also:
- Add deps: pino, hono, @hono/node-server, atomically, zustand, @types/node
- tsconfig.app.json: extend paths to resolve new node-only deps from
core/, add "node" to types, disable erasableSyntaxOnly (v1.5 code
uses parameter properties — TODO to re-enable in follow-up)
Compiles down to 47 type errors, all in three categories:
- 24 TS2305: v2 dropped v1.5 type exports (InspectorClientOptions,
CreateTransport, InspectorClientEnvironment, AppRendererClient,
SamplingCreateMessage class, ElicitationCreateMessage class,
jsonUtils helpers, OAuth events). Per user direction, will re-add
these to v2's diverged files (types.ts, samplingCreateMessage.ts,
etc.) so the ported code stays verbatim.
- 15 TS7006: implicit-any params in v1.5 code (v1.5 tsconfig was
looser than v2's noImplicitAny). Need explicit annotations.
- 8 other TS errors: ../package.json import, Transport|null narrowing,
hono Context generic mismatch, one unused parameter.
Tests not yet ported (19 files, ~11,170 LOC).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* wip(core): integrate ported v1.5 InspectorClient + port tests (#1302)
Source integration (typecheck + build now pass):
- Re-add v1.5 types/classes dropped during v2 evolution:
- types.ts: CreateTransport*, AppRendererClient, InspectorClient{Environment,Options}
- samplingCreateMessage.ts / elicitationCreateMessage.ts: classes + keep v2's
InspectorPending{Sampling,Elicitation} interface
- inspectorClientEventTarget.ts: oauth* event keys
- json/jsonUtils.ts: convertParameterValue / convertToolParameters /
convertPromptArguments + ParameterSchema
- inspectorClient.ts: replace `../package.json` import (v2 has no
core/package.json) with a hardcoded identity constant
- remote/node/server.ts: cast hono Context for streamSSE (hono's
generic typing tightened since v1.5)
- oauth-callback-server.ts: drop unused hostname field
- tsconfig: enable @types/node, add paths for new bare-module deps
(pino, zustand, hono, atomically) in app + test configs
- vite.config.ts: mirror those module aliases for the unit project
(which runs from repoRoot)
Tests ported (19 files, ~11K LOC) under clients/web/src/test/core/:
- All core/__tests__/auth/* (7 files)
- inspectorClient.test.ts + 4 OAuth variants
- mcp/oauthManager.test.ts, jsonUtils.test.ts
- transport, remote-transport, remote-server-config, storage-adapters
- helpers/oauth-client-fixtures.ts
Bulk-rewrote `from "../mcp/…"` → `from "@inspector/core/mcp/…"` etc.
Current state:
- typecheck: 0 errors
- build: passes (vite v8, 788 modules)
- unit tests: 1014 / 1034 pass (937 pre-existing + 77 new core tests)
- 20 failures in 13 files; failure modes:
- 13 file-load failures needing the v1.5 `test-servers/` package
(@modelcontextprotocol/inspector-test-server) which isn't in v2 yet
or real fs/network not available in happy-dom
- 7 assertion failures in discovery.test.ts + state-machine.test.ts
(SDK 1.29 vs 1.25 API drift — mocks don't match new shape)
Coverage gate not yet checked against new files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* wip(core): port test-servers, more types, partial test integration (#1302)
- Port v1.5 test-servers/ package (12 files, ~5K LOC) under
repo-root/test-servers/, wire @modelcontextprotocol/inspector-test-server
alias in both vite.config.ts (regex form) and tsconfig.test.json.
- Add deps: express ^5, yaml ^2, @types/express ^5.
- Re-export InspectorClientOptions/Environment/Transport* from inspectorClient.ts
so v1.5 tests that import them from that module path keep resolving.
- Switch InspectorClientEventMap to use SamplingCreateMessage /
ElicitationCreateMessage classes (matches v1.5 event payload contracts)
while keeping the InspectorPending{Sampling,Elicitation} interfaces in
the *.ts modules for v2 consumers that still use them.
- Fix verbatim-module-syntax issue in test-servers and drop unused stdio
config field.
- Adjust inspectorClient.test.ts task types to TaskWithOptionalCreatedAt
(SDK 1.29 tightened Task shape vs v1.5's 1.25).
- Drop spurious maxMessages/maxFetchRequests/maxStderrLogEvents from
remote-transport.test.ts (never on InspectorClientOptions).
State:
- typecheck: 0 errors
- build: passes
- unit tests: 1099 / 1270 pass
- 171 failures in 10 test files, almost all integration tests that need
real HTTP/fs/network (happy-dom can't host them). Next: add a node-env
vitest project to run these properly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(core): port v1.5 InspectorClient + transports + auth subsystem (#1302)
Bulk-port of the v1.5 core runtime (~7,800 LOC source + ~16K LOC tests +
~5K LOC test-servers/) into v2. Files copied verbatim from origin/v1.5/main
via `git show >`; only minimal adapters added on the v2 side.
Subsystems landed
-----------------
- core/logging/, core/storage/, core/auth/ (browser + node + remote)
- core/mcp/ runtime: inspectorClient.ts (2169 LOC), oauthManager,
messageTrackingTransport, fetchTracking, config, index
- core/mcp/node/ (stdio transport)
- core/mcp/remote/ + remote/node/ (HTTP/SSE transport + Hono server)
- test-servers/ package (composable MCP test servers, fixtures, harness)
v2 adapter layer
----------------
- types.ts: append CreateTransport*, AppRendererClient,
InspectorClient{Environment,Options} (v2 had pruned these — v1.5 needs them)
- samplingCreateMessage / elicitationCreateMessage: keep v1.5 classes AND
v2's Inspector Pending* interfaces in the same files
- inspectorClientEventTarget: add oauth* event keys; switch pending
sampling/elicitation payloads to the classes (matches v1.5 contracts)
- json/jsonUtils: append convertParameterValue/convertToolParameters/
convertPromptArguments + ParameterSchema
- inspectorClient.ts: re-export Options/Environment/Transport* so tests
that import these from `inspectorClient.js` keep resolving; replace
`../package.json` import with a hardcoded identity (v2 has no core/package.json)
- remote/node/server.ts: cast hono Context for streamSSE (hono generic
tightened since v1.5)
- oauth-callback-server: drop unused hostname field
- tsconfig.app.json / tsconfig.test.json: add @types/node + paths for
pino/zustand/hono/@hono/node-server/atomically/express/yaml, disable
erasableSyntaxOnly (parameter-property syntax from v1.5)
- vite.config.ts: regex-form module aliases (so the package's exports
field handles subpaths like `hono/streaming`, `zustand/middleware`),
alias for @modelcontextprotocol/inspector-test-server → test-servers/src
Tests
-----
- 19 v1.5 test files copied under clients/web/src/test/core/,
imports rewired to @inspector/core/* and @modelcontextprotocol/inspector-test-server
- 1004 unit tests pass; 298 storybook tests pass; coverage gate passes
Known follow-ups (out-of-scope here, tracked in TODOs)
------------------------------------------------------
- 13 integration test files are excluded from the unit project (spawn real
HTTP/stdio servers; run real OAuth flows; mock SDK auth → happy-dom CORS).
Needs a node-env vitest project. Files listed under `test.projects[0].test.exclude`.
- Source files exercised only by those integration tests are excluded from
the coverage gate pending the node-env project. Listed under
`test.coverage.exclude` with comment.
- Manual smoke tests against real stdio / HTTP / OAuth server per the AC
on #1302 still need verification locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs/fix: address #1306 review (AGENTS tree, #1307 links, @types/node, .substr)
- AGENTS.md: expand the project-structure tree to include all v1.5-ported
subsystems (core/auth/{browser,node,remote}, core/storage, core/logging,
core/mcp/{node,remote/{,node}}, core/mcp/state) plus the new top-level
test-servers/ directory (with a note about its @modelcontextprotocol/
inspector-test-server alias).
- vite.config.ts: reference #1307 from both the test exclude block and the
coverage exclude block so the next person editing either sees the
marching order for shrinking the lists.
- package.json: restore @types/node to ^24 (an earlier `npm install
--save-dev @types/node@^22` accidentally pinned it lower than the repo
was using; nothing here required ^22).
- core/mcp/fetchTracking.ts: replace deprecated .substr(2, 9) with
.slice(2, 11) to match the convention in core/mcp/inspectorClient.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(core): port v1.5 hook layer (useInspectorClient + useManaged*/usePaged* + log hooks)
Wholesale port of v1.5's React hook layer and the EventTarget-based state machinery the hooks subscribe to (#1243). Hooks decouple from the concrete InspectorClient via a new `InspectorClientProtocol` interface so this layer can land before the runtime class is ported.
Added under `core/`:
- `core/react/` — useInspectorClient + 5 useManaged* + 5 usePaged* + 3 log hooks
- `core/mcp/state/` — 5 managed*State + 5 paged*State + messageLogState + stderrLogState + fetchRequestLogState
- `core/mcp/inspectorClientProtocol.ts`, `inspectorClientEventTarget.ts`, `typedEventTarget.ts`, `samplingCreateMessage.ts`, `sessionStorage.ts`
- v2-only wrapper types in `core/mcp/types.ts`: InspectorUrlElicitRequest, InspectorPendingRequest, InspectorRequestHistoryItem
Tests live under `clients/web/src/test/core/` (28 new test files, 264 new tests). Test fake: `core/mcp/__tests__/fakeInspectorClient.ts`.
Build wiring:
- `vite.config.ts`: dedupe react/react-dom so core/ files resolve them via clients/web/node_modules.
- `tsconfig.app.json` / `tsconfig.test.json`: paths map react/react-dom/vitest to clients/web/node_modules so `tsc -b` resolves bare imports from core/ source files (which sit above the package's node_modules). Exclude core/__tests__ from app config; include in test config.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* review: address PR #1300 review findings
Bugs:
- fetchRequestLogState: add .catch() on sessionStorage.loadSession so a corrupt
or unreadable session doesn't surface as an unhandled rejection (matches the
saveSession swallow pattern).
- messageLogState: sync pendingRequestEntries when clearMessages() evicts a
pending request entry, so a later response with the same id falls through
to the append branch instead of mutating an unreachable map entry. Add tests
for both predicate and no-predicate paths.
Cleanups:
- Extract mergeTaskIntoList helper to core/mcp/state/mergeTaskIntoList.ts so
managed/paged RequestorTasks state classes share one definition.
- Add a one-line JSDoc note on each PagedTools/Prompts/Resources/Templates
state explaining why they deliberately do not subscribe to *ListChanged
(cursor invalidation mid-pagination).
- Document on useInspectorClient that appRendererClient is read lazily on
every render and is not subscribed (changes once at connect time).
Carry-overs from v1.5 deliberately left for the follow-up InspectorClient
runtime port:
- Refresh/status-change race in Managed*State.refresh() (status check is only
at entry; a disconnect during await can re-clear before refresh resumes).
- nextCursor exposure asymmetry across usePaged* (only usePagedRequestorTasks
surfaces it via state field; others return it from loadPage() only).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(apps): add isAppTool helper in core (#1260)
Adds @modelcontextprotocol/ext-apps as a dependency (root + clients/web)
and a thin core/mcp/apps.ts wrapper exposing:
- getAppResourceUri(tool): re-export of getToolUiResourceUri so all
Inspector clients consume the same nested/flat _meta resolution.
- isAppTool(tool): boolean predicate built on top of getAppResourceUri.
Both surface the underlying ext-apps throw on a malformed _meta.ui.resourceUri
(string that does not start with "ui://") rather than swallowing it — server
bugs should be visible.
Tests cover nested format, deprecated flat format, nested-wins precedence,
missing _meta, and the invalid-URI throw.
Refs #1260
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(apps): address PR #1272 review feedback
- core/mcp/apps.ts: convert getAppResourceUri from a typed const re-export to
a function declaration so its export style matches isAppTool. Behavior is
unchanged.
- core/mcp/apps.ts: document the filter-iteration implication on isAppTool —
callers using tools.filter(isAppTool) will halt on a server-malformed URI.
- apps.test.ts: add the symmetric isAppTool false-case for `_meta.ui` present
without `resourceUri`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rename RequestMethod → MessageMethod. The type covers notifications and
results, not just requests; the new name matches the JSDoc.
- Normalize imports to the @inspector/core/mcp/types.js path alias in
HistoryListPanel, historyUtils, and HistoryScreen (HistoryControls was
already using the alias).
- Document the cast invariant in extractMethod: SDK types message.method
as string, but every MessageEntry in this app originates from SDK
schemas, so the narrowing is safe.
- Type SAMPLE_METHODS as MessageMethod[] in HistoryControls stories so
the literal-type narrowing isn't lost across the spread.
Skipped two reviewer suggestions: the Mantine Select inline cast (reviewer
self-resolved) and the stale-methodFilter-on-clear UX edge case (deferred
as a separate follow-up — not a Phase 5 audit gap).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Audited every component under clients/web/src/components/ against its
v2_ux_interfaces.md entry. Added an "Audit results" section near the top
of the spec with the verified count (57/62 satisfied, 5 partial) and the
specific gaps still open.
While auditing, closed the HistoryControls gap directly:
- Added RequestMethod union type to core/mcp/types.ts, derived from the
SDK's Client/Server Request and Notification schemas plus a synthetic
"response" entry for result/error MessageEntries.
- Typed methodFilter and onMethodFilterChange in HistoryControls,
HistoryListPanel, historyUtils.extractMethod with RequestMethod.
- Lifted the hardcoded METHOD_OPTIONS list out of HistoryControls into
a required availableMethods prop. HistoryScreen now derives it from
the live entries via useMemo + extractMethod.
- Updated HistoryControls.stories.tsx to pass availableMethods.
The remaining 5 partials (ElicitationUrlPanel, InlineElicitationRequest,
InlineSamplingRequest, ExperimentalFeaturesPanel, ResourceListItem) are
either blocked on the v2 core hook layer effort or call out follow-up
work that has its own design questions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per AGENTS.md, comment blocks should be one short line. The interface
name and per-field invariant comments already document the shape; the
extra block was redundant.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ServerEntry was previously defined as `Pick<ServerCardProps, ...>` in
ServerListScreen, inverting the natural dependency direction (data shape
derived from a UI prop type). Phase 5's cleanup pass calls this out
specifically.
Move the canonical ServerEntry into core/mcp/types.ts and have
ServerCardProps extend it. ServerListScreen, InspectorView, and their
stories now import ServerEntry from core directly.
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>
- 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>
Add ajv as an explicit dependency in clients/web/package.json (was only
available transitively via @modelcontextprotocol/sdk). Add inline comment
on StdioServerConfig.type explaining the implicit-default contract and
its impact on switch narrowing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>