Wirepane:运行在 Claude Code 内的 HTTPS 调试代理插件
Show HN: Wirepane – An HTTPS debugging proxy that lives inside Claude Code
Wirepane 是一个 Claude Code 插件,把 Claude Code 变成类似 Proxyman、Charles、mitmproxy 的 HTTPS 调试代理。
Wirepane 是一个 Claude Code 模组(一种函数钩子插件)。 它把 Claude Code 变成一个类似 Proxyman、Charles 或 mitmproxy 的 HTTPS 调试代理: 它拦截并解密你的浏览器、iOS 模拟器、iPhone、 Android 模拟器或 Android 手机的 HTTP 和 HTTPS 流量。它在一个可筛选的列表中显示每个请求,并让 Claude 读取同样的流量,因此你可以问 “为什么登录请求返回 401?”,它会 查看真实的请求和响应。
安装
需要 macOS、Claude Code 2.1.292 或更新版本,以及 openssl(macOS 内置)。代理运行在
Node.js 18 或更新版本上,它会自行找到:在 PATH 中,或 Homebrew、Volta、nvm、fnm、mise、
asdf、nodenv 或 MacPorts 放置它的位置。如果都没有,面板会提供安装选项。在 Claude Code 提示符下:
/plugin install wirepane --marketplace legostin/wirepane
回答 y 以添加市场并选择范围。在 shell 中同样如此:
claude plugin marketplace add legostin/wirepane claude plugin install wirepane@wirepane
然后运行 /proxy:代理在 127.0.0.1:8899 上启动,面板打开。空列表会提供
它在这台 Mac 上找到的接入方式。
● 127.0.0.1:8899 · 342 requests [ Stop ] View [ List ] [ Tree ] [ Clear ] [ Setup ]
Filter host:*.api.example.com is:error
401 POST https://api.example.com/v1/login 1.2KB 180ms
503 GET https://api.example.com/v1/feed 87B 2.1s
CERT CONNECT gateway.icloud.com:443 0B 0ms
该命令接受:
/proxy open the pane and start the proxy
/proxy setup set up a browser, iOS, Android, macOS or CLI client
/proxy stop stop it (and point Android devices back)
/proxy clear clear the list
/proxy rules the rules that change requests and responses
/proxy track the domains this session decrypts and records
/proxy status one line about its state
/proxy tree show the requests as a tree (host → path → requests)
/proxy list show them as a flat list
为什么
调试移动端或 Web 客户端通常意味着要一个单独的代理应用、在每个设备上折腾证书, 以及手动把请求复制到聊天中。Wirepane 把这一切都保留在你已经工作的地方:
- 无需单独的应用。 代理、其证书颁发机构和请求列表都位于 Claude Code 中。
- 在你所在之处快速开始。 空列表会提供在这台 Mac 上找到的接入方式:打开 浏览器、使用模拟器、启动模拟器、设置手机、仅跟踪你的应用。
- 浏览器一键搞定。 它会打开一个单独的 Chrome、Edge、Brave 或 Chromium 窗口,其 全部流量都经过代理,包括 localhost,且无需安装证书。
- 模拟器为你设置好。 从列表中选择一个模拟器并按 Use:它会 启动、获取 CA,并且 Mac 的系统代理指向该代理。选择一个 Android 模拟器, 它启动时流量就已经经过代理。
- Claude Code 继续工作。 开启 macOS 系统代理后,Mac 上的每个应用都经过 代理;Claude 的主机会绕过它,Claude 运行的任何内容都被隧道传输,绝不解密。
- Claude 能看到流量。 两个工具为模型提供请求列表和任何请求的完整内容: 标头和已解码的正文。
功能
- MITM HTTPS 代理:使用来自其自身本地 CA 的按主机证书解密 TLS。纯 HTTP、 WebSocket 升级和服务器发送事件直接通过。
- 带筛选语言的请求列表:
method:POST status:4xx host:*.example.com type:json is:error -text。 - 树视图:请求按主机和路径分组,每个节点都有其请求数和失败数。
在面板中用 View: List / Tree(
l/t)或/proxy tree切换;该选择会被记住。 - 每个客户端的确切代理地址:手机的 Mac Wi-Fi 地址,从 VPN 隧道和 虚拟机网桥中挑选,以及手机扫描以打开设置页面并获取证书的二维码。
- 请求详情:标头、美化打印的 JSON、gzip、brotli、deflate 和 zstd 解码、 Copy as curl、To prompt。
- 诊断证书问题:拒绝代理证书的客户端(CA 不受信任,或
证书固定)会显示为
CERT行,而不是静默失败。 - 由代理自身在
http://claude.proxy/提供的设置页面:一个 iOS.mobileconfig、一个 Android.crt和一个.pem。 - 无需解密即可隧道传输的主机(固定服务),默认包含 Apple 的。
- 网络内安全:在
lan模式下,手机可以使用代理,但网络上的任何其他设备都无法通过它访问这台 Mac 的 localhost。 - 按会话跟踪域名:仅解密并记录你的应用的主机(支持通配符);其他一切原样通过,因此手机自身的服务仍可正常工作。
- 规则引擎:延迟、限速、模拟、重写请求头、URL 和请求体、状态码、丢弃连接和脚本,按优先级串联;可在面板中管理,也可由 Claude 管理。
- 无依赖:一个 Node.js sidecar 和
openssl,无需从 npm 安装任何东西。
设置客户端
| 客户端 | 方式 |
|---|---|
| 独立浏览器 | Setup → Browser → Open Google Chrome(或 Edge、Brave、Chromium)。它会以独立配置文件启动一个新实例,--proxy-server、--proxy-bypass-list=<-loopback> 以便 localhost 也被捕获,以及 --ignore-certificate-errors-spki-list 以便它信任代理的证书而无需触碰钥匙串。 |
| iOS 模拟器 | Setup → iOS:这台 Mac 上的模拟器,需先启动。Use(或 Boot & use)会启动一个,添加 CA(simctl keychain add-root-cert)并打开 macOS 系统代理,因为模拟器自身没有代理设置。 |
| iPhone / iPad | Setup → iOS → iPhone / iPad:Listen on LAN,用相机扫描二维码安装描述文件,在 Certificate Trust Settings 中启用它,然后将 Wi-Fi 代理设置为显示的服务器和端口。当手机流量到达时该区域会确认,当手机拒绝证书时也会提示。 |
| Android 模拟器 | Setup → Android → Emulator:你的 AVD。Start through the proxy 会以 -http-proxy 启动一个,等待其启动完成并在其浏览器中打开 CA 页面:轻点一下即可安装证书。正在运行的模拟器可通过 Android → proxy(10.0.2.2)指向代理,并通过 Revert 还原。 |
| USB 连接的 Android 手机 | Setup → Android → Phone:Point USB phones at the proxy 使用 adb reverse,因此无需 Wi-Fi。 |
| Wi-Fi 连接的 Android 手机 | Setup → Android → Phone:Listen on LAN,扫描二维码下载并安装证书,然后将 Wi-Fi 代理设置为显示的主机名和端口。应用仅在具有 network_security_config 时才信任用户 CA;config snippet 会复制一份。 |
| Safari 和原生 Mac 应用 | Setup → macOS → Turn on for this Mac 将系统代理指向此处(Claude 的主机在其绕过列表中),Trust CA on this Mac 将 CA 添加到登录钥匙串。代理停止时两者都会被还原。 |
| curl、Node、Python、Go | curl -x http://127.0.0.1:8899 --cacert ~/.claude/proxy-mod/ca/ca.pem …;Setup → macOS / CLI 会复制 HTTPS_PROXY、NODE_EXTRA_CA_CERTS、SSL_CERT_FILE 和 REQUESTS_CA_BUNDLE。 |
Claude Code 保持正常工作
Claude Code 不信任代理的 CA,因此它自己发起的、被代理解密的连接会失败;在 macOS 系统代理开启的情况下,它的流量会像每个应用一样来到这里。两道防护保证其完好:
- Anthropic 和 Claude 的主机(
*.anthropic.com、*.claude.ai、*.claude.com)在系统代理的绕过列表中,而且代理也从不解密它们。 - 当系统代理指向该代理时,进程源自 Claude 的本地连接(任何 Claude Code 会话、它运行的命令和 MCP 服务器、Claude 应用)会被原样隧道传输。其他所有应用照常解密。
系统代理开关会保留它替换掉的设置,并在代理停止时、会话结束时,以及从代理自身检测到 Claude Code 退出时将其还原。
跟踪域名
一部手机要与数十个主机通信:推送、iCloud、分析、其他应用。打开跟踪列表后,代理只会解密并记录你指定的域名;其他所有连接都原样通过且不被记录,因此手机自身的服务仍能正常工作(固定主机上不会出现 CERT 失败),而列表只保留你应用的流量。
/proxy track app.kolesa.kz *.kolesa.kz track these (wildcards: *.example.com covers example.com)
/proxy untrack app.kolesa.kz stop tracking one
/proxy untrack switch the list off: every domain again
/proxy track open the Domains view
Domains 视图(d)列出这些模式以及各自捕获的请求数,可开启和关闭列表,并显示未被跟踪而通过的主机,按最繁忙排序,每个都带有 track 和 track *.domain 按钮:连接手机,使用应用,然后从那里挑选它的主机。该列表属于 Claude Code 会话,并随 --resume 一起恢复。Claude 通过 mcp__wirepane__track_domains 管理它。
有些客户端连接到地址而非名称(Android 模拟器自行解析名称):代理从 TLS 握手中读取主机名,因此列表、规则和请求列表看到的都是 api.example.com,而不是 203.0.113.7。
规则:修改请求和响应
规则会在匹配的请求发送前修改它们,并在客户端收到响应前修改响应:让某个端点变慢、用模拟响应应答它、翻转状态码、重写 JSON 字段、将 /v1/* 发送到你的本地服务器、断开连接。用平实的语言向 Claude 提出(“让 GET /api/feed 耗时 3 秒”、“用 500 应答 POST /login”),它就会编写规则;Rules 视图(/proxy rules,或窗格中的 r)会列出这些规则并用文字说明各自的作用,可开启和关闭,并上下移动。
规则存放在项目中,位于 .claude/proxy-rules.json,因此可以被提交和共享。文件一发生变化,代理就会重新加载它。
{
"rules": [
{
"id": "slow-feed",
"description": "Simulate a slow backend for the feed",
"match": { "methods": ["GET"], "host": "api.example.com", "path": "/v1/feed*" },
"request": [{ "type": "delay", "ms": 2000 }],
"response": [
{ "type": "setStatus", "status": 503 },
{ "type": "mergeJson", "json": { "error": "down" } }
]
}
]
}顺序与链式执行。 第一条规则最先应用。每条开启且匹配的规则按顺序应用,规则内的动作也按顺序应用;"stop": true 会结束链条。
匹配。 给出的每个条件都必须成立:url、host、path(通配符如 *.example.com 或 /v1/*,或 re:<regex>)、methods、headers、query、bodyContains,以及在响应侧 status(404、4xx、>=400、500-599)和 contentType。
| 动作 | 发送前 | 响应时 |
|---|---|---|
delay {ms, msMax?}、throttle {bytesPerSecond} |
✓ | ✓ |
setHeader {name, value}、removeHeader {name} |
✓ | ✓ |
setQuery、removeQuery |
✓ | |
mapRemote {scheme?, host?, port?, path?}、replaceUrl {pattern, with} |
✓ | |
setBody {text | json | file}、replaceBody {pattern, with}、mergeJson {json} |
✓ | ✓ |
respond {status, headers?, text | json | file}:不经过服务器直接应答 |
✓ | |
setStatus {status} |
✓ | |
fail {kind: reset | close | timeout} |
✓ | ✓ |
script {code} |
✓ | ✓ |
只有当规则修改响应体时才会将其暂缓(先解压 gzip 或 brotli);仅修改标头或状态的规则会让响应继续流式传输,因此服务器发送事件仍能正常工作。
脚本。 code 是 async (req, res, ctx) => {} 的主体,在代理中运行:发送前它可以修改 req.method、req.url、req.headers、req.body 或设置 req.respond = { status, headers, body };在响应时它可以修改 res.status、res.headers 和 res.body(req.json() 和 res.json() 解析主体)。脚本只有在其 SHA-256 被批准后才会运行,因此随克隆仓库而来的规则文件无法未经询问就在你的机器上运行代码:在 Rules 视图中按 Allow script。Claude 通过其工具添加的脚本会随工具一起获得批准。
在列表中, 被规则修改过的请求会标记为 ✎;其详情会说明每条规则做了什么,筛选器接受 is:modified 和 rule:<id>。
筛选
以空格分隔的多个词项必须全部成立,前导的 - 表示对某个词项取反。自由文本匹配 URL 的子串。
| 词项 | 匹配 |
|---|---|
method:POST、method:get,post |
方法 |
status:404、status:4xx、status:>=400、status:500-599 |
响应状态 |
host:api.example.com、host:*.example.com |
主机(子串或通配符) |
path:/v1/login |
路径的子串 |
type:json|html|xml|js|css|img|font|media|text|form|ws|tunnel|other |
内容类型 |
is:error|ok|pending|tunnel|ws|https|rejected |
状态(rejected:客户端拒绝了证书) |
client:192.168.1.20 |
客户端的地址 |
例如,host:*.api.com -type:img is:error。
Claude 的工具
| 工具 | 模型获得的内容 |
|---|---|
mcp__wirepane__list_requests({ filter?, limit? }) |
代理的状态以及每个请求一行:id、方法、状态、URL、大小、时间、类型、错误。 |
mcp__wirepane__get_request({ id, max_body_chars? }) |
完整的一条请求:URL、状态、耗时、客户端、错误、请求与响应头、解码后的正文、规则做了什么。 |
mcp__wirepane__track_domains({ add?, remove?, set?, enabled? }) |
本次会话跟踪的域名,以及代理看到过的未跟踪主机,按繁忙程度排序。 |
mcp__wirepane__list_rules() |
按顺序排列的规则,开启或关闭,每条用文字说明做什么、错误、每条改动了多少请求。 |
mcp__wirepane__add_rule({ rule, position? })、update_rule({ id, changes?, enabled?, position? })、remove_rule({ id }) |
写入规则文件;代理立即应用更改。 |
可以这样问:“列出到 api.example.com 的失败请求,并告诉我它们的共同点”,或者 “比较请求 #12 和 #14”。在请求详情中点击 To prompt 就会为你发起这样的问题。
选项
在 /config 中设置,或在 /plugin → Installed → wirepane → Configure options 中设置。
| 选项 | 默认值 | |
|---|---|---|
| 端口 | 8899 |
|
| 监听于 | local |
lan 让网络中的手机可以访问代理 |
| 不解密的主机 | *.apple.com,*.icloud.com,*.mzstatic.com,*.apple-cloudkit.com |
原样隧道传输 |
| 保留的请求 | 2000 |
工作原理
Claude Code mod ──spawns──▶ node sidecar/proxy.mjs ◀── :8899 ── browser · simulator · phone
▲ │ JSON lines: one summary per request
│ │ headers and bodies → ~/.claude/proxy-mod/flows/
pane · status line · tools │ openssl → ~/.claude/proxy-mod/ca, certs
mod 在沙箱中运行,没有自己的套接字,因此代理是一个小型 Node.js 进程,由 mod 为本次会话启动。它用每个主机各自的证书终止 TLS,证书由你机器上生成的 CA 签名(RSA-2048,保存在 ~/.claude/proxy-mod/ca,私钥仅你可读)。请求摘要通过 stdout 返回;头和正文留在磁盘上,只有当你打开某个请求或 Claude 请求查看时才读取。docs/design.md 有详细说明。
它运行什么、改动什么
Wirepane 自身不向任何地方发送任何东西:没有遥测、没有更新检查、没有下载。它建立的唯一连接,是为你指向它的客户端中继到这些客户端所请求的服务器。只有当 Claude 调用某个工具时,请求才会到达 Claude;它读取的内容随后会成为对话的一部分,就像 Claude 读取的文件一样。
代理开启期间,它会运行:
node sidecar/proxy.mjs,即代理本身,监听127.0.0.1(在lan模式下也监听网络),当你停止代理或会话结束时用kill停止。它运行在 Install 下所列位置中第一个对--version返回 18 或更高版本的 Node 上。openssl,用于生成 CA 以及每个主机的证书。route、networksetup和scutil,用于查找这台 Mac 的地址并读取系统代理,以及ps和lsof,用于区分 Claude 自身的连接,使其被隧道传输、绝不解密。
仅当你按下对应按钮时:
| 面板中 | 运行 | 改动 |
|---|---|---|
| macOS → Turn on for this Mac、iOS → Use | networksetup,当 macOS 要求管理员权限时通过 osascript |
系统代理,代理停止时恢复 |
| macOS → Trust CA on this Mac | security add-trusted-cert,macOS 会要求你确认 |
登录钥匙串中的 CA |
| iOS → Use、Boot & use | xcrun simctl、open -a Simulator |
该模拟器钥匙串中的 CA |
| Browser → Open | open -na <browser>,使用它自己的配置文件 |
~/.claude/proxy-mod/browser 之外没有任何改动 |
| Android → Start through the proxy | emulator -avd <name> -http-proxy …、adb |
无:代理设置仅在本次运行期间有效 |
| Install Node.js,在未找到 Node 时显示 | brew install node,然后代理启动 |
来自 Homebrew 的 Node.js |
| Download Node.js,不使用 Homebrew 的同样操作 | open https://nodejs.org/en/download |
无 |
| Android → proxy、Point USB phones at the proxy | adb shell settings put global http_proxy、adb reverse |
设备的代理,由 Revert 以及代理停止时恢复 |
它写入的文件:
~/.claude/proxy-mod/ca和certs:CA(RSA-2048,私钥仅你可读)以及由它生成的证书。~/.claude/proxy-mod/flows/<session>:已记录请求的头和正文。它们可能包含你所调试应用的密码、令牌和个人数据。会话文件夹在其最后一次使用两天后被删除。~/.claude/proxy-mod/sessions、trusted-scripts.json和system-proxy-backup.json:每个会话跟踪的域名、你批准的规则脚本,以及要恢复的系统代理设置。<project>/.claude/proxy-rules.json,一旦你或 Claude 添加了一条规则。
卸载
/proxy stop会恢复系统代理以及指向此处的 Android 设备。/plugin uninstall wirepane@wirepane,或在/plugin→ 已安装 中点击 卸载。- 在信任它的地方移除 CA:在 Mac 上的“钥匙串访问”中(搜索 Wirepane CA),iPhone 上的 设置 → 通用 → VPN 与设备管理 下,以及 Android 上的用户凭据下。
rm -rf ~/.claude/proxy-mod会删除 CA、记录的请求和浏览器配置文件。
常见问题
它能替代 Proxyman、Charles 或 mitmproxy 吗? 对于日常的“我的应用发送了什么、返回了什么”调试,可以,而且无需离开 Claude Code。 规则涵盖重写、模拟和限速;没有交互式断点、HTTP/2 或 gRPC。
我必须在 Mac 上安装证书吗? 对于独立的浏览器不需要:它通过 SPKI 哈希信任代理。Safari、原生 macOS 应用和 iOS 模拟器需要信任 CA;设置选项卡中给出了命令。
为什么有些请求显示 CERT?
客户端拒绝了代理的证书。要么它的 CA 尚未被信任(完成设置
步骤),要么该应用固定了其证书;将此类主机添加到 不解密的主机。
我的流量会离开我的机器吗?
只会发往它本来就要去的服务器。除非你选择
lan,否则代理监听在 127.0.0.1,并且记录的请求保留在 ~/.claude/proxy-mod 中。Claude 仅在
调用工具时读取请求,然后该请求就成为对话的一部分。
它会捕获 Claude Code 自身的流量,或 Claude 运行的命令吗? 不会。它捕获的是你指向它的客户端。
限制
- 客户端仅被提供 HTTP/1.1,因此基于 HTTP/2 的 gRPC 无法通过。
- WebSocket 帧不会被解码;一次升级显示为一行。
- 系统代理会在停止时、会话结束时以及 Claude Code 退出时恢复;只有用
kill -9杀死的 代理才可能使其保持开启(系统设置 → 网络 → 详细信息 → 代理)。 - 规则脚本在代理内的 Node
vm模块中运行:只批准你自己会运行的代码。 - Mods 是早期访问的 Claude Code API。
开发
node --test sidecar/proxy.spec.mjs # the proxy, against local upstreams, driven by curl claude plugin test . # the logic, the pane (terminal and desktop) and the tools claude plugin validate --strict .
要运行一个可用的副本:claude --plugin-dir /path/to/wirepane。
许可证
MIT。与 Anthropic、Proxyman、Charles 或 mitmproxy 无关联。
来源:Hacker News · github.com