| name | mcpsnoop-mcp-debugging |
| description | Debug MCP client-server traffic in real-time using mcpsnoop, a transparent proxy for Model Context Protocol communications |
| triggers | ["debug MCP traffic between client and server","inspect MCP tool calls and responses","troubleshoot MCP server communication issues","set up mcpsnoop to monitor MCP messages","replay MCP tool calls for testing","view MCP capabilities negotiation","monitor JSON-RPC frames in MCP","diagnose why MCP tool isn't being called"] |
mcpsnoop MCP Debugging Skill
Skill by ara.so — MCP Skills collection.
mcpsnoop is a transparent proxy for Model Context Protocol (MCP) that sits between your AI client (Claude Desktop, Cursor, Claude Code) and your MCP servers. Unlike the official MCP Inspector which connects as a separate client, mcpsnoop intercepts the actual traffic between your real client and server, showing every JSON-RPC frame live in your terminal.
Installation
Using Go
go install github.com/kerlenton/mcpsnoop/cmd/mcpsnoop@latest
Using Homebrew
brew tap kerlenton/mcpsnoop
brew install mcpsnoop
Pre-built Binaries
Download from the Releases page for your platform.
Core Concepts
mcpsnoop operates in two modes:
- Shim mode (
mcpsnoop -- <server-command>): Acts as a transparent proxy between client and server
- UI mode (
mcpsnoop): Displays the captured traffic in an interactive TUI
The shim and UI communicate via a well-known socket and on-disk logs, so they can start in any order.
Configuration
Stdio Transport (Most Common)
Wrap your server command in your MCP client's configuration file. For Claude Desktop, edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"my-server": {
"command": "mcpsnoop",
"args": ["--", "node", "build/index.js"]
}
}
}
Everything after -- is your normal server launch command.
Examples:
Python server:
{
"mcpServers": {
"weather": {
"command": "mcpsnoop",
"args": ["--", "python", "-m", "weather_server"]
}
}
}
TypeScript server with npx:
{
"mcpServers": {
"filesystem": {
"command": "mcpsnoop",
"args": ["--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed"]
}
}
}
Compiled binary:
{
"mcpServers": {
"custom": {
"command": "mcpsnoop",
"args": ["--", "/usr/local/bin/my-mcp-server", "--port", "8080"]
}
}
}
HTTP/SSE Transport
For servers using streamable HTTP, run mcpsnoop as a reverse proxy:
mcpsnoop http --target http://localhost:3000/mcp --listen :7000
Then point your client to http://localhost:7000.
Key Commands
CLI Commands
| Command | Description |
|---|
mcpsnoop | Launch the interactive TUI to view traffic |
mcpsnoop -- <cmd> | Wrap a server command (shim mode) |
mcpsnoop http | Start HTTP reverse proxy |
mcpsnoop demo | Run a scripted demo session |
mcpsnoop --help | Show all options |
TUI Keybindings
| Key | Action |
|---|
enter | Drill into frame details |
esc | Go back |
r | Replay selected tool call |
c | View capability negotiation |
y | Copy frame to clipboard |
/ | Enter filter mode |
: | Command mode |
p | Pause/unpause stream |
f | Follow mode (scroll to latest) |
ctrl-d | Delete session |
j/k | Move up/down |
ctrl-f/ctrl-b | Page forward/back |
g/G | Jump to top/bottom |
? | Show help |
Filtering Traffic
Press / in the TUI to filter frames. Combine tokens with spaces (ANDed):
Filter Syntax
tool:search status:slow # Slow calls to search tool
dir:s2c kind:req # Server-to-client requests
method:tools/call id:123 # Specific method and ID
status:error tool:database # Failed database tool calls
kind:notif # All notifications
dir:c2s status:pending # Pending client requests
Available Filters
- tool: Filter by tool name (e.g.,
tool:search, tool:write_file)
- method: JSON-RPC method (e.g.,
method:tools/call, method:initialize)
- id: Request/response ID
- kind:
req (request), resp (response), notif (notification)
- dir:
c2s (client-to-server), s2c (server-to-client)
- status:
ok, error, slow, pending
Plain text searches match method, tool name, ID, and payload content.
Common Patterns
Debugging a Tool That Isn't Being Called
- Configure mcpsnoop wrapper in your client
- Restart the client
- Open mcpsnoop TUI:
mcpsnoop
- Press
c to view capabilities
- Verify your tool is listed in server capabilities
- Check if client accepted the capability
- Use filter:
/tool:your_tool_name
- Attempt to use the tool in your client
- Look for
PENDING status (indicates hung call) or absence of call
Inspecting Capability Negotiation
mcpsnoop
Replaying a Tool Call
This is useful for:
- Testing fixes without restarting your client
- Comparing responses after code changes
- Debugging non-deterministic behavior
Monitoring Slow Tools
/status:slow
Debugging Server Stderr
Server stderr appears in the stream with special highlighting:
[STDERR] Warning: database connection slow
[STDERR] Error: timeout connecting to external API
Filter to see only stderr: /kind:notif
Real-World Examples
Example 1: Debugging a File System Server
{
"mcpServers": {
"filesystem": {
"command": "mcpsnoop",
"args": [
"--",
"npx",
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/dev/projects"
]
}
}
}
In TUI:
# Filter to file operations
/tool:read_file
# Or see all filesystem tools
/method:tools/call
# Check which directory was authorized
# Press 'c' for capabilities, look for "roots"
Example 2: Monitoring a Database Tool
{
"mcpServers": {
"database": {
"command": "mcpsnoop",
"args": ["--", "python", "db_server.py"],
"env": {
"DATABASE_URL": "postgresql://localhost/mydb"
}
}
}
}
In TUI:
# See only database queries
/tool:query
# Find slow queries
/status:slow tool:query
# Inspect a specific query
# Navigate with j/k, press enter to see full JSON
# Press 'y' to copy query details
Example 3: HTTP Server Debugging
python http_server.py --port 3000
mcpsnoop http --target http://localhost:3000/mcp --listen :7000
mcpsnoop
Example 4: Multi-Server Setup
{
"mcpServers": {
"weather": {
"command": "mcpsnoop",
"args": ["--", "python", "weather_server.py"]
},
"database": {
"command": "mcpsnoop",
"args": ["--", "node", "db-server.js"]
},
"filesystem": {
"command": "mcpsnoop",
"args": ["--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/home/user"]
}
}
}
The TUI shows all servers in separate sessions. Use :sessions command to switch between them.
Troubleshooting
UI Shows "No sessions"
Cause: Shim hasn't started or client hasn't launched the server yet.
Solution:
- Verify mcpsnoop is in your client config
- Restart your AI client completely
- Trigger an MCP action to start the server
- Wait a few seconds and refresh UI
Tool Call Hangs (Shows PENDING)
Symptoms: Request shows PENDING with increasing timer, no response.
Debug:
- Check server stderr in the frame list
- Press
enter on the PENDING frame to see full request
- Look for resource locks or external API timeouts
- Press
r to replay with debug logging
Server Not Starting
Check:
node build/index.js
which node
which mcpsnoop
Capabilities Mismatch
Symptoms: Client doesn't see tool server advertises.
Debug:
- Press
c in TUI
- Compare server capabilities vs client capabilities
- Check server's
initialize response
- Verify tool schema matches MCP spec
Frames Not Appearing in TUI
Check:
- Socket connection:
ls -la ~/.config/mcpsnoop/ (Linux/macOS)
- Log directory: Check for
.jsonl files
- Permissions: Ensure shim can write logs
- Try
mcpsnoop demo to verify TUI works
Replay Fails
Possible causes:
- Server has state dependencies
- External resources unavailable
- Non-idempotent operations
Solution:
Check stderr in replay output and compare request parameters.
Advanced Usage
Custom Log Directory
mcpsnoop --log-dir /custom/path
Filtering in Shim Mode
mcpsnoop --filter tool:search -- python server.py
Exporting Sessions
cat ~/.config/mcpsnoop/sessions/*.jsonl | jq .
Performance Considerations
- mcpsnoop adds minimal latency (microseconds for copying frames)
- Disk I/O is async and buffered
- Large payloads (>1MB) may slow down TUI rendering
- Use filters to reduce noise in busy systems
Integration with Development Workflow
During Development
code .
mcpsnoop
Testing Tools
CI/CD Integration
mcpsnoop logs are structured JSONL, suitable for automated testing:
mcpsnoop --log-dir ./test-logs -- python server.py &
jq 'select(.kind == "response" and .status == "error")' test-logs/*.jsonl
Resources