camoufox-jsreverser-mcp
camoufox-jsreverser-mcp
面向 Firefox 的前端 JavaScript 逆向工程 MCP 服务器,底层走 WebDriver BiDi 与 Firefox Remote Debugging Protocol (RDP)。
对外暴露约 88 个 MCP 工具,覆盖:
页面状态、Frame、导航、截图
脚本:列出 / 取源码 / 跨脚本搜索 / 单脚本检索
调试器:行/列断点与文本断点、暂停 / 恢复 / 步入步过步出、callframe 求值、对象 inspect
Hook:函数 hook、trace、采样通道、任意 preload 注入
网络与 WebSocket:请求池、initiator 调用栈、帧捕获、XHR 断点
DOM:query / 结构 / 点击 / 输入 / 等待元素
Storage 以及会话级 save / load / dump / restore
Stealth:
firefox-defaultpreset、跨 realm 的inject_stealth_hook、worker 推送AST 与 LLM:反混淆、摘要、理解、加密规则识别
Rebuild + 证据链:bundle 构建、环境差异、证据写入、报告导出
Worker、per-context preference(
set_javascript_enabled/set_csp_enabled)
为什么是 Camoufox(而不是原版 Firefox)
工具集中大约 80%(调试器 / 脚本 / DOM / 网络 / Hook / AST / LLM)与浏览器二进制无关——它走 WebDriver BiDi 和 Firefox RDP,这两个协议原版 Firefox 150 同样支持。那为什么仍要绑定 Camoufox?因为剩下的 20%——反检测面——需要C++ 层面的二进制补丁,任何 preload 脚本都无法等价实现。
差异分布如下:
能力 | 实现位置 | 原版 Firefox | Camoufox |
调试器 / 脚本 / DOM / 网络 / Hook / AST / LLM 工具 | BiDi + RDP 的 TypeScript | ✅ 可用 | ✅ 可用 |
| TypeScript preload | ✅ 可用 | ✅ 可用 |
| C++ 二进制补丁 | ❌ 锁死为 | ✅ 已 patch |
| C++ 注入 | ❌ 空或过短 | ✅ 真实 |
WebGL vendor / renderer 伪装 | C++ 覆盖 | ❌ 泄露真实 GPU 或 | ✅ 伪装 |
Canvas 2D / AudioContext 像素与采样级噪声 | C++ 注入 | ❌ 指纹稳定可识别 | ✅ 加噪 |
字体枚举伪装 | C++ 字体表替换 | ❌ 真实安装字体 | ✅ 伪装 |
WebDriver 协议侧信道(RemoteAgent 类、Marionette 残留) | C++ 删除 | ❌ 可被探测 | ✅ 清理 |
| 字符串问题 | n/a | 可用 |
结论:在原版 Firefox 上,仅 navigator.webdriver === true 这一条,就足以让 CreepJS / sannysoft / 商业反爬评分系统直接判定为机器人,根本走不到我们 preload 那一层。TypeScript 层的 Object.defineProperty(navigator, 'webdriver', ...) 只能影响主 realm,覆盖不到 worker、iframe、特权页;何况 Firefox 150 上 webdriver 属性描述符是锁死的,重定义会抛错。用 Proxy 包 navigator 也会被 navigator === window.navigator.constructor.prototype.constructor 这类比较探测到。
我们的 inject_stealth_hook 已经把 Hook 表面清理干净(Function.toString 伪装、跨 realm 探针、零全局变量——证据见 stealth-evidence/SUMMARY.md stage 6),但它有意止步于 Hook 边界。引擎级信号(navigator.webdriver、Canvas 噪声、GPU 字符串)按设计不在其能力范围内。
安装
需要 Node.js 20+。
支持的浏览器组合:Camoufox + geckodriver,且仅此一种。 原版 firefox --remote-debugging-port 暴露的是 CDP,不是 WebDriver BiDi,本项目不支持;并且 stealth 那半工具链也只对 Camoufox 生效(详见 为什么是 Camoufox)。
macOS
Camoufox:从 https://github.com/daijro/camoufox/releases 下载最新 macOS
.dmg,拖入/Applications。首次运行右键 → 打开 绕过 Gatekeeper。geckodriver:
brew install geckodriver。Apple Silicon 装到
/opt/homebrew/bin/geckodriver。Intel 装到
/usr/local/bin/geckodriver(与代码默认值一致)。
项目本体:
npm install npm run build
集成 / e2e 套件需要 Camoufox 与 geckodriver 实际可用——握手失败会直接抛错,不会自动 skip。单元测试(npm test)不依赖任何浏览器二进制。
Linux / Windows
未做常规验证。从 Camoufox releases 与 geckodriver releases 自行安装,再通过 CAMOUFOX_PATH / GECKODRIVER_PATH(或 --camoufox-path / --geckodriver-path)指向二进制路径即可。
--stealth 到底控制什么
--stealth=auto(默认)会在会话初始化时把 src/stealth-scripts/ 下的 firefox-default preload 注入进去。--stealth=off 仅跳过这一层 preload —— Camoufox 的 C++ stealth 始终生效,与这个开关无关。
在 MCP 客户端中注册
本服务的预期使用方式是被 AI agent 驱动(Claude Code、Claude Desktop、Cursor 等)。从 shell 单独跑它不是真实的逆向工作流,唯一合理的场景是验证安装是否成功(见下方 冒烟测试)。
Claude Code (CLI)
# 在仓库目录下执行,确保 build 路径解析正确
claude mcp add camoufox-jsreverser \
--env LLM_PROVIDER=openai \
--env LLM_API_KEY=sk-... \
--env GECKODRIVER_PATH=/opt/homebrew/bin/geckodriver \
-- node "$(pwd)/build/src/index.js" --stealth=auto或者直接编辑 ~/.claude.json:
{
"mcpServers": {
"camoufox-jsreverser": {
"command": "node",
"args": [
"/绝对路径/camoufox-jsreverser-mcp/build/src/index.js",
"--stealth=auto"
],
"env": {
"LLM_PROVIDER": "openai",
"LLM_API_KEY": "sk-...",
"GECKODRIVER_PATH": "/opt/homebrew/bin/geckodriver"
}
}
}
}env 块就是 agent 需要的全部配置。可用变量:
变量 | 用途 |
|
|
| 所选 provider 的 Bearer key。 |
|
|
| 可选的默认 model id。 |
| Camoufox 二进制路径。macOS 默认: |
| geckodriver 二进制路径。默认 |
understand_code、summarize_code、deobfuscate_code 这三个 LLM 后处理工具在未配置 provider 时会干净地返回 LlmNotConfigured——绝不会抛——所以即便没配 LLM key,其余工具面依然完全可用。
CLI flag
这些 flag 由 MCP 客户端通过 args 透传。常用的有:
Flag | 含义 |
| 初始化时是否注入 |
| 覆盖会被识别的 |
| 覆盖 Camoufox 二进制(优先级高于 |
| 覆盖 geckodriver 二进制(优先级同上)。 |
| 不启动新进程,而是连接已运行的 geckodriver 会话。仅开发/调试用。 |
冒烟测试安装
要确认服务能起、MCP 客户端能与之握手,本地手动跑一次:
node build/src/index.js --stealth=auto它会通过 stdio 讲 MCP 协议。成功启动没有任何 banner——静默就是对的。按 Ctrl-C 退出。这种 shell 直跑模式下的本地 env 覆盖,可以放在仓库根目录的 .env 文件里(cp .env.example .env);优先级为:MCP 客户端 env > .env > 系统环境。日常配置请始终放在客户端那边。
Stealth 工具
工具 | 用途 |
| 通过 BiDi preload 应用 stealth preset(默认 |
| 把 preset 推送到 dedicated / shared worker realm(worker 序章已运行后再注入)。 |
| 用 Function.toString 伪装 + 通道采样的 Proxy 包装某个全局点路径(如 |
| 直接注入任意 preload JS——上面三个都套不上时的逃生口。 |
| 反查 capability 已知的所有 preset / feature。 |
| 通过 BiDi emulation 覆盖 |
测试分层
npm run lint # eslint
npm run typecheck # tsc --noEmit
npm test # vitest test/unit(快,不需要浏览器)
npm run test:integration # 真 BiDi/RDP,经 geckodriver
npm run test:e2e # 完整 MCP-over-stdio 工作流(W1–W7)集成 / e2e 在缺少 Firefox 或 geckodriver 时会干净 skip,因此开发者机器上没装浏览器也不会污染单元测试结果。
CI 在 Firefox latest + latest-esr 两条线上各跑一遍三层(见 .github/workflows/ci.yml)。
License
ISC。
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/wukaka/camoufox-jsreverser-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server