browser-to-api
browserbase/skills
通过分析观察到的 HTTP 流量、对 URL 进行模板化处理,并从请求/响应样本中推断 JSON 模式,根据浏览器跟踪捕获数据生成 OpenAPI 3.1 规范。
...展开全部浏览器到 API
基于重放的 API 发现。读取浏览器跟踪数据,配对其中的 CDP 请求/响应事件,对观察到的 URL 进行模板化处理,从样本中推断 JSON 模式,并生成OpenAPI 3.1文档以及一份易于阅读的覆盖率报告。
此技能不会捕获流量。它纯粹是在browser-trace 的 cdp/network/*.jsonl存储桶基础上进行的离线后处理。这两个技能组合使用:
browser-trace → .o11y//cdp/network/{requests,responses}.jsonl
browser-to-api → .o11y//api-spec/index.html + openapi.yaml + client.mjs
何时使用
- 用户希望为第三方或未文档化的网站 API 获取 OpenAPI 文档。
- 用户已运行过
浏览器跟踪,并希望从中提取端点和模式。 - 用户正在针对未发布规范的网站构建客户端/SDK。
- 用户需要一份覆盖率报告,以显示哪些流程会扩展该规范。
如果用户需要捕获流量,请先引导其使用浏览器跟踪功能。
两步工作流
1. 使用browser-trace捕获流量(可选:通过“浏览网络”功能捕获请求体)
# 针对现有可调试 Chrome 目标的本地示例
TARGET=9222
node ../browser-trace/scripts/start-capture.mjs "$TARGET" my-site
browse open about:blank --cdp "$TARGET"
browse network on # 捕获请求/响应正文
browse open https://example.com
# ...执行您希望捕获的任何流量操作...
# 在关闭捕获功能之前对正文目录进行快照(临时目录是
# 按会话共享的,因此如果跳过此步骤,后续的 `browse network on` 运行会将您的正文
# 与未来捕获写入的内容混在一起)。
cp -r "$(browse network path | jq -r .path)" .o11y/my-site/cdp/network/bodies/
browse network off
node ../browser-trace/scripts/stop-capture.mjs my-site
node ../browser-trace/scripts/bisect-cdp.mjs my-site
启用“browse network”是 可选的,但强烈建议启用——若未启用,规范中将没有响应正文模式(“browse cdp”使用的 CDP 数据流不包含正文)。启用后,请求正文(已由 CDP 捕获)和响应正文都会通过 CDPrequestId 合并到跟踪记录中。
2. 生成规范
node scripts/discover.mjs --run .o11y/my-site
# → .o11y/my-site/api-spec/index.html ← 打开此文件
# .o11y/my-site/api-spec/client.mjs
# .o11y/my-site/api-spec/openapi.yaml
# .o11y/my-site/api-spec/openapi.json
# .o11y/my-site/api-spec/report.md
# .o11y/my-site/api-spec/confidence.json
# .o11y/my-site/api-spec/samples/*.json
# .o11y/my-site/api-spec/intermediate/*.jsonl
discover.mjs会自动检测若要使用来自其他位置的请求体(例如未创建快照,希望获取实时浏览网络目录),请显式传入--bodies。
3. 打开 HTML 报告
discover.mjs运行完成后,请务必打开生成的 HTML 报告:
打开 .o11y/my-site/api-spec/index.html
该报告是一个自包含的 HTML 文件(无需服务器),将每个发现的操作以可展开的卡片形式展示,其中包含变量、客户端用法、请求/响应示例,以及底部生成的client.mjs代码片段。这是主要交付成果——务必为用户打开此报告。
CLI 参数
| 参数 | 必填 | 含义 |
|---|---|---|
--run |
是 | 浏览器跟踪运行目录的路径 |
--out |
否 | 输出目录;默认 |
--bodies |
无 | 浏览网络捕获目录以将其加入跟踪(若存在,则从自动检测) |
--include |
否 | 仅包含匹配正则表达式的 URL(可重复使用) |
--exclude |
否 | 排除匹配正则表达式的 URL(可重复指定;除默认规则外) |
--origins |
否 | 以逗号分隔的来源白名单(例如:api.example.com,example.com) |
--format |
无 | 输出格式。默认同时输出 |
--title |
无 | OpenAPIinfo.title。默认值来自主要来源 |
--redact |
否 | 需要屏蔽的额外标头名称/JSON键(以逗号分隔) |
--min-samples |
否 | 每个端点至少包含的样本数。默认值为1 |
--stage |
无 | 仅运行一个阶段:加载、过滤、归一化、推断、输出 |
输出布局
/api-spec/
├── index.html 可视化报告 — 打开此文件(自包含,无需服务器)
├── client.mjs 零依赖的 fetch 客户端,每项操作均带有类型化函数
├── openapi.yaml 机器可读规范
├── openapi.json 镜像文件
├── report.md Markdown 摘要 + curl 示例
├── confidence.json 各端点的置信度 + 标准化标志
├── samples/ 经过处理的请求/响应示例
│ └──__.json
└── intermediate/ 管道处理副产品(配对/过滤后的端点 jsonl 文件)
通过“浏览 CDP”和“浏览网络”功能可获得的内容
两个互补的捕获来源:
| 来源 | 提供 | 限制 |
|---|---|---|
browse cdp(由browser-trace 使用) |
请求方法/URL/头部/POST数据,响应状态码/头部/MIME类型,完整的事件时间戳 |
不包含响应正文。必须通过Network.getResponseBody 获取响应正文,而 Firehose 无法执行此操作。 |
浏览网络(单独命令) |
请求正文和响应正文存储在磁盘上,以 CDP请求 ID作为键 |
捕获目录在每次浏览会话中共享;若在执行下一次“browse network on”之前创建快照,则会覆盖该目录。 |
若向`discover.mjs`传递`--bodies` 参数(或将其存储在 `` 目录下,该目录会被自动检测),该脚本将从网络浏览目录中提取请求体和响应体。匹配基于`requestId`进行——网络浏览功能会将其写入每个`request.json`文件中的`id` 字段,我们直接进行关联。
当存在请求正文时,以下内容会发生变化:
- ✅ 路径模板、查询参数模式、状态码、内容类型——无论是否存在请求体,这些都保持不变。
- ✅ 请求正文模式——CDP 提供的
postData已足够;对于非 postData情况,请求正文目录仅作为补充。 - ✅响应正文模式——完全从真实样本中推导得出。若无正文,则生成
{ description, content:这样的骨架结构。}
该报告会标记所有没有响应正文样本的端点。
自动噪声过滤
规范化阶段会自动分类并过滤基础设施噪声:
- 跟踪/分析— 包含
/track、/pixel、/beacon、/impression、/pageview、/dag/v*的路径 - 机器人防御— Akamai (
/akam/)、指纹有效载荷 (sensor_data)、经过混淆的多段路径 - 会话管理—
/session、/authenticate/start、Cookie 同意、A/B 实验端点 - HTML 页面渲染— 返回
text/html的GET请求(指渲染后的页面,而非 API)
这通常会过滤掉 60-80% 的捕获流量。可通过--include标志挽救误报。
GraphQL / 多路复用端点分解
当调用单个端点(如/dapi/fe/gql)时,若其operationName值不同,该技能会自动将其拆分为独立的逻辑操作。每个操作都会获得:
- OpenAPI 路径条目(例如
/dapi/fe/gql [自动完成]) - 仅根据该操作的样本推导出的请求/响应模式
- 报告中的 Curl 示例和变量表
检测机制基于请求体字段(operationName、method、action)和查询参数(opname、op)进行。这涵盖了 GraphQL(APQ 和内联)、JSON-RPC 以及类似的分发模式。
限制
- 覆盖范围受捕获流的限制。跟踪中未调用的端点将不会显示。该技能无法保证完整性。
- 模式是归纳推导出的,而非契约约定。即使所有样本都包含某个字段,该字段在服务器端也可能是非必填的。
- 身份验证仅被观察到,而非明确指定。该技能会将符合身份验证格式的头部信息记录在
x-observed-auth扩展中,但不会断言具体的安全方案。 - 路径模板化采用启发式方法。按分段检测数值、UUID、十六进制和 slug 模式。模糊的 URL 会在
confidence.json中被标记。 - 信息屏蔽采用尽最大努力原则。默认屏蔽涵盖常见凭据,但应用程序特定的密钥可能被遗漏;对于已知的自定义标头/密钥,请使用
--redact 参数。
最佳实践
- 引导您希望记录的操作流。浏览器跟踪记录越丰富,规范就越详尽。
- 对于信息冗余的网站,请使用
--origins 选项。营销页面可能调用数十个分析服务器;请仅限制为您关心的 API 源。 - 请先查看
report.md 文件。其中包含适用于 curl 的示例,以及每项已发现操作的响应样本。 - 若希望最终文档中仅包含形态明确的端点,请将
--min-samples值调高至 2 以上——从而过滤掉长尾数据。 - 当响应正文结构至关重要时,请配合
开启“浏览网络”功能。仅使用 CDP 数据流时,它包含请求正文但没有响应正文。
有关管道内部机制和文件格式参考,请参阅 REFERENCE.md。
---
name: browser-to-api
description: Generate an OpenAPI 3.1 specification from a browser-trace capture by analyzing observed HTTP traffic, templating URLs, and inferring JSON schemas from request/response samples.
license: MIT
---
# Browser to API
Replay-driven API discovery. Consume a `browser-trace` capture, pair its CDP request / response events, templatize observed URLs, infer JSON schemas from samples, and emit an **OpenAPI 3.1** document plus a human-readable coverage report.
This skill **does not capture traffic**. It is purely offline post-processing on top of `browser-trace`'s `cdp/network/*.jsonl` buckets. The two skills compose:
```
browser-trace → .o11y/<run>/cdp/network/{requests,responses}.jsonl
browser-to-api → .o11y/<run>/api-spec/index.html + openapi.yaml + client.mjs
```
## When to use
- The user wants an OpenAPI document for a third-party or undocumented website API.
- The user has a `browser-trace` run and wants endpoints + schemas extracted from it.
- The user is building a client/SDK against a site that doesn't publish a spec.
- The user wants a coverage report showing which flows would broaden the spec.
If the user wants to **capture** traffic, send them to `browser-trace` first.
## Two-step workflow
### 1. Capture with `browser-trace` (and optionally bodies via `browse network on`)
```bash
# Local example against an existing debuggable Chrome target
TARGET=9222
node ../browser-trace/scripts/start-capture.mjs "$TARGET" my-site
browse open about:blank --cdp "$TARGET"
browse network on # capture request/response bodies
browse open https://example.com
# ...drive whatever flows you want covered...
# Snapshot the bodies dir BEFORE turning capture off (the temp dir is shared
# per-session, so subsequent `browse network on` runs would mix your bodies
# with whatever a future capture writes if you skip this step).
cp -r "$(browse network path | jq -r .path)" .o11y/my-site/cdp/network/bodies/
browse network off
node ../browser-trace/scripts/stop-capture.mjs my-site
node ../browser-trace/scripts/bisect-cdp.mjs my-site
```
`browse network on` is **optional but strongly recommended** — without it, the spec has no response-body schemas (the CDP firehose used by `browse cdp` does not embed bodies). With it, both request bodies (already captured by CDP) *and* response bodies are joined into the trace by CDP `requestId`.
### 2. Generate the spec
```bash
node scripts/discover.mjs --run .o11y/my-site
# → .o11y/my-site/api-spec/index.html ← open this
# .o11y/my-site/api-spec/client.mjs
# .o11y/my-site/api-spec/openapi.yaml
# .o11y/my-site/api-spec/openapi.json
# .o11y/my-site/api-spec/report.md
# .o11y/my-site/api-spec/confidence.json
# .o11y/my-site/api-spec/samples/*.json
# .o11y/my-site/api-spec/intermediate/*.jsonl
```
`discover.mjs` auto-detects `<run>/cdp/network/bodies/`. To use a body capture from elsewhere (e.g. didn't snapshot, want the live `browse network` dir), pass `--bodies <path>` explicitly.
### 3. Open the HTML report
After `discover.mjs` finishes, **always open the generated HTML report**:
```bash
open .o11y/my-site/api-spec/index.html
```
The report is a self-contained HTML file (no server needed) that shows each discovered operation as an expandable card with variables, client usage, request/response examples, and a generated `client.mjs` snippet at the bottom. This is the primary deliverable — always open it for the user.
## CLI flags
| Flag | Required | Meaning |
|---|---|---|
| `--run <path>` | yes | Path to a `browser-trace` run directory |
| `--out <path>` | no | Output dir; default `<run>/api-spec/` |
| `--bodies <path>` | no | `browse network` capture dir to join into the trace (auto-detected from `<run>/cdp/network/bodies/` when present) |
| `--include <regex>` | no | Only include URLs matching regex (repeatable) |
| `--exclude <regex>` | no | Exclude URLs matching regex (repeatable; in addition to defaults) |
| `--origins <list>` | no | Comma-separated origin allow-list (e.g. `api.example.com,example.com`) |
| `--format <yaml\|json\|both>` | no | Output format. Default `both` |
| `--title <string>` | no | OpenAPI `info.title`. Default derived from primary origin |
| `--redact <list>` | no | Extra header names / JSON keys to redact (comma-separated) |
| `--min-samples <n>` | no | Minimum samples per endpoint to include. Default `1` |
| `--stage <name>` | no | Run only one stage: `load`, `filter`, `normalize`, `infer`, `emit` |
## Output layout
```
<run>/api-spec/
├── index.html visual report — open this (self-contained, no server)
├── client.mjs zero-dep fetch client with typed functions per operation
├── openapi.yaml machine-readable spec
├── openapi.json mirror
├── report.md markdown summary + curl examples
├── confidence.json per-endpoint confidence + normalization flags
├── samples/ redacted request/response examples
│ └── <method>__<path-hash>.json
└── intermediate/ pipeline byproducts (paired/filtered/endpoints jsonl)
```
## What you get from `browse cdp` and `browse network`
Two complementary capture sources:
| Source | Provides | Limitation |
|---|---|---|
| `browse cdp` (used by `browser-trace`) | request method/URL/headers/`postData`, response status/headers/mimeType, full event timing | **Does not embed response bodies.** Bodies must be pulled with `Network.getResponseBody`, which the firehose doesn't do. |
| `browse network on` (separate command) | request bodies AND response bodies on disk, keyed by CDP `requestId` | Capture dir is shared per `browse` session; snapshot before another `browse network on` overwrites it. |
`discover.mjs` will pull bodies from a `browse network` dir if you pass `--bodies <path>` (or stash them under `<run>/cdp/network/bodies/`, which is auto-detected). The matching is by `requestId` — `browse network` writes that into each `request.json` as `id`, and we join directly.
What changes when bodies are present:
- ✅ Path templating, query-param schemas, status codes, content-types — same either way.
- ✅ Request-body schemas — `postData` from CDP is enough; bodies dir is a nice-to-have for non-`postData` cases.
- ✅ **Response-body schemas** — fully inferred from real samples. Without bodies you get `{ description, content: <mimeType> }` skeletons.
The report flags every endpoint that has no response-body sample.
## Automatic noise filtering
The normalize stage automatically classifies and drops infrastructure noise:
- **Tracking / analytics** — paths containing `/track`, `/pixel`, `/beacon`, `/impression`, `/pageview`, `/dag/v*`
- **Bot defense** — Akamai (`/akam/`), fingerprint payloads (`sensor_data`), obfuscated multi-segment paths
- **Session plumbing** — `/session`, `/authenticate/start`, cookie consent, A/B experiment endpoints
- **HTML page renders** — `GET` requests returning `text/html` (the rendered page, not the API)
This typically drops 60-80% of captured traffic. The `--include` flag can rescue a false positive.
## GraphQL / multiplexed endpoint decomposition
When a single endpoint (like `/dapi/fe/gql`) is called with different `operationName` values, the skill automatically splits it into separate logical operations. Each gets its own:
- OpenAPI path entry (e.g. `/dapi/fe/gql [Autocomplete]`)
- Request/response schema inferred from only that operation's samples
- Curl example and variables table in the report
Detection works on body fields (`operationName`, `method`, `action`) and query params (`opname`, `op`). This covers GraphQL (APQ and inline), JSON-RPC, and similar dispatch patterns.
## Limitations
- **Coverage is bounded by the captured flow.** Endpoints not exercised in the trace will not appear. The skill cannot prove completeness.
- **Schemas are inductive, not contractual.** A field might be optional on the server even if every sample contained it.
- **Auth is observed, not specified.** The skill records auth-shaped headers in an `x-observed-auth` extension but won't claim a security scheme.
- **Path templating is heuristic.** Numeric / UUID / hex / slug patterns are detected per segment. Ambiguous URLs are flagged in `confidence.json`.
- **Redaction is best-effort.** Default redactions cover common credentials, but app-specific secrets may slip through; use `--redact` for known custom headers/keys.
## Best practices
1. **Drive the flows you want documented.** The richer the browser-trace, the richer the spec.
2. **Use `--origins` for noisy sites.** A marketing page hits dozens of analytics hosts; restrict to the API origin you care about.
3. **Inspect `report.md` first.** It has curl-ready examples and response samples for every discovered operation.
4. **Bump `--min-samples` to 2+** when you want only confidently-shaped endpoints in the final doc — drop the long tail.
5. **Pair with `browse network on`** when response-body schemas matter. The CDP firehose alone has request bodies but not response bodies.
For pipeline internals and the file format reference, see [REFERENCE.md](REFERENCE.md).





首页
