npx MCP Inspector: Run It, Connect It, Read the Errors | MCP Hunter

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.

MCP Hunter team 7 min read

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 -v first. 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, --cli for scripts and CI, --tui for 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 now MCP_INSPECTOR_API_TOKEN [2].
  • A URL that does not end in /mcp or /sse needs --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.

Sources

  1. MCP Inspector README, modelcontextprotocol/inspector on GitHub
  2. Migrating from Inspector v1 to v2
  3. Inspector environment variables
  4. Inspector launcher README
  5. Inspector CLI README