Open source · Developer tooling

MCP Payload Audit

Find what makes your MCP tool results large—without changing them.

A small Python CLI that reads saved tools/call responses, measures their size, and points to repeated data and large fields. Run it locally or put a byte budget in CI. No live server required.

How it works

Saved JSON in. A useful breakdown out.

Audit one result, or compare a baseline with a candidate. Both paths produce a text or JSON report; size and growth limits are opt-in.

Audit one saved result or compare before and after. Analyze compact UTF-8 bytes, text and structured mirrors, repeated structured subtrees, and largest encoded leaf values. Output text or JSON and optionally check budgets. No tool or model calls; no rewriting; bytes are not tokens.
Open full-size diagram Download editable Excalidraw

Four things the report makes visible

01 Response size
Compact UTF-8 bytes, separate from the original file’s formatting and JSON-RPC envelope.
02 Text / structured mirrors
Whole JSON values repeated in both text blocks and structuredContent.
03 Repeated subtrees
Repeated objects and arrays inside structured content, including copied rows or evidence.
04 Large leaf values
Encoded value sizes with JSON Pointer paths, so you can find the fields worth inspecting.

A small example

Synthetic fixture

The repository includes a deliberately repetitive result. Its rows appear again inside an evidence object, and a text block mirrors the structured data.

Command
mcp-payload-audit audit examples/mirrored.json --top 3
Abbreviated outputRead-only
Compact result: 4,879 bytes
Text/structured mirrors: 1 (informational)
Repeated structured subtrees: 3

2 occurrences × 907 value bytes:
  /structuredContent/evidence/normalized_result
  /structuredContent/rows

Largest encoded leaf value:
  /content/0/text — 2,922 bytes

These are measurements of the included synthetic fixture, not a production benchmark. Duplicate groups may overlap; adding their sizes would double-count data. Bytes are not tokens or promised savings.

Get started

Try it with a saved result

You’ll need Python 3.11 or newer and Git. Version 0.1.0 is an early-stage source release; it is not published to PyPI yet.

Install · macOS / Linux
git clone https://github.com/SiluPanda/mcp-payload-audit.git
cd mcp-payload-audit
python -m venv .venv

source .venv/bin/activate
python -m pip install .
mcp-payload-audit audit examples/mirrored.json

If your Python executable is named python3, use that when creating the environment. No API key, model download, or MCP server setup is needed.

Install on Windows (PowerShell)
Install · Windows
git clone https://github.com/SiluPanda/mcp-payload-audit.git
cd mcp-payload-audit
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install .
.\.venv\Scripts\mcp-payload-audit.exe audit examples/mirrored.json

No activation script is needed. Use .\.venv\Scripts\mcp-payload-audit.exe in place of mcp-payload-audit in the other examples.

Machine-readable output
mcp-payload-audit audit examples/mirrored.json --format json
Use the Python API instead
from mcp_payload_audit import analyze_result, loads_document

result = loads_document('{"content": [{"type": "text", "text": "hello"}]}')
report = analyze_result(result)
assert report["compact_result_bytes"] <= 65536

Make unexpected growth a CI failure

Set an absolute byte ceiling, or compare two results from the same representative workload. Both checks use compact result bytes—not file size.

Budget examples
# This included fixture passes a 64 KiB ceiling.
mcp-payload-audit audit examples/mirrored.json --max-bytes 65536

# This comparison deliberately exits 1: the candidate grew.
mcp-payload-audit compare examples/lean.json examples/mirrored.json --max-growth-percent 10 --max-bytes 65536

Replace these synthetic fixtures with your own sanitized captures. Keep workloads comparable and review baseline updates. The tool does not capture responses or assert that a smaller result is semantically complete.

CLI exit codes
CodeMeaning
0Configured budgets passed, or none were configured.
1A size or growth budget was exceeded.
2Invalid input or arguments, or an I/O error.

A size-budget pass does not prove the tool succeeded. A result with isError: true can still fit the budget; check behavior separately.

Small scope, explicit limits

The CLI accepts inputs up to 16 MiB, with depth, node-count, and expanded-path limits. Numeric comparisons use Python’s parsed representations, not arbitrary-precision decimals. See the measurement contract for the full definitions and edge cases.

Code, docs, and the drawing