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.
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.
// ---
// 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 |
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
claude 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 |
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