npx MCP Inspector: Run It, Connect It, Read the Errors
The exact npx commands for the MCP Inspector v2: web UI, CLI and TUI, stdio and Streamable HTTP, headers and OAuth, the exit codes, and the v1 habits that now fail silently.
The MCP Inspector is the official developer tool for poking at an MCP server: connect, list its tools, call one with arguments, read resources and prompts, run an OAuth flow. You start it with one command:
npx @modelcontextprotocol/inspector
That opens the web UI. Everything below is checked against the Inspector's own README and docs as of version 2.9.0, the latest tag on npm on 3 October 2026 [1]. Version 2 is a rewrite, and most of the advice you will find for this command was written for version 1, so the places where the two differ are called out as you go.
TL;DR:
- Check
node -vfirst. v2 needs Node 22.19.0 or newer. npm only warns on an older Node, and the Inspector then fails later and obscurely [2]. - One package, three modes: the web UI by default,
--clifor scripts and CI,--tuifor a terminal UI. The mode flag must come first [2]. - There is no proxy on port 6277 any more. v2 runs one web server on
6274, and the auth token variable is nowMCP_INSPECTOR_API_TOKEN[2]. - A URL that does not end in
/mcpor/sseneeds--transport. v1 guessed SSE; v2 stops with an error [2]. - It proves your server answers your machine, not the internet. For that half, see the last section.
The three modes
npx @modelcontextprotocol/inspector # web UI (default)
npx @modelcontextprotocol/inspector --cli # CLI
npx @modelcontextprotocol/inspector --tui # TUI
All three ship in the one package, @modelcontextprotocol/inspector. v1 published three sub-packages beside it (-client, -server, -cli); those are frozen at 1.0.1, deprecated, and will not see a 2.x [2]. If a tutorial tells you to install @modelcontextprotocol/inspector-cli, it is describing v1.
The web UI is served on port 6274. Each launch generates a random API token and prints it in the launch banner; set MCP_INSPECTOR_API_TOKEN if you want a fixed one [3]. The old name, MCP_PROXY_AUTH_TOKEN, still works as a deprecated fallback [2].
Connecting to a stdio server
Put the command that starts your server after the Inspector:
npx @modelcontextprotocol/inspector node build/index.js
Environment variables go in with -e, and arguments meant for your server go after --:
npx @modelcontextprotocol/inspector -e API_KEY=value -- node build/index.js --server-flag
Under --cli that separator works the other way round: everything before -- is the target and everything after it is the Inspector's own options [2]:
npx @modelcontextprotocol/inspector --cli node build/index.js -- --method tools/list
Connecting to a remote server over Streamable HTTP
npx @modelcontextprotocol/inspector --cli https://your-server.example.com/mcp --method tools/list
v2 infers the transport from the end of the URL path, and only from that [2]:
| URL path ends in | Transport used |
|---|---|
/mcp |
Streamable HTTP |
/sse |
SSE |
anything else, including /mcp/ with a trailing slash |
error: Transport type not specified and could not be determined from URL |
So a server at https://example.com/api needs the flag spelled out:
npx @modelcontextprotocol/inspector --cli https://example.com/api --transport http --method tools/list
To open the same server in the web UI instead, pass it with --server-url [4]:
npx @modelcontextprotocol/inspector --web --server-url https://example.com/api --transport http
Sending an API key or a bearer token
Use --header, once per header [5]:
npx @modelcontextprotocol/inspector --cli https://your-server.example.com/mcp \
--method tools/list --header "Authorization: Bearer your-token"
If the server uses OAuth instead, the Inspector runs the flow itself. In the CLI, a 401 starts a callback listener on http://127.0.0.1:6276/oauth/callback, prints the authorization URL, and opens your browser when it is running in a terminal; the web UI uses http://localhost:6274/oauth/callback [5]. That loopback address is the one to register if your authorization server wants redirect URIs listed in advance. For CI, --stored-auth-only never opens a browser and fails at once instead of waiting on a callback nobody will click [5].
Calling a tool from the CLI
npx @modelcontextprotocol/inspector --cli node build/index.js \
--method tools/call --tool-name get_weather --tool-arg location=Amsterdam
--tool-arg can repeat, and its values are JSON-parsed, so count=1 arrives as a number. When that coercion gets in the way, --tool-args-json '{"zip":"012"}' passes one object verbatim [5]. Add --format json for a single {"result": ...} object on stdout that pipes cleanly into jq [5].
The methods it accepts include initialize, tools/list, tools/call, resources/list, resources/read, prompts/list and prompts/get [5]. For what a tools/list answer actually contains, field by field, see our MCP tools list reference.
Exit codes
v1 exited 0 or 1. v2's CLI gives each class of failure its own code and writes one JSON line describing it to stderr. These are the ones a plain connect, list or call can return [5]:
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Usage or unexpected error |
3 |
The server requires authentication (401 or 403) |
4 |
Server unreachable: DNS, connection refused, timeout, fetch failed |
5 |
Tool error: tools/call returned isError: true, or the tool was not found |
Code 5 is the one that changes existing scripts. A tools/call that came back with isError: true exited 0 under v1, so a && chain carried on past it; under v2 it stops [2]. The failure class is readable without scraping prose:
npx @modelcontextprotocol/inspector --cli ... 2>&1 | tail -1 | jq .error
The errors people hit on the first run
The Inspector connected, but to the wrong server. Under --cli the target must come before every flag. --cli --method tools/list node build/index.js does not error: the target is dropped and the Inspector falls back to your saved catalog in ~/.mcp-inspector/mcp.json, so it looks as if it worked [2].
Transport type not specified and could not be determined from URL. The path ends in neither /mcp nor /sse. Add --transport http [2].
A generic fetch error against https://localhost. Node, not your browser, makes the connection, so it does not trust a self-signed certificate even after you clicked through the browser warning. Point NODE_EXTRA_CA_CERTS at the certificate or its CA [3].
HOST=0.0.0.0 exits with an error. v2 refuses an all-interfaces bind unless DANGEROUSLY_BIND_ALL_INTERFACES=true is also set [3].
--server is ignored. It selects an entry from a config file only under --cli. The web UI logs a warning and loads every entry instead [2].
You need v1 back. npx @modelcontextprotocol/inspector@v1-latest [2].
What the Inspector cannot tell you
The Inspector runs on your machine, so it reaches whatever your machine reaches: localhost, your VPN, a staging host behind your office firewall. A server that passes every check in it can still be unreachable for everyone else, and that is the case a client on somebody else's network actually meets.
Our MCP connection test covers that half and nothing more. It calls a public URL from our network rather than yours, sends three JSON-RPC calls and stops: it never calls a tool, and it never runs an OAuth flow, so a guarded server shows up as answering 401 rather than as broken. What you get back is a dated result at its own URL, which is something you can send to another person, where the Inspector leaves you a screen. The two together answer different questions: does my server work, and can anyone else reach it.