*p5.brush
p5.js 환경에서 자연스러운 텍스처를 탐구하는 아티스트·디자이너·취미자를 위한 다목적 라이브러리
브라우저, iOS, Android에서 HTTPS를 가로채고 복호화해 요청을 필터링하며 Claude가 내용을 읽게 합니다
Intercept and decrypt HTTPS from your browser, iOS and Android, filter the requests, and let Claude read them. No separate proxy app.
플러그인TypeScript · JavaScriptGitHub @legostin온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Wirepane: an HTTPS debugging proxy inside Claude Code (Proxyman/Charles alternative). Intercepts and decrypts traffic from your browser, iOS Simulator, iPhone and Android, lists and filters every request, and lets Claude read them.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Wirepane: an HTTPS debugging proxy inside Claude Code
Wirepane is a Claude Code mod (a plugin of function hooks).
It turns Claude Code into an HTTPS debugging proxy in the spirit of Proxyman, Charles or mitmproxy:
it intercepts and decrypts the HTTP and HTTPS traffic of your browser, the iOS Simulator, an iPhone,
the Android emulator or an Android phone. It shows every request in a filterable list, and lets
Claude read the same traffic, so you can ask "why does the login request return 401?" and it
looks at the real request and response.README 전문 보기 ↗Wirepane turns Claude Code into an HTTPS debugging proxy for the browser, the iOS Simulator, iPhones, the Android emulator and Android phones. It is a mod: a plugin of function hooks. It decrypts HTTP/1.1, HTTP/2, gRPC, WebSockets and server-sent events, shows them in a pane next to your conversation, and gives Claude the same traffic through 16 tools.
So instead of copying requests into the chat, you ask:
"Why does checkout return 402 on the phone but not in the browser?" "Wait while I tap Log in, then tell me what the app sent." "Make the feed take 3 seconds and fail one request in five." "Answer the price socket with a mock that sends a tick every subscription." "Nothing shows up from the emulator. Fix it."
Claude finds the request, reads only the part it needs, compares the one that works with the one that fails, replays it with a change, writes a rule, and fixes your code. When something is in the way, a missing CA, a pinned certificate, a VPN or Charles holding the system proxy, the doctor names it and fixes it.
Website · Install · What Claude can do · Doctor · Rules · Limits · Design notes · Privacy
You need macOS, Claude Code 2.1.292 or newer, and openssl (built into macOS).
The proxy runs on Node.js 18 or newer and finds it by itself: on PATH, or where Homebrew, Volta, nvm, fnm, mise, asdf, nodenv or MacPorts put it. With no Node at all, the pane offers to install it.
At the Claude Code prompt:
/plugin install wirepane --marketplace legostin/wirepane
Or from a shell:
claude plugin marketplace add legostin/wirepane
claude plugin install wirepane@wirepane
Then run /proxy. The proxy starts on 127.0.0.1:8899, the pane opens, and an empty list offers the ways in it found on this Mac: a browser, a booted simulator, an emulator, a phone.
● 127.0.0.1:8899 · 342 requests [ Stop ] View [ List ] [ Tree ] [ Clear ] [ Setup ] [ Rules (2) ] [ Health (1) ]
Filter host:*.api.example.com is:error
401 POST https://api.example.com/v1/login 1.2KB 180ms
200 POST ✎ https://api.example.com/pkg.Cart/Checkout 41B 95ms
101 GET wss://api.example.com/chat ↑14 ↓52 …
CERT CONNECT gateway.icloud.com:443 0B 0ms
It reads every protocol a modern app speaks.
gRPC NOT_FOUND: no such user.application/x-protobuf), decoded the same way.It reaches every client in one press.
adb reverse for Android phones on USB, so no Wi-Fi is needed.It changes traffic, not just shows it. A rules engine for requests, responses and WebSocket messages:
Claude writes rules in plain words. You manage them in the Rules view.
It works on office networks. An upstream proxy carries every connection to the servers: HTTP, HTTPS, HTTP/2, tunnels and WebSockets. It can be an HTTP proxy that signs in with Basic or Windows NTLM credentials, SOCKS5, or a PAC file that picks per URL. The doctor offers the network's own proxy for it.
It tells you what is wrong, and fixes it. The doctor checks the proxy, the system proxy, VPNs, other proxy apps, the CA on each client, pinned hosts, upstream failures and Android devices. Each finding names its fix, and many have a button. The proxy repairs some things on its own:
It keeps Claude's context small. Long URLs are cut, requests are read part by part, and bodies share one budget. json_path picks one field of a big body. since and wait_for_request replace polling.
It keeps secrets out of Claude's context. Tokens, passwords, keys and cookies read ‹hidden 243 chars #a1b2c3› in every tool and in HAR files. The fingerprint tells one token from another, and replays send the real values. You choose what is hidden.
One proxy, every session. A single proxy serves every Claude Code session on the Mac:
It runs locally.
~/.claude/proxy-mod.| Tool | What it does |
|---|---|
list_requests({ filter?, since?, limit? }) | The proxy's state and one line per request: id, method, status, URL (long ones cut), size, time, type, WebSocket and event counts, rules, error. since lists only what is new. |
get_request({ id, part?, json_path?, max_chars?, from?, limit? }) | One request, by part: summary, headers, request, response, messages, all. Bodies share one budget. JSON is compact when pretty would not fit, and json_path picks one field. gRPC, protobuf, trailers, WebSocket messages and events are included. |
search_requests({ text, where?, filter? }) | Which requests hold some text in their URL, headers, bodies, messages or events, with the text in context. |
wait_for_request({ filter, timeout_s?, until? }) | Waits for the request the person is about to trigger, and answers it the moment it ends. |
diff_requests({ a, b }) | What differs between two requests: method, URL, query, headers, status, JSON field by field. |
replay_request({ id, method?, url?, headers?, body?, json? }) | Sends a request again, as it was or changed, through the proxy, so it is recorded and rules apply. |
resume_request({ id, action?, changes?, respond? }) | Lets go of an exchange held at a breakpoint: as it was, changed (method, URL, headers, body, status), answered by hand, or cut. |
send_ws_message({ id, to, text | json | b64 }) | Injects a message into a live WebSocket, to the client or to the server. |
close_websocket({ id, code?, reason? }) | Closes a live WebSocket, to test reconnects. |
add_rule, update_rule, remove_rule, list_rules | The rules file, applied at once. |
track_domains({ add?, remove?, set?, enabled? }) | Decrypt and record only the app's hosts, and see what passed through. |
export_har({ filter?, file? }) | HAR 1.2 with bodies and WebSocket messages, for a teammate or Chrome DevTools. |
diagnose() |
The plugin also ships three skills that Claude loads when the task calls for them:
wirepane-debugging: the order that works, from filter to summary to part, then search, diff, replay and verify. Also how to read gRPC, WebSocket and SSE traffic cheaply.wirepane-troubleshooting: symptom, check, fix, for everything the doctor knows. It includes the fix in your own app: Android network_security_config, OkHttp and iOS pinning in debug builds, Flutter HttpOverrides, and proxy settings for Node, Go, Python, Java, Docker and Unity.wirepane-rules: recipes for mocks, latency, chaos, JSON rewrites, GraphQL operations and WebSocket mocks. Every one is tested to validate.The tools show Claude what it needs to debug, without the tokens, passwords and keys. Hiding is on by default. You see everything in the pane.
authorization: Bearer ‹hidden JWT 812 chars #a1b2c3, exp 2026-10-30T12:00:00Z, 3 min before the request›
cookie: session=‹hidden 64 chars #9f04e1›; theme=dark
{ "email": "[email protected]", "password": "‹hidden 12 chars #77c2d0›" }
What is hidden. Four kinds, the first three on:
Authorization and Proxy-Authorization (the scheme stays), cookie values (names, attributes and short values like theme=dark stay), and headers named like a token, key, secret or session;password, token, client_secret or api_key, at any depth. Numbers stay (max_tokens: 1024);Bearer and Basic credentials, AWS, GitHub, GitLab, Slack, Stripe, OpenAI, Anthropic, Google and npm keys, PEM private keys, and a URL's password, in any text: bodies, WebSocket messages, events, errors;The fingerprint. #a1b2c3 is an HMAC of the value under a key made for your install. The same token has the same fingerprint in every request and on every day, so Claude can tell whether the token changed without seeing it. search_requests finds a fingerprint; it never finds a hidden value by its text.
A JWT also says when it expires, against the request's time. Its other claims stay hidden.
Claude still uses the values. replay_request and resume_request send a hidden header as it was when Claude leaves it out. A placeholder passed back, in a URL, a header, a body or JSON, goes as the value it stands for. A login can be replayed with a new user name and the password Claude never saw.
HAR files from export_har are hidden the same way. /proxy export --with-secrets [file], typed by you, writes the real values.
Only you turn it down. /proxy secrets (or p in the list) opens the Secrets view:
The same settings are in /config. In the request detail, each header Claude does not see is marked hidden from Claude.
/proxy doctor, the Health view (h), or Claude's diagnose check:
| Check | Finds | Fix |
|---|---|---|
| The proxy and its process | Stopped, failed, a port taken (and by whom; a Wirepane 0.7 proxy still running after an update); pid, uptime, memory, disk, sessions | Start again, Stop it and start, Restart |
| The system proxy | Left on by a dead proxy (no internet); held by Charles or Proxyman | Put back; Setup |
| VPN and other proxy apps | A utun default route; Charles, Proxyman, mitmproxy, HTTP Toolkit running | What to try |
| The CA on this Mac | Safari and Mac apps would refuse HTTPS | Trust on this Mac |
| Refusals per client | Every host refused: the CA is missing. One host among working ones: it pins its certificate | Setup for that client, or Never decrypt it |
| Pinned hosts | Passed through after two refusals (or an OkHttp-style close right after the handshake) | Decrypt them again once trusted |
| Upstream failures | DNS (ENOTFOUND), self-signed dev servers, closed ports, localhost confusion, unreachable networks | Accept its certificate; what to check |
| The network's own proxy | The system proxy pointed at an office's or a VPN's proxy before Wirepane took its place | Use it upstream |
| Tracked domains | A list that matches nothing that came, and what passed instead | Add the real hosts |
| Android devices | Not pointed at the proxy; apps that will not trust a user CA; a rootable image | Setup; Trust in all apps |
| Client | How |
|---|---|
| A separate browser | Setup → Browser → Open Google Chrome (or Edge, Brave, Chromium). It starts a new instance with a profile of its own:--proxy-server--proxy-bypass-list=<-loopback>, so localhost is captured too--ignore-certificate-errors-spki-list, so it trusts the proxy without the keychainHTTP/2 and WebSockets work as they do anywhere. |
| iOS Simulator | Setup → iOS: Use (or Boot & use) boots one, adds the CA (simctl keychain add-root-cert) and turns on the macOS system proxy, since a simulator has no proxy setting of its own. |
| iPhone / iPad | Setup → iOS → iPhone / iPad:1. Listen on LAN.2. Scan the QR code to install the profile.3. Turn on full trust under Certificate Trust Settings.4. Set the Wi-Fi proxy to the address shown.The section confirms when traffic arrives. |
| Android emulator | Setup → Android → Emulator: Start through the proxy launches an AVD with -http-proxy and opens the CA page in its browser.Apps trust a user CA only with a network_security_config. On a Google APIs image, Health → Trust in all apps makes the CA a system CA until the next reboot. |
| Android phone | Setup → Android → Phone: on USB, Point USB phones at the proxy (adb reverse, no Wi-Fi needed); on Wi-Fi, Listen on LAN, the QR code, and the proxy setting shown. |
| Safari and Mac apps | Setup → macOS → Turn on for this Mac (Claude's hosts bypass it) and Trust CA on this Mac. Both are put back when the proxy stops. |
| curl, Node, Python, Go, Java, Docker | Setup → CLI copies HTTPS_PROXY, NODE_EXTRA_CA_CERTS, SSL_CERT_FILE and REQUESTS_CA_BUNDLE. The troubleshooting skill covers the clients that ignore the proxy. |
Claude Code does not trust the proxy's CA, and with the system proxy on, its own traffic would come here. Two guards keep it whole:
Rules change matching requests before they are sent, responses before the client gets them, and WebSocket messages both ways.
r) lists them in words, with hit counts. It turns them on and off, reorders them, and removes them..claude/proxy-rules.json, so you can commit them. The file is reloaded the moment it changes."stop": true ends the chain.{
"rules": [
{
"id": "slow-feed",
"description": "The feed on a bad 3G line, failing now and then",
"match": { "methods": ["GET"], "host": "api.example.com", "path": "/v1/feed*" },
"request": [{ "type": "delay", "ms": 800, "msMax": 2500 }],
"response": [{ "type": "throttle", "bytesPerSecond": 50000 }]
},
{
"id": "mock-prices-socket",
"description": "A price feed, with no server",
"match": { "path": "/ws/prices" },
"request": [{ "type": "respond", "status": 101 }],
"messages": [
{ "type": "send", "on": "open", "to": "client", "json": { "type": "hello" } },
{ "type": "reply", "when": "\"subscribe\"", "json": { "type": "price", "price": 42.5 } }
]
}
]
}
Match. Every condition given must hold:
url, host and path take globs (*.example.com, /v1/*) or re:<regex>;methods, headers, query and bodyContains;status (404, 4xx, >=400, 500-599) and contentType.| Action | Request | Response |
|---|---|---|
delay {ms, msMax?}, throttle {bytesPerSecond} | ✓ | ✓ |
setHeader, removeHeader | ✓ | ✓ |
setQuery, removeQuery, mapRemote {scheme?, host?, port?, path?}, replaceUrl | ✓ | |
setBody {text | json | file}, replaceBody {pattern, with}, mergeJson {json} | ✓ | ✓ |
respond {status, headers?, text | json | file}: no server asked (101 on a WebSocket: a mock server) | ✓ | |
setStatus {status} | ✓ | |
fail {kind: reset | close | timeout} | ✓ | ✓ |
breakpoint {timeoutMs?}: held until you (the Held view) or Claude (resume_request) let it go, changed or not; after its time (5 min) it goes on as it was | ✓ | ✓ |
script {code} | ✓ | ✓ |
WebSocket step (messages) | What it does |
|---|---|
direction: out | in | both, when: "text" | "re:…", on: open | Which messages it takes (or once, as the socket opens) |
replaceMessage {pattern, with}, setMessage {text | json | file}, mergeJson {json} | Change the message |
drop, delay {ms, msMax?} | Lose it, or hold it |
reply {text | json} | Answer the sender; the message goes no further |
send {to, text | json} | One more message, to the client or the server |
close {code?, reason?} | Close both sides |
script {code} | async (msg, ctx) => {}: change msg.text, msg.drop = true, ctx.send(to, …), ctx.close(…) |
Bodies. A response body is held back only when a rule changes it, so server-sent events keep streaming under header rules.
Scripts. A script runs only once its SHA-256 is approved. A rules file cloned with a repository cannot run code unasked; press Allow script. Scripts Claude adds through its tools are approved with them.
In the list. A request a rule changed is marked ✎, and its detail says what each rule did. Filter with is:modified or rule:<id>.
Terms separated by spaces must all hold; a leading - negates one. Free text matches a substring of the URL.
| Term | Matches |
|---|---|
method:POST, method:get,post | the method |
status:404, status:4xx, status:>=400, status:500-599 | the response status |
host:api.example.com, host:*.example.com | the host |
path:/v1/login, path:/orders/*/refund | a substring of the path; * stands for any run of characters |
type:json|html|xml|js|css|img|font|media|text|form|grpc|ws|tunnel|other | the content type |
is:error|ok|pending|tunnel|ws|https|h2|grpc|held|rejected|modified | the state (error includes failed gRPC calls; held: waiting at a breakpoint) |
client:192.168.1.20, rule:slow-feed | the client, a rule |
A row opens its detail: the status, the timing, what the rules did, and tabs for Request and Response, plus Messages for a WebSocket and Events for a stream (keys 1 to 4). It opens on the response, or on the messages or the events.
Find searches the tab you are on, case aside: the headers and the body as shown (pretty JSON), or the messages. Every match is marked, the current one brighter, with 3 of 14 · line 340. Enter or j goes to the next, k to the one before, and the body scrolls to it, however deep. It stays as you switch tabs, so you can look for the same token in the request and the response.
A phone talks to dozens of hosts. Turn on the tracking list and the proxy decrypts and records only your app's domains. Everything else passes through untouched and unrecorded.
/proxy track app.example.com *.example.com track these (*.example.com covers example.com)
/proxy untrack app.example.com stop tracking one
/proxy untrack every domain again
The Domains view (d) shows the hosts that passed through, busiest first, each with a track button. Clients that connect to an address (the Android emulator) are tracked by the name in their TLS handshake.
The first session that needs the proxy starts it detached; the others attach to it.
/clear and --resume keep everything in place./proxy stop stops it for everyone and says how many other sessions it served./proxy restart replaces it at once./proxy open the pane and start (or attach to) the proxy
/proxy setup set up a browser, iOS, Android, macOS or CLI client
/proxy doctor the doctor's findings, and the Health view
/proxy rules the rules
/proxy track the tracked domains
/proxy secrets what is kept from Claude
/proxy export write a HAR file (.claude/wirepane-<time>.har, or the path given), secrets hidden
/proxy export --with-secrets [file] the same with the real values
/proxy restart restart the proxy
/proxy stop stop it (and point the system proxy and Android devices back)
/proxy clear clear this session's list
/proxy status one line about its state
/proxy tree|list the requests as a tree (host → path) or a list
Set them in /config, or in /plugin → Installed → wirepane → Configure options.
| Option | Default | |
|---|---|---|
| Proxy port | 8899 | |
| Proxy reachable from | local | lan opens it to phones on the network (never to this Mac's localhost) |
| Hosts never decrypted | *.apple.com,*.icloud.com,*.mzstatic.com,*.apple-cloudkit.com | tunnelled untouched; hosts that refuse the certificate twice are added on their own |
| Hosts with unchecked certificates | (none) | dev servers with self-signed certificates, by host |
| Upstream proxy (office, VPN) | (none) | an office's or a VPN's proxy every connection to a server goes through: http://[user:password@]host:port (Basic or NTLM, whichever it asks for; a Windows DOMAIN\user as DOMAIN%5Cuser), socks5://[user:password@]host:port, or a PAC file as pac+http://[user:password@]host/proxy.pac (the credentials go to the proxies it names, not to the PAC's server) |
| Hosts that skip the upstream proxy | (none) | hosts reached without the upstream proxy; this Mac's own addresses and *.local always are |
| Requests to keep | 2000 | |
| Hide secrets from Claude | on | Secrets kept from Claude |
| What is hidden | headers,fields,tokens | add personal for e-mail, phone and card numbers |
| Also hidden from Claude | (none) | header, field or cookie names, and re:<regex> for values in any text |
| Never hidden from Claude | (none) | header, field or cookie names Claude always sees |
session A ──spawns──▶ node sidecar/attach.mjs ─┐ ┌── browser
session B ──spawns──▶ node sidecar/attach.mjs ─┼─ events ─▶ node sidecar/proxy.mjs --daemon ◀── :8899 ── simulator
pane · tools · status line └─ commands ─▶ (one per Mac, detached) └── phone · emulator
│ headers, bodies, messages → ~/.claude/proxy-mod/flows/
│ watchdog: puts the system proxy back if it is killed
A mod runs sandboxed, with no sockets of its own, so the proxy is a small Node.js process.
docs/design.md has the details.
Wirepane sends nothing of its own anywhere: no telemetry, no update checks. The proxy reads each request a client sends it (the URL, the headers and the body, which can include tokens and personal data from the app you are debugging) and forwards that request to the host in the URL. With an upstream proxy set, it sends the same request there instead, and that proxy connects onward. A rule that sends a request to another address (mapRemote, replaceUrl), and a replay or a held request given another URL, send it there, headers and cookies included. An upstream given as pac+http(s)://… is a PAC file: the proxy downloads it when a request first needs it, and again once its copy is ten minutes old, and runs its FindProxyForURL in a sandbox to pick the upstream for each request. Recordings stay on this Mac, in ~/.claude/proxy-mod; a proxy that starts deletes the run folders not changed for two days. A request reaches Claude only when Claude calls a tool, or when you send a prompt that a pane button (To prompt, Ask Claude to change it) filled in; what it reads then becomes part of the conversation, like a file Claude reads. PRIVACY.md has the whole account.
While the proxy is on, it runs:
node sidecar/proxy.mjs --daemon on 127.0.0.1 (on the network too in lan mode). It is detached so other sessions can use it, and stops when the last session leaves.node sidecar/attach.mjs, one per session, which passes the proxy's events to the mod.node sidecar/watchdog.mjs, which puts the system proxy back if the proxy is killed.openssl: makes the CA and the host certificates.route, networksetup and scutil find this Mac's addresses and read the system proxy. ps and lsof tell Claude's own connections apart. The doctor uses ps, lsof and adb too.kill, by pid: on the proxy and on the session link when the proxy stops, a session leaves or a session links up again after a /clear, on a proxy of Wirepane 0.7 still holding the port when the proxy starts, and on the old proxy the doctor's Stop it and start names.curl to this Mac only: if a proxy that did not shut down left the system proxy on, Wirepane asks curl whether http://127.0.0.1:<that port>/ still answers (no proxy, two seconds) before putting the old settings back. The control socket the tools use is the same kind of call, to http://127.0.0.1:<port>/ on this machine. replay_request sends a recorded request again with curl through the proxy on 127.0.0.1, which forwards it to its host like any other request./bin/sh -c, for an emulator: Android → Start through the proxy starts emulator with nohup, so it keeps running after the press, then waits for it to boot with adb, seq, awk, head, tr and sleep. The port and the emulator name are this Mac's.osascript, when macOS asks for an administrator: the networksetup commands that turn the system proxy on or put it back run again through osascript … with administrator privileges when macOS refuses them without one, and macOS shows its password dialog. That can happen on , and , when the proxy stops, on the doctor's , and when a session starts and finds the system proxy left on by a proxy that did not shut down.Only when you press the button for it:
| In the pane | Runs | Changes |
|---|---|---|
| macOS → Turn on for this Mac, iOS → Use | networksetup, through osascript when macOS asks for an administrator | The system proxy, put back when the proxy stops |
| macOS → Trust CA on this Mac | security add-trusted-cert, which macOS asks you to confirm | The CA in your login keychain |
| iOS → Use, Boot & use | xcrun simctl, open -a Simulator | The CA in that simulator's keychain |
| Browser → Open | open -na <browser> with a profile of its own | Nothing outside ~/.claude/proxy-mod/browser |
| Android → Start through the proxy, Android → proxy, Point USB phones | emulator -http-proxy, adb shell settings put global http_proxy, adb reverse | The device's proxy, put back by Revert and when the proxy stops |
| Health → Trust in all apps (Android) | adb root, adb push, a shell script that mounts a tmpfs over the system CA store | The emulator's system CAs, until it reboots |
| Listen on LAN, Health → Accept its certificate, Never decrypt it, Use it upstream | Nothing | This plugin's own settings, wirepane.listen, wirepane.insecureHosts, wirepane.noDecrypt and wirepane.upstreamProxy. The proxy restarts with them. None of these is Claude's permission mode |
| Secrets view: on/off, kinds, hide, remove, the inputs | Nothing | This plugin's own settings, wirepane.hideSecrets, wirepane.secretKinds, wirepane.alsoHide and wirepane.neverHide. The proxy does not restart |
| Install Node.js, shown when no Node was found | brew install node |
Files it writes:
ca, certs: the CA (RSA-2048, the key readable by you only) and the certificates made from it.flows/<run>: the headers, bodies, WebSocket messages and events of recorded requests. They can hold the passwords, tokens and personal data of the apps you debug. When a proxy starts, it deletes the run folders not changed for two days; nothing deletes them on a timer. A running proxy keeps the files of its latest 2000 requests.sidecar.json, sidecar.log: where the running proxy is, and its log.tracking.json, trusted-scripts.json: the tracked domains, and the rule scripts you approved.system-proxy-backup.json, android-proxied.json: what to put back. The proxy process reads these and obeys them: it restores the system proxy and points the listed Android devices back if its last session vanished.<project>/.claude/proxy-rules.json: written once you or Claude add a rule. The proxy process reads it and applies those rules.<project>/.claude/wirepane-*.har: written by export_har and /proxy export, secrets hidden unless you asked for them.Wirepane only reads <project>/.claude/wirepane-secrets.json, which you write. The key for fingerprints is kept in the plugin's own store.
All of these live in ~/.claude/proxy-mod except the rules file, which lives in your project.
/proxy stop. It puts back the system proxy and the Android devices, and stops the shared proxy./plugin uninstall wirepane@wirepane.rm -rf ~/.claude/proxy-mod to delete the CA, the recordings and the browser profiles.Is it a replacement for Proxyman, Charles, mitmproxy or HTTP Toolkit? For "what did my app send, what came back, and why does it fail", yes, without leaving Claude Code. That covers HTTP/2, gRPC, WebSockets and SSE, with rules, mocks, replays and diffs, and it works behind an office proxy. What it does not have is in the limits. Proxyman and HTTP Toolkit have MCP servers too. Wirepane is built around the agent: the doctor, the waiting, search and diff tools, the context budget, and the skills that fix the app's own code.
Do I have to install the certificate on my Mac? Not for the separate browser, which trusts the proxy by SPKI hash. Safari, native Mac apps and the iOS Simulator need the CA. One press each.
Why do some requests show CERT?
The client refused the proxy's certificate. Either it does not trust the CA yet, or the app pins its certificates. diagnose tells which. A pinned host passes through after two refusals, so the app keeps working.
I see nothing from my Flutter (or Go, or Unity) app. Some runtimes ignore the system proxy. The troubleshooting skill has the few lines that fix it in a debug build.
Does my traffic leave my machine?
Only to the servers it was going to anyway, unless you set an upstream proxy or a rule sends it elsewhere. Recordings stay in ~/.claude/proxy-mod. Claude reads a request only through a tool, or in a prompt you send, and the tools hide its secrets (see Secrets kept from Claude). With Listen on LAN the proxy asks no password, so turn it off when the phone is done.
Does it capture Claude Code's own traffic, or the commands Claude runs? No. It captures the clients you point at it.
upstreamProxy at it. Basic and NTLM (also inside Negotiate) sign in by themselves.vm module: approve only code you would run yourself.claude plugin validate --strict .
claude plugin test . # the mod: logic, the pane (terminal and desktop), the tools
node --test --test-force-exit sidecar/*.spec.mjs # the proxy against local HTTP/1.1, HTTP/2, gRPC and WebSocket upstreams
To run a working copy, use claude --plugin-dir /path/to/wirepane.
MIT. Not affiliated with Anthropic, Proxyman, Charles, mitmproxy or HTTP Toolkit.
| The doctor: every check, each finding with its fix. |
For a team. Commit <project>/.claude/wirepane-secrets.json:
{ "hide": ["x-my-app-token", "re:kz_[A-Za-z0-9]{32}"], "kinds": ["personal"] }
It only adds to what is hidden. A re: pattern hides its match in any text, or only its first group when it has one. A cloned repository, or Claude editing the file, cannot show what /config hides.
The recordings on disk. ~/.claude/proxy-mod/flows keeps the real values. While hiding is on, Wirepane refuses Claude's own Read, Grep, Glob and Bash calls that reach that folder, and points Claude to its tools instead; the CA and the log stay readable. The Bash check reads the command's text, so it is a best effort, not a sandbox: a script can reach a folder in ways no text shows. For a second lock that holds without the plugin, add this to ~/.claude/settings.json:
"permissions": { "deny": ["Read(~/.claude/proxy-mod/flows/**)"] }
Binary WebSocket messages that nothing could read are looked at byte by byte; one whose bytes hold a secret is shown as ‹base64 withheld: the bytes hold hidden values›.
| Node.js from Homebrew |