CLI Reference
Laurel Proxy is controlled entirely from the command line. Running laurel-proxy with no arguments launches an interactive terminal menu. All commands follow the pattern:
laurel-proxy <command> [options]start
Start the proxy server in the foreground.
laurel-proxy start [options]| Option | Default | Description |
|---|---|---|
--port <number> | 8080 | Proxy listening port |
--ui-port <number> | 8081 | Web UI and API port |
--db-path <path> | ~/.laurel-proxy/data.db | SQLite database location |
# Default ports
laurel-proxy start
# Custom ports
laurel-proxy start --port 9000 --ui-port 9001
# Custom database location
laurel-proxy start --db-path /tmp/proxy.dbThe process writes its PID to ~/.laurel-proxy/pid and responds toSIGINT/SIGTERM for graceful shutdown.
stop
Stop the running proxy server.
laurel-proxy stop [options]| Option | Default | Description |
|---|---|---|
--ui-port <number> | 8081 | API port to send shutdown request to |
Sends a graceful shutdown request via the API. Falls back to SIGTERM via the PID file if the API is unreachable.
laurel-proxy stop
laurel-proxy stop --ui-port 9001status
Show proxy status.
laurel-proxy status [options]| Option | Default | Description |
|---|---|---|
--ui-port <number> | 8081 | API port to query |
laurel-proxy statusExample output:
Status Running
Proxy port 8080
Requests 142
DB Size 3.2MBrequests
Query captured requests from the database. This is the most powerful command in Laurel Proxy.
laurel-proxy requests [options]| Option | Default | Description |
|---|---|---|
--host <pattern> | Filter by hostname (substring match) | |
--status <code> | Filter by HTTP status code | |
--method <method> | Filter by HTTP method | |
--kind <kind> | Filter by request kind: http or websocket. An unrecognised kind is an error. Also works with --tail | |
--client-protocol <protocol> | Filter by client-hop wire protocol: http/1.1 or h2. Exact match, no NULL fallback. An unrecognised value is an error. Also works with --tail | |
--origin-protocol <protocol> | Filter by origin-hop wire protocol: http/1.1 or h2. Same semantics as --client-protocol, and combinable with it | |
--search <pattern> | Search URLs (substring match) | |
--since <time> | After this time (Unix ms or ISO date) | |
--until <time> | Before this time (Unix ms or ISO date) | |
--limit <n> | 100 | Maximum number of results |
--format <format> | table | Output format: table, json, or agent |
--tail | Stream new requests in real-time (interactive TUI) | |
--ui-port <number> | 8081 | UI/API port (used with --tail) |
--db-path <path> | ~/.laurel-proxy/data.db | Database location |
Filter aliases
Shorthand flags for common queries:
| Alias | Description |
|---|---|
--failed | Show only 4xx and 5xx responses |
--last-hour | Requests from the last hour |
--last-day | Requests from the last 24 hours |
--slow <ms> | Requests slower than threshold (in milliseconds) |
Output formats
The default output is a human-readable table. Use --format json for piping to jq or feeding to scripts. Use --format agent for LLM-optimized output that is compact and structured for AI consumption.
In table format, an h2 client hop is tagged with a magenta H2 next to the method, the same "only the non-default is worth a badge" approach as the WebSocketWS marker (the two never co-occur, since a WebSocket's client hop is always HTTP/1.1). Every format also carries client_protocol/origin_protocol -- see HTTP/2 Support for the full field reference.
Examples
# All 500 errors
laurel-proxy requests --status 500
# POST requests to a specific host
laurel-proxy requests --host api.example.com --method POST
# Search URLs
laurel-proxy requests --search "/api/v2"
# Limit results
laurel-proxy requests --format table --limit 20
# Time-bounded query
laurel-proxy requests --since "2024-01-15T00:00:00Z" --until "2024-01-16T00:00:00Z"
# JSON for piping to jq
laurel-proxy requests --format json --host stripe.com | jq '.data[].url'
# LLM-optimized output
laurel-proxy requests --format agent --failed
# Only WebSocket connections (handshakes appear as ordinary rows, tagged with a WS marker)
laurel-proxy requests --kind websocket --format agent
# HTTP/2 exchanges, and the mixed-hops case (h2 client, HTTP/1.1 origin)
laurel-proxy requests --client-protocol h2 --format agent
laurel-proxy requests --client-protocol h2 --origin-protocol http/1.1 --format agent
# Only failed requests from the last hour
laurel-proxy requests --failed --last-hour
# Slow requests from the last day
laurel-proxy requests --slow 1000 --last-day
# Combine aliases with other filters
laurel-proxy requests --failed --host api.example.com --last-hourReal-time tailing
The --tail flag launches an interactive terminal UI that streams new requests as they arrive:
# Tail all traffic (auto-starts proxy + system proxy if needed)
laurel-proxy requests --tail
# Tail with filters
laurel-proxy requests --host todoist.com --tail
laurel-proxy requests --status 500 --tail
laurel-proxy requests --method POST --host api.example.com --tailWhat --tail does automatically:
- Starts the proxy if it is not already running
- Enables the macOS system proxy so all traffic routes through Laurel Proxy
- Opens an interactive TUI with arrow-key navigation
- On quit (
Ctrl+C), disables the system proxy and stops the proxy it started
TUI keyboard shortcuts
| Key | Action |
|---|---|
Up / Down | Navigate requests |
Enter | View full request detail (headers, body) |
Esc | Back to list from detail view |
g / G | Jump to top (newest) / bottom (oldest) |
Ctrl+C | Quit (cleans up proxy and system proxy) |
New requests auto-scroll to the top. Scrolling down disables auto-scroll; pressing g re-enables it.
To get raw JSON streaming instead of the TUI, use --format json --tail.
request
Show full details of a single captured request, including headers and bodies.
laurel-proxy request <id> [options]| Option | Default | Description |
|---|---|---|
--format <format> | json | Output format: json or table |
--db-path <path> | ~/.laurel-proxy/data.db | Database location |
laurel-proxy request a1b2c3d4-e5f6-7890-abcd-ef1234567890
laurel-proxy request a1b2c3d4-e5f6-7890-abcd-ef1234567890 --format table--format table prints separate Client Hop and Origin Hoplines showing the wire protocol negotiated on each side (http/1.1 or h2, or unknown for a legacy row predating this feature). --format jsoncarries the same information as client_protocol/origin_protocol.
messages
Show captured WebSocket frames for a single connection.
laurel-proxy messages <id> [options]| Option | Default | Description |
|---|---|---|
--follow | Stream new frames as they arrive | |
--limit <n> | 500 | Maximum number of frames per page |
--format <format> | table | Output format: table, json, or agent |
--ui-port <number> | 8081 | UI/API port |
--db-path <path> | ~/.laurel-proxy/data.db | Database location |
<id> must be the id of a request with kind: 'websocket'. Find it with:
laurel-proxy requests --kind websocket --format agentlaurel-proxy messages a1b2c3d4-e5f6-7890-abcd-ef1234567890
laurel-proxy messages a1b2c3d4-e5f6-7890-abcd-ef1234567890 --follow
laurel-proxy messages a1b2c3d4-e5f6-7890-abcd-ef1234567890 --format json --limit 100Pointing <id> at an HTTP request fails with a message telling you to use laurel-proxy request <id> instead. The output is one page, not the whole connection -- --limit defaults to 500, and every format reports how many frames exist in total so you know when to raise it. In --format json/--format agent, text frames are decoded to UTF-8 strings and non-text frames (binary, ping, pong, close) are base64, with a payload_encoding field saying which.
clear
Delete all captured traffic from the database.
laurel-proxy clear [options]| Option | Default | Description |
|---|---|---|
--ui-port <number> | 8081 | API port |
laurel-proxy clearthrottle
Simulate slower network conditions on traffic passing through the proxy: a preset modeled on a common connection type, or explicit down/up/latency values.
laurel-proxy throttle [preset] [options]| Option | Description |
|---|---|
[preset] | One of 56k, edge, 3g, 4g, dsl, wifi, or off |
--down <kbps> | Custom download rate (enables throttling) |
--up <kbps> | Custom upload rate (enables throttling) |
--latency <ms> | Added latency, injected once per HTTP exchange before the first response byte |
--status | Show current throttle settings instead of changing them |
--format <format> | Output format for --status: table, json, or agent |
# Apply a preset
laurel-proxy throttle 3g
# Disable
laurel-proxy throttle off
# Explicit rates (enables throttling)
laurel-proxy throttle --down 500 --up 100 --latency 200
# Show current settings
laurel-proxy throttle --status
laurel-proxy throttle --status --format jsonRunning laurel-proxy throttle with no preset and no rate flags also shows current status, the same as --status. Presets:
| Preset | Down (kbps) | Up (kbps) | Latency (ms) |
|---|---|---|---|
56k | 56 | 33 | 120 |
edge | 240 | 200 | 400 |
3g | 780 | 330 | 100 |
4g | 4000 | 3000 | 20 |
dsl | 2000 | 256 | 40 |
wifi | 30000 | 15000 | 5 |
Throttling models one shared virtual link per direction, not one per connection -- concurrent requests contend for the same bandwidth budget and queue behind each other, the same as a single real network link would. A WebSocket connection is bandwidth-paced in both directions but gets no added latency, since delaying every frame of a long-lived connection would distort the timing that WebSocket debugging usually cares about.
Throttling inflates the recorded duration of affected requests -- the proxy's own delay is indistinguishable from upstream slowness in the stored data, the same way Chrome DevTools network throttling works. The web UI marks throttled durations with a badge; the CLI has no equivalent marker, so remember this yourself when scripting against laurel-proxy requests or reading duration while throttling is on.
trust-ca
Install and trust the Laurel Proxy CA certificate for HTTPS interception.
laurel-proxy trust-ca [options]| Option | Description |
|---|---|
--no-interactive | Skip prompts; print cert path and manual instructions |
# Interactive (prompts for sudo password)
laurel-proxy trust-ca
# Non-interactive (CI, scripts)
laurel-proxy trust-ca --no-interactiveuninstall-ca
Remove the Laurel Proxy CA certificate from the system trust store.
laurel-proxy uninstall-ca [options]| Option | Description |
|---|---|
--no-interactive | Skip prompts; print removal instructions |
# Interactive (prompts for sudo password)
laurel-proxy uninstall-ca
# Non-interactive
laurel-proxy uninstall-ca --no-interactiveOn macOS, removes via security remove-trusted-cert. On Linux, removes from/usr/local/share/ca-certificates/ and refreshes the store. Only available when the certificate is currently installed.
proxy-on
Configure Laurel Proxy as the system-wide HTTP/HTTPS proxy. macOS only.
laurel-proxy proxy-on [options]| Option | Default | Description |
|---|---|---|
--port <number> | 8080 | Proxy port |
--service <name> | auto-detected | Network service (e.g., "Wi-Fi", "Ethernet") |
laurel-proxy proxy-on
laurel-proxy proxy-on --port 9000 --service "Wi-Fi"proxy-off
Remove Laurel Proxy from system proxy settings. macOS only.
laurel-proxy proxy-off [options]| Option | Default | Description |
|---|---|---|
--service <name> | auto-detected | Network service |
laurel-proxy proxy-offRelated
- Getting Started - Install and capture your first request
- REST API - Programmatic access to captured traffic
- Configuration - Config file, storage limits, and auto-cleanup
- HTTPS Interception - CA trust setup for trust-ca and uninstall-ca commands
- HTTP/2 Support - --client-protocol/--origin-protocol filters in full
- AI Agent Plugin - Uses --format agent for AI-optimized output