loading…
Search for a command to run...
loading…
Read-only MCP server that brings Reqable's captured HTTP traffic into Claude Code conversations, enabling querying, searching, waiting for, and analyzing reques
Read-only MCP server that brings Reqable's captured HTTP traffic into Claude Code conversations, enabling querying, searching, waiting for, and analyzing requests without requiring Reqable Pro.
Bring Reqable's captured HTTP traffic into your Claude Code conversation.
Read-only · zero-touch · no Reqable Pro required.
Reqable is a native macOS HTTP/HTTPS debugging proxy. Every request it captures lands in a local ObjectBox/LMDB database. reqable-mcp is a read-only Model Context Protocol server that hands that traffic to Claude Code so you can ask the AI things like:
"List the last 10 requests Chrome sent to
api.target.com. Tell me which fields are dynamic per request — those are likely the encryption signature.""Wait for the next POST to
/login, then decode the JWT in the response and show its claims.""Diff request
0e65fcea-...andf06fdfd2-...to figure out what changed in the auth flow."
Reqable keeps doing what Reqable does best (mitm, GUI, breakpoints, mocks). This project just adds an AI-readable view on top of its existing data — no replacement, no overlap.
[!IMPORTANT] No second proxy layer while in use. Reqable is already your system proxy when capturing. Stacking another proxy (Clash, Surge, SwitchyOmega…) on top creates a request loop that will pollute capture data and may deadlock. The daemon enforces this in three places — see Proxy loop guard below.
scutil --proxy detection + zero HTTP-client imports anywhere in the codebase..fbs files shipped, no version pinning.git clone https://github.com/Wanghaibo10/Reqable-Mcp.git
cd Reqable-Mcp
./install.sh
# restart Claude Code, then in any chat:
# "Use list_recent to show me the 5 newest captures."
Sanity-check from the shell at any time:
.venv/bin/reqable-mcp status
brew install [email protected] if you need it./install.sh
What it does, in order:
$PATH.venv/ and installs the package in editable mode~/.reqable-mcp/ with 0700 permissions (cache, logs)~/.claude/mcp.jsonWhat it does not do:
~/Library/Application Support/com.reqable.macosx/sudopython3.13 -m venv .venv
.venv/bin/pip install -e .
mkdir -m 700 -p ~/.reqable-mcp
Then add this entry to ~/.claude/mcp.json (create the file if missing):
{
"mcpServers": {
"reqable": {
"command": "/absolute/path/to/.venv/bin/reqable-mcp",
"args": ["serve"]
}
}
}
Restart Claude Code. /mcp should list reqable as connected.
./uninstall.sh
Removes only ~/.reqable-mcp/ and the reqable entry in ~/.claude/mcp.json. Reqable's own data and configuration are untouched.
| Tool | Tier | What it does |
|---|---|---|
list_recent |
query | Most recent captures, filterable by host / method / status / app. |
get_request |
query | One capture in full — headers + body (body fetched on demand). |
search_url |
query | URL substring or regex search. |
search_body |
query | Full-text search across request/response body content. |
to_curl |
query | Render a capture as a runnable curl command (auto-adds --noproxy '*'). |
list_apps_seen |
query | Recently captured apps (Chrome / Safari / native binaries). |
stats |
query | Host / method / status distribution over a window. |
diff_requests |
query | Field-level diff between two captures (metadata + headers). |
wait_for |
sync | Block until the next matching capture appears (or until timeout). |
find_dynamic_fields |
reverse | Detect fields that vary request-to-request — likely tokens / signatures. |
decode_jwt |
reverse | Decode a JWT, or extract one from a captured request's headers. |
extract_auth |
reverse | List Authorization / Cookie / X-*-Token values seen on a host. |
status |
meta | Daemon + LMDB schema + sync counters (also a CLI command). |
Each tool's docstring is what Claude Code shows when it lists tools — keep that in mind if you hack on them.
Once installed, just talk to Claude Code. Every interaction below is what an actual conversation looks like — Claude calls the tool itself based on intent.
You: What URLs has Chrome hit in the last 5 minutes? Group by host.
Claude (uses
list_apps_seenthenlist_recentfiltered by app): In the last 5 min Chrome made 168 requests across these hosts:www.vipdlt.com(36),outlook.live.com(23),s.c-ctrip.com(14)…
You: I'm reverse-engineering
target-api.com. Which request fields look like they're freshly generated each call?Claude (uses
find_dynamic_fields(host="target-api.com")): Across 20 sampled requests these vary on every call — likely signatures / nonces:
header:x-bm-sensor-data(long base64)query:_t(millisecond timestamps)body.requestId(UUIDs)Stable across all 20:
header:host,header:user-agent,query:appid.
You: I'm about to click "checkout" — wait for the order POST and tell me what auth headers it carries.
Claude (uses
wait_for(host="api.shop.com", method="POST", path_pattern="/orders", timeout_seconds=120)thenextract_auth): Got it — captureb51c72ac-…. The request carriedAuthorization: Bearer eyJhbGciOiJIUz…, plus four cookies:session_id,csrf,device_fp,cart_token. The Bearer is a JWT — decoded payload hassub: 4892731,expin 14 minutes.
You: Give me a curl that reproduces the latest call to
/api/v2/quote.Claude (uses
search_url("/api/v2/quote", limit=1)→to_curl):curl --noproxy '*' -X POST \ -H 'host: api.example.com' \ -H 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp…' \ -H 'content-type: application/json' \ --data-raw '{"hotelId":12345,"checkin":"2026-05-01"}' \ 'https://api.example.com/api/v2/quote'
[browser / app]
│
▼
[Reqable mitm proxy] (Reqable.app — unchanged)
│
├──▶ [box/data.mdb] ◀── LMDB poller (250 ms, idle backoff)
│ (ObjectBox: metadata)
│
└──▶ [capture/{conn}-{sess}- ◀── Body source (read on demand)
{req_raw|res-raw|res-extract}-body.reqable]
┌─────────────── reqable-mcp serve (single process) ───────────────┐
│ proxy_guard env scrub + scutil --proxy detection │
│ LmdbSource FlatBuffers parse, base64+gzip+json decode │
│ BodySource capture/ file lookup by (conn_ts, conn_id, sid)│
│ Database SQLite WAL + FTS5 — metadata index only │
│ WaitQueue threading.Event broadcast for wait_for │
│ FastMCP stdio JSON-RPC, 13 tools registered │
└──────────────────────────────┬──────────────────────────────────┘
│ stdio
▼
[Claude Code]
Key design choices (see .spec/reqable-mcp/spec.md for full rationale):
capture/*.reqable.reqable-mcp serve, the daemon lives only as long as that stdio session. Cold-start ≈ 250 ms.requests/urllib3/aiohttp/httpx out — they'd inherit env-driven proxy config and break the loop guard.[!CAUTION] Reqable as system proxy is fine. Any second proxy on top is not.
The daemon enforces this on three layers:
| Layer | Mechanism |
|---|---|
| L1 — process env | scrub_env() deletes every *_PROXY variable on startup and sets NO_PROXY=*. |
| L2 — system proxy detection | scutil --proxy is parsed at startup; non-loopback proxies emit a stderr warning. Set REQABLE_MCP_STRICT_PROXY=1 to exit instead. |
| L3 — code review | The codebase contains zero imports of requests / urllib3 / aiohttp / httpx — tests/test_e2e.py::test_no_http_clients_imported greps the source tree to enforce this on every test run. |
| Variable | Default | Effect |
|---|---|---|
REQABLE_MCP_STRICT_PROXY |
0 |
When 1, exit with code 2 if a non-loopback system proxy is active at startup. |
| Path | Purpose |
|---|---|
~/.reqable-mcp/cache.db |
SQLite metadata index (WAL mode). Safe to delete; rebuilt on next run. |
~/.reqable-mcp/daemon.log |
Daemon stderr (verbosity controlled by --log-level). |
~/.reqable-mcp/state.json |
Future use; currently unused. |
~/Library/Application Support/com.reqable.macosx/box/ |
Reqable LMDB. Read-only. |
~/Library/Application Support/com.reqable.macosx/capture/ |
Reqable body files. Read-only. |
reqable-mcp serve # MCP stdio server (Claude Code spawns this)
reqable-mcp status # Daemon snapshot as JSON, then exit
reqable-mcp install-help # Print MCP registration JSON
reqable-mcp --version
reqable-mcp --help
| Tested | |
|---|---|
| macOS | 14, 15 |
| Reqable | 3.0.40 (April 2026) |
| Python | 3.10 / 3.11 / 3.12 / 3.13 |
| MCP SDK | 1.27.0 |
ObjectBox schema is parsed at runtime, so additive changes (new fields) are tolerated automatically. Breaking changes (renamed fields, new dbData envelope) require updating the projection in lmdb_source.py. The decoder is fail-safe: any individual record that won't decode is logged and skipped, never crashes the daemon.
This project does not support mitmproxy / Charles / Proxyman — those use different storage formats and would each need their own source module.
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest # 111 tests; integration ones skip if no Reqable LMDB
.venv/bin/ruff check src/ tests/
.venv/bin/mypy src/
The repository layout:
.
├── .spec/reqable-mcp/ # Specification: read this before changing things
│ ├── spec.md # Requirements + design decisions + data model
│ ├── tasks.md # Module-by-module task plan
│ └── checklist.md # Acceptance checklist
├── src/reqable_mcp/
│ ├── proxy_guard.py # L1+L2 of the proxy guard
│ ├── paths.py # Filesystem path resolution
│ ├── db.py + schema.sql # SQLite cache layer
│ ├── wait_queue.py # Broadcast wait queue (threading.Event)
│ ├── daemon.py # Component composition
│ ├── mcp_server.py # FastMCP stdio entry
│ ├── __main__.py # `reqable-mcp` CLI dispatch
│ ├── sources/
│ │ ├── flatbuffers_reader.py # No-schema FB parser (stdlib only)
│ │ ├── objectbox_meta.py # ObjectBox entity introspection
│ │ ├── lmdb_source.py # 250 ms poller + decoder
│ │ └── body_source.py # capture/ file reader
│ └── tools/
│ ├── query.py # 8 query tools
│ ├── wait.py # wait_for
│ └── analysis.py # JWT / dynamic-fields / auth extraction
├── tests/ # 111 tests (unit + integration)
├── install.sh / uninstall.sh
└── pyproject.toml
Integration tests use a real_lmdb_required fixture that resolves to your local Reqable LMDB if one exists; otherwise they skip cleanly. Pure-logic tests have no such requirement.
capture/ files can be purged by Reqable. The tools surface body_status: "unavailable" in that case.method=CONNECT and limited metadata.The MVP covers query, search, wait, and analysis. Two future phases extend into write-back territory:
tag_pattern / comment_request to highlight captures in Reqable's UI, plus mock_response / block / replace_body. Requires Reqable Pro (the script feature) and writing to config/capture_config's scriptConfig. Entry condition: a week of MVP daily-use without daemon crashes, plus three concrete write-back use cases.dump_body, export_har, replay_request(uid, modifications)..fbs filereqable-mcp 把 Reqable 抓到的 HTTP/HTTPS 流量,通过 Model Context Protocol 只读地暴露给 Claude Code。
安装: ./install.sh,然后重启 Claude Code。
强约束: Reqable 抓包时本身就是系统代理,所以不要再叠第二层代理(Clash / Surge 等),否则会形成回环。
详细中文版设计文档见 .spec/reqable-mcp/spec.md(需求 + 架构 + 数据模型 + 决策追溯)。
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"reqable-mcp": {
"command": "npx",
"args": []
}
}
}