Skip to main content
Glama
TonyChen-SH

Camoufox Reverse MCP

by TonyChen-SH

Camoufox Reverse MCP

本地采集 Camoufox 原生 API 日志,按脚本位置查看调用和返回值摘要,并通过只读 MCP 工具分析。配套浏览器源码:camoufox-reverse。Python 模块名为 camoufox_trace_mcp,避免与其他同名 Camoufox 工具混淆。

另支持 VisibleV8 原始日志及原生引擎分段传输:保留线程、isolate、脚本全文与 eval 来源,按线程导出标准日志。binding 与 engine 通道分别统计;原始 VV8 没有提供的返回值和异常结果保持未知。接收端已通过合成记录与真实 SDK 回归;新增原生引擎浏览器的构建和运行结果须以配套仓库证据为准,不能由本包测试推断。完整协议与使用方法。

支持通用 WebIDL 的读、写、方法和构造事件,已通过真实监控浏览器日志的 SDK stdio 联调。原生侧已完成 Linux x86_64 全量编译,生成清单含 1,030 个接口、9,884 个 API 名和 12,852 个操作入口;逐次完整运行门禁与下载以配套构建工作流为准。下载监控浏览器并校验安装包,再按下面的步骤采集。普通 Camoufox 安装包不输出这些原生事件。离线 fixtures/ 是合成测试记录。

快速运行

Python 3.11+。从本仓库根目录运行以下命令;离线分析只用标准库,无须安装 MCP SDK:

python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e .
python -m camoufox_trace_mcp summarize fixtures/pilot.jsonl
python -m camoufox_trace_mcp events fixtures/pilot.jsonl --api WebGLRenderingContext.getParameter --limit 20
python -m camoufox_trace_mcp compare fixtures/pilot.jsonl fixtures/pilot.jsonl
python -m camoufox_trace_mcp events fixtures/webidl.jsonl --op set --scope instance
python -m camoufox_trace_mcp events fixtures/webidl.jsonl --op construct --scope constructor
python -m camoufox_trace_mcp events fixtures/webidl.jsonl --op call --scope static
python -m camoufox_trace_mcp summarize fixtures/engine.jsonl --channel engine
python -m camoufox_trace_mcp events fixtures/engine.jsonl --channel engine --op get --property-name userAgent
python -m camoufox_trace_mcp scripts fixtures/engine.jsonl
python -m camoufox_trace_mcp script-source fixtures/engine.jsonl --index 0

摘要包括 API 次数、脚本 URL/行列、调用位置聚合、返回值摘要变体、异常与截断情况。compare 输出调用计数及调用位置结果摘要的差异;它不匹配同一个逻辑调用,也不把差异认定为风控原因。对象只含类名、字符串可能截断,相同摘要不能证明原值相同。

events 的 --op 可选 get、set、call、construct;--scope 可选 instance、static、constructor、unknown。筛选可与 API、URL、PID、异常、分页组合。unknown 选出缺少 scope 的旧日志,不将其推断为实例成员。调用位置聚合与比较包含 op 和 scope,静态成员与实例成员分开;API 总计仍按 API 名聚合。

数值负零会保留符号;返回摘要按计数与规范 JSON 键稳定排序,相同结果集合不会因线程完成顺序或进程编号改变而产生差异。

Related MCP server: AgentInspect MCP Server

采集

POSIX 系统可显式启动一个本地命令,收集 stderr 中带 CAMOUFOX_TRACE 标记的事件,写入新 JSONL 文件。拒绝覆盖已有文件,不使用 shell。这个功能仅在 CLI 提供,MCP 不执行进程。

mkdir -p traces
python -m camoufox_trace_mcp collect --output traces/demo.jsonl --timeout 10 -- python fixtures/replay.py
python -m camoufox_trace_mcp summarize traces/demo.jsonl

fixtures/replay.py 回放合成事件并夹入普通日志,用于验证采集链路。真实采集时把 -- 后的命令换成使用已编译监控浏览器的启动程序。采集器自动传入 CAMOUFOX_TRACE=1;需要栈时在外层设置 CAMOUFOX_TRACE_STACK=1。普通 stdout 丢弃,普通 stderr 不写入 trace,结果 JSON 单独输出到 CLI stdout。

接入现有 Camoufox 脚本时,先把脚本中的 executable_path 指向监控版的 bin/camoufox-bin。Playwright 驱动会接管浏览器 stderr,所以采集 Python 脚本还需打开驱动的浏览器日志,并关闭日志颜色以保留 JSON 行:

DEBUG=pw:browser DEBUG_COLORS=0 CAMOUFOX_TRACE_STACK=1 \
python -m camoufox_trace_mcp collect --output traces/session.jsonl --timeout 180 -- python your_script.py

这条命令从当前目录运行你的 your_script.py。如果脚本向 Camoufox 显式传入 env,应把继承的环境合并进去,让 CAMOUFOX_TRACE 等设置进入实际浏览器进程。脚本正常关闭浏览器后,使用 summarize traces/session.jsonl 找到脚本位置,再用 events 查询该 API 的原始参数、返回摘要和栈。

浏览器对应的 Python 启动器验证版本为 Camoufox b6205b0 与 Playwright 1.62.0。在当前虚拟环境中安装同一版本:

git clone https://github.com/daijro/camoufox.git ../camoufox-launcher
git -C ../camoufox-launcher checkout b6205b0ee1e4c2e8e4bb9eb0e084472028a9c6a3
python -m pip install 'playwright==1.62.0' -e ../camoufox-launcher/python
python ../camoufox-launcher/python/scripts/pin-fpgen-model.py

不使用自动化脚本时,也可直接采集浏览器;在窗口内复现问题并正常关闭浏览器后分析:

trace_profile=$(mktemp -d)
CAMOUFOX_TRACE_STACK=1 python -m camoufox_trace_mcp collect \
  --output traces/manual.jsonl --timeout 300 -- /absolute/path/bin/camoufox-bin \
  -no-remote -profile "$trace_profile" https://example.com
python -m camoufox_trace_mcp summarize traces/manual.jsonl
python -m camoufox_trace_mcp events traces/manual.jsonl --api HTMLCanvasElement.toDataURL --limit 20

把网址换成要排查的页面。独立临时配置让这次采集使用新浏览器进程;也可按监控版安装包中的 examples/ 启动本地回归页面,先验证链路。静态页面没有执行这些 API 时可能没有事件。

超时、中断、非零/信号退出、无法启动、输出上限和 stderr 未排空都会保存在 collection 记录。POSIX 进程组负责回收仍在同组内的子进程;自行脱离进程组的程序不在这个保证内。关闭浏览器后采集才正常结束;到达 --timeout 会终止进程并返回 124。

CLI 退出码:0 为已观察到事件且没有已知采集丢失,3 为无事件,65 为已知不完整/格式损坏,2 为参数或文件错误;子进程失败保留其非零状态(超时 124、中断 130、启动失败 127)。0 不代表网站无检测。

MCP 接入

MCP 使用固定版本 SDK;锁文件固定开发验证所用的依赖版本。Python 3.12 / Linux 为 CI 环境。文件访问与 stdio 管道实现需要 POSIX。

python -m pip install -r requirements-mcp.lock
python -m pip install --no-deps -e .
mkdir -p traces
cp fixtures/pilot.jsonl traces/pilot.jsonl
python -m camoufox_trace_mcp serve --trace-root "$PWD/traces"

最后一条命令等待 MCP 客户端输入。支持 stdio 的客户端配置示例(替换绝对路径):

{
  "mcpServers": {
    "camoufox-trace": {
      "command": "/absolute/path/camoufox-reverse-mcp/.venv/bin/python",
      "args": ["-m", "camoufox_trace_mcp", "serve", "--trace-root", "/absolute/path/camoufox-reverse-mcp/traces"]
    }
  }
}

只读工具:

工具

用途

list_traces

分页列出根目录下 JSONL 文件

summarize_trace

聚合 API、脚本位置、结果摘要和采集状态

get_trace_events

按 API、op、scope、URL、PID、异常筛选并分页

compare_traces

比较两份日志的观察差异并保留双方限制

get_trace_scripts

分页列出原生脚本注册、线程/isolate、eval 父脚本和源码哈希

get_trace_script_source

按脚本列表 index 分页读取完整注册源码

get_trace_raw_records

按线程查看重组后的原始 VV8 记录

传入相对 .jsonl 或 .log 路径,例如 pilot.jsonl。拒绝绝对路径、..、符号链接与特殊文件;逐层使用目录文件描述符和 O_NOFOLLOW 打开文件。MCP 不访问任意文件、不打开浏览器、不执行网页脚本。stdio 使用事件循环管道并复用 SDK 的协议处理,避免阻塞文件读取依赖工作线程唤醒。

get_trace_events 的 op 和 scope 取值与 CLI 相同,例如 {"path":"webidl.jsonl","op":"call","scope":"static","limit":20}。未传筛选项时保留所有操作与 scope;scope:"unknown" 可查询旧 pilot 记录。

引擎查询可组合 channel:"engine"、tid、isolate、script_id、property_name 与 source_offset。summarize_trace 和 compare_traces 也可按 channel 筛选;不筛选时,各通道的 API 总计与调用位置仍分开。脚本源码分页的 offset 使用 Unicode 码点,事件 source_offset 保留 UTF-16 单位。

协议与解释边界

支持原生 schema: 1 的 meta、api、limit,既可读原始 stderr 标记,也可读裸 JSONL。旧生产者的 coverage:"binding-pilot" 和新生产者的 coverage:"webidl-bindings" 均保留原值;后者描述 WebIDL 绑定覆盖,不能据此推断普通 JavaScript 函数或未经过这些绑定的内部调用均被监控。序号在原生调用入口分配,退出时写出,允许乱序;重复或缺号标为不完整。直接调用列号由生产者 metadata 声明,读取器不自行偏移。

通用 WebIDL API 名采用 Interface.member,普通构造器采用 Interface.constructor;旧式工厂保留其 IDL 成员名:

字段

取值与含义

op

get 读取、set 赋值、call 方法调用、construct 构造

可选 scope

instance 实例成员、static 静态成员、constructor 构造器

旧日志可以没有 scope。原始事件保留字段缺失;聚合输出以 scope:null 表示未知,与所有已声明 scope 分开。比较旧日志和新日志时,相同 API/位置但 scope 未知与已声明的记录会成为不同组;读取器不补造归属。非法操作或 scope 会明确报告为格式错误。

最多读取 64 MiB,单行 1 MiB、保留 100000 个事件和处理 200000 个记录;达到上限会报告状态。每个调用位置最多展示 10 种返回摘要和 3 个事件位置示例,超出时标记。no_known_loss 仅说明没有发现这些检查能识别的丢失;传输尾部丢失仍可能无法识别。

  • no_events、no_producer_metadata、格式错误、未知 schema、上限、截断和子进程退出均会显示;空日志不证明页面没有检测。

  • URL/行列可为空;没有 frame、Worker、request ID,不能从 PID 或 realm 类名补造。栈与值只保留日志实际提供的内容。

  • threw 是原生绑定退出时的待处理异常状态;外层 Promise 包装器可能再把它转换为 rejected Promise,不能据此断定页面同步抛出。Promise 摘要只包含对象类名,不包含异步完成值。

  • 旧 PropertyTracer 数据须加 --legacy;其 s 为原生源码位置,不能作为 JS 位置,v 也不视为调用时返回值。

  • API 调用不等于风控命中。IP、账号、TLS、HTTP、行为和服务端判定无法从这份日志直接还原。

测试

PYTHONPATH=src python -m unittest discover -s tests -v
PYTHONPATH=src python -m unittest discover -s tests_mcp -v

第二组需要锁文件中的 SDK,使用真实 stdio 客户端检查初始化、七个工具、结构化结果和路径拒绝。第一组覆盖独立 CLI、格式与序号、返回摘要差异、采集退出/超时及文件根目录约束;不需要浏览器。CI 缺少依赖会失败,不静默跳过。

当前为 88 个核心测试和 5 个真实 SDK stdio 集成测试。覆盖四种操作、CLI/MCP 组合筛选、scope 缺失兼容、静态/实例区分,以及 VV8 分片、完整源码/参数、UTF-16 行列与孤立代理码元、跨线程/isolate、eval 来源、显式未知调用者、producer 停止原因、来源不可得元数据的有界分页及全量 manifest 往返、分段连续导入及滚段导出。SDK 测试验证全部只读工具,并逐字段恢复源码、参数、属性及 symbol token 中的原始 UTF-16 码元。

最终原生运行通过五种采集模式和真实 MCP SDK 联调;带栈采集包含 929 条事件,官方 Python 启动器采集包含 1,724 条事件。四个工具、读写/构造/静态操作筛选、Worker、负零及重排比较均通过。页面回归要求原有 16 个 API 与新增操作合计 35 个不同 API 名;生成入口数量与逐项实测数量分别报告。

配套构建工作流 在浏览器五种模式、完整上游补丁守卫与 build-tester 全部通过后上传 camoufox-trace-linux-x86_64 和 native-browser-evidence。从成功的通用版本运行下载报告与原始 JSONL,可核对该次验证范围。测试结果不能直接确定目标网站的风控原因。

MIT License,见 LICENSE。

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    C
    maintenance
    Enables coding agents to query, compare, and audit local profiler traces, benchmarks, memory captures, and execution evidence without uploading code or data, using CLI and MCP interfaces.
    111
    88 PyPI
    220
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Read-only local MCP server for inspecting AgentInspect TypeScript AI-agent traces. Lists runs, exposes bounded causal-failure and TraceFacts evidence, evaluates TraceContract checks, compares runs, and creates share-checked evidence without mutating traces or invoking agent tools.
    24,326 npm
    168
    MIT
  • F
    license
    C
    quality
    B
    maintenance
    Bridges with an installed API monitoring application to enable launching and status checks, live background capture, process attach, filter-tree inspection, GUI actions, and opening, validating, decoding, searching, inspecting, exporting, and comparing saved captures and related metadata.
    59
    3
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables inspection of local SudokuPad replay files by exposing read-only tools that return replay metadata, filtered and paginated event timelines with undo/redo links, and full reconstructed grid states at a given action or time.
    MIT