What Is MCP Inspector?
MCP Inspector is a developer tool built by the MCP team. It acts as an MCP client that connects to your server and gives you a visual interface to test everything: list tools, call them with inputs, read resources, and inspect the raw JSON-RPC messages going back and forth.
Think of it like Postman for REST APIs, but for MCP. Instead of manually constructing JSON-RPC messages and piping them to stdin, you click through a UI.
You do not need to install the Inspector globally. It runs via npx, which downloads and executes it on the fly.
Step 1: Starting Inspector
Make sure your server is built. From your my-first-mcp-server directory:
npm run buildNow launch the Inspector, telling it how to start your server:
npx @modelcontextprotocol/inspector node build/index.jsThe Inspector starts and prints a URL, typically http://localhost:5173. Open this in your browser.
Here is what is happening under the hood:
1. npx downloads and runs the Inspector tool
2. The Inspector launches "node build/index.js" as a child process
3. It connects to your server via stdio (same as Claude Desktop would)
4. It performs the MCP initialization handshake
5. It opens a web UI where you can interact with your serverImportant: The command after
@modelcontextprotocol/inspectoris the exact command used to start your server. If your server required environment variables, you would set them before the command or pass them via the Inspector's environment settings.
Step 2: The Interface
When the Inspector loads in your browser, you will see several areas:
- Connection status — At the top, shows whether the Inspector is connected to your server. If it says "Connected," the handshake succeeded and your server is responding.
- Server info — Shows your server's name, version, and capabilities (tools, resources, prompts). This information comes from the initialization handshake.
- Tools tab — Lists every tool your server registered. Click a tool to see its schema and test it.
- Resources tab — Lists every resource and resource template. Click one to read its contents.
- Notifications tab — Shows server notifications like resource change alerts.
Click the Connect button if the Inspector has not auto-connected. You should see the connection status change and your server's name appear.
Step 3: Testing Tools
Click the Tools tab. You should see all the tools you registered in the previous modules: echo, calculate, format_date, random_fact, and placeholder_image.
Let us test each one systematically:
Test 1: Echo
- Click on
echo. - The Inspector shows the tool's description and input schema. You should see one field:
message(string, required). - Enter
Hello from Inspector!in the message field. - Click Run Tool.
- Verify the response shows:
Echo: Hello from Inspector!
Test 2: Calculate
- Click on
calculate. - You should see three fields:
a(number),b(number), andoperation(enum). - Enter
a: 15,b: 4,operation: multiply. - Click Run Tool.
- Verify:
15 multiply 4 = 60.
Test 3: Format Date
- Click on
format_date. - Enter
date: 2025-06-15. Leave locale and style empty (they are optional). - Click Run Tool.
- Verify it returns a formatted date string like
June 15, 2025. - Now test with optional params:
locale: fr-FR,style: full. Verify the format changes.
Test 4: Random Fact
- Click on
random_fact. - This tool has no inputs. Click Run Tool.
- Verify it returns a text fact. Run it again — you should get a different fact.
Test 5: Placeholder Image
- Click on
placeholder_image. - Enter
width: 200,height: 100. - Click Run Tool.
- The Inspector should display the returned image. If the Inspector shows raw base64 instead, that is also fine — the data is correct.
Step 4: Testing Error Cases
Testing the happy path is not enough. You need to verify that your error handling works correctly. Try these:
Division by Zero
- Call
calculatewitha: 10,b: 0,operation: divide. - Verify the response has
isError: trueand the message says "Division by zero."
Invalid Date
- Call
format_datewithdate: not-a-date. - Verify the response has
isError: trueand an error message about parsing.
Schema Validation
- Try calling
calculatewithout providing theoperationfield. The Inspector may prevent this in the UI, but if you can submit it, the SDK should reject it with a validation error. - Look at the error response — it comes from Zod validation, not your handler.
Key observation: Notice the difference between errors your handler returns (with
isError: true) and errors the SDK returns (validation failures). Handler errors are in theresultfield. SDK errors are in theerrorfield of the JSON-RPC response. Both are important to test.
Step 5: Testing Resources
Click the Resources tab. You should see your registered resources.
Test: Server Config
- Find
server-configin the list (URI:config://server). - Click to read it.
- Verify you see JSON with the server name, version, tool count, and timestamp.
Test: System Info
- Find
system-info(URI:system://info). - Click to read it.
- Verify the hostname, platform, memory, and CPU count match your machine. Read it again — values like uptime and free memory should change slightly.
Test: Environment Variable Template
- Find the
environment-variabletemplate (URI template:env:///{name}). - The Inspector should let you fill in the
nameparameter. EnterHOME. - Verify it returns your home directory path (e.g.,
/home/yournameor/Users/yourname). - Try a variable that does not exist:
NONEXISTENT_VAR. Verify you get the "not set" message.
Step 6: Reading Raw Messages
The Inspector has a message log or console that shows the raw JSON-RPC messages flowing between the Inspector (client) and your server. This is invaluable for debugging.
Look for a section showing the message history. You should see the initialization handshake messages from when you connected:
→ Client sent: {
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": { ... },
"clientInfo": { "name": "mcp-inspector", "version": "..." }
}
}
← Server sent: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-03-26",
"capabilities": { "tools": {}, "resources": {} },
"serverInfo": { "name": "my-first-server", "version": "1.0.0" }
}
}
→ Client sent: {
"jsonrpc": "2.0",
"method": "notifications/initialized"
}When you call a tool, you see the full request and response:
→ Client sent: {
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "echo",
"arguments": { "message": "Hello!" }
}
}
← Server sent: {
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [{ "type": "text", "text": "Echo: Hello!" }]
}
}Reading these messages teaches you what the MCP protocol actually looks like on the wire. Every server.tool() call you wrote translates to this JSON-RPC structure.
Debugging Connection Failures
If the Inspector cannot connect to your server, here is how to diagnose the problem:
1. "Failed to start server" or "Process exited immediately"
Your server crashed before it could respond. Common causes:
- Missing build step — Run
npm run buildfirst. The Inspector runs the compiled JavaScript, not TypeScript. - Wrong path — Double-check the path to your built file. It should be
build/index.jsrelative to your project directory. - Import errors — A missing dependency or wrong import path causes the Node.js process to crash on startup. Try running
node build/index.jsdirectly in your terminal to see the error message.
2. "Connection timed out"
The server started but did not respond to the initialization request.
- Console.log interference — If your server writes to stdout with
console.log(), those messages mix with the JSON-RPC protocol and corrupt it. Useconsole.error()for debug output instead — stderr does not interfere with the protocol. - Server not calling connect() — Make sure you have
await server.connect(transport)at the end of your file. Without it, the server exists but never starts listening.
3. "Protocol version mismatch"
Your SDK version and the Inspector version disagree on the protocol version. Update both:
npm update @modelcontextprotocol/sdk
npx @modelcontextprotocol/inspector@latest node build/index.jsDebugging Invalid Responses
Sometimes the connection works but tool calls return unexpected results.
Tool Returns Empty or Null
Check that your handler returns an object with a content array. If you return undefined or forget the return statement, the SDK sends an empty result.
Resource Returns Wrong Data
Check that the URI in the contents response matches the URI the client requested. Mismatched URIs can cause the client to discard the response.
Unexpected Error Messages
Look at the raw JSON-RPC messages. If the error is in the error field (not in result.content), it is a protocol-level error from the SDK, not from your handler. Common causes:
- Input validation failure (Zod rejected the input)
- Unhandled exception in your handler (SDK caught it)
- Malformed return value (your handler returned something the SDK cannot serialize)
Inspector CLI Options
The Inspector accepts several useful flags:
# Basic usage
npx @modelcontextprotocol/inspector node build/index.js
# Pass environment variables to your server
npx @modelcontextprotocol/inspector -e API_KEY=abc123 node build/index.js
# Pass arguments to your server
npx @modelcontextprotocol/inspector node build/index.js --port 3000
# Use a specific port for the Inspector UI
npx @modelcontextprotocol/inspector --port 8080 node build/index.jsThe -e flag is particularly useful for servers that need API keys or configuration. The environment variables are passed to the child process (your server), not to the Inspector itself.
Try It Yourself
Create a systematic test checklist and run through it with the Inspector. Test every tool and resource in your server:
- For each tool: Test with valid input, test with edge cases (empty strings, zero, very long inputs), and test error paths.
- For each resource: Read it and verify the content is correct and well-formatted.
- For resource templates: Test with valid parameters and with parameters that should produce errors or empty results.
- Read the raw messages: For at least one tool call and one resource read, look at the raw JSON-RPC messages and make sure you understand the request/response structure.
Here is a concrete checklist to work through:
Testing Checklist:
[ ] echo — normal message
[ ] echo — empty string
[ ] calculate — addition
[ ] calculate — division by zero
[ ] format_date — valid date with defaults
[ ] format_date — valid date with locale and style
[ ] format_date — invalid date string
[ ] random_fact — returns a fact
[ ] placeholder_image — 200x100
[ ] placeholder_image — with custom text
[ ] server-config resource — returns JSON
[ ] system-info resource — values match your system
[ ] env:///HOME — returns your home directory
[ ] env:///NONEXISTENT — returns "not set" message
[ ] Raw messages — read the initialization handshake
[ ] Raw messages — read a tool call round-tripTroubleshooting
Inspector command not found
Make sure you have a recent version of npm (8+) that supports npx executing remote packages. Run npm --version to check.
Browser shows blank page
The Inspector UI sometimes takes a moment to build. Wait 5-10 seconds after the URL appears. If it stays blank, try a different browser or clear the cache. Check the terminal for error messages.
Server works in terminal but not in Inspector
The most common cause is console.log() in your server code. Any stdout output that is not valid JSON-RPC corrupts the protocol stream. Switch all debug logging to console.error().
Inspector hangs after clicking Connect
Your server might be crashing silently. Run your server manually first to verify it starts:
node build/index.jsIf it sits there waiting (no error output), it is running correctly. If you see an error message, fix it before trying the Inspector again.
What You Accomplished
- Launched MCP Inspector and connected to your server
- Tested every tool with valid inputs and edge cases
- Tested error handling paths
- Read and listed resources and resource templates
- Inspected raw JSON-RPC messages to understand the protocol
- Learned to debug connection and response issues
In the next module, you will take this same server and add it to Claude Desktop — so you can use your tools in a real AI conversation.