Command line (wirelens)
Search captures, export HAR, add rules and control capture from Terminal and from scripts.
WireLens for Mac comes with a command line tool, wirelens. It reads the capture while the app is recording, writes rules, and asks the running app to start or stop capture, change the system proxy or install the certificate.
The tool is free. Rules you add from it count against the same free allowances as the app. A few commands reach features that need WireLens Pro: export csv, protobuf --path, proxy upstream set, cert identity add, network-extension install and enable, mcp inspect, and config set for a Pro setting such as HTTP/3 decryption. On the free plan these exit with code 6, as does a rule past its allowance.
Install#
There is nothing extra to download. The tool ships inside the app, at /, and always matches the version of WireLens that recorded your capture.
Installing the app does not add wirelens to your PATH. Until you link it, run it by its full path:
/ Applications/ WireLens.app/ Contents/ Helpers/ wirelens ls --status 5xx
To type wirelens instead, link it once. In the app, choose Help ▸ Install Command Line Tool…, or run:
/ Applications/ WireLens.app/ Contents/ Helpers/ wirelens install-symlink
Both do the same thing: / becomes a link to the copy inside the app and stays on the app's version through every update. If that folder needs an administrator, both hand you the matching sudo ln -sf line to copy. Open WireLens once before you link it: until the app has created its data folder, install-symlink stops with exit code 3.
The rest of this page writes wirelens on its own, which assumes you have linked it. If you have not, put the full path in front of any command.
The live session#
Run wirelens with no arguments in a terminal for an interactive session (wirelens watch, repl and top open the same thing). Traffic streams above a prompt pinned to the bottom of the window. Off a terminal, for example in a script, plain wirelens prints the help instead.
| Command | Does |
|---|---|
/ | Narrow the stream and every report. Keys: host=, method=, path=, search=, type=, status= (404 or 4xx), slower-than= (ms), session=, plus the bare word failed. / removes it. |
/follow, /pause | Resume the live stream, or freeze it |
/ls, / | The last matching flows; headers and timing for one flow |
/, / | Request or response body of one flow |
/ | Print a runnable curl command |
/ | Search request and response bodies |
/hosts, /sessions, /rules | Hosts for the active filter, capture runs, everything configured |
/ | Add or remove a host on the SSL Proxying Include list |
/ | Add or remove a host on the Block List |
/ | Delay every decrypted request (0 turns it off) |
/ | Write the flows that match the filter as HAR |
/doctor | Capture and configuration health |
/clear, /help, /quit | Clear the screen (the capture stays), list commands, leave |
Text that does not start with / searches inside bodies.
Read the capture#
wirelens ls --host api.example.com --status 5xx
wirelens ls --method POST --min-duration 1000 --since 10m --json
wirelens show 3f9c --body response --json-path '$.error'
wirelens grep 'invalid_grant'
wirelens hosts
wirelens sessions
wirelens llm spend --session 5e8f
ls(orlist) filters with--host,--method,--status,--path,--search,--content-type,--failed,--min-duration(ms),--since,--session,--afterand--limit(default 50).grepandhoststake the same filters.--statustakes a code (404) or a class (5or5xx).--sincetakes90s,10m,2h,1d, an ISO 8601 date or epoch seconds. Any other value stops with exit code2.llm spendtotals what AI-model calls cost, per model, and takes the same filters (Pro).showon a model call prints its tokens, and with Pro its cost.showprints one flow.--body requestor--body responseprints a body,--json-pathnarrows JSON,--rawprints the bytes as captured, and--limitcaps how many bytes print.- Flow ids can be shortened to any unique prefix.
- Every read command takes
--jsonfor scripts.
Export#
wirelens export har --out capture.har
wirelens export har --session <id> --out run.har
wirelens export har --after <id> --out new.har
wirelens export csv --out capture.csv --columns method,status,url --bom
wirelens export curl <id>
wirelens export raw <id> --out request.txt
wirelens export session --out ./checkout-bug
harandcsvtake the same filters asls.--after <id>exports only flows newer than that one, for incremental exports.csvalso takes--columns,--bom(for Excel) and--no-header.rawwrites one flow as a raw HTTP request message.sessionwrites a session package folder with bodies and WebSocket frames, which WireLens reopens as the capture it was.--session <id>picks a run.
Rules#
wirelens rules list
wirelens rules get <id>
wirelens rules ssl add api.example.com
wirelens rules block add ads.example.com
wirelens rules map-local --pattern 'https:// api.example.com/ v2/ catalog*' --content '{"items":[]}'
wirelens rules map-remote --from 'https:// api.example.com/ *' --to 'https:// staging.example.com'
wirelens rules rewrite --pattern 'https:// api.example.com/ *' --set-header 'X-Debug: 1'
wirelens rules breakpoint --host api.example.com --path / v2/ cart
wirelens rules update <id> --set enabled=false
wirelens rules rm <id>
| Verb | Writes |
|---|---|
ssl add| | SSL Proxying Include list |
bypass add HOST… | SSL Proxying Exclude list (add only) |
insecure add| | Invalid origin certificate exceptions (unsafe) |
block add| | Block List |
allow [rm] --pattern H [--action capture| | Capture Allow List |
throttle --delay MS | Added latency on every request (Network Conditions) |
map-local --pattern P --content TEXT [--status-code N] | Map Local |
map-remote --from P --to URL | Map Remote |
rewrite --pattern P [flags] | Rewrite |
breakpoint --host H [--path P] | Breakpoint |
script --host H [--path P] [--name N] [--on-request JS | --on-request-file F] [--on-response JS | --on-response-file F] | Script |
reverse-proxy --listen-port N --target-host H [--target-port N] [--target-scheme S] [--preserve-host] [--note T] | Reverse Proxy |
dns --pattern H --ipv4 IP [--ttl N] [--note T] | DNS Spoof |
protobuf --path FILE or protobuf off | The descriptor set the inspector decodes Protobuf with |
rewrite takes --method, --host, --path, --set-header, --remove-header, --set-query, --remove-query, --request-body, --status, --set-response-header, --remove-response-header, --response-body and --note. wirelens help shows a short form; run wirelens rules rewrite without --pattern to print the full list.
By id, enable, disable, rm and get work on any rule. update <id> --set field= changes one field in place and keeps the rule's id and position; the field names are the ones rules get prints. rules create reads one rule as a JSON object on stdin, with a kind field (map-local, map-remote, rewrite, breakpoint, script, reverse-proxy, dns, allow, block, ssl, protobuf):
echo '{"kind":"map-local","pattern":"https:// api.example.com/ v2/ cart","status":200,"body":"{}"}' | wirelens rules create
Rules take effect on the next request, with no restart. A rule with no pattern is refused. rules writes straight away and ignores --dry-run.
Settings#
wirelens config get
wirelens config set <name> true
wirelens settings export --out settings.json
wirelens settings export --tools map-local,rewrite --enabled-only
wirelens settings import settings.json --dry-run
wirelens settings tools
config get [NAME]reads settings andconfig set NAME true|flips a switch.false config setwrites straight away and ignores--dry-run.settings exportwrites a whole rule set to share. Secrets inside rules are left out unless you pass--include-secrets.--toolspicks tools by id (settings toolslists them) and--enabled-onlykeeps only rules that are switched on.settings importadds the rules in a file.--updatechanges rules that already exist,--replacereplaces your rules with the file's,--mergemerges them, and--dry-runreports what would change.
From Proxyman or Charles#
wirelens import session.proxymansessionv2
wirelens import rules.config --dry-run
wirelens import --proxyman-rules
wirelens import --charles-settings
wirelens convert capture.chlsj --out capture.har
import opens a session (.proxymansessionv2, .proxymanlogv2, .chlsj, .chlz, .chls, .har, .wirelens) in the running app as its own run, and imports a rule set (a Proxyman .config export or Charles settings) straight away. --proxyman-rules and --charles-settings read the copy installed on this Mac. convert writes a HAR from a Proxyman or Charles session and does not need the app. settings import accepts the same rule files.
Control the app#
wirelens capture start
wirelens capture status
wirelens proxy restore
wirelens cert install --scope user
wirelens open <id>
wirelens clear
| Command | Does |
|---|---|
capture start| | Start or stop capture. status says whether the proxy is listening, and where. |
proxy enable| | Point this Mac's system proxy at WireLens, or put it back |
proxy restore | Put the system proxy back exactly as it was, for example after WireLens quit unexpectedly |
proxy upstream status| | The external proxy WireLens sends traffic through: set --kind http| with --host, --port, --username, --pac-url and --bypass. off keeps the server details. |
network-extension install| | The experimental Network Extension capture (ne for short) |
helper install [--open]| | WireLens Helper, which changes network settings without asking for your password each time |
cert status | The root certificate, its fingerprint and whether it is trusted |
cert install [--scope user| | Trust the root certificate for your user, or for every user (administrator) |
cert export --out FILE. | Save the root certificate where a client can read it |
cert identity list| | Client and server certificates: add --host GLOB [--port N] with --p12 FILE --password PASS [--remember-password], --cert PEM --key PEM, or --cert-der FILE --key-der FILE, and --kind client| |
tls keylog on| | Write TLS session keys in SSLKEYLOGFILE format, for reading a packet capture in Wireshark. HTTP/3 keys are not included. |
clear | Delete every captured flow. This cannot be undone. |
open <id> | Bring WireLens forward on one flow (reveal works too) |
Most of these ask the running app to act, because the app owns the listener and the helper. With WireLens closed they exit with code 4 and say so. Three work with the app closed: capture status reads what the app last wrote, and proxy upstream and cert identity write the configuration directly.
Add --dry-run to any of these, or to import and mcp policy, to see what a command would do without doing it.
MCP setup#
The same tool sets up the MCP server for your AI agents:
| Command | Does |
|---|---|
mcp status [--json] [--project] | Each client, whether WireLens is installed in it, its config file and its install command |
mcp install [CLIENT] [--read-only] [--project] [--all] | Write wirelens-mcp into the clients found on this Mac, or the one you name |
mcp uninstall CLIENT | Remove the WireLens entry and nothing else |
mcp command [CLIENT] [--json] | Print the config snippet and the install command |
mcp guide | Install notes for every client, as Markdown |
mcp policy on| | Allow or lock off the server's HTTP transport on this Mac |
mcp servers | Every MCP server your agents run, and which ones MCP Inspector records |
mcp inspect <name>|--all [--client C] | Put MCP Inspector in front of a local MCP server and see its calls in the capture |
mcp uninspect <name>|--all | Restore the server's original command |
Client names: claude-code, claude-desktop, codex, gemini, cursor. claude on its own means Claude Desktop.
Global options#
--json (output for scripts), --no-color, --store DIR (read a capture other than the default), --dry-run, --timeout SECONDS (how long to wait for the app), --version and --help.
Exit codes#
| Code | Meaning |
|---|---|
0 | Success |
1 | General error |
2 | Usage error |
3 | No capture found |
4 | WireLens is not running, or did not answer |
5 | Flow, file or setting not found |
6 | The command needs WireLens Pro, or the rule is past its free allowance |
7 | The capture was written by a different version of WireLens |
Safe while the app records#
Reading a live capture from the command line leaves it untouched. If the capture was written by another version of WireLens, the tool stops with code 7. wirelens doctor checks the capture and the configuration when something looks off.
To rename or delete sessions, annotate flows, test scripts, diagnose setup, set up simulators or inject into Electron apps, use the MCP server.
Something here is unclear, or wrong for your setup? Contact support or write to support@wirelens.app.