modelcontextprotocol / modelcontextprotocol/inspector
Inspector mcpi client
@BobDickinson is already working on this.
Since Jun 4, 2026.
- Dominant language
- TypeScript
- Stars
- 10.9k
- Forks
- 1.5k
- Avg merge
- 6h 17m
- Merged PRs (30d)
- 151
Description
Inspector mcpi design
The following describes the planned next-generation Inspector command-line client: what exists today, what we want to build, why, and how. CLI v2 is new work in clients/cli on @modelcontextprotocol/inspector-core.
Our goal is for the Inspector v2 CLI to fully support all aspects and modalities of MCP (as supporterd by the TUI and Web Inspectors), including complex operations and multiple operations per server connection. In addition, the Inspector v2 CLI will expose all aspects of MCP in a way that can be leveraged by production hosts to access those MCP aspects and modalities even when the host does not directly support them via its MCP implementation (with the host using the Inspector CLI via its CLI mechanism).
This approach was inspired by mcpc from Apify.
Related docs: shared-code-architecture.md, environment-isolation.md, protocol-and-state-managers-architecture.md, mcp-server-configuration.md, clients/cli/README.md.
1. Introduction
The Inspector CLI today is a one-shot client: each command connects to an MCP server, performs one operation, prints JSON, and exits. CLI v2 adds a session-oriented model—connect once, run many commands against a named session, then disconnect—on the same InspectorClient stack the web and TUI already use.
1.1 How the Inspector CLI works today
The launcher selects CLI mode with --cli. Every invocation is self-contained:
- Parse which server to use (
--config+--server, or a URL, plus transport/headers/env—see mcp-server-configuration.md). - Require
--methodnaming a single MCP operation. connect()→ perform that operation → printJSON.stringify(result)to stdout →disconnect()→ exit.
There is no persistent session and no subcommands—only “pick method + args.”
Example: list tools, then call one
Each line below is a separate process with its own spawn, handshake, and teardown:
# List tools (connect → tools/list → disconnect)
inspector --cli \
--config mcp.json --server myserver \
--method tools/list
# Call a tool (connect → tools/call → disconnect)
inspector --cli \
--config mcp.json --server myserver \
--method tools/call \
--tool-name search \
--tool-arg query=hello
That works well for scripts and CI that need one JSON blob per run. It is awkward when you want to explore a server, run several related steps, or use MCP features that span multiple RPCs over one connection (tasks, subscriptions, OAuth that you do not want to repeat every time).
Supported --method values and flags are listed in §3.2; see clients/cli/README.md for more examples.
1.2 CLI v2 session workflow
CLI v2 supports a session-oriented workflow alongside v1 one-shots:
- Connect to a server and register a named session (conventionally
@name). - Run many subcommands against that session without reconnecting.
- Disconnect when finished.
Unlike v1, connection setup happens once per session; subsequent commands reuse that MCP connection. A background session daemon (§5.3) holds each InspectorClient; it starts automatically—users run connect and session commands only, with no separate “start daemon” step.
Example: connect, run commands, disconnect (illustrative command names; see §5.4)
mcp connect --config mcp.json --server myserver @myserver
mcp @myserver tools list
mcp @myserver tools call search query=hello
mcp @myserver tasks get task-abc123
mcp @myserver disconnect
v1 --method one-shots remain for backward compatibility and work alongside session mode—see §2, §5, and §6.
1.3 Why session-oriented CLI matters
Exercise a server across multiple operations. Real workflows are rarely a single RPC: list tools, inspect a schema, call a tool, read a resource, adjust log level, then call again. Session mode matches how people use kubectl, docker, or database CLIs—a stable context and many commands—instead of repeating server selection and handshake on every line of a script or manual debugging session.
Exercise advanced MCP client behavior. Some protocol features only make sense across calls on one connection:
- Tasks — launch a long-running operation (often via a task-augmented tool call), poll
tasks/get, fetchtasks/result, ortasks/cancelwhile the server keeps state. - Subscriptions —
resources/subscribe, then observenotifications/resources/updatedover time. - Logging — set level once, then
logging tail(follownotifications/message) during later tool calls. - OAuth — authenticate once per session instead of on every ephemeral invocation.
Example: long-running task over one session (illustrative CLI v2 ergonomics; exact command names TBD):
mcp connect --config mcp.json --server batch @batch
mcp @batch tools call start_export format=json # may return a task id
mcp @batch tasks get export-task-42 # poll status
mcp @batch tasks result export-task-42 # fetch result when done
mcp @batch disconnect
That sequence is impossible to express cleanly with v1’s one-shot --method model—you would need a custom script that reconnects and somehow preserves server-side task identity across separate processes.
The web and TUI Inspector clients already do this interactively. CLI v1 exposes only a narrow one-shot subset; CLI v2 closes the ergonomics gap, not a gap in core protocol support (§7).
Access full MCP via CLI when the host lacks native support. Agent hosts often implement only part of the MCP client protocol—commonly tools, sometimes resources or prompts, rarely tasks, subscriptions, roots, completions, or sampling/elicitation. The server may still expose the full feature set. Inspector CLI v2’s job is to let an agent reach any of those server capabilities through documented CLI commands, using a shell tool the host already provides, instead of requiring the host to add native MCP client support for every feature and modality.
The model does not need a tasks/get (or prompts/get, resources/subscribe, …) RPC on its primary MCP connection. It runs Inspector CLI; the CLI uses InspectorClient to speak MCP to the server and returns JSON the model can parse. Native MCP where the host supports it; CLI bridge where it does not—same server, full protocol surface available to the agent.
Example: tasks via CLI when the host has tools MCP only
The agent’s MCP connection supports tools/* but not tasks. The user asks for a long export. The model uses the CLI session to call the tool, poll task status, and fetch the result:
mcp connect --config mcp.json --server jobs @jobs
mcp @jobs tools call start_export format=json
mcp @jobs tasks get export-task-42
mcp @jobs tasks result export-task-42
The same pattern applies to any modality the host omits: prompts get, resources subscribe, logging tail, and so on—whatever InspectorClient supports and the server advertises, exposed as CLI subcommands rather than native MCP in the agent runtime.
2. Summary
CLI v2 evolves clients/cli in place: session-oriented subcommands on InspectorClient, with v1 --method one-shots preserved (§6).
| Today (CLI v1) | Target (CLI v2) | |
|---|---|---|
| Package | clients/cli → @modelcontextprotocol/inspector-cli |
Same package and launcher; add mcp command (§5.2) |
| Process model | Connect → one MCP operation → disconnect per invocation | Session: connect once, many commands on a named @session (implicit daemon, §5.3); ephemeral: v1 one-shots unchanged |
| Protocol coverage | tools, resources, prompts, logging/setLevel (one-shot only) |
Full client surface aligned with TUI / web (InspectorClient + state managers)—tools, resources, prompts, tasks, logging, roots, subscriptions, OAuth, completions, etc. (phased) |
| Use cases | Scripts, CI, agents needing a single JSON result per run | Multi-step server exercise; advanced MCP over one connection (tasks, subscriptions, …); agents reach any server capability via CLI when the host lacks native MCP support for that feature |
| Output | JSON to stdout | JSON by default; human-readable mode where useful |
| Implementation | Commander wrapper over InspectorClient |
Same package; clients/cli/src/daemon/ for session daemon + IPC (§7.2); subcommands, v1 compat layer |
3. What we have today (CLI v1)
§1.1 covers the user-facing behavior; this section is the implementation reference.
3.1 Code location and shape
| Piece | Location |
|---|---|
| Entry / argument parsing | clients/cli/src/cli.ts |
| Launcher forwarding | clients/launcher/src/index.ts (--cli → CLI workspace) |
| MCP client | @modelcontextprotocol/inspector-core → InspectorClient |
| Transport + config resolution | core/mcp/node/config.ts (resolveServerConfigs), createTransportNode |
| Tests | clients/cli/__tests__/ (Vitest, stdio + HTTP against test servers) |
Each invocation:
- Parses which server to use (shared flags:
--config,--server, positional command/URL,--transport, headers, env—see mcp-server-configuration.md). - Requires
--methodnaming an MCP-style operation. - Constructs
InspectorClient,connect(), performs exactly one operation, printsJSON.stringify(result),disconnect(), exits.
There is no persistent session, no subcommands beyond “pick method + args”, and no interactive shell.
3.2 Supported operations (v1)
--method must be one of (see error text in cli.ts):
--method |
Purpose | Extra flags |
|---|---|---|
tools/list |
List tools | --metadata |
tools/call |
Call a tool by name | --tool-name, --tool-arg, --tool-metadata, --metadata |
resources/list |
List resources | --metadata |
resources/read |
Read a resource | --uri, --metadata |
resources/templates/list |
List resource templates | --metadata |
prompts/list |
List prompts | --metadata |
prompts/get |
Get a prompt | --prompt-name, --prompt-args, --metadata |
logging/setLevel |
Set server log level | --log-level |
Anything else throws Unsupported method.
Internally, list operations use core state managers (ManagedToolsState, etc.) for a single refresh; tools/call resolves the tool by name from that list, then calls InspectorClient.callTool(tool, …)—the same pattern TUI uses when invoking a tool from the managed list.
3.3 What v1 does not cover (but core already does)
InspectorClient and the TUI/web clients already support (or are adding) capabilities not exposed on the CLI today, for example:
- Tasks (list/get/cancel, task-augmented tool calls, streaming progress)
- Sampling / elicitation (client-as-requestor flows)
- Resource subscriptions and list-changed notifications
- Roots (
getRoots,setRootson the client; answers serverroots/listrequests) - Completions (prompt/resource argument completion)
- OAuth flows and token management as first-class UX
- Pagination (
listTools/listResourceswith cursors) - Structured tool results, metadata on prompts/resources beyond what v1 passes through
CLI v1 is intentionally minimal. The gap is CLI surface area and session ergonomics (§1.3), not missing protocol support in core.
4. Goals and principles
- One CLI product — Evolve v1 inside
clients/cli(same npm package and launcher entry). - Core-first — All MCP I/O through
InspectorClientand the same state managers TUI/web use (ManagedToolsState,MessageLogState, etc.). CLI v2 composes existing APIs (list → resolve entity → call/read/get); it does not depend on new core helpers. Do not bypass core with a raw SDKClientin the CLI layer. - Two lifecycles, one implementation
- Ephemeral: connect → one operation (or fixed sequence) → disconnect — backward compatible with today’s
inspector --cli … --method …. - Session: named session, many commands; implicit session daemon (§5.3) holds the connection—no user-managed start step.
- Ephemeral: connect → one operation (or fixed sequence) → disconnect — backward compatible with today’s
- Parity trajectory — CLI v2 should be able to expose the same MCP client capabilities as TUI/web over time (phased commands, not a big-bang).
- Shared configuration and auth — Same
mcp.json/ CLI flags as today (mcp-server-configuration.md); sameOAuthManagerand Node credential storage as other Node clients (environment-isolation.md). - Automation-safe — JSON output, stable exit codes; in scripts and CI, require an explicit
@session(or--session @name)—do not rely on default-session resolution unless opted in via env (§5.6). - No interactive shell — Each command is a separate
mcp …invocation (session commands talk to the implicit daemon over IPC). No REPL, noshellsubcommand—now or later. Interactive exploration remains the job of TUI / web; automation and agents use subprocess + JSON.
5. Target architecture
V2 examples in this section use mcp (§5.2). inspector --cli and mcp-inspector --cli remain supported for backward compatibility (§6).
5.1 High-level picture
┌─────────────────────────────────────┐
│ mcp (primary CLI command, §5.2) │
│ inspector --cli (launcher, compat)│
└─────────────────┬───────────────────┘
│
┌─────────────────▼──────────-─────────┐
│ CLI v2 (Commander / subcommands) │
│ • session admin (connect, list, …) │
│ • MCP commands (tools, resources, …)│
│ • compat layer (--method …) │
└─────────┬───────────────┬──────-─────┘
│ │
ephemeral │ │ session mode
(in-process) │ │
▼ ▼
┌───────────---───┐ ┌───────────────-───┐
│ InspectorClient │ │ Session daemon │
│ connect → op │ │ (one Client each) │
│ → disconnect │ │ ◄── IPC ──► CLI │
└───────────---───┘ └─────────┬─────────┘
│ │
└────-──-───┬─────────┘
▼
@modelcontextprotocol/inspector-core
(transport, OAuth, state managers)
5.2 The mcp command
Today the CLI is reached through the launcher: inspector --cli … (installed binary mcp-inspector, plus mcp-inspector-cli from the CLI workspace). CLI v2 adds mcp as the primary command—it runs the same CLI entrypoint the launcher forwards to, without the --cli flag.
| Command | What runs |
|---|---|
mcp … |
clients/cli directly—primary v2 UX |
inspector --cli … |
Launcher → clients/cli (unchanged) |
mcp-inspector --cli … |
Same as above (unchanged) |
Implementation — no change to how we publish @modelcontextprotocol/inspector. Add a bin entry on the root package (and matching entry on @modelcontextprotocol/inspector-cli) pointing at clients/cli/build/index.js, alongside existing bins. Update Commander’s program name to mcp for help text.
5.3 Session daemon (implicit)
Session mode uses a session daemon—a long-lived Node process that owns live MCP connections. Users do not start or manage it in normal use. The first session-mode need (typically connect, or a command against an existing session) auto-spawns the daemon in the background if it is not already running; later mcp invocations attach over IPC (Unix domain socket or platform equivalent).
Daemon responsibilities
- Own one
InspectorClientper named session - Accept IPC from short-lived CLI front-end processes
- Forward list/call/read/… to the right client and return JSON (or structured errors)
- Handle notifications (logging, list-changed) and optionally broadcast them to attached clients
Lifecycle
mcp connectmay bootstrap daemon + session in one step—no prior daemon required.- Single instance per user/machine (socket + lock file); stale socket after crash is detected and recovered on next command.
- Shutdown: daemon exits when all sessions are **
disconnect**ed and an idle timeout elapses (duration TBD), or when the last open session closes—whichever policy we implement. - Ephemeral mode (v1
--methodone-shots) never uses the daemon;InspectorClientruns in-process and exits.
When users need visibility (optional, not required for everyday use)
mcp daemon status— is the daemon running, active sessions, socket pathmcp daemon stop— tear down daemon and all sessions (troubleshooting)mcp daemon run(optional) — run daemon in foreground for debugging
The daemon uses InspectorClient with the same OAuth and transport setup as TUI. Secrets are not passed on argv when spawning sessions over IPC (see §5.7).
5.4 Command surface (planned categories)
Exact names are TBD; illustrative grouping:
| Category | Examples | Core backing |
|---|---|---|
| Session | connect, disconnect, sessions list, session use; optional daemon status / daemon stop |
Implicit daemon (§5.3) + session store |
| Tools | tools list, tools call, tools call --task |
ManagedToolsState, callTool, callToolStream |
| Resources | resources list, resources read, resources templates list, resources subscribe |
listResources, readResource, subscriptions |
| Prompts | prompts list, prompts get, prompts complete |
listPrompts, getPrompt, getCompletions |
| Logging | logging set-level, logging tail (follow notifications) |
setLoggingLevel, MessageLogState |
| Tasks | tasks list, tasks get, tasks cancel, tasks result |
ManagedRequestorTasksState, callToolStream, … |
| Auth | auth login, auth logout, auth status |
OAuthManager (via connect), Node storage |
| Roots | roots list, roots set |
getRoots, setRoots |
| Compat | Hidden or documented: --method tools/list … |
Maps to same handlers as subcommands |
Global flags (all modes): --json, --config, --server, verbosity, --session @name (or positional @name).
5.5 Config and server selection
Unchanged from v1: resolution via resolveServerConfigs and shared flags documented in mcp-server-configuration.md.
Session records store at minimum:
- Session name (user-chosen,
@-prefixed in UX) - Server identity (config path + server id, or normalized ad-hoc target)
- Connection state (in daemon)
- Last accessed timestamp — updated whenever the user (or agent) runs a command against that session; drives default session for
@-less commands (§5.6)
5.6 Default session (@-less commands)
When a session-mode command omits @name (e.g. mcp tools list instead of mcp @myserver tools list), the CLI targets the most recently accessed session—the session last used by any session-scoped command, including connect, an explicit @name …, or sessions use @name.
- Update last-accessed on every command that successfully targets a named session (including
connect, which creates or reopens that session). - No sessions → clear error telling the user to
connectfirst. - Automation / CI → default session is disabled unless explicitly opted in (non-TTY, or
MCP_SESSION=@nameset, or--session @namepassed). Pipelines must not accidentally hit the wrong server because an interactive user connected to something else earlier on the same machine. - Explicit
@namealways wins when provided; default session is a convenience for interactive use and agent sessions where the model has been working in one context.
mcp connect --config mcp.json --server a @alpha
mcp connect --config mcp.json --server b @beta
mcp @alpha tools list # last accessed → @alpha
mcp tools list # same (still @alpha)
mcp @beta resources list # last accessed → @beta
mcp tools call search q=hello # uses @beta
5.7 OAuth and secrets
CLI v2 must use the same paths as other Node clients:
OAuthManagerinsideInspectorClient.connect()— no CLI-only OAuth stack- Node
OAuthStoragein core (same store as TUI; see environment-isolation.md)
Daemon startup must not put secrets on argv (stdio env/args, HTTP headers): pass full server config over IPC after the socket is listening, before connect().
6. Backward compatibility (CLI v1)
6.1 Requirement
Existing scripts and docs that use:
inspector --cli … --method tools/list
must keep working through a compatibility entrypoint (same flags, same JSON shape on stdout, same exit behavior on error). mcp … --method … is equivalent (§5.2).
6.2 Implementation approach
- Ephemeral handler shared with v2 subcommands: parse v1 argv → build
MCPServerConfig→InspectorClient→ dispatch by--method→ print JSON. - v1
--methodtable (§3.2) remains supported; new methods may be added under--methodor only under subcommands (document per method). - Deprecation: if we later prefer subcommands in docs, v1 flags stay until a major Inspector release with a published migration guide.
6.3 Mapping (v1 → v2 ergonomics)
| CLI v1 | CLI v2 (illustrative) |
|---|---|
inspector --cli … --method tools/list |
mcp tools list (ephemeral) or mcp @s tools list (session) |
inspector --cli … --method tools/call --tool-name X --tool-arg k=v |
mcp tools call X k=v |
… --config mcp.json --server myserver --method resources/list |
mcp connect myserver then mcp @myserver resources list |
Session mode is opt-in; v1 one-liners remain valid without connect.
7. Building on core (same stack as TUI / web)
CLI v2 does not require new MCP capabilities in @modelcontextprotocol/inspector-core. Web and TUI already cover the full client feature set through InspectorClient and optional state managers (protocol-and-state-managers-architecture.md). CLI v2 adds subcommands, session lifecycle, output formatting, and optionally a session daemon—composition work in clients/cli, not protocol gaps in core.
7.1 Patterns to reuse (not reimplement)
| CLI need | How v1 / TUI / web do it today |
|---|---|
| Call tool by name | ManagedToolsState (or listTools) → find by name → callTool(tool, args, …). v1 already does this in clients/cli/src/cli.ts; TUI passes the selected Tool from the managed list. Scripts pass a name; the CLI resolves it from the cached list—the same pattern as picking a tool in the UI. |
| List tools / resources / prompts | Managed*State for full lists (auto-refresh on *ListChanged), or Paged*State / cursor loops on listTools(cursor) etc. v1 uses managed states for a one-shot refresh per invocation. |
| Logging tail | MessageLogState subscribes to protocol message events (includes server logging via notifications/message). Stream or filter entries for logging tail. |
| Tasks | ManagedRequestorTasksState / PagedRequestorTasksState; streaming tool calls via callToolStream. |
| Roots | getRoots() / setRoots() on InspectorClient. |
| Subscriptions, completions, OAuth | Direct InspectorClient methods and events; Node credential storage per environment-isolation.md—same as TUI. |
7.2 Where CLI v2 work actually lives
All implementation belongs in clients/cli—one npm package (@modelcontextprotocol/inspector-cli), same publish story as today. No separate cli-daemon workspace.
Layout
| Area | Location |
|---|---|
| CLI front-end (Commander, subcommands, v1 compat) | clients/cli/src/ (existing + new command modules) |
| Session daemon (IPC server, session registry, auto-spawn) | clients/cli/src/daemon/ |
| Shared command handlers | Callable from both ephemeral CLI and daemon IPC paths |
The daemon subdirectory owns long-lived process management; the CLI front-end stays short-lived subprocess invocations talking to it over IPC (§5.3). mcp and the daemon share types and handlers in-process within the same package—no cross-workspace imports.
Responsibilities
- Subcommand tree and argv parsing (Commander)
- Ephemeral vs session-daemon process model and IPC
- JSON / human-readable output and exit codes
- v1
--methodcompatibility routing to shared handlers - Per-session wiring of
InspectorClient,createTransportNode,resolveServerConfigs, and the state managers above
If a workflow feels awkward, check how TUI/web solve it with existing core APIs before proposing core changes.
8. Phased delivery
Note: This work should be done on the v2 branch after the v1.5 CLI has been ported to the v2 branch and verified.
Suggested phases (adjust in planning):
| Phase | Deliverable |
|---|---|
| 0 — Design | This doc; command naming RFC; daemon IPC sketch |
| 1 — Compat + structure | Commander subcommand tree; v1 --method routed through shared handlers; mcp bin (§5.2); tests ported/extended |
| 2 — Session daemon | Implicit auto-spawn; connect / disconnect / sessions list; IPC; @session on subcommands |
| 3 — Breadth | Tools/resources/prompts/logging subcommands via managed/paged state managers; pagination, structured content |
| 4 — Advanced | Tasks, subscriptions, roots, completions, OAuth UX—same InspectorClient + managers as TUI |
| 5 — Polish | Docs, launcher help text, ergonomics polish |
Each phase should ship test coverage (Vitest + test-servers harness, same as v1).
9. Testing and documentation
- Unit / integration: Extend
clients/cli/__tests__/; use@modelcontextprotocol/inspector-test-servercomposable fixtures where possible. - Session daemon: Separate test suite with mock IPC or in-process daemon for CI.
- Docs: Update clients/cli/README.md with v2 command reference; keep a “Legacy
--methodinterface” section until removal. - Cross-links: mcp-server-configuration.md unchanged except examples showing session commands.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.