Capture 文档
Capture 是 macOS 上的 HTTP/HTTPS 调试代理。它记录应用发出的请求,让你查看、过滤和修改它们。
请求列表的样子。这个文档的目录也按同样的方式操作:方向键切换,/ 搜索。
从这里开始
- 第一次使用:安装,然后看快速开始。
- 开着 Shadowrocket、Clash 等 VPN:看在 VPN 下抓包。
- 想让 Claude Code 读取和操作流量:看 MCP 与 Claude Code。
- 之前用 Charles:看从 Charles 迁移。
Capture 是 macOS 上的 HTTP/HTTPS 调试代理。它记录应用发出的请求,让你查看、过滤和修改它们。
请求列表的样子。这个文档的目录也按同样的方式操作:方向键切换,/ 搜索。
从源码构建,需要 macOS 14 或更高版本、Go 和 Xcode 命令行工具。
./scripts/build.sh
open build/Capture.app构建结果在 build/Capture.app,应用内已经包含抓包核心 capture-core 和命令行工具 capture-cli。
选择 ,会把 capture-cli 链接到 ~/.local/bin。详见命令行。
三步看到第一个解密的 HTTPS 请求。
127.0.0.1:9090。开启系统代理会修改 macOS 的网络设置。Capture 退出或崩溃后会恢复原值。
只抓某个命令时直接指定代理,系统设置不受影响:
curl -x http://127.0.0.1:9090 https://example.com端口被占用时 Capture 会自动使用后面的端口,实际端口显示在工具栏和底部状态栏。
Shadowrocket、Clash 等 TUN 模式 VPN 开启时,macOS 不采用网络服务里的系统代理。无需关闭 VPN,按范围选一种方式。
| 要抓什么 | 做法 | 影响范围 |
|---|---|---|
| 浏览器 | 只有这个 Chrome | |
| 命令行程序 | 同一窗口的 | 只有这个终端窗口 |
| 单条命令 | curl -x http://127.0.0.1:9090 … | 只有这条命令 |
| 某些域名的所有流量 | 在 VPN 里把这些域名转发到 Capture,见 | 这些域名 |
| 所有应用 | 开启系统代理,Capture 会请求管理员密码,把代理写入 VPN 的网络状态 | 整台 Mac,退出时恢复 |
VPN 把流量转发给 Capture 时,Capture 需要绕过 VPN 出站,否则请求会回环。默认自动处理,可在 切换。
主窗口左侧按应用和域名归类,中间是请求,右侧是选中请求的详情。
.har、.capture、.chlsj 文件拖到窗口上即可打开。⌃⌘T 新建列表标签,每个标签有自己的过滤条件。⌃⌘\ 打开 Split View,并排显示两个列表,菜单和详情跟随你最后操作的一侧。
在 添加列,来源可以是请求或响应的 Header,也可以是 JSON 字段,如 data.items.0.id。
右键域名可以收藏、隐藏、导出或删除它的请求。隐藏的域名仍会被捕获,可在设置中恢复。
请求和响应各有一组标签,只显示适用于当前内容的标签。
| 标签 | 内容 |
|---|---|
| 头部、查询、Cookie | 双击复制值,右键可用这个值过滤列表 |
| 正文、JSON | 语法高亮和树状视图,支持 jq 和 JSONPath 查询 |
| GraphQL | 操作名、格式化后的查询、变量,识别批量和持久化查询 |
| Protobuf、MessagePack | 无 schema 时按字段号解码,配置 .proto 后按消息类型解码 |
| 事件 | SSE 响应的事件列表,流式过程中实时更新 |
| 消息 | WebSocket 消息,可按方向和类型筛选,支持 Protobuf 解码 |
| 预览 | 图片和 HTML |
| 自定义 | 中用脚本生成的内容 |
| 时序、Hex、原始 | 各阶段耗时和连接信息、十六进制、原始报文 |
每个面板右上角的 菜单可以保存正文或原始报文,也可以强制按 Protobuf 或 MessagePack 解码。
⌥⌘1 切换请求面板,⌥⌘2 切换响应面板,⌥⌘3 切换整个详情区。把当前请求放到独立窗口,内容不随列表变化。
列表上方的搜索和分类用于日常筛选,高级过滤可以按 Header 和 Body 组合条件。
按网址搜索,也匹配方法名和状态码。写成 /正则/ 时按正则匹配。
⌥⌘F 打开。添加多个条件,选择满足全部或任一,应用后新流量也按此过滤。常用的条件可以保存。可用字段见过滤字段。
| 想找 | 字段 | 运算符 | 值 |
|---|---|---|---|
| 带某个 Header 的请求 | 请求 Header | 存在 | Header 名填 X-Trace-Id |
| 业务错误码不为 0 | 响应体 | jq | .code != 0 |
| 超过一秒的请求 | 耗时(毫秒) | 大于 | 1000 |
每个列表标签和 Split View 的每一侧都有独立的过滤条件。
从整体看流量,或者比较两个请求。
⇧⌘O 打开流量仪表盘:请求趋势、状态分布、耗时分布、域名和应用排行。点击条目跳到对应请求,报告可以复制或保存为 Markdown。
选中两个请求后右键,并排显示差异。JSON 会先规范化再比较。
⌥⌘W 把选中或当前过滤的请求排在同一时间轴上。单个请求的各阶段耗时在响应面板的标签。
暂停匹配的请求或响应,修改后再放行。
5 分钟内没有处理的消息会自动按原样继续。
窗口顶部可切换到,直接编辑完整文本。常用的 Header 和 Body 可通过保存和套用。
用本地内容回答请求,或把请求转到另一个地址。
响应可以来自自定义内容、本地文件或目录,请求不会发到服务器。右键请求选会预填当前响应。
要 Mock 多个接口,选中它们后右键,规则会放进一个新文件夹。
替换协议、主机、端口、路径前缀和查询参数,例如把线上接口切到本地服务:
匹配 https://api.example.com/*
目标 http://localhost:3000也可以映射到 ws:// 或 wss://。
重放和新建的请求同样经过 Capture,会被记录,规则也会生效。
左侧可在 Header、Query、Cookie、Form 之间切换。Form 非空时会作为 multipart 请求体发送,每行写一项:
title=测试
file=@/Users/me/photo.png发送过的请求保存在右上角的中。
右键,可生成 Swift、Python、JavaScript、Go 或 HTTPie。
所有调试规则集中在(⌥⌘U)。
输入 URL,会列出命中的全部规则和未启用的规则,也显示是否解密、走哪个外部代理。这个测试不发送请求,也不计入命中次数。
规则的写法见 URL 匹配语法。
都在菜单里,规则支持按 URL 匹配。
| 工具 | 作用 |
|---|---|
| 黑名单 | 匹配的请求返回 403 或直接断开连接 |
| 白名单 | 只记录匹配的请求,其他请求照常转发 |
| 网络条件 | 模拟带宽、延迟和丢包,提供 3G、弱网、离线等预设 |
| DNS 欺骗 | 把域名解析到指定 IP |
| 不缓存 | 移除缓存相关 Header,可在设置中限定 URL |
用 JavaScript 修改请求、响应和 WebSocket 消息。⌥⌘I 打开脚本列表。
async function onRequest(context, url, request) {
request.headers["X-Debug"] = "1";
return request;
}
async function onResponse(context, url, request, response) {
if (typeof response.body === "object") response.body.debug = true;
return response;
}| 对象 | 字段 |
|---|---|
request | method url scheme host port path queries headers body isBinaryBody |
response | statusCode headers body isBinaryBody |
body | JSON 和表单自动解析成对象,文本是字符串,二进制是 null |
| 全局 | console sharedState env btoa atob require |
勾选 后不访问服务器,由 onResponse 生成响应。脚本默认 5 秒超时,出错时请求继续,错误显示在控制台。
function onWebsocket(context, url, message) {
// message: { direction: "client" | "server", isBinary, data }
if (message.data.includes("ping")) return null; // 丢弃
message.data = message.data.replace("old", "new");
return message;
}二进制消息的 data 是 base64 字符串。
脚本不能访问文件和网络,但可以 require Addons 目录里的模块。。
const sign = require("@addons/sign.js");中定义 onPreview(context, url, request, response),返回的文本显示在响应的标签中。
解密 HTTPS 需要客户端信任 Capture 的根证书,并把域名加入 SSL 代理列表。
信任根证书后,持有这张证书私钥的程序可以解密这台 Mac 的 TLS 流量。不再使用时选
⇧⌘L 打开,支持通配符和正则。只有列表中的域名会被解密,排除列表优先。
在按域名添加。客户端证书用于要求 mTLS 的服务器,服务端证书替代自动签发的证书。文件需要 PEM 格式,p12 可以这样转换:
openssl pkcs12 -in client.p12 -nodes -out client.pem写入 SSLKEYLOGFILE 格式的文件,可供 Wireshark 解密。
这个文件能解密抓到的流量,用完后请关闭记录并删除文件。
端口、局域网访问在,其余选项在 。
| 功能 | 说明 |
|---|---|
| 系统代理 | ⌥⌘P 开关,可设置绕过域名,关闭时恢复原值 |
| 局域网访问 | 允许手机等设备连接,可用访问控制限定 IP 或网段 |
| SOCKS5 | 开启后代理端口同时接受 SOCKS5,无需认证 |
| 外部代理 | 上游可选 HTTP、HTTPS、SOCKS5 或 PAC,支持按域名路由 |
| 反向代理 | 增加一个端口转发到目标服务,流量会被记录 |
| HTTP/2 | 默认开启,可在代理设置中关闭 |
在 调整。默认保留 20000 个请求,Body 内存预算 512 MB,磁盘预算 4 GB,单个 Body 最多捕获 64 MB。
内存超过预算时,已完成请求的 Body 写入磁盘,查看时自动读回。磁盘超过预算时淘汰最旧的请求。重启后磁盘上的 Body 会被清除,需要保留时请保存会话。
打开,这些操作只影响所选设备或新窗口。
| 目标 | 操作 |
|---|---|
| iOS 模拟器 | 启动模拟器后,选中并点 |
| Android | 通过 adb 设置代理,并把证书推送到设备的 Download 目录 |
| 终端 | 打开带代理和证书环境变量的新窗口 |
| Chrome | 用独立配置目录启动一个走 Capture 的 Chrome |
| iPhone 真机 | ,扫码安装证书 |
用完 Android 设备后点,否则 Capture 退出后设备会无法联网。
当前流量可以保存成文件,也可以导出给其他工具。
| 格式 | 打开 | 导出 |
|---|---|---|
Capture 会话 .capture、旧版 .captrue | 支持 | 支持 |
| HAR | 支持 | 支持 |
Charles .chlsj | 支持 | — |
Charles .chls .chlz | 需要安装 Charles | — |
| CSV、Markdown 报告 | — | 支持 |
| OpenAPI 3.0、Postman | — | 支持 |
| cURL、代码 | — | 复制到剪贴板 |
在 设置间隔,默认关闭。历史文件从打开。
选中请求后选,需要已登录 gh。Gist 不公开列出,但拿到链接的人都能查看。
Authorization、Cookie 等 Header 会脱敏,URL 和 Body 可能仍含敏感信息,分享前请确认。
规则和抓包记录都可以带过来。
.xml 文件。支持 Map Local、Map Remote、断点、黑白名单、DNS 欺骗、反向代理和 SSL 域名。规则放进新的“Charles 导入”文件夹,相同的规则会跳过。
在 Charles 中启用的规则导入后立即生效。反向代理默认停用,因为启用后会占用端口。
.chlsj 可以直接打开。.chls 和 .chlz 需要本机安装 Charles 来转换,也可以先在 Charles 里导出为 HAR。
连接后,Claude Code 可以读取流量、定位问题、创建调试规则。使用时 Capture 要保持运行。
在点。也可以在终端运行:
claude mcp add --scope user capture -- \
/path/to/Capture.app/Contents/MacOS/capture-core mcp同一窗口还提供其他客户端的 JSON 配置,以及带 Token 的 localhost HTTP 端点。
| 类别 | 工具 |
|---|---|
| 读取 | get_status list_flows search_flows filter_flows get_flow get_errors get_slow_requests get_overview get_websocket_messages export_curl decode_body |
| 规则 | list_rules create_breakpoint create_map_local create_map_remote create_script create_block_rule set_rule_enabled delete_rule move_rule test_rule_match set_ssl_proxying |
| 文件夹 | list_folders create_folder rename_folder set_folder_enabled delete_folder |
| 断点 | list_paused resume_paused |
| 发送 | repeat_request send_request |
| 会话 | set_recording clear_flows annotate_flows export_flows open_session import_charles_rules |
| 设置 | get_capture_settings set_capture_settings list_saved_filters save_filter |
capture-cli 需要 Capture 正在运行。加 --json 输出原始 JSON。
capture-cli status
capture-cli flows --host api.example.com --status 5xx
capture-cli flow 42
capture-cli search token --in response_body
capture-cli decode 42 --jq '.items[].id'
capture-cli curl 42
capture-cli repeat 42
capture-cli record off
capture-cli har out.harcapture-cli rules
capture-cli map-local add 'api.example.com/v1/*' --file mock.json --folder Mocks
capture-cli map-remote add 'api.example.com/*' http://localhost:3000
capture-cli block add 'ads.example.com/*' --drop
capture-cli script add 'api.example.com/*' --file script.js
capture-cli ssl enable api.example.com运行 capture-cli help 查看全部命令。
也可以按 ⇧⌘P 打开命令面板,搜索任意命令。
| ⇧⌘P | 命令面板 |
| ⌘L | 聚焦网址搜索 |
| ⇧⌘F | 过滤域名 |
| ⌥⌘F | 高级过滤 |
| ⌥⌘E | 只显示错误 |
| ⌥⇧⌘R | 重置过滤条件 |
| ⇧⌘O | 概览 |
| ⌃⌘S | 切换侧栏 |
| ⌥⌘L | 切换上下 / 左右布局 |
| ⌥⌘D | 切换请求 / 响应并排 |
| ⌥⌘1 ⌥⌘2 ⌥⌘3 | 切换请求面板、响应面板、详情区 |
| ⌃⌘\ | Split View |
| ⌃⌘T ⌃⌘W ⌃⇥ | 新建、关闭、切换列表标签 |
| ⌘R | 重复 |
| ⌥⌘R | 编辑并重复 |
| ⌘N | 构建请求 |
| ⇧⌘C | 复制 cURL |
| ⌥⌘N | 添加备注 |
| ⌥⌘S | 保存响应体 |
| ⇧⌘D | 打开差异视图 |
| ⌘K ⇧⌘K | 清除会话、删除全部 |
| ⌘, | 设置 |
| ⇧⌘R | 切换录制 |
| ⌥⌘P | 系统代理 |
| ⇧⌘L | SSL 代理列表 |
| ⌥⌘U | 规则管理器 |
| ⇧⌘B | 断点 |
| ⇧⌘M ⌥⌘M | 本地映射、远程映射 |
| ⌥⌘I | 脚本列表 |
| ⌥⌘W | 瀑布图 |
| ⌘T | 新会话 |
| ⌘O | 打开 |
| ⌘S | 保存会话 |
| ⇧⌘E | 导出 HAR |
断点、Map、黑白名单、脚本和网络条件都用同一种写法。
| 写法 | 匹配 |
|---|---|
https://api.example.com/v1/* | * 匹配任意字符 |
api.example.com/v1/* | 不写协议时,同时匹配 http 和 https |
https://a.com/list | 不写查询参数时,匹配带任意查询参数的 URL |
/^https:\/\/api\d+\./ | 用斜杠包裹时按正则匹配 |
规则可以附加 GraphQL 操作名条件,如 getUser、get* 或 /^(login|logout)$/。
SSL 列表、DNS 欺骗、外部代理路由按域名匹配:example.com、*.example.com(同时匹配 example.com 本身)或 /正则/。
高级过滤和 MCP 的 filter_flows 使用同一套字段。下面的英文名用于 MCP。
| 字段 | 名称 |
|---|---|
| 网址、域名、路径 | url host path |
| 方法、状态码、应用 | method status app |
| 响应类型、请求类型 | content_type request_content_type |
| Header | request_header response_header,可填 Header 名 |
| Body | request_body response_body,自动解压 |
| 其他文本 | graphql note tag error |
| 数值 | duration request_size response_size |
| 运算符 | 说明 |
|---|---|
contains not_contains | 包含、不包含,不区分大小写 |
equals not_equals | 等于、不等于 |
starts_with ends_with | 开头、结尾 |
regex | 正则,不区分大小写 |
gt lt | 大于、小于,只用于数值字段 |
exists | 有值 |
jq jsonpath | 只用于 Body,结果非空且不为 false 时命中 |
会检查代理、证书和 VPN 状态。
| 现象 | 怎么办 |
|---|---|
| 列表里没有请求 | 确认录制没有暂停(⇧⌘R),白名单未启用。开着 VPN 时看在 VPN 下抓包。 |
| HTTPS 只显示为隧道 | 右键请求启用 SSL Proxying,重新发起请求。 |
| 提示 TLS 握手失败 | 安装并信任根证书。已信任仍失败时,应用可能启用了证书固定,把域名加入 SSL 排除列表。 |
| 规则没有生效 | 用测试规则匹配查看规则和文件夹是否启用。 |
| MCP 提示没有运行 | 打开 Capture.app 后重试。 |
| Body 显示被截断 | 在设置中调大单个 Body 捕获上限。 |
~/Library/Application Support/Capture
| 位置 | 内容 |
|---|---|
rules.json | 全部规则和设置 |
ca.pem ca-key.pem | 根证书和私钥 |
bodies/ | 写入磁盘的 Body,重启时清除 |
Sessions/ | 自动保存的会话 |
Addons/ | 脚本模块 |
tls-keys.log | TLS 密钥日志 |