Follow Discord
Sweep 09 Oct 2026 · 17:27Z Build v2.1.296 517 read Stable v2.1.287 Latest v2.1.296 Next v2.1.296 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · mcp

CLI client changeddocs/2026-07-28/tools/inspector/cli

Nearest release: v2.1.295, published 5 hours after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 8 Oct 2026 12:58 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 8 Oct 2026 13:07 UTC.

Upstream edited
Recorded here
Lines+66added
Lines−14removed
From line 8 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits3to this page, all time

### CI gates ### Editing the catalog

The whole hunk

from line 8, old and new numbered
/
lines
from line 8
88npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/list
99```
1010 
11<Tip>
12 Running several commands against the same server, or a flow that spans one
13 session (tasks, subscriptions, elicitation)? The [mcpdo connection
14 client](/docs/2026-07-28/tools/inspector/mcpdo) connects once and keeps the
15 connection open between commands.
16</Tip>
17 
1118The examples below use the installed `mcp-inspector` binary. Without a global install, prefix each command with `npx @modelcontextprotocol/inspector` instead, as above.
1219 
1320## Choosing a server
from line 38
3138 
3239<Note>
3340 **The config file is the only durable way to give a run its
34 [roots](/specification/draft/client/roots):** there is no roots flag, and
35 `--method roots/set` applies only to that one short-lived connection. Roots
36 configured for a server are advertised at connect, so a server that calls
37 `roots/list` (as `@modelcontextprotocol/server-filesystem` does, to learn its
38 allowed directories) gets them.
41 [roots](/specification/draft/client/roots):** there is no roots flag, and the
42 CLI has no `roots/set` method. Roots configured for a server are advertised at
43 connect, so a server that calls `roots/list` (as
44 `@modelcontextprotocol/server-filesystem` does, to learn its allowed
45 directories) gets them.
3946</Note>
4047 
4148See [Configuration and flags](/docs/2026-07-28/tools/inspector/configuration) for `--catalog` vs. `--config`, the `--` separator, and the shared server-selection flags.
from line 52
4552| `--method` | Required companions | Notes |
4653| - | - | - |
4754| `initialize` | None | Connect-only probe: `{serverInfo, protocolVersion, capabilities, instructions}`. |
48| `tools/list` | None | |
49| `tools/call` | `--tool-name`, plus `--tool-arg` / `--tool-args-json` | |
55| `tools/list` | None | `--strict` turns its schema portability check into a gate (see [CI gates](#ci-gates)). |
56| `tools/call` | `--tool-name`, plus optional `--tool-arg` / `--tool-args-json` | |
5057| `resources/list` | None | |
5158| `resources/read` | `--uri` | |
5259| `resources/templates/list` | None | |
60| `resources/directory/read` | `--uri`, plus optional `--cursor` | One page at a time; pass back the previous page's `nextCursor`. |
5361| `prompts/list` | None | |
54| `prompts/get` | `--prompt-name`, `--prompt-args` | |
62| `prompts/get` | `--prompt-name`, plus optional `--prompt-args` | |
5563| `logging/setLevel` | `--log-level` | Legacy era only; modern servers opt in per request instead. |
56| `servers/list`, `servers/show` | None | Read the catalog **without connecting** to anything. |
64| `skills/list` | None | `--verify` checks the skills returned (see [CI gates](#ci-gates)). |
65| `skills/get` | `--uri` | Same `--verify` option. |
66| `servers/list` | None | Read the catalog **without connecting** to anything. |
67| `servers/show` | `--server` | Same, for one entry. |
68| `servers/add` | `--server`, plus a positional target or `--server-url` | Write the catalog without connecting (see [Editing the catalog](#editing-the-catalog)). |
69| `servers/edit` | `--server`, plus what to change | Same. |
70| `servers/remove` | `--server` | Same. |
5771 
5872Stream- or session-only methods (`logging/tail`, for example) are rejected, since a process that exits can't hold a stream open.
5973 
6074### Passing arguments
6175 
62`--tool-arg` takes `key=value` and **coerces** values by JSON-parsing them, so `count=1` becomes a number and `"012"` becomes `12`:
76`--tool-arg` takes `key=value` and **coerces** each value by JSON-parsing it when it parses, so `count=1` and `zip=10001` both send numbers. A value that is not valid JSON (`zip=012`, a bare word) is sent as a string, and a string is then converted to the type the tool's input schema declares for that property, so `zip=012` against a numeric `zip` still sends `12`:
6377 
6478```bash theme={null}
6579mcp-inspector --cli <server> --method tools/call --tool-name mytool \
from line 80
6680 --tool-arg key=value --tool-arg count=1 --tool-arg 'options={"format":"json"}'
6781```
6882 
69`--tool-args-json` takes the whole argument object at once and passes it **verbatim**, with no coercion, so `"012"` stays the string `012`. The two are mutually exclusive:
83`--tool-args-json` takes the whole argument object at once and skips the `key=value` parsing, so `{"zip":"10001"}` sends the string `"10001"` rather than a number. The schema conversion still applies to string values, so this only keeps a string a string when the schema types that property as a string (or doesn't declare it). The two flags are mutually exclusive:
7084 
7185```bash theme={null}
7286mcp-inspector --cli <server> --method tools/call --tool-name mytool \
from line 110
96110 
97111Exit codes distinguish the outcomes: a tool with an app exits `0`, one with no app exits `2`, and a missing tool exits `5`, so a typo isn't mistaken for "no app". A probe failure (unreadable UI resource, malformed `resourceUri`) is reported in a `resourceError` field rather than aborting, so one bad tool never kills a whole listing.
98112 
113The CLI can't render an App, so by default it doesn't advertise the MCP Apps extension at `initialize`. A server that exposes its App tools only to clients claiming App support will then look app-less (exit `2`). Add `--advertise-apps` to claim the extension for that run.
114 
99115<Note>
100116 `tools/list --app-info` always emits NDJSON (one line per tool) regardless of
101117 `--format`; `--format json` reshapes only the single-tool output of
from line 125
109125| Code | Meaning |
110126| - | - |
111127| `0` | Success. |
112| `1` | Usage or unexpected error (the catch-all). |
128| `1` | Usage or unexpected error (the catch-all), including an unreadable secret store or OAuth state file. |
113129| `2` | No MCP App found on the tool (`--app-info` probe). |
114| `3` | Server requires authentication (401/403, `WWW-Authenticate`, OAuth). |
130| `3` | Server requires authentication (HTTP 401/403, or an SDK authorization error). |
115131| `4` | Server unreachable (DNS, connection refused, timeout, `fetch failed`). |
116132| `5` | Tool error: `tools/call` returned `isError: true`, or the tool wasn't found. |
133| `6` | `--strict` found an error-severity tool-schema portability problem. |
134| `7` | `--verify` found a skill that violates SEP-2640 (conformance, digest, or size mismatch). |
135| `8` | `--verify` couldn't check every skill within its read bounds. |
136| `9` | `--verify --require-digests` found a skill that advertises no digests. |
117137 
118138On any non-zero exit the CLI also writes a **single JSON line to stderr**:
119139 
from line 148
128148}
129149```
130150 
151The envelope carries `code` and `message` always, plus `cause` (the underlying error, such as a DNS failure), `status` (the HTTP status) and `url` when known. Query-string secrets in a URL are redacted. `code` is a stable name for the failure: `auth_required`, `unreachable`, `tool_not_found`, `tool_is_error`, `no_app`, `schema_unportable`, `store_unavailable`, `oauth_state_unrecognized`, or the catch-all `error`, among others.
152 
131153Because it's one line, a caller can parse it with `2>&1 | tail -1 | jq .error`.
132154 
133155A `tools/call` that returns `isError: true` still prints its payload, but exits `5`, so an `&&` chain doesn't proceed on a failed call.
from line 159
137159By default the CLI runs the same loopback OAuth flow as the TUI: it opens a browser and waits on a localhost callback that a CI job can't complete. Two flags make non-interactive runs predictable:
138160 
139161* `--stored-auth-only`: never start interactive OAuth or step-up, and never auto-open a browser. Use tokens from the shared store if present, otherwise fail immediately with `auth_required`. This is the flag CI wants.
140* `--use-stored-auth`: reuse a token that the web Inspector already obtained on this machine, refreshing it first when a refresh token is stored.
162* `--use-stored-auth`: reuse a token that the web Inspector already obtained on this machine, refreshing it first when a refresh token is stored. It looks the token up by URL, so it requires `--server-url`.
141163 
142164Without either, and with no TTY on stdin or stderr, the CLI fails fast with `auth_required` rather than hanging for fifteen minutes on a callback nobody will complete.
143165 
from line 178
156178 | jq -e '.result.tools | map(.name) | index("get_weather")' > /dev/null
157179```
158180 
181### CI gates
182 
183Three flags turn a check into a non-zero exit, each with its own code so a job can tell the failures apart:
184 
185* `--strict` (with `tools/list`): reports tool-schema portability problems in full on stderr (path, issue, suggested fix) and exits `6` if any is error-severity. Without it, `tools/list` prints only a one-line count. Under `--format json` the findings are folded into the output as `schemaFindings`.
186* `--verify` (with `skills/list` or `skills/get`): runs the SEP-2640 conformance and digest checks, writes one JSON report per skill on stdout, and exits `7` on a violation or `8` when the read bounds stopped it before every skill was checked. `--skill-catalog-max-skills` and `--skill-catalog-max-bytes` set those bounds.
187* `--require-digests` (with `--verify`): exits `9` for a skill that advertises no digests, instead of reporting it as unverifiable and exiting `0`.
188 
189```bash theme={null}
190mcp-inspector --cli <server> --method tools/list --strict > /dev/null
191mcp-inspector --cli <server> --method skills/list --verify --require-digests
192```
193 
159194### Branch on the failure class
160195 
161196```bash theme={null}
from line 225
190225 server `url` (userinfo or query tokens) or in stdio `args`. Treat raw URL and
191226 `detail` fields as sensitive before pasting them into an issue.
192227</Warning>
228 
229### Editing the catalog
230 
231`servers/add`, `servers/edit`, and `servers/remove` write the catalog without connecting to anything. They go through the same code as the web client's server list, so `env` values and client secrets land in the [secret store](/docs/2026-07-28/tools/inspector/configuration#where-secrets-are-stored) exactly as they would from the UI, and a running web client picks up the change.
232 
233```bash theme={null}
234# Add: the positional target or --server-url describes the entry, not a server to connect to
235mcp-inspector --cli node build/index.js -e API_KEY=secret --method servers/add --server my-server
236 
237# Edit: change the target, -e, --cwd, --header, or --protocol-era, or rename it
238mcp-inspector --cli --method servers/edit --server my-server --rename my-renamed-server
239 
240# Remove the entry and its stored secrets
241mcp-inspector --cli --method servers/remove --server my-renamed-server
242```
243 
244Only the writable catalog (`--catalog`, `MCP_CATALOG_PATH`, or the default) can be written; `--config` is refused. With an in-memory secret store, a write that supplies `-e` values (and a `--rename`) is refused, since the secrets would be lost when the run exits.
193245 
194246## Proxies
195247 
Feedback