# Mcpsnoop MCP Debugging

> Debug MCP client-server traffic in real-time using mcpsnoop, a transparent proxy for Model Context Protocol communications

- Skill: `aradotso/mcpsnoop-mcp-debugging` (Agent Skill)
- Install (CLI): `npx skillmds@latest add aradotso/mcpsnoop-mcp-debugging`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aradotso/mcpsnoop-mcp-debugging/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: aradotso (https://skillmd.com/u/aradotso)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/aradotso/mcpsnoop-mcp-debugging

---


# mcpsnoop MCP Debugging Skill

> Skill by [ara.so](https://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

```bash
go install github.com/kerlenton/mcpsnoop/cmd/mcpsnoop@latest
```

### Using Homebrew

```bash
brew tap kerlenton/mcpsnoop
brew install mcpsnoop
```

### Pre-built Binaries

Download from the [Releases page](https://github.com/kerlenton/mcpsnoop/releases) for your platform.

## Core Concepts

mcpsnoop operates in two modes:

1. **Shim mode** (`mcpsnoop -- <server-command>`): Acts as a transparent proxy between client and server
2. **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):

```json
{
  "mcpServers": {
    "my-server": {
      "command": "mcpsnoop",
      "args": ["--", "node", "build/index.js"]
    }
  }
}
```

Everything after `--` is your normal server launch command.

**Examples:**

Python server:
```json
{
  "mcpServers": {
    "weather": {
      "command": "mcpsnoop",
      "args": ["--", "python", "-m", "weather_server"]
    }
  }
}
```

TypeScript server with npx:
```json
{
  "mcpServers": {
    "filesystem": {
      "command": "mcpsnoop",
      "args": ["--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed"]
    }
  }
}
```

Compiled binary:
```json
{
  "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:

```bash
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

1. Configure mcpsnoop wrapper in your client
2. Restart the client
3. Open mcpsnoop TUI: `mcpsnoop`
4. Press `c` to view capabilities
5. Verify your tool is listed in server capabilities
6. Check if client accepted the capability
7. Use filter: `/tool:your_tool_name`
8. Attempt to use the tool in your client
9. Look for `PENDING` status (indicates hung call) or absence of call

### Inspecting Capability Negotiation

```bash
# Start your client with mcpsnoop wrapper
# Open TUI
mcpsnoop

# Press 'c' to view capabilities screen
# Navigate between:
# - Client capabilities (what the AI client supports)
# - Server capabilities (what your server advertises)
# - Handshake details
```

### Replaying a Tool Call

```bash
# In TUI, navigate to a tools/call request
# Press 'r' to replay
# mcpsnoop spawns a fresh isolated server instance
# Executes the exact same call
# Shows the new response
```

This is useful for:
- Testing fixes without restarting your client
- Comparing responses after code changes
- Debugging non-deterministic behavior

### Monitoring Slow Tools

```bash
# In TUI
/status:slow

# Shows only slow calls (threshold configurable)
# Each frame shows elapsed time
# PENDING calls show live timer
```

### 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

```json
{
  "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

```json
{
  "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

```bash
# Terminal 1: Start your HTTP MCP server
python http_server.py --port 3000

# Terminal 2: Start mcpsnoop proxy
mcpsnoop http --target http://localhost:3000/mcp --listen :7000

# Terminal 3: View traffic
mcpsnoop

# Configure client to connect to http://localhost:7000
```

### Example 4: Multi-Server Setup

```json
{
  "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:**
1. Verify mcpsnoop is in your client config
2. Restart your AI client completely
3. Trigger an MCP action to start the server
4. Wait a few seconds and refresh UI

### Tool Call Hangs (Shows PENDING)

**Symptoms:** Request shows `PENDING` with increasing timer, no response.

**Debug:**
1. Check server stderr in the frame list
2. Press `enter` on the PENDING frame to see full request
3. Look for resource locks or external API timeouts
4. Press `r` to replay with debug logging

### Server Not Starting

**Check:**
```bash
# Test server command directly
node build/index.js  # Or your actual command

# Check mcpsnoop can find the command
which node
which mcpsnoop

# Look at client logs
# Claude Desktop: ~/Library/Logs/Claude/
```

### Capabilities Mismatch

**Symptoms:** Client doesn't see tool server advertises.

**Debug:**
1. Press `c` in TUI
2. Compare server capabilities vs client capabilities
3. Check server's `initialize` response
4. Verify tool schema matches MCP spec

### Frames Not Appearing in TUI

**Check:**
1. Socket connection: `ls -la ~/.config/mcpsnoop/` (Linux/macOS)
2. Log directory: Check for `.jsonl` files
3. Permissions: Ensure shim can write logs
4. 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

```bash
mcpsnoop --log-dir /custom/path
```

### Filtering in Shim Mode

```bash
# Only log specific tools (reduces disk usage)
mcpsnoop --filter tool:search -- python server.py
```

### Exporting Sessions

```bash
# Sessions are stored as JSONL
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

```bash
# Terminal 1: Your editor/IDE
code .

# Terminal 2: mcpsnoop TUI
mcpsnoop

# Terminal 3: Test client or manual testing
# Make changes to server code
# Restart client or use replay feature to test immediately
```

### Testing Tools

```bash
# Capture a successful tool call
# Press 'y' to copy JSON
# Paste into your test suite as expected output

# Replay with modified server code
# Press 'r' repeatedly while iterating
```

### CI/CD Integration

mcpsnoop logs are structured JSONL, suitable for automated testing:

```bash
# Run test, capture logs
mcpsnoop --log-dir ./test-logs -- python server.py &
# Run your MCP client test
# Parse logs
jq 'select(.kind == "response" and .status == "error")' test-logs/*.jsonl
```

## Resources

- [MCP Specification](https://spec.modelcontextprotocol.io/)
- [mcpsnoop GitHub](https://github.com/kerlenton/mcpsnoop)
- [MCP Inspector](https://github.com/modelcontextprotocol/inspector) (alternative tool)
- [Demo Walkthrough](https://github.com/kerlenton/mcpsnoop/blob/main/docs/DEMO.md)

