Show HN: JSON-RPC Debugger. Pause, inspect, and modify calls in real-time

4 months ago 15

A terminal-based JSON-RPC debugger with interception capabilities, built with Rust and ratatui. Inspect, modify, and debug JSON-RPC requests and responses in real-time.

Demo video of pointing metamask JSON-RPC at the debugger:

Screen.Recording.2025-06-03.at.3.44.25.PM.mov
  • 🔍 Real-time monitoring of JSON-RPC requests and responses with timing information
  • ⏸️ Request interception - pause, inspect, and modify requests before forwarding
  • 🎨 Syntax highlighting for JSON content with proper indentation
  • 📊 HTTP headers display for debugging transport details
  • ⌨️ Vim-style navigation with comprehensive keyboard shortcuts
  • 🎯 Dynamic configuration - change target URL and port on the fly
  • 📝 External editor support for request/response modification
  • 📋 Table view with status, transport, method, ID, and duration columns
  • 🔄 Custom response creation for intercepted requests
cargo install jsonrpc-debugger
cargo install --git https://github.com/shanejonas/jsonrpc-debugger
git clone https://github.com/shanejonas/jsonrpc-debugger.git cd jsonrpc-debugger cargo build --release

Start the debugger with default settings (port 8080, no default target):

jsonrpc-debugger # or during development: cargo run
# Custom port jsonrpc-debugger --port 9090 # Custom target URL jsonrpc-debugger --target https://your-api.com # Both custom port and target jsonrpc-debugger --port 9090 --target https://your-api.com # Show help jsonrpc-debugger --help

Once the debugger is running, send JSON-RPC requests to the proxy:

curl -X POST http://localhost:8080 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"your_method","params":[],"id":1}'

The TUI is divided into three main sections:

┌─ Status ─────────────────────────────────────────────────────────────────────────────┐ │ JSON-RPC Debugger | Status: RUNNING | Port: 8080 | Target: https://api.example.com │ └──────────────────────────────────────────────────────────────────────────────────────┘ ┌─ JSON-RPC ────────────────────────────┐ ┌─ Details ──────────────────────────────────┐ │ Status │Transport│Method │ID│Dur│ │ Transport: Http │ │ ✓ Success │ HTTP │ eth_call │1 │45m│ │ Method: eth_call │ │ ✗ Error │ HTTP │ eth_send │2 │12m│ │ ID: 1 │ │⏳ Pending │ HTTP │ eth_block│3 │11m│ │ │ │ │ │ REQUEST: │ │ │ │ HTTP Headers: │ │ │ │ content-type: application/json │ │ │ │ │ │ │ │ JSON-RPC Request: │ │ │ │ { │ │ │ │ "jsonrpc": "2.0", │ │ │ │ "method": "eth_call", │ │ │ │ "params": [...], │ │ │ │ "id": 1 │ │ │ │ } │ └───────────────────────────────────────┘ └────────────────────────────────────────────┘ ┌─ Controls ───────────────────────────────────────────────────────────────────────────┐ │ q quit | ↑↓/^n/^p navigate | j/k/d/u/G/g scroll | s start/stop | t target | p pause │ └──────────────────────────────────────────────────────────────────────────────────────┘
  • Success - Request completed successfully
  • Error - Request returned an error
  • Pending - Request sent, waiting for response
  • ↑/↓ or Ctrl+p/Ctrl+n - Navigate between requests
  • j/k - Scroll details panel up/down (vim-style)
  • d/u or Ctrl+d/Ctrl+u - Page down/up in details
  • G - Go to bottom of details
  • g - Go to top of details
  • s - Start/stop the proxy server
  • t - Edit target URL
  • c - Create new request (normal mode) / Complete request with custom response (intercept mode)
  • q - Quit application
  • p - Toggle pause mode (intercept new requests)
  • a - Allow selected intercepted request
  • e - Edit selected request body in external editor
  • h - Edit selected request headers in external editor
  • c - Complete request with custom response
  • b - Block selected request
  • r - Resume all pending requests

The debugger supports Charles Proxy-style request interception:

  1. Enable pause mode: Press p to start intercepting requests
  2. Make requests: Send JSON-RPC requests to the proxy
  3. Inspect: Intercepted requests appear in the pending list with ⏸ icon
  4. Modify:
    • Press e to edit request body in your external editor
    • Press h to edit HTTP headers
    • Press c to create a custom response
  5. Control: Press a to allow, b to block, or r to resume all

The debugger uses your system's default editor for request modification:

  • Checks $EDITOR environment variable
  • Falls back to $VISUAL
  • Defaults to vim, then nano, then vi

Modified requests show with a ✏ icon and [MODIFIED] or [BODY]/[HEADERS] labels.

  • EDITOR - Preferred text editor for request modification
  • VISUAL - Alternative editor (fallback)

Some ports may conflict with system services:

  • Port 7000: Used by Apple AirPlay on macOS
  • Port 5000: Often used by other development tools

Use alternative ports like 8080, 9090, 3000, 4000, 8000, or 8888.

# Start debugger jsonrpc-debugger --port 8080 # Set target URL in the TUI (press 't') # Then make requests in another terminal curl -X POST http://localhost:8080 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
  1. Start the debugger: jsonrpc-debugger
  2. Set target URL: Press t and enter your target
  3. Enable pause mode: Press p
  4. Make a request (it will be intercepted)
  5. Edit the request: Press e to modify body or h for headers
  6. Allow the modified request: Press a
  1. Enable pause mode and intercept a request
  2. Press c to create a custom response
  3. Edit the JSON response in your external editor
  4. The custom response is sent back to the client
  1. Press c in normal mode
  2. Edit the JSON-RPC request template in your external editor
  3. The request is sent through the proxy to the target

If you get a "port already in use" error:

# Check what's using the port netstat -an | grep :8080 # Use a different port jsonrpc-debugger --port 9090

If requests fail with "connection refused":

  • Check that the target URL is correct and reachable
  • Verify the target server is running
  • Test the target directly with curl
  • Make sure you've set a target URL (press t in the TUI)

If external editing fails:

# Set your preferred editor export EDITOR=code # VS Code export EDITOR=nano # Nano export EDITOR=vim # Vim

The debugger displays JSON with:

  • 2-space indentation
  • Syntax highlighting (keys in cyan, strings in green, numbers in blue, etc.)
  • Proper line breaks and formatting

If JSON appears malformed, check that the original request/response is valid JSON.

# Debug build cargo build # Release build cargo build --release
src/ ├── main.rs # CLI and main application loop ├── app.rs # Application state and logic ├── ui.rs # TUI rendering and layout ├── proxy.rs # HTTP proxy server implementation └── lib.rs # Library exports for testing

MIT License - see LICENSE file for details.

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request
  • Built with ratatui for the terminal UI
  • Uses warp for the HTTP proxy server
  • Inspired by Charles Proxy and similar debugging tools
Read Entire Article