Observability: Inspecting MCP Traffic

RoadmapsAI Engineering

Scenario

Your local MCP server crashes instantly when Claude Desktop tries to connect. You spend two hours configuring Charles Proxy to intercept the traffic to find the bug. When you boot the server, Charles Proxy shows absolutely zero traffic, yet the server still crashes.

A developer attempts to use an HTTP proxy to debug a local MCP server, but the proxy captures no traffic. Why?

Mental model

Standard proxies listen to phone calls. stdio servers are passing notes under the table.

Because local MCP servers use the `stdio` transport, they don't use network sockets at all. They communicate via raw subprocess standard input and output. An HTTP proxy like Wireshark or Charles literally cannot see this traffic. To see what's happening, you have to use a specialized proxy (the MCP Inspector) that specifically wraps the subprocess execution to read the notes being passed under the table.

Deep dive

When a standard REST API fails, the server logs a 400 or 500 error, telling you what went wrong. (General tracing and logging was covered in the `observability-traces-logging` lesson — this is the MCP transport wrinkle.) MCP doesn't work like this. If your server returns a malformed JSON-RPC schema during the `tools/list` negotiation, the Host application immediately rejects it and terminates the subprocess.

In MCP, the Host controls execution and will abruptly kill the server if the protocol is violated.

Because the server is just a dumb subprocess that got killed, your Python or Node logs will be completely empty. The server has no idea why it died. This 'silent failure' drives developers crazy, making them assume the Host application is broken.

Protocol errors result in silent failures on the server side because the server is simply terminated.

To figure out why the Host rejected your payload, you need to see the exact JSON-RPC messages (the Protocol Trace). But as you learned in the Transports lesson, local servers use `stdio`. There is no network traffic. HTTP proxies like Wireshark are useless here.

Standard HTTP proxies cannot capture stdio traffic because there are no network sockets.

The solution is the official MCP Inspector. You run the inspector, and you tell the inspector to run your server. The inspector acts as a middleman Host. It spawns your server, captures the `stdio` traffic passing between them, and provides a web UI to view the exact JSON payloads.

The MCP Inspector wraps the server execution to intercept and visualize stdio traffic.

By viewing the raw JSON in the Inspector, you can immediately spot if your FastMCP decorator missed a required type hint, or if a rogue print statement corrupted the stdout stream before the Host could parse it.

Protocol traces in the Inspector reveal the exact formatting errors causing silent failures.

Code examples

Launching the MCP Inspector

# 1. Your normal boot command for the server:
# python server.py

# 2. Wrapping it with the Inspector:
npx @modelcontextprotocol/inspector python server.py

# The inspector will spawn a local web server (UI defaults to http://localhost:6274, proxy on 6277)
# Open that URL to see the intercepted JSON-RPC traffic in real-time.

You don't change your server code. You just prefix your boot command with the inspector wrapper. (Ports verified against official README)

What a Protocol Trace looks like

// Intercepted traffic shown in the Inspector UI
// The Host (Inspector) requests tools:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}

// The Server responds (this is what you debug):
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      { "name": "broken_tool", "inputSchema": { /* missing required fields */ } }
    ]
  }
}

If Claude Desktop was silently failing, this trace reveals exactly which tool schema is malformed.

Common mistakes

Glossary

Protocol Trace
The exact, raw JSON-RPC messages sent back and forth over the transport layer (stdin/stdout or HTTP).
MCP Inspector
An official debugging tool that acts as a middleman proxy, intercepting and visualizing the JSON-RPC traffic between a Host and a Server.
Silent Failure
A scenario where a Host disconnects from an MCP Server due to a protocol error, but the server logs show nothing because it was simply killed by the Host.

Recall questions

Questions & answers

How do you debug an MCP server when standard logging fails?

You use the official MCP Inspector. Because local servers use `stdio`, standard HTTP proxies won't work, and protocol errors cause the Host to silently kill the server without leaving server-side logs. The Inspector wraps the execution command to intercept and visualize the raw JSON-RPC traffic, allowing you to identify malformed schemas.

Approach: Explain the 'silent failure' nature of protocol errors, explicitly rule out Wireshark/Charles, and state how the Inspector acts as a middleman for stdio.

Why can't you use Wireshark to debug a local MCP server?

Local MCP servers communicate with the Host over the `stdio` transport, using raw subprocess standard input and output. Wireshark only listens on network interfaces and sockets. Because `stdio` doesn't use the network stack, Wireshark cannot see the traffic.

Approach: Identify `stdio` as a subprocess communication method and note that Wireshark requires network sockets.

Continue learning

Previous: MCP Transports: stdio and Streamable HTTP

Return to AI Engineering Roadmap