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.
- 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
Spacefor 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
.protofiles are provided - Process identification — See which OS process initiated each request (best with sudo)
- Persistent settings — Configure defaults in
~/.httpmon/config.jsonor via the TUI settings screen (P) - Keyboard-driven — Vim-style navigation throughout — no mouse required
brew install kostyay/tap/httpmongo install github.com/kostyay/httpmon/cmd/httpmon@latestgit clone https://github.com/kostyay/httpmon.git
cd httpmon
make build
./httpmonhttpmon # 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 versionThen configure your browser or app to use http://localhost:8080 as its HTTP proxy.
The easiest way — run once with sudo:
sudo httpmon --install-caThis 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.pemLinux:
sudo cp ~/.httpmon/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/httpmon.crt
sudo update-ca-certificatesScripts are JavaScript files stored in ~/.httpmon/scripts/. Each script has a YAML frontmatter header and exports onRequest and/or onResponse hooks.
// ---
// 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
}| Field | Description |
|---|---|
name |
Display name (required) |
match |
URL patterns to match — * wildcards supported (required) |
enabled |
true or false — defaults to true if omitted |
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 |
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.
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.
Simulate slow network conditions. Throttling applies to all response bodies.
| 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 |
httpmon --throttle 3g # Apply 3G preset
httpmon --throttle wifi --latency 200ms # WiFi bandwidth + custom latencyPress 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.
Serve local files instead of fetching from upstream. Map Local is implemented through the scripting system using ctx.respondWith({file}).
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.
// ---
// 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.
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.
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 let you pause requests or responses mid-flight and edit them interactively in the TUI before they continue.
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
}
}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.
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").
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
httpmon includes an MCP (Model Context Protocol) server so LLM agents can programmatically inspect and debug HTTP traffic.
httpmon --mcp # Start on default addr (127.0.0.1:9551)
httpmon --mcp --mcp-addr :9600 # Custom addresshttpmon --mcp-tokenclaude mcp add --transport http httpmon http://127.0.0.1:9551/mcp \
--header "Authorization: Bearer $(httpmon --mcp-token)"| 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 |
Press ? anywhere for the full help overlay, or Space for a context-aware action menu.
| 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 |
| 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 |
| Key | Action |
|---|---|
S |
Scripts manager |
T |
Throttle settings |
B |
Breakpoints queue |
P |
Settings |
? |
Help overlay |
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.
make all # lint + test + build
make test # tests with race detection
make lint # golangci-lint
make security # gosec, govulncheck, gitleaks, trufflehog
