Skip to content

limijd/trace_claude

Repository files navigation

trace_claude

Intercept and visualize all communication between Claude Code CLI and the Anthropic API — requests, responses, and SSE streaming events.

中文文档

Web UI screenshot

Install Dependencies

pip3 install mitmproxy aiohttp

Quick Start

1. Start the proxy + Web UI

./bin/trace_claude listen

Output:

✓ Proxy listening on http://127.0.0.1:8000
✓ Web UI at http://127.0.0.1:8001
✓ Logs: sessions/session_20260329_112707.jsonl

  Run claude with:
    trace_claude_run claude -p "hello"

  Press Ctrl+C to stop.

2. Run Claude Code through the proxy (in another terminal)

./bin/trace_claude_run claude -p "hello"

trace_claude_run automatically sets ANTHROPIC_BASE_URL=http://127.0.0.1:8000 then execs your command. All Claude Code arguments work as usual:

# Interactive mode
./bin/trace_claude_run claude

# Specify model
./bin/trace_claude_run claude --model opus -p "explain this code"

# With tool restrictions
./bin/trace_claude_run claude --allowedTools "Read,Grep" -p "find all TODOs"

You can also skip trace_claude_run and set the environment variable manually:

ANTHROPIC_BASE_URL=http://127.0.0.1:8000 claude -p "hello"

3. Open the browser to view the event stream

Navigate to http://127.0.0.1:8001

Features:

  • Real-time timeline: API events displayed chronologically, new events auto-appended
  • Event type filtering: REQ (request), HDR (response headers), SSE (streaming events), RES (full response), END (stream end)
  • Click cards to expand/collapse JSON details
  • Auto-scroll toggle button
  • Expand All / Collapse All for batch operations
  • Clear to reset the display

Command Reference

trace_claude listen

trace_claude listen [--port PORT] [--web-port WEB_PORT] [--sessions-dir DIR]
Parameter Default Description
--port 8000 mitmproxy reverse proxy listen port
--web-port 8001 Web UI listen port
--sessions-dir ./sessions Directory for JSONL log files

trace_claude_run

trace_claude_run <command> [args...]

Injects ANTHROPIC_BASE_URL then executes the specified command. Use TRACE_CLAUDE_PORT to specify a non-default proxy port:

TRACE_CLAUDE_PORT=9000 ./bin/trace_claude_run claude -p "hello"

Running via python -m

# Equivalent to ./bin/trace_claude listen
python3 -m trace_claude listen

# trace_claude_run via module
python3 trace_claude/trace_claude_run.py claude -p "hello"

JSONL Log Format

Each listen session creates a session_YYYYMMDD_HHMMSS.jsonl file in the sessions/ directory. One JSON event per line:

{"ts":"...","type":"request","flow_id":"...","method":"POST","path":"/v1/messages","headers":{...},"body":{...}}
{"ts":"...","type":"response_headers","flow_id":"...","status_code":200,"headers":{...},"streaming":true}
{"ts":"...","type":"sse","flow_id":"...","event":"message_start","data":{...}}
{"ts":"...","type":"sse","flow_id":"...","event":"content_block_delta","data":{"delta":{"type":"text_delta","text":"Hello"}}}
{"ts":"...","type":"sse","flow_id":"...","event":"message_stop","data":{}}
{"ts":"...","type":"stream_end","flow_id":"..."}

Event Types

type Description
request Request sent to Anthropic API (headers + body)
response_headers Response headers arrived (includes streaming boolean)
sse A single SSE event from a streaming response
response Full response (non-streaming response body)
stream_end Streaming response finished

SSE Event Types (event field)

event Description
message_start Response started, contains model and input_tokens
content_block_start Content block started (text or tool_use)
content_block_delta Incremental content (text_delta or input_json_delta)
content_block_stop Content block ended
message_delta stop_reason, output_tokens
message_stop Response ended
ping Heartbeat

Analyzing Logs with jq

# View model and message count for all requests
jq 'select(.type=="request") | {model: .body.model, msgs: (.body.messages | length)}' sessions/*.jsonl

# Extract all text output
jq -r 'select(.type=="sse" and .event=="content_block_delta") | .data.delta.text // empty' sessions/*.jsonl

# View token usage
jq 'select(.type=="sse" and .event=="message_start") | .data.message.usage' sessions/*.jsonl
jq 'select(.type=="sse" and .event=="message_delta") | .data.usage' sessions/*.jsonl

# View all tool calls
jq 'select(.type=="sse" and .event=="content_block_start" and .data.content_block.type=="tool_use") | .data.content_block.name' sessions/*.jsonl

# Count SSE events by type
jq -r 'select(.type=="sse") | .event' sessions/*.jsonl | sort | uniq -c | sort -rn

Notes

  • The proxy uses mitmproxy reverse proxy mode. Client-to-proxy communication is HTTP (not HTTPS) — no certificate installation required
  • One proxy can serve multiple Claude Code instances simultaneously; traffic is distinguished by flow_id
  • JSONL files store full bodies without truncation (system prompts can be very long); use jq to filter as needed
  • API keys appear in request headers — be mindful of log file security

About

Intercept and visualize all communication between Claude Code CLI and the Anthropic API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors