feat(mcpi): experimental session CLI client (#1432) - #1783
Open
BobDickinson wants to merge 11 commits into
Open
Conversation
Add servers/list and servers/show, --relogin / --stored-auth-only, browser OAuth navigation with OSC 8 links, and extract method handlers under clients/cli/src/handlers. Tracks #1781. Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce clients/mcpi (session front-end + local daemon), wire it into monorepo validate/build/coverage/install, and document the design. Not shipped in the published inspector tarball. Closes #1432. Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Jul 25, 2026
Take the merged #1782 CLI sources from v2/main; keep mcpi client wiring in root validate/format/coverage; register mcpi in format-coverage verify. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
# Conflicts: # AGENTS.md # README.md # clients/launcher/package-lock.json # package.json
Two interface-drift breaks surfaced only at build/runtime (the git merge itself was clean): - clients/cli/handlers/method-types.ts dropped metaValueToString when _meta was widened to RequestMetadata (JsonValue, not string) in #1910. mcpi's stringifyMeta was flattening to strings for a type that no longer exists; pass the already-JSON metadata through directly instead. - core/ gained proper-lockfile (auth/node/file-lock.ts) and yaml (mcp/skillFile.ts) as new dependencies. Both are bundled into mcpi's daemon via the noExternal @inspector/core reach-in, and both do a dynamic require() of a Node builtin in their CJS internals, which esbuild's ESM bundle output can't satisfy — the daemon threw on startup with 'Dynamic require of "process"/"path" is not supported' and every session-CLI test that needed a live daemon timed out waiting for it. Externalize both packages (already root dependencies, resolvable from node_modules at runtime). Verified: npm run build:mcpi succeeds, npm run validate:mcpi (lint + typecheck + 117 tests, coverage gate) passes clean.
Ad-hoc connect targets (bare URL/stdio, no catalog entry) had no way to request auto/modern era negotiation - loadServerEntries/ headersToServerSettings never populate protocolEra, so an ad-hoc connect always defaulted to legacy with no override, unlike a catalog entry with a protocolEra field. Add --era <legacy|auto|modern> to mcpi connect, applied via a new withEraOverride() helper (mirrors the existing withConnectTimeout() pattern) that overrides protocolEra on the resolved settings, or synthesizes a bare-defaults settings object carrying just the override when the target had none.
mcpi initialize never sent a live initialize request - it replayed InspectorClient's cached connect-time state, which is populated the same way regardless of era (legacy initialize response vs. modern server/discover). The name was misleading, and it omitted the two fields that do differ by era: protocolEra and (when probed) supportedVersions. Remove "initialize" from SESSION_RPC_METHODS (kept in ONE_SHOT_METHODS - the one-shot CLI's --method initialize still matches the literal wire method name on purpose). Add mcpi sessions/show [session], combining daemon session bookkeeping (name, serverIdentity, timestamps, isMru) with live connection state (serverInfo, protocolVersion, protocolEra, capabilities, instructions, supportedVersions). New daemon op sessions/show plus SessionRegistry.sessionFor() backing both it and the existing clientFor(). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CI (npm run validate) failed on verify:typecheck-coverage: mcpi had no typecheck script wired into validate, unlike cli/tui/launcher. Fixing that surfaced further gaps once mcpi's own toolchain was actually exercised end-to-end: - clients/mcpi: add typecheck/check scripts (validate -> check -> typecheck), tsconfig.test.json (mirrors cli's pattern), and the same compilerOptions overrides cli/tui use so core/'s noUncheckedIndexedAccess strictness doesn't spuriously fail here. - clients/mcpi/package.json: bump @modelcontextprotocol/client, core, server, and server-legacy from a stale 2.0.0-beta.5 to 2.0.0 (real SDK version skew vs. the rest of the monorepo, caught by verify:dep-lockstep). Per AGENTS.md, the shared toolchain (eslint, vitest, typescript, etc.) is declared once at the repo root and in no client manifest, so drop mcpi's own copies of all of it instead of keeping them in sync by hand - matching cli/tui/launcher exactly, it now resolves the root copies via npm/Node's directory walk-up. Keep only what's genuinely client-specific: tsup (its bundler) and @types/express (needed transitively by the test-server barrel import, same reason cli has it). That transitive import also drags in a hoisted @types/node that drifts from root's, so pin it via overrides the same way clients/cli does. - Fix real bugs typecheck caught: an unsound cast in format-session.ts, wrong-arity expectCliFailure() calls and an invalid AuthChallengeReason literal in two test files, and two throws missing an Error cause (preserve-caught-error) once the root's current eslint actually ran against this client for the first time. - Register mcpi with the repo's cross-cutting guards that assumed a fixed client list: verify-test-timeouts.mjs (CONFIG_ROOTS / EXPECTED_PROJECTS plus its own test fixtures), verify-bundle- externals.mjs (BUNDLED_CLIENTS, since mcpi ships a tsup bundle), workflow-gate.test.mjs (local:validate must reach mcpi the same way it reaches its siblings), and root package.json's local:validate script. Verified: npm run validate passes clean end-to-end (guards, core, and all six clients). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d them The previous commit fixed verify:typecheck-coverage, which unblocked two CI jobs that had never run to completion on this branch before: the per-file branch-coverage gate and the externalized-dependency check. Coverage (clients/mcpi, >=90% branches per file): - server.ts, format-human.ts, and mcp.ts had branch coverage below the 90% gate. The gaps traced to two features added this session that had thin or subprocess-only test coverage: sessions/show's enrichment fields (era, serverInfo, capabilities, supportedVersions, instructions) and the --era flag (previously untested at all). - Added in-process tests (server.handle()/callDaemon() against a daemon constructed directly in the test file) instead of runMcp() subprocess calls, since subprocess code isn't visible to coverage instrumentation. Covers sessions/show's absent-field fallback paths and full success path, the --era auto/invalid-value paths, and the mcp.ts positional sessionArg fallback for sessions/show. Build gate (verify:bundle-externals): - mcpi's tsup entry is named mcp-bin.js (multi-entry config), not index.js like web/cli/tui, so the script's hardcoded index.js existence check reported "build/index.js is missing" for mcpi even after a real build. Added a per-client `entry` override (defaults to index.js) so mcpi's real entry file is checked. - Once buildable, the scan found @modelcontextprotocol/ext-apps (a root runtime dependency reachable through cli's noExternal reach-in) had been inlined into mcpi's bundle instead of staying external. cli and tui already list it as external; added the same entry to mcpi's tsup config. npm run validate and npm run coverage both pass cleanly at the repo root after these changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1432
Depends on #1782 (CLI improvements — handlers and shared helpers live there).
Summary
clients/mcpisession CLI (connect once, many commands) with an implicit local Unix-socket daemonclients/clihandlers / OAuth helpers via a temporary build-time@inspector/clialiasvalidate/build/coverage/install-clientsand document in AGENTS +specification/v2_cli_v2.mdPackaging
@modelcontextprotocol/inspectortarball (filesallowlist unchanged)bin.mcpi— install vianpm linkfromclients/mcpifor local use (seeclients/mcpi/README.md)Test plan
cd clients/mcpi && npm run validate(117 tests)v2/mainafter CLI: catalog listing, auth flags, and OAuth browser UX #1782 mergesnpm run cifrom repo root on the stacked branchMade with Cursor