▸ Agent Skills
8 min read

Documentation Index

Fetch the complete documentation index at: https://modelcontextprotocol.io/llms.txt Use this file to discover all available pages before exploring further.

mcpdo connection client

Connect to an MCP server once, then run many commands against that named connection

mcpdo is an experimental command-line client that ships in the @modelcontextprotocol/inspector package alongside mcp-inspector. Where the CLI client connects, runs one --method and disconnects, mcpdo connects once and keeps the connection open, so you can run many commands against it from any shell, the way ssh-agent keeps keys loaded.

mcp-inspector --climcpdo
LifecycleConnect, one --method, disconnectConnect once, many commands
StateNone between runsNamed connections held by a daemon
Best forCI assertions, one JSON blob per runExploring a server, agent tool use, multi-step flows over one session (tasks, subscriptions, elicitation)

Connections are held by a local background daemon, mcpdod, which mcpdo starts on demand and stops after its last connection closes. You never start it by hand. What it exposes, and how it is protected, is described under The mcpdo connection daemon.

Watch the mcpdo tutorial video.

Install

mcpdo is a second bin in the same package, so install the package globally, or run it through npx -p:

npm install -g @modelcontextprotocol/inspector
mcpdo --help

# or without installing
npx -p @modelcontextprotocol/inspector mcpdo --help

Quickstart

mcpdo servers/list                            # catalog entries you can connect
mcpdo connect my-server                       # connect a catalog entry
mcpdo @my-server tools/list
mcpdo @my-server tools/call echo message:=hi
mcpdo @my-server resources/read file:///tmp/notes.txt
mcpdo connections/list                        # what's open
mcpdo disconnect my-server

mcpdo help, or mcpdo \<command\> --help, prints the full, authoritative list of commands and flags.

Choosing what to connect

connect takes a catalog entry name or an ad-hoc target:

mcpdo connect my-server                        # from the default catalog
mcpdo connect my-server --config ./mcp.json    # from a read-only config file
mcpdo connect https://example.com/mcp          # ad-hoc HTTP/SSE server
mcpdo connect node build/index.js              # ad-hoc stdio server

The catalog and --config behave exactly as for the other clients (see Configuration and flags): the default catalog is ~/.mcp-inspector/mcp.json, overridable with --catalog or MCP_CATALOG_PATH. servers/list and servers/show \<name\> read entries from disk. connections/* shows what the daemon currently holds. There are no commands to edit the catalog; edit the file directly.

A stdio server runs with the working directory and command resolution of the shell that ran connect, not of the daemon, so relative paths and bare command names mean what you would expect.

Addressing a connection

A catalog connection is named after its entry. An ad-hoc one is named after its first token (node, docker, or the URL itself) unless you name it at connect time with @name:

mcpdo connect @api https://example.com/mcp

Name the connection on each command with @name, or with --connection \<name\> (shorthand --conn). A connection named after a URL can only be addressed with --conn \<url\>, since @name takes only letters, digits, _, . and -:

mcpdo @my-server tools/list
mcpdo --conn my-server tools/list

Omitting the name falls back to the most recently used connection, but only on an interactive TTY. From a script or an agent, where stdin is not a TTY, an unqualified command is an error, so that a background job never acts on whichever server you last used. Set MCP_ALLOW_DEFAULT_CONNECTION=1 to allow the fallback anyway.

Connections self-heal: a dropped transport (an expired HTTP session, an exited stdio child) is re-dialed transparently on next use with the stored credentials. Only an auth_required error needs you to run connect again.

A connection runs one call at a time. Commands against it from other shells queue behind the call in flight, and while a call is parked on an elicitation, new calls on that connection are refused until it is answered. A long call does not block other connections.

Tasks

A tool that requires task support is refused by a plain tools/call; add --task to make a task-augmented call. It still blocks until the task finishes, then prints the final result:

mcpdo @my-server tools/call --task start_job size:=large

If the task reaches input_required, its question is handled like any other elicitation.

Output

FlagOutput
--format text (default)Human-readable, with ANSI styling on a TTY unless --plain or NO_COLOR is set.
--format jsonThe pretty-printed payload, with no { result } envelope. For scripts and agents.

The global flags are --format, --plain, --connection / --conn, --catalog / --config, and --stored-auth-only. They may go before or after the subcommand, but before any --. The @name shorthand must come before the subcommand.

Terminal-bound text (results, elicitation prompts, daemon errors) has control characters stripped, so a server cannot rewrite your terminal. --format json stays verbatim.

Authorization

mcpdo shares oauth.json and the secret store with the other Inspector clients, so a server you have already authorized elsewhere connects without a prompt. OAuth runs at connect time. Mid-session step-up is handled by the one-shot CLI, not by mcpdo.

CommandEffect
mcpdo connect \<name\> --relogin (-r)Clear this server’s stored tokens before connecting (HTTP/SSE only), so it signs in fresh if the server requires auth.
mcpdo disconnect \<name\> --clear-auth (-c)Close the connection and clear its stored tokens, so the next connect signs in fresh.
mcpdo auth/listStored credentials, each annotated with the catalog or connection names it is “known as”, and ● live when an open connection holds it.
mcpdo auth/clear <url-or-name>Clear one stored credential, by store URL or friendly name. --all --yes clears every one.
mcpdo auth/ema-login / auth/ema-status / auth/ema-logoutEnterprise-managed authorization: sign in to the IdP once, then connect to EMA servers silently.

When a browser sign-in is needed and neither stdin nor stderr is a TTY (and MCP_AUTO_OPEN_ENABLED is not forced on), connect exits 0 immediately with pendingAuth: true and an authUrl. Relay that URL to whoever will sign in. The connection completes on its own once they do: the next real command against it finishes the connection, and connections/list reports pendingAuthSignedIn in the meantime. Don’t reconnect to fix a pending sign-in.

On a host with no OS keychain, mcpdo stores tokens in the shared secrets.json file, never in memory, because its commands and the daemon are separate processes. That file is plaintext unless you supply a key; see Where secrets are stored.

Elicitation

When a server asks a question mid-call (a legacy elicitation/create, a modern MRTR round, or a task that reaches input_required):

  • On an interactive TTY, mcpdo prompts inline. Form mode renders one prompt per field with a review step. URL mode prints the URL and waits for you to confirm you finished.
  • From a script or agent (--format json, or no TTY), the command returns elicitationPending with an elicitationId, and the call stays parked on the daemon. Answer it from any shell:
mcpdo elicitation/respond <elicitationId> approved:=true   # form fields as key:=value or JSON
mcpdo elicitation/respond <elicitationId> --done           # URL mode: I finished
mcpdo elicitation/respond <elicitationId> --decline        # form mode only
mcpdo elicitation/respond <elicitationId> --cancel         # either mode

A parked elicitation is cancelled after 10 minutes, and a connection holds one at a time; until it is answered, other calls on that connection are refused. URL mode is never auto-accepted. To keep a server from asking at all, connect with --elicit off. --elicit url, form or both (the default) choose which modes are advertised.

Protocol eras

mcpdo negotiates the same protocol eras as the other clients. connect --era legacy|auto|modern overrides a catalog entry’s protocolEra, and is the only way to set it for an ad-hoc target. connections/list tags each connection [legacy] or [modern], and connections/show \<name\> gives the negotiated version, server info, capabilities, and the supported-versions list when the server was probed.

The daemon

CommandEffect
mcpdo daemon statusWhether a daemon is running, and its connections and idle countdown.
mcpdo daemon stopClose every connection and stop the daemon.
eval "$(mcpdo private)"Give this shell its own daemon and connections.

By default every shell you run mcpdo from shares one daemon, so a connection opened in one terminal is usable in another. mcpdo private exports MCP_INSPECTOR_DAEMON_DIR and MCP_INSPECTOR_DAEMON_TOKEN so the current shell gets a separate daemon. That keeps connections apart; it is not a security boundary against other processes running as you.

The daemon exits about a minute after its last connection closes. A daemon started before an upgrade keeps running the old code until then, so run mcpdo daemon stop after upgrading the package.

Isolating untrusted stdio servers

The daemon’s token controls who can command the daemon, not what a server can do. A stdio server runs with your full user privileges. To contain one you don’t fully trust, make the stdio command a container:

mcpdo connect @sandboxed -- docker run -i --rm --network none -v "$PWD:/work:ro" <server-image>

Without @sandboxed, the connection would be named docker.

Adjust the network and mount flags to what the server needs. HTTP and SSE servers run no local code, so they need no process isolation.

Environment variables

mcpdo reads the same catalog, storage and secret-store variables as the other clients (see Environment variables), plus these:

VariableEffect
MCP_INSPECTOR_DAEMON_DIRDirectory holding the daemon’s socket, lock, token and log. Defaults to MCP_STORAGE_DIR when set, else ~/.mcp-inspector. Set by mcpdo private.
MCP_INSPECTOR_DAEMON_TOKENIPC token to present to, or start, the daemon. Unset, the mcpdo command that starts the daemon generates one, and the daemon publishes it to mcpdod.token. Set by mcpdo private.
MCP_ALLOW_DEFAULT_CONNECTION1 lets a command without @name / --connection use the most recently used connection even when stdin is not a TTY.

Using mcpdo from a coding agent

The package ships an agent skill that teaches an agent to drive mcpdo: connections it holds then extend the agent’s toolset, and it knows to relay sign-in URLs and answer parked elicitations. mcpdo agent-help prints the guide, mcpdo agent-help --skill-path prints the path of the installable skill file, and mcpdo agent-help --instructions prints a block to append to a project’s CLAUDE.md or AGENTS.md.


Last updated Oct 11, 2026