feat(cli): session-oriented mcpi CLI with daemon (#1432)#1727
feat(cli): session-oriented mcpi CLI with daemon (#1432)#1727BobDickinson wants to merge 4 commits into
mcpi CLI with daemon (#1432)#1727Conversation
Land the living design doc under specification/ so we can iterate there; cross-link from the as-built CLI/TUI launcher and catalog specs. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Note: This is a first pass. There are noted open / future issues in the spec. We're trying to land a base PR to build from. @claude review |
|
Claude finished @BobDickinson's task in 3m 49s —— View job Review: session-oriented
|
Arm the session daemon idle timer on start (and after failed connect) so session-less spawns self-reap. JSON.stringify structured --metadata values. Rename the session bin from mcp to mcpi to avoid PATH collisions, and clarify --relogin as ignore-stored-OAuth (no-op for stdio). Co-authored-by: Cursor <cursoragent@cursor.com>
mcp CLI with daemon (#1432)mcpi CLI with daemon (#1432)
|
OK, Cursor updated the PR description with responses to review comments, which isn't ideal. But I think generally we're good now. |
| npx @modelcontextprotocol/inspector --cli # CLI | ||
| npx @modelcontextprotocol/inspector --cli # one-shot CLI | ||
| npx @modelcontextprotocol/inspector --tui # TUI | ||
| npx --package=@modelcontextprotocol/inspector mcpi servers/list # session CLI |
There was a problem hiding this comment.
This seems like a toe-stubber (different command line for one client). Can the launcher not be the entry point and hand off to the mcpi?
Closes #1432
Summary
Implements the session-oriented Inspector CLI from #1432, as documented in
specification/v2_cli_v2.md:mcpientrypoint (bin.mcpi→clients/cli/build/mcp-bin.js) with an implicit local session daemon (IPC). Connect once, run many MCP subcommands against a named session, then disconnect — ssh-agent-style private binding viaeval "$(mcpi private)".mcp-inspector --clistill connects → one--method→ disconnect, never starts the daemon. Both paths sharehandlers/run-method.ts+InspectorClient.servers/list|show), session lifecycle (connect/disconnect/sessions/*), auth store (auth/list,auth/clear), daemon control, and MCP methods including streams (logging/tail,resources/subscribe), tasks, and roots.--format json, no{ result }envelope); TTY styling / OSC 8; connect-time OAuth with--relogin/--stored-auth-only.Known gaps stay in the spec To-do (mid-session auth over IPC, Windows named pipes, daemon lock hardening, etc.) — not claimed as done here.
Review follow-ups (Claude on this PR)
Addressed in
5fbd3b9e:ensureDaemonfrom e.g.mcpi tools/listwith no sessions still self-reaps (~60s). Covered by a session-less start test.stringifyMetamangling (Low) — Non-string metadata values (objects/arrays fromkey={"a":1}) are nowJSON.stringify'd instead ofString(v)→"[object Object]", in both session and one-shot paths.--reloginon stdio (Low/UX) — Documented, not rejected: the flag means “ignore stored OAuth for this connect; interactive login only if auth is required.” For stdio / no URL-keyed store entry it is a deliberate no-op (nothing to clear). Help text, README, andv2_cli_v2.mdupdated accordingly.mcp→mcpi(MCP Inspector) in root +clients/clipackage.json, docs, examples, and Commander.name(), to avoid claiming a genericPATHname.Deferred (already in spec To-do / out of scope for this base PR):
ensureDaemonunlink on failed ping vs auth mismatch — rare private-token edge case; leave for later hardening.ipc-glue.ts/stream-client.ts— already tracked in the spec To-do.Test plan
npm run validate(web / cli / tui / launcher)clients/cliunit suite + per-file ≥90 coverage gate (test:coverage), with the exclusions listed in the specmcpi connect <server> --config …→tools/list→tools/call …→disconnect→daemon stopmcpi connect … --relogin,auth/list,auth/clear <url>,auth/clear --all --yeseval "$(mcpi private)"isolates the daemon from the default socketmcp-inspector --cli …still works for the same catalog entrymcpirename