Skip to content

kostyay/httpmon

Repository files navigation

httpmon

Docs Website

Terminal-native HTTP/HTTPS debugging proxy. Intercept, inspect, and filter traffic — all from your terminal with vim-style navigation.

Think Proxyman or Charles, but in your terminal.

httpmon demo

Features

  • MITM proxy — Intercept HTTP and HTTPS traffic with auto-generated CA certificates
  • Live flow list — Watch requests stream in real-time with color-coded methods and status codes
  • Tree view — Group flows by host or process, expand/collapse, focus on a single group
  • Detail inspector — Headers, syntax-highlighted bodies, collapsible sections, image preview
  • Action menu — Press Space for a context-aware command popup — no memorization needed
  • Quick filter/ to filter by host, path, method, status code, or content type
  • HAR export — Export all flows or a single flow to HAR format
  • Request tools — Compose new requests, repeat captured ones, copy as cURL
  • Diff view — Mark two flows and compare request/response side-by-side
  • Host filtering — Block or allow hosts at the proxy layer with wildcard patterns
  • Scripting — JavaScript hooks to modify requests/responses on the fly
  • Breakpoints — Pause and edit requests/responses mid-flight via script hooks
  • Bandwidth throttling — Simulate 3G/4G/WiFi network conditions
  • Map Local — Serve local files instead of upstream responses (via scripting)
  • Protobuf / gRPC-Web — Decode and display protobuf and gRPC-Web bodies as JSON when .proto files are provided
  • Process identification — See which OS process initiated each request (best with sudo)
  • Persistent settings — Configure defaults in ~/.httpmon/config.json or via the TUI settings screen (P)
  • Keyboard-driven — Vim-style navigation throughout — no mouse required

Quick Start

Homebrew (macOS/Linux)

brew install kostyay/tap/httpmon

Install from source

go install github.com/kostyay/httpmon/cmd/httpmon@latest

Build locally

git clone https://github.com/kostyay/httpmon.git
cd httpmon
make build
./httpmon

Usage

httpmon                          # Start proxy on :8080
httpmon --port 9090              # Custom port
httpmon --buffer-size 5000       # Max flows in memory (default 10000)
httpmon --data-dir ~/my-httpmon  # Custom data directory (default ~/.httpmon)
httpmon --block "*.ads.com"      # Block hosts matching pattern
httpmon --allow "api.example.*"  # Only intercept matching hosts
httpmon --throttle 3g            # Simulate 3G network (750 kbps)
httpmon --throttle 4g            # Simulate 4G network (4 Mbps)
httpmon --latency 100ms          # Add 100ms latency to responses
httpmon --proto-path ./protos    # Load .proto files for protobuf decoding
httpmon --proto-include ./inc    # Protoc -I style import paths
httpmon --mcp                    # Start with MCP server enabled
httpmon --mcp-token              # Print MCP bearer token
httpmon --install-ca             # Install CA cert into system trust store (needs sudo)
httpmon --version                # Print version

Then configure your browser or app to use http://localhost:8080 as its HTTP proxy.

Trust the CA certificate

The easiest way — run once with sudo:

sudo httpmon --install-ca

This generates the CA cert (if it doesn't exist yet) and adds it to your system trust store. Supports macOS and Linux.

Manual installation

macOS:

sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain ~/.httpmon/mitmproxy-ca-cert.pem

Linux:

sudo cp ~/.httpmon/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/httpmon.crt
sudo update-ca-certificates

Scripting

Scripts are JavaScript files stored in ~/.httpmon/scripts/. Each script has a YAML frontmatter header and exports onRequest and/or onResponse hooks.

Script format

// ---
// name: Add Auth Header
// match:
//   - "*://api.example.com/*"
// enabled: true
// ---

function onRequest(ctx) {
  ctx.headers["Authorization"] = "Bearer my-token";
}

function onResponse(ctx) {
  // ctx.status, ctx.headers, ctx.body
}

Header fields

Field Description
name Display name (required)
match URL patterns to match — * wildcards supported (required)
enabled true or false — defaults to true if omitted

Hooks

onRequest(ctx) — runs before the request is sent upstream.

Field Type Description
ctx.method string HTTP method (read/write)
ctx.url string Full URL (read/write)
ctx.headers object Request headers (read/write)
ctx.body string Request body (read/write)
ctx.blocked bool Set to true to block the request
ctx.respondWith(opts) function Short-circuit with a synthetic response (see below)
ctx.breakpoint() function Pause execution for interactive editing in the TUI
ctx.readFile(path) function Read a file relative to the script directory

onResponse(ctx) — runs before the response reaches the client.

Field Type Description
ctx.status int Status code (read/write)
ctx.headers object Response headers (read/write)
ctx.body string Response body (read/write)
ctx.respondWith(opts) function Replace the response entirely
ctx.breakpoint() function Pause execution for interactive editing in the TUI
ctx.readFile(path) function Read a file relative to the script directory

ctx.respondWith(opts)

Short-circuit a request with a synthetic response, or replace a response entirely. Accepts an options object:

// Return a custom body
ctx.respondWith({
  status: 200,
  body: '{"mocked": true}',
  headers: { "Content-Type": "application/json" }
});

// Serve a local file (content type inferred from extension)
ctx.respondWith({
  file: "mock-response.json"
});

When called in onRequest, it halts script execution and returns the response immediately without contacting the upstream server. This is the mechanism behind Map Local — serving local files instead of upstream responses.

Managing scripts

Press S in the TUI to open the scripts manager. From there:

  • Space — Toggle a script on/off
  • n — Create a new script from template (opens in $EDITOR)
  • e — Edit selected script in $EDITOR
  • m — Quick-add a Map Local rule (pattern + local file path)
  • d — Delete a script (with confirmation)

Scripts are reloaded each time the manager opens. Scripts are tagged with category badges (Script, Map Local, Breakpoint) based on which APIs they use.

Throttle

Simulate slow network conditions. Throttling applies to all response bodies.

Presets

Preset Bandwidth Latency
3g 750 kbps (93,750 B/s) 100ms
4g 4 Mbps (500,000 B/s) 50ms
wifi 30 Mbps (3,750,000 B/s) 5ms

CLI

httpmon --throttle 3g             # Apply 3G preset
httpmon --throttle wifi --latency 200ms  # WiFi bandwidth + custom latency

TUI

Press T to open the throttle modal. Select a preset with j/k and press Enter to apply. The active preset shows in the status bar.

Map Local

Serve local files instead of fetching from upstream. Map Local is implemented through the scripting system using ctx.respondWith({file}).

Quick add via TUI

Press S to open the scripts manager, then m to add a Map Local rule. Enter a URL pattern and a local file path — httpmon generates a script that serves the file for matching requests.

Manual script

// ---
// name: Mock API Config
// match:
//   - "*://api.example.com/config*"
// enabled: true
// ---

function onRequest(ctx) {
  ctx.respondWith({
    file: "config.json",   // relative to script directory
    status: 200             // optional, defaults to 200
  });
}

Scripts tagged with ctx.respondWith() show a Map Local badge in the scripts manager.

Protobuf / gRPC-Web

httpmon can decode protobuf and gRPC-Web response/request bodies into readable JSON when you supply .proto files.

httpmon --proto-path ./protos              # Single dir or file
httpmon --proto-path ./a --proto-path ./b  # Multiple paths
httpmon --proto-include ./vendor           # Import search dirs (like protoc -I)

Proto paths persist in ~/.httpmon/config.json. When a request/response has a matching content type (application/grpc-web, application/grpc-web+proto, application/x-protobuf), the body is automatically decoded and displayed as JSON in the detail view.

Per-host proto registries

For services that use different .proto definitions, configure per-host registries in ~/.httpmon/config.json:

{
  "proto_hosts": {
    "api.example.com": {
      "paths": ["./protos/example"],
      "includes": ["./protos/common"]
    },
    "*.internal.dev": {
      "paths": ["./protos/internal"]
    }
  }
}

Host patterns support * wildcards. Per-host registries take precedence over the global proto_paths for matching hosts.

Breakpoints

Breakpoints let you pause requests or responses mid-flight and edit them interactively in the TUI before they continue.

Adding breakpoints via scripts

Use ctx.breakpoint() in a script hook to pause execution:

// ---
// name: Debug API Calls
// match:
//   - "*://api.example.com/*"
// enabled: true
// ---

function onRequest(ctx) {
  ctx.breakpoint(); // Pauses here — edit headers/body in the TUI
}

function onResponse(ctx) {
  if (ctx.status >= 400) {
    ctx.breakpoint(); // Pause on errors
  }
}

TUI

Press B to open the breakpoints queue. When a breakpoint is hit, you can edit headers and body before resuming the flow. Scripts using ctx.breakpoint() show a Breakpoint badge in the scripts manager.

Process Identification

httpmon identifies which OS process originated each proxied request. The PROCESS column appears in the flow list, and tree mode (t) can group by process instead of host.

Works out of the box; run with sudo for full resolution accuracy. Configure tree grouping via the settings screen (P) or ~/.httpmon/config.json (TreeGroupBy: "process").

Settings

Persistent configuration is stored in ~/.httpmon/config.json (created on first run). CLI flags override config values for that session.

Press P in the TUI to open the settings screen where you can edit:

  • Proxy port, buffer size
  • MCP enabled/address
  • Throttle preset
  • List mode (flat/tree), tree group by (host/process)
  • Proto paths and import dirs

MCP Server

httpmon includes an MCP (Model Context Protocol) server so LLM agents can programmatically inspect and debug HTTP traffic.

Start the MCP server

httpmon --mcp                        # Start on default addr (127.0.0.1:9551)
httpmon --mcp --mcp-addr :9600       # Custom address

Get the bearer token

httpmon --mcp-token

Configure Claude Code

claude mcp add --transport http httpmon http://127.0.0.1:9551/mcp \
  --header "Authorization: Bearer $(httpmon --mcp-token)"

Available tools

Tool Description
list_requests List captured HTTP flows with optional filter
get_request Get full request/response details
search_requests Search flows by substring
get_request_count Count flows matching a filter
export_har Export flows as HAR 1.2 JSON
set_throttle Set bandwidth throttling (3g/4g/wifi presets)
get_throttle Get current throttle settings
replay_request Replay a captured request or compose a new one
mock_response Mock a response for matching URLs
list_scripts List scripting hooks
create_script Create a new script
get_script Get script source
toggle_script Enable/disable a script
delete_script Remove a script

Keyboard Shortcuts

Press ? anywhere for the full help overlay, or Space for a context-aware action menu.

Flow List

Key Action
j / k Navigate up/down
g / G Jump to first/last
Ctrl+D / Ctrl+U Page down/up
Enter Open flow detail
t Cycle flat → host tree → process tree
f Focus group (tree mode)
l / h Expand/collapse group (tree mode)
/ Focus filter bar
Space Open action menu
x Export HAR
C Compose request
d Mark for diff
q Quit

Detail View

Key Action
1 / 2 Request/Response tab
j / k Scroll up/down
d / u Half-page down/up
n / N Next/previous flow
p Toggle pretty/raw
e Open body in external editor
i Toggle image preview
g / h / b Collapse general/headers/body
/ Search in content
Space Open action menu
x Export HAR
c Copy as cURL
r Repeat request
Esc Back to list

Global

Key Action
S Scripts manager
T Throttle settings
B Breakpoints queue
P Settings
? Help overlay

Architecture

cmd/httpmon/          CLI entry point, flag parsing, wiring
internal/proxy/       MITM proxy engine (go-mitmproxy wrapper)
internal/store/       Thread-safe ring buffer for captured flows
internal/tui/         Bubble Tea terminal UI (list, detail, menu, compose, diff, export)
internal/filter/      Quick filter + advanced filter expressions
internal/hostfilter/  Wildcard-based host block/allow at proxy layer
internal/har/         HAR 1.2 export
internal/diff/        Flow diff engine
internal/highlight/   Syntax highlighting for response/request bodies
internal/certutil/    CA certificate generation and system trust installation
internal/throttle/    Bandwidth throttling (wraps io.Reader with rate limiting)
internal/scripting/   JavaScript scripting hooks (goja runtime, YAML frontmatter, map local, breakpoints)
internal/breakpoint/  Breakpoint controller for pausing and editing flows mid-flight
internal/bodydecoder/ Wire format decoding (protobuf, gRPC-Web, per-host proto registries)
internal/config/      Persistent settings (~/.httpmon/config.json)
internal/procinfo/    Process identification for proxied requests
internal/mcpserver/   MCP server for LLM-driven debugging

Built with go-mitmproxy and Bubble Tea.

Contributing

make all        # lint + test + build
make test       # tests with race detection
make lint       # golangci-lint
make security   # gosec, govulncheck, gitleaks, trufflehog

License

MIT

About

Terminal-native HTTP/HTTPS debugging proxy with MITM intercept, ring buffer store, and Bubble Tea TUI

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors