MCP Inspector is the reference debugging tool for Model Context Protocol servers, and you run it with npx @modelcontextprotocol/inspector. That command starts a local web UI at http://127.0.0.1:6274, where you connect a server, call its tools, read its resources and test its prompts. Add --cli for a scriptable client or --tui for a terminal UI. There is no install step, but the current release needs Node 22.19.0 or newer, according to the MCP Inspector docs.

I ran version 2.9.0 on an Apple M1 against a small Python FastMCP server over stdio, Streamable HTTP and SSE, and the outputs, exit codes and timings on this page come from that run. Three results matter most. v2 has no proxy on port 6277, so a "proxy session token" error means you are still on v1. The transport is inferred from the last path segment of the URL, so /mcp works and /mcp/ with a trailing slash fails. And the CLI exits with fixed codes from 0 to 5, which makes it usable in CI.

What MCP Inspector is and which version you are running

MCP Inspector is a developer client for the Model Context Protocol (MCP), the open protocol that lets AI applications call tools and read data from external servers. It ships as one npm package, @modelcontextprotocol/inspector, with three front ends behind one mcp-inspector binary: web (the default), CLI and TUI.

The version matters because many tutorials still describe v1. The latest tag on the npm registry is 2.9.0, a v2 rewrite published on 2026-09-30, and v2 changed exactly the parts people search for. This table condenses the official v1 to v2 migration guide.

v1 (v1-latest tag)v2 (latest tag)
Node floor>=22.7.5>=22.19.0
Processes and portsUI on 6274 plus MCP proxy on 6277one server on 6274, MCP Apps sandbox on 6275
Token variableMCP_PROXY_AUTH_TOKENMCP_INSPECTOR_API_TOKEN
Modesweb, --cliweb, --cli, --tui
Server listbrowser localStoragecatalog file ~/.mcp-inspector/mcp.json
CLI exit codes0 or 10 to 5 plus a JSON error line

To stay on v1, pin it with npx @modelcontextprotocol/inspector@v1-latest. v1 now receives security fixes only.

When I checked, npm resolved latest to 2.9.0 and v1-latest to 1.0.2. I also tried Node v22.18.0, one release below the floor: a cold npx install printed 2 EBADENGINE warnings (for the Inspector and undici), yet the stdio tools/list call still exited 0. The migration guide warns that an older Node "fails later, obscurely", so I would upgrade anyway.

How to use MCP Inspector with a Python FastMCP server

The Inspector is a Node tool, but it inspects servers written in any language because it only needs the command that starts them. There is no separate Python build of the official Inspector. FastMCP is the most common Python framework for MCP servers, and the FastMCP docs note that its mcp.run() call defaults to stdio.

This is the whole server I tested: one tool, one resource and one prompt.

import sys
from fastmcp import FastMCP

mcp = FastMCP("inspector-demo")

@mcp.tool
def add(a: int, b: int) -> int:
    """Add two integers."""
    return a + b

@mcp.resource("config://app")
def app_config() -> str:
    """Static app configuration."""
    return '{"env": "dev", "version": "1.0"}'

@mcp.prompt
def review_code(code: str) -> str:
    """Ask for a code review."""
    return f"Review this code and list bugs:\n\n{code}"

if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "http":
        mcp.run(transport="http", host="127.0.0.1", port=8000)
    else:
        mcp.run()

Install FastMCP in a virtual environment, then hand the Inspector the Python command:

uv venv venv && uv pip install --python venv/bin/python fastmcp
npx @modelcontextprotocol/inspector venv/bin/python server.py

FastMCP also has its own launcher, fastmcp dev inspector server.py, which starts your server together with the Inspector. In my run, FastMCP 4.0.10 pulled in the mcp SDK 2.2.0. Its fastmcp dev inspector --help still describes --server-port as the "Port for the MCP Inspector Proxy server", and the source sets SERVER_PORT. The package spec it passes to npx has no version pin, so it launches the v2 Inspector. My reading is that in v2 SERVER_PORT only moves the MCP Apps sandbox, so that flag no longer changes anything you browse.

Connecting over stdio, Streamable HTTP or SSE

Stdio is the default: the positional command is what the Inspector spawns. For a running server, pass its URL. With no --transport flag, v2 infers the transport from the URL's last path segment and nothing else.

To see how strict that is, I ran the same FastMCP server with transport="http" on port 8000 and transport="sse" on port 8001, then pointed the CLI at each URL shape. Nothing listened on port 8999.

URL passed to --cli--transportResult
http://127.0.0.1:8000/mcpnoneconnected as Streamable HTTP, exit 0
http://127.0.0.1:8000/mcp/noneexit 1: "Transport type not specified and could not be determined from URL"
http://127.0.0.1:8000noneexit 1, same message
http://127.0.0.1:8000/mcp/httpconnected, exit 0
http://127.0.0.1:8001/ssenoneconnected as SSE, exit 0
http://127.0.0.1:8000/mcpsseexit 1: "SSE error: Non-200 status code (400)"
http://127.0.0.1:8999/mcpnoneexit 4, unreachable, ECONNREFUSED

One documentation trap: the CLI README still says a bare remote URL defaults to SSE. In 2.9.0 it does not; the bare-host row above failed. Prefer Streamable HTTP for new servers, since FastMCP calls SSE a legacy transport kept for older clients.

MCP Inspector CLI mode: tools, resources and prompts

CLI mode connects, runs one --method, prints the result and exits, which suits terminals, CI jobs and coding agents. With --format json, the CLI docs say, you get one {"result": ...} object with no banners, ready for jq.

These are the calls I ran against the stdio server, with what came back:

TaskCommand after npx @modelcontextprotocol/inspector --cli venv/bin/python server.pyOutput
Handshake--method initializeserverInfoinspector-demo, capabilities logging, prompts, resources, tools
List tools--method tools/listadd, with an input and output schema
Call a tool--method tools/call --tool-name add --tool-arg a=2 --tool-arg b=3text 5 and structuredContent.result5
List resources--method resources/listconfig://app
Read a resource--method resources/read --uri config://apptext/plain JSON string
List prompts--method prompts/listreview_code
Get a prompt--method prompts/get --prompt-name review_code --prompt-args code=print(1)one user message

--tool-arg JSON-parses each value, so count=1 arrives as a number. Use --tool-args-json '{"zip":"10001"}' when a string must stay a string.

Argument order is the classic mistake. Under --cli, the leading run of non-dash tokens is the server, so --cli --method tools/list venv/bin/python server.py drops the target and falls back to your catalog. In my run that command exited 1 with "No servers found in config file" and left an empty {"mcpServers":{}} catalog behind. When the server itself takes flags, the migration guide says to put them before a -- and the Inspector's options after it.

A warm CLI round trip took a median of 1413 ms over stdio, which includes spawning Python, and 834 ms over HTTP against a running server (five runs each).

Exit codes for CI and scripts

Every non-zero exit maps to a fixed failure class, and the CLI also writes one JSON line to stderr, so a script can branch on the cause instead of parsing prose.

CodeMeaningWhat triggered it in my run
0successevery valid call
1usage or unexpected errorno --method, bad URL shape, wrong transport
2no MCP App on the toolnot exercised
3server requires authenticationnot exercised
4server unreachablenothing on port 8999
5tool error or tool not founda=x for an int, and --tool-name nope

A failing tool now fails the process. tools/call with a=x printed the result with isError true on stdout and still exited 5 with {"error":{"code":"tool_is_error"}}. A missing tool returned tool_not_found, also exit 5. In v1 a failing tool call exited 0.

A minimal CI check is mcp-inspector --cli <server> --method tools/list --format json | jq -e '.result.tools | length > 0'. For OAuth-protected servers, add --stored-auth-only so the job fails fast instead of waiting on a browser login.

Using a config file: --config vs --catalog

Both flags take the familiar mcpServers JSON shape, but they behave differently. --config is a read-only session file that must exist; --catalog is the Inspector's own writable list, created if missing, with ~/.mcp-inspector/mcp.json as the default.

This is the file I used, with one stdio entry and one Streamable HTTP entry:

{ "mcpServers": {
  "demo-stdio": { "type": "stdio", "command": "/path/to/venv/bin/python", "args": ["/path/to/server.py"] },
  "demo-http":  { "type": "streamable-http", "url": "http://127.0.0.1:8000/mcp" }
} }

Select an entry with --server, which only works under --cli:

npx @modelcontextprotocol/inspector --cli --config ./mcp.json --server demo-http --method tools/list

Both entries connected. --method servers/list returned demo-http and demo-stdio without connecting, and the file's hash was unchanged after the runs. A missing file failed with "Config file not found", and combining --config with a positional server failed with "--config cannot be combined with an ad-hoc server URL/command".

Ports, the session token and Docker

The official Inspector runs locally, not as a hosted website. The web launcher binds to 127.0.0.1 by default and guards every /api/* route with a bearer token in the x-mcp-remote-auth header. The environment variables reference says the token is random per launch unless you set MCP_INSPECTOR_API_TOKEN.

On my machine the web process listened on 127.0.0.1 ports 6274, 6275 and 6278, and the v1 proxy port did not answer. The banner printed a 64-character token both in the URL and on its own line, so open the exact printed URL. The page itself loads without it: GET / returned 200 and embedded the token in the page, while /api/config returned 401 without the header or with a wrong token, and 200 with it. Setting MCP_INSPECTOR_API_TOKEN made the banner use my fixed value, which gives you a stable URL. HOST=0.0.0.0 exited 1 with "Refusing to bind".

Because the page itself carries the token, anyone who can reach port 6274 can drive a backend that spawns processes. Keep it on loopback, as the official container recipe in the migration guide does:

docker run --rm -p 127.0.0.1:6274:6274 ghcr.io/modelcontextprotocol/inspector:latest

Publish 6275 as well if you test MCP Apps, and never set DANGEROUSLY_OMIT_AUTH on a reachable host.

Fixing common MCP Inspector errors

Most "MCP Inspector not connecting" reports fit a few patterns. The first three messages below come from v1; a Stack Overflow question on the proxy error has over 14,000 views and no accepted answer. The v2 causes come from the migration guide, and the last four messages are the exact text my run produced.

Error you seeLikely causeFix
"Connection Error - Check if your MCP server is running and proxy token is correct"v1 web UI could not reach its proxy with the tokenupgrade to latest, open the exact printed URL, or set MCP_PROXY_AUTH_TOKEN on v1
"Error Connecting to MCP Inspector Proxy"v1 proxy on 6277 not running or blockedv2 has no proxy; upgrade, or free port 6277 on v1
"PORT IS IN USE" on 6277an old v1 process still runningkill it; v2 does not use 6277
"Transport type not specified and could not be determined from URL"URL ends in neither /mcp nor /sse, or has a trailing slashadd --transport http or fix the path
"SSE error: Non-200 status code (400)"SSE client pointed at a Streamable HTTP endpointuse --transport http
unreachable / ECONNREFUSEDserver not running on that host and portstart it, check the port
"No servers found in config file"--cli target placed after the flagsput the server command first

On Windows the command is the same: install Node 22.19.0 or newer, then run npx @modelcontextprotocol/inspector from PowerShell or Command Prompt, followed by your server's start command. I did not test on Windows. A 2026 "Cannot find native binding" failure after an update was tracked in issue #1852 and closed as fixed, so update to the latest release before debugging further.

How I tested this

  • Machine: Apple M1, macOS (Darwin 26.3, arm64).
  • Versions: MCP Inspector 2.9.0 (npm latest), Node v22.23.3 for the main runs and v22.18.0 for the below-floor check, Python 3.13.5, FastMCP 4.0.10 with the mcp SDK 2.2.0.
  • Date: October 2, 2026.
  • What I ran: a shell harness that installs the Inspector through npx in an isolated directory, starts the FastMCP server above (the harness copy adds an sse branch on port 8001), runs every CLI method and error case shown on this page, times five warm round trips per transport, and probes the web launcher's ports and token checks with HTTP requests.
  • What I did not test: Windows or Linux, the TUI, clicking through the web UI, OAuth-protected servers (exit 3), MCP Apps (exit 2), the Docker image, and v1 itself, which I only resolved on npm.
  • Raw record: every metric is in the public results.json.

References