
mcpsnoop v0.16.0
Wireshark for MCP. A transparent proxy that shows every real tool call between your AI client and your MCP servers, live in your terminal.
Wireshark for MCP. A transparent proxy that shows every real tool call between your AI client and your MCP servers, live in your terminal.
The problem
The official MCP Inspector connects as its own client, so it never sees what your client (Cursor, Claude Code, Codex) actually sends your server. And anything that waits for a request to arrive can't show the call the model never made, or made with the wrong arguments. When a tool silently isn't called, capabilities don't line up, or a call just hangs, you're left digging through logs and guessing.
mcpsnoop sits in the real data path instead. Wrap your server command with it and watch every JSON-RPC frame live, as your real client and server talk.
In CI
This page is also the listing for the mcpsnoop GitHub Action, so here is the whole of it. It checks a captured session, files every finding as a code scanning alert, and fails the job on what you gated on.
permissions:
security-events: write
contents: read
steps:
- uses: kerlenton/[email protected]
with:
session: artifacts/session.jsonl
Pin whichever release you want. The newest is on the releases page. Every input, what the exit codes mean, and how to wire it up without the action are in The GitHub Action further down.
Quick start
See it right away, with nothing to set up.
mcpsnoop demo
To use it for real, wrap your server in your client's MCP config.
{
"mcpServers": {
"my-server": {
"command": "mcpsnoop",
"args": ["--", "node", "build/index.js"]
}
}
}
Everything after -- is the command that normally launches your server. Swap in
whatever you already use, like python server.py, npx -y @scope/server, or a
compiled binary.
On Claude Desktop you don't have to make that edit by hand.
mcpsnoop wrap my-server # route my-server through mcpsnoop
mcpsnoop unwrap my-server # put it back
wrap finds claude_desktop_config.json, copies it to
claude_desktop_config.json.mcpsnoop.bak the first time, and rewrites only that
one server's entry, so your formatting and every other server are left alone.
Inside the rewritten entry the keys come back in alphabetical order. unwrap
restores the file, and removes the backup once no server is wrapped any more.
Restart Claude Desktop after either, since MCP servers are launched once at
startup.
Then use your client as usual and open the UI.
mcpsnoop
No flags, no socket paths, no startup order to remember. The shim and the UI find each other on their own, and the UI backfills past sessions from disk.
For a streamable-HTTP server, run mcpsnoop as a reverse proxy.
mcpsnoop http --target http://localhost:3000/mcp --listen :7000
The HTTP status of every response shows in the stream, so a response that carries
no JSON-RPC message of its own is still a visible frame rather than nothing: the
401 challenge, the 403 on a rejected Origin, the 202 that acknowledges a
notification, and the 502 when the target cannot be reached at all. A 401's WWW-Authenticate header is kept verbatim and shown in the inspector,
since it names the auth scheme and the resource metadata to go to next. Filter by
status with status:401 in the TUI, or by any failure with status:err. A 4xx
or 5xx counts as an error, so a default mcpsnoop check run fails on it.
No server of your own? Try it for real against a published test server, driven by your own client. To inspect a session after it happened, see review past sessions from logs.
Config file
If you reuse the same shim flags across a project, put them in a
.mcpsnoop.toml file in the current working directory.
label = "filesystem"
trace-file = "trace.jsonl"
redact-secrets = true
redact-key = "token,authorization"
redact-value = "sk-[A-Za-z0-9]+"
redact-path = "$.params.arguments.password"
no-trace = false
Repeat redact-key, redact-value, and redact-path on their own lines to add
more than one of each.
Those are all the keys it supports.
The file is only looked up in the current working directory, not in parent directories.
Explicit command-line flags override values from the config file.
Commands
| Command | What it does |
|---|---|
mcpsnoop -- <server> | wrap a stdio server as a transparent shim |
mcpsnoop | open the live TUI |
mcpsnoop http --target <url> | proxy a streamable-HTTP server |
mcpsnoop export | render a session to json, html, text, har, or otlp |
mcpsnoop check | fail CI on errors, invalid frames, warnings, routing mismatches, hung calls, late results, or a latency budget |
mcpsnoop baseline | inspect, accept, or reset trusted tool definitions |
mcpsnoop diff | compare tools and calls across two captured sessions |
mcpsnoop open | open a saved session in the TUI |
mcpsnoop inventory | list every server that has run through mcpsnoop on this machine |
mcpsnoop stats | fold every stored capture into one row per server and tool |
mcpsnoop prune | delete saved session logs older than a cutoff |
mcpsnoop wrap <server> | route one of Claude Desktop's servers through mcpsnoop |
mcpsnoop unwrap <server> | put that server's entry back the way it was |
mcpsnoop remote <user@host> | print the SSH tunnel command |
mcpsnoop demo | play a scripted session |
Run mcpsnoop help for the full list, or mcpsnoop help <command> for the flags of one.
How it compares
| MCP Inspector | mcpsnoop | |
|---|---|---|
| Sees your real client and server traffic | no | yes |
| Flags hung calls and stream errors | no | yes |
| Flags stray output that corrupts the stream | no | yes |
| Flags malformed JSON-RPC frames | no | yes |
| Detects tool definition drift after approval | no | yes |
| Interactive terminal UI | no | yes |
| Zero-config, no flags or ordering | no | yes |
| Capability inspector | partial | yes |
| Replay a captured call | no | yes, over stdio and over HTTP |
| Session export (json / html / text / otlp) | no | yes |
| Single binary, no runtime deps | no | yes |
Install
npm
No Go toolchain needed. Most MCP servers are written in Node or Python, so this is the shortest way in.
npx mcpsnoop -- node build/index.js
The npm package ships no code of its own. Six platform packages each carry one
build, and npm installs the single one that matches your machine, so there is
nothing to download at install time and nothing to unblock in a proxy. To keep it
around rather than fetching it each run, npm i -g mcpsnoop.
Go
go install github.com/kerlenton/mcpsnoop/cmd/mcpsnoop@latest
Homebrew
brew install mcpsnoop
Prebuilt binaries for every platform are on the Releases page.