P220 min

Testing with MCP Inspector

Use MCP Inspector to test tools, read resources, and debug connection and response issues.

On This Page

Key Concepts

  • MCP Inspector as a development tool
  • Connecting to your server
  • Interactive tool testing
  • Resource listing and reading
  • Raw JSON-RPC message inspection
  • Debugging connection and response issues
  • CLI flags for custom configurations

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 build

Now launch the Inspector, telling it how to start your server:

npx @modelcontextprotocol/inspector node build/index.js

The 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 server

Important: The command after @modelcontextprotocol/inspector is 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:

  1. 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.
  2. Server info — Shows your server's name, version, and capabilities (tools, resources, prompts). This information comes from the initialization handshake.
  3. Tools tab — Lists every tool your server registered. Click a tool to see its schema and test it.
  4. Resources tab — Lists every resource and resource template. Click one to read its contents.
  5. 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

  1. Click on echo.
  2. The Inspector shows the tool's description and input schema. You should see one field: message (string, required).
  3. Enter Hello from Inspector! in the message field.
  4. Click Run Tool.
  5. Verify the response shows: Echo: Hello from Inspector!

Test 2: Calculate

  1. Click on calculate.
  2. You should see three fields: a (number), b (number), and operation (enum).
  3. Enter a: 15, b: 4, operation: multiply.
  4. Click Run Tool.
  5. Verify: 15 multiply 4 = 60.

Test 3: Format Date

  1. Click on format_date.
  2. Enter date: 2025-06-15. Leave locale and style empty (they are optional).
  3. Click Run Tool.
  4. Verify it returns a formatted date string like June 15, 2025.
  5. Now test with optional params: locale: fr-FR, style: full. Verify the format changes.

Test 4: Random Fact

  1. Click on random_fact.
  2. This tool has no inputs. Click Run Tool.
  3. Verify it returns a text fact. Run it again — you should get a different fact.

Test 5: Placeholder Image

  1. Click on placeholder_image.
  2. Enter width: 200, height: 100.
  3. Click Run Tool.
  4. 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

  1. Call calculate with a: 10, b: 0, operation: divide.
  2. Verify the response has isError: true and the message says "Division by zero."

Invalid Date

  1. Call format_date with date: not-a-date.
  2. Verify the response has isError: true and an error message about parsing.

Schema Validation

  1. Try calling calculate without providing the operation field. The Inspector may prevent this in the UI, but if you can submit it, the SDK should reject it with a validation error.
  2. 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 the result field. SDK errors are in the error field 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

  1. Find server-config in the list (URI: config://server).
  2. Click to read it.
  3. Verify you see JSON with the server name, version, tool count, and timestamp.

Test: System Info

  1. Find system-info (URI: system://info).
  2. Click to read it.
  3. 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

  1. Find the environment-variable template (URI template: env:///{name}).
  2. The Inspector should let you fill in the name parameter. Enter HOME.
  3. Verify it returns your home directory path (e.g., /home/yourname or /Users/yourname).
  4. 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 build first. The Inspector runs the compiled JavaScript, not TypeScript.
  • Wrong path — Double-check the path to your built file. It should be build/index.js relative 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.js directly 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. Use console.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.js

Debugging 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.js

The -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:

  1. For each tool: Test with valid input, test with edge cases (empty strings, zero, very long inputs), and test error paths.
  2. For each resource: Read it and verify the content is correct and well-formatted.
  3. For resource templates: Test with valid parameters and with parameters that should produce errors or empty results.
  4. 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-trip

Troubleshooting

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.js

If 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.