Skip to main content
Glama

mcp-msgdump

Zero-dependency MCP server and CLI that proxies, inspects, and analyzes JSON-RPC message streams between MCP clients and servers.

A passive MCP proxy that lets you see every JSON-RPC message crossing the wire — in CI, headless environments, or embedded in test suites.

MIT License Python 3.11+

Quick Start

# Install (PyPI package coming soon — use git install for now)
pip install git+https://github.com/prasad-a-abhishek/mcp-msgdump.git

# Analyze a trace log
mcp-msgdump analyze /tmp/mcp_session.jsonl --format summary

# Run as an MCP proxy (all messages forwarded + logged to stderr)
mcp-msgdump proxy --target localhost:3000 --port 8080
# Library API
from mcp_msgdump import analyze_log, check_schemas, replay_session

report = analyze_log("/tmp/mcp_session.jsonl")
print(report.total_requests)       # e.g. 47
print(report.error_count)          # e.g. 3
print(report.tools_called)          # ['read_file', 'write_file', 'list_dir']

Why mcp-msgdump?

MCP server developers debugging transport issues and AI tooling integrators validating MCP server behavior in CI have no way to inspect, replay, or audit the JSON-RPC message stream without manual debugging or complex proxy setups. Existing tools either require a browser GUI (MCP Inspector), are tied to a specific visualization layer (mcp-reticle), or are too lightweight to be useful in headless/CI environments.

mcp-msgdump is the only zero-dependency, stdio-native MCP server that provides both proxy inspection and structured log analysis, usable in both interactive CLI sessions and automated CI pipelines.

Key Features

  • Zero dependencies — pure Python 3.11+ stdlib only; no pip install surprises

  • Two operating modes — proxy (pass-through with logging) and analysis (structured report from a log file)

  • MCP stdio server — exposes analyze_log, replay_session, and check_schemas as MCP tools

  • Structured output — JSON output for machine consumption, summary format for humans

  • CI-friendly — non-zero exit codes on malformed input, headless/stdin-safe, no GUI required

  • Schema auditing — detects dangerously untyped parameters, missing descriptions, and empty object types

CLI Reference

mcp-msgdump [--help]
mcp-msgdump analyze [FILE] [--format {summary,json}]
mcp-msgdump proxy --target HOST:PORT [--port PORT]

analyze subcommand

Parses a JSONL log file and emits a structured analysis report.

Flag

Description

FILE

Path to JSONL log file (use - for stdin)

--format summary

Human-readable summary to stdout (default)

--format json

Machine-readable JSON to stdout

Exit codes: 0 clean log, 1 file not found or malformed input.

proxy subcommand

Runs as a passive man-in-the-middle between an MCP client and server. All traffic is forwarded verbatim; every message is also emitted to stderr.

Flag

Description

--target HOST:PORT

Target MCP server address (required)

--port PORT

Listen port for the proxy (default: 8080)

Library API Reference

analyze_log(path: str) -> AnalysisReport

Parse a JSONL log file and return an AnalysisReport:

from mcp_msgdump import analyze_log

report = analyze_log("/tmp/session.jsonl")
assert report.total_requests == 47
assert report.error_count == 3
assert "read_file" in report.tools_called
assert report.schema_issues == []

check_schemas(path: str) -> list[SchemaIssue]

Validate tool schemas in a log file. Returns a list of issues:

from mcp_msgdump import check_schemas

issues = check_schemas("/tmp/session.jsonl")
for issue in issues:
    print(f"[{issue.severity.value}] {issue.tool_name}.{issue.parameter_name}: {issue.message}")

Issues detected:

  • type: string with no descriptiondangerously_untyped warning

  • type: object with no propertiesempty_object warning

  • Missing type annotation → missing_type error

  • Missing description on typed parameter → missing_description warning

replay_session(path: str, start_index: int = 0, filter_tool: str | None = None) -> list[ReplayResult]

Replay tool calls from a log file, optionally filtered:

from mcp_msgdump import replay_session

results = replay_session("/tmp/session.jsonl", filter_tool="read_file")
for r in results:
    print(f"#{r.index} {r.tool_name}: {r.params}")

Data Models

from mcp_msgdump import AnalysisReport, ReplayResult, SchemaIssue, ToolCall, Mismatch, Severity

# AnalysisReport fields:
report.total_requests    # int — count of JSON-RPC requests seen
report.error_count       # int — count of error responses
report.tools_called      # list[str] — unique tool names called
report.slowest_call     # ToolCall | None — slowest tool call by latency_ms
report.schema_mismatches # list[Mismatch] — schema mismatches (v1: always empty)
report.tool_calls        # list[ToolCall] — all tool call records
report.schema_issues     # list[SchemaIssue] — detected schema issues
report.batch_sub_requests # int — count of sub-requests inside batch arrays
report.empty_file       # bool — true if input was empty
report.malformed_lines   # int — count of unparseable lines

# ToolCall fields:
tc.method               # str — JSON-RPC method name (e.g. "tools/call")
tc.params              # dict — parameters passed to the tool
tc.id                  # int | str | None — request ID
tc.latency_ms          # float | None — latency in ms (set when response has duration)
tc.is_notification     # bool — true if id was null (no response expected)
tc.is_error            # bool — true if response contained an error
tc.error_message       # str | None — error message if is_error is True

# ReplayResult fields:
r.index                # int — position in the log
r.method               # str — JSON-RPC method name
r.params               # dict — parameters
r.response             # dict | None — response if available
r.skipped              # bool — true if filtered out by filter_tool
r.skip_reason          # str | None — reason if skipped

# SchemaIssue fields:
issue.tool_name        # str — name of the tool
issue.parameter_name   # str | None — affected parameter name
issue.issue_type       # str — e.g. "untyped", "dangerously_typed", "missing_description"
issue.message          # str — human-readable description
issue.severity         # Severity — Severity.WARNING or Severity.ERROR

# Mismatch fields:
m.tool_name            # str
m.field                # str
m.expected              # Any
m.actual               # Any
m.description          # str | None

Limitations

  • The proxy mode is a TCP socket proxy — it does not speak the MCP stdio protocol over the proxy itself (the proxy is for TCP-based MCP servers)

  • MCP stdio server mode only; HTTP/SSE transport is out of scope for v1

  • Streaming/chunked JSON-RPC is not supported in v1

  • No persistent storage — logs are written to a file or stdout, not internally buffered

  • No authentication, access control, or rate limiting

Non-Goals

  • Executing tools or making real network calls beyond forwarding to the proxy target

  • Visualization or GUI output

  • HTTP/SSE MCP server transport

  • Persistent internal log storage

  • Authentication or rate limiting

Test Suite

pytest -v

165 tests covering: proxy forwarding, log analysis, schema checking, replay, CLI parsing, MCP protocol, and zero-dependency enforcement.

MCP Client Configuration

mcp-msgdump is a stdio MCP server — point any MCP client at it to capture and analyze JSON-RPC traffic.

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "mcp-msgdump": {
      "command": "python",
      "args": ["-m", "mcp_msgdump", "analyze", "/path/to/session.jsonl"]
    }
  }
}

Cursor

Add to Cursor settings (JSON mode):

{
  "mcpServers": {
    "mcp-msgdump": {
      "command": "python",
      "args": ["-m", "mcp_msgdump", "analyze", "/path/to/session.jsonl"]
    }
  }
}

Windsurf

Add to Windsurf MCP settings:

{
  "mcpServers": {
    "mcp-msgdump": {
      "command": "python",
      "args": ["-m", "mcp_msgdump", "analyze", "/path/to/session.jsonl"]
    }
  }
}

Cline

Add to Cline MCP settings:

{
  "mcpServers": {
    "mcp-msgdump": {
      "command": "python",
      "args": ["-m", "mcp_msgdump", "analyze", "/path/to/session.jsonl"]
    }
  }
}

AGY

mcp_servers:
  mcp-msgdump:
    command: python
    args: ["-m", "mcp_msgdump", "analyze", "/path/to/session.jsonl"]

License

MIT — Prasad A Abhishek

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/prasad-a-abhishek/mcp-msgdump'

If you have feedback or need assistance with the MCP directory API, please join our Discord server