js-reverse-mcp-debugging

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

js-reverse-mcp-debugging

js-reverse-mcp-debugging

Skill by ara.so — MCP Skills collection.
ara.so 开发的技能 —— MCP Skills 合集。

Overview

概述

js-reverse-mcp is an MCP server that gives AI agents full JavaScript debugging capabilities: breakpoints, call stacks, scope inspection, network analysis, and WebSocket message capture. Built on Patchright (CDP protocol anti-detection) with optional CloakBrowser (49 C++ fingerprint patches) for strong anti-bot sites.
Key features:
  • Headful debugging — visible browser, breakpoints, step-through, call stacks
  • Persistent sessions — cookies/localStorage survive restarts
  • Dual anti-detection — Patchright (protocol layer) + optional CloakBrowser (binary patches)
  • 21 MCP tools — script analysis, breakpoint control, network inspection, WebSocket analysis
  • Zero JS injection — no
    Object.defineProperty
    hacks that leak automation signals
js-reverse-mcp 是一款MCP服务器,可为AI Agent提供完整的JavaScript调试能力:断点设置、调用栈查看、作用域检查、网络分析以及WebSocket消息捕获。它基于Patchright(CDP协议反检测技术)构建,可选搭配CloakBrowser(包含49项C++指纹补丁),可应对反机器人防护严格的网站。
主要特性:
  • 可视调试 —— 可见浏览器界面、断点设置、单步执行、调用栈查看
  • 持久会话 —— Cookie/本地存储在重启后依然保留
  • 双重反检测 —— Patchright(协议层)+ 可选CloakBrowser(二进制补丁)
  • 21种MCP工具 —— 脚本分析、断点控制、网络检查、WebSocket分析
  • 零JS注入 —— 不使用
    Object.defineProperty
    这类会暴露自动化痕迹的 hack

Installation

安装

NPX (Recommended)

NPX(推荐)

Add to your MCP client configuration:
json
{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp"]
    }
  }
}
Claude Code:
bash
claude mcp add js-reverse npx js-reverse-mcp
Codex:
bash
codex mcp add js-reverse -- npx js-reverse-mcp
将以下配置添加到你的MCP客户端配置中:
json
{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp"]
    }
  }
}
Claude Code 命令:
bash
claude mcp add js-reverse npx js-reverse-mcp
Codex 命令:
bash
codex mcp add js-reverse -- npx js-reverse-mcp

Local Install

本地安装

bash
git clone https://github.com/zhizhuodemao/js-reverse-mcp.git
cd js-reverse-mcp
npm install
npm run build
Then configure with local path:
json
{
  "mcpServers": {
    "js-reverse": {
      "command": "node",
      "args": ["/path/to/js-reverse-mcp/build/src/index.js"]
    }
  }
}
bash
git clone https://github.com/zhizhuodemao/js-reverse-mcp.git
cd js-reverse-mcp
npm install
npm run build
然后使用本地路径进行配置:
json
{
  "mcpServers": {
    "js-reverse": {
      "command": "node",
      "args": ["/path/to/js-reverse-mcp/build/src/index.js"]
    }
  }
}

Configuration Options

配置选项

CLI flags (all optional):
  • --cloak
    — Use CloakBrowser binary with 49 C++ fingerprint patches (auto-downloads ~200MB on first run)
  • --isolated
    — Use temporary profile (no persistent cookies/localStorage)
  • --browserUrl, -u
    — Connect to existing Chrome instance (CDP endpoint, e.g.
    http://127.0.0.1:9222
    )
  • --logFile
    — Write debug logs to file (use with
    DEBUG=*
    env var)
CLI 参数(均为可选):
  • --cloak
    —— 使用带有49项C++指纹补丁的CloakBrowser二进制文件(首次运行时自动下载约200MB内容)
  • --isolated
    —— 使用临时配置文件(不保留持久化Cookie/本地存储)
  • --browserUrl, -u
    —— 连接到已运行的Chrome实例(CDP端点,例如
    http://127.0.0.1:9222
  • --logFile
    —— 将调试日志写入文件(需配合
    DEBUG=*
    环境变量使用)

Common Configurations

常见配置

Default (System Chrome + Persistent Login):
json
{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp"]
    }
  }
}
Anti-Bot Sites (Cloudflare, DataDome, FingerprintJS):
Pre-download CloakBrowser binary first (one-time, ~30-60s):
bash
npx cloakbrowser install
Then configure:
json
{
  "mcpServers": {
    "js-reverse-cloak": {
      "command": "npx",
      "args": ["js-reverse-mcp", "--cloak"]
    }
  }
}
Dual Setup (Switch Based on Target):
json
{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp"]
    },
    "js-reverse-cloak": {
      "command": "npx",
      "args": ["js-reverse-mcp", "--cloak"]
    }
  }
}
Connect to Running Chrome:
  1. Launch Chrome with debugging:
    bash
    # macOS
    /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug
    
    # Windows
    "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="%TEMP%\chrome-debug"
  2. Configure MCP:
    json
    {
      "mcpServers": {
        "js-reverse": {
          "command": "npx",
          "args": ["js-reverse-mcp", "--browserUrl", "http://127.0.0.1:9222"]
        }
      }
    }
默认配置(系统Chrome + 持久化登录):
json
{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp"]
    }
  }
}
针对反机器人网站(Cloudflare、DataDome、FingerprintJS):
先预下载CloakBrowser二进制文件(仅需一次,耗时约30-60秒):
bash
npx cloakbrowser install
然后配置:
json
{
  "mcpServers": {
    "js-reverse-cloak": {
      "command": "npx",
      "args": ["js-reverse-mcp", "--cloak"]
    }
  }
}
双配置(根据目标切换):
json
{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp"]
    },
    "js-reverse-cloak": {
      "command": "npx",
      "args": ["js-reverse-mcp", "--cloak"]
    }
  }
}
连接到已运行的Chrome:
  1. 启动带调试功能的Chrome:
    bash
    # macOS
    /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug
    
    # Windows
    "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="%TEMP%\chrome-debug"
  2. 配置MCP:
    json
    {
      "mcpServers": {
        "js-reverse": {
          "command": "npx",
          "args": ["js-reverse-mcp", "--browserUrl", "http://127.0.0.1:9222"]
        }
      }
    }

MCP Tools (21)

MCP工具(共21种)

Page & Navigation

页面与导航

ToolPurpose
select_page
List open pages or switch debugging context by index
new_page
Create new page and navigate to URL
navigate_page
Navigate, back, forward, or refresh
select_frame
List/select iframe execution context
take_screenshot
Capture page screenshot
工具用途
select_page
列出已打开页面或通过索引切换调试上下文
new_page
创建新页面并导航到指定URL
navigate_page
执行导航、后退、前进或刷新操作
select_frame
列出/选择iframe执行上下文
take_screenshot
捕获页面截图

Script Analysis

脚本分析

ToolPurpose
list_scripts
List all loaded JavaScript files
get_script_source
Fetch script source (supports line ranges, character offsets)
save_script_source
Save full script to local file (large/minified/WASM)
search_in_sources
Search all scripts for string/regex
工具用途
list_scripts
列出所有已加载的JavaScript文件
get_script_source
获取脚本源码(支持行范围、字符偏移量)
save_script_source
将完整脚本保存到本地文件(支持大文件、压缩文件、WASM)
search_in_sources
在所有脚本中搜索字符串/正则表达式

Breakpoints & Execution

断点与执行控制

ToolPurpose
set_breakpoint_on_text
Set breakpoint by searching code text (works in minified code)
break_on_xhr
Set XHR/Fetch breakpoint by URL pattern
remove_breakpoint
Remove by ID, URL, or all; auto-resumes execution
list_breakpoints
List all active breakpoints
get_paused_info
Get pause state, call stack, scope variables
pause_or_resume
Toggle pause/resume
step
Step over/into/out, returns location + source context
工具用途
set_breakpoint_on_text
通过搜索代码文本设置断点(适用于压缩代码)
break_on_xhr
根据URL模式设置XHR/Fetch断点
remove_breakpoint
通过ID、URL删除断点或清除所有断点;自动恢复执行
list_breakpoints
列出所有活跃断点
get_paused_info
获取暂停状态、调用栈、作用域变量
pause_or_resume
切换暂停/恢复状态
step
执行单步跳过/进入/退出操作,返回位置及源码上下文

Network & WebSocket

网络与WebSocket

ToolPurpose
list_network_requests
List requests or get single request details by reqid
get_request_initiator
Get JavaScript call stack for network request
get_websocket_messages
List connections, analyze message patterns, get message details
工具用途
list_network_requests
列出请求或通过reqid获取单个请求详情
get_request_initiator
获取网络请求的JavaScript调用栈
get_websocket_messages
列出连接、分析消息模式、获取消息详情

Inspection

检查工具

ToolPurpose
evaluate_script
Execute JavaScript (supports breakpoint context, main world, save results/binary to file)
list_console_messages
List console messages or get single message by msgid
工具用途
evaluate_script
执行JavaScript(支持断点上下文、主环境、将结果/二进制数据保存到文件)
list_console_messages
列出控制台消息或通过msgid获取单个消息详情

Common Workflows

常见工作流

1. Basic Reverse Engineering

1. 基础逆向工程

typescript
// User: "Debug the encryption on example.com"

// Step 1: Open target page
await use_mcp_tool("js-reverse", "new_page", {
  url: "https://example.com"
});

// Step 2: Find encryption functions
const searchResults = await use_mcp_tool("js-reverse", "search_in_sources", {
  query: "encrypt|crypto|AES|cipher",
  isRegex: true
});

// Step 3: Set breakpoint on encryption function
await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
  searchText: "function encrypt(data)",
  scriptUrl: searchResults[0].url
});

// Step 4: Trigger action (user does this in browser or via evaluate_script)
// ... breakpoint hits ...

// Step 5: Inspect paused state
const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});
// Returns: call stack, scope variables, current location

// Step 6: Evaluate in breakpoint context
const params = await use_mcp_tool("js-reverse", "evaluate_script", {
  expression: "data",
  returnByValue: true
});

// Step 7: Step through execution
await use_mcp_tool("js-reverse", "step", {
  action: "into"  // or "over", "out"
});
typescript
// 用户:"调试example.com上的加密逻辑"

// 步骤1:打开目标页面
await use_mcp_tool("js-reverse", "new_page", {
  url: "https://example.com"
});

// 步骤2:查找加密函数
const searchResults = await use_mcp_tool("js-reverse", "search_in_sources", {
  query: "encrypt|crypto|AES|cipher",
  isRegex: true
});

// 步骤3:在加密函数上设置断点
await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
  searchText: "function encrypt(data)",
  scriptUrl: searchResults[0].url
});

// 步骤4:触发操作(用户在浏览器中执行或通过evaluate_script触发)
// ... 断点命中 ...

// 步骤5:检查暂停状态
const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});
// 返回:调用栈、作用域变量、当前位置

// 步骤6:在断点上下文中执行代码
const params = await use_mcp_tool("js-reverse", "evaluate_script", {
  expression: "data",
  returnByValue: true
});

// 步骤7:单步执行
await use_mcp_tool("js-reverse", "step", {
  action: "into"  // 或 "over", "out"
});

2. Network Request Analysis

2. 网络请求分析

typescript
// User: "Find where this API request is initiated"

// Step 1: List network requests
const requests = await use_mcp_tool("js-reverse", "list_network_requests", {});

// Step 2: Find target request
const apiRequest = requests.find(r => r.url.includes("/api/user"));

// Step 3: Get JavaScript call stack
const initiator = await use_mcp_tool("js-reverse", "get_request_initiator", {
  reqid: apiRequest.reqid
});
// Returns: full JS stack trace from initiation point

// Step 4: Set breakpoint at initiation
await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
  searchText: initiator.callFrames[0].functionName,
  scriptUrl: initiator.callFrames[0].url
});
typescript
// 用户:"找出这个API请求的发起位置"

// 步骤1:列出网络请求
const requests = await use_mcp_tool("js-reverse", "list_network_requests", {});

// 步骤2:找到目标请求
const apiRequest = requests.find(r => r.url.includes("/api/user"));

// 步骤3:获取JavaScript调用栈
const initiator = await use_mcp_tool("js-reverse", "get_request_initiator", {
  reqid: apiRequest.reqid
});
// 返回:从发起点开始的完整JS调用栈

// 步骤4:在发起位置设置断点
await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
  searchText: initiator.callFrames[0].functionName,
  scriptUrl: initiator.callFrames[0].url
});

3. XHR/Fetch Interception

3. XHR/Fetch拦截

typescript
// User: "Break on all requests to /api/encrypt"

// Set XHR breakpoint with URL pattern
await use_mcp_tool("js-reverse", "break_on_xhr", {
  urlPattern: "*/api/encrypt*"
});

// Execution will pause before matching XHR/fetch
// Then inspect request body, headers, call stack
const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});

// Evaluate request payload
const payload = await use_mcp_tool("js-reverse", "evaluate_script", {
  expression: "arguments[0]",  // xhr.send() argument
  returnByValue: true
});
typescript
// 用户:"拦截所有指向/api/encrypt的请求"

// 设置带URL模式的XHR断点
await use_mcp_tool("js-reverse", "break_on_xhr", {
  urlPattern: "*/api/encrypt*"
});

// 匹配的XHR/fetch请求执行前会暂停
// 然后检查请求体、请求头、调用栈
const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});

// 评估请求负载
const payload = await use_mcp_tool("js-reverse", "evaluate_script", {
  expression: "arguments[0]",  // xhr.send()的参数
  returnByValue: true
});

4. WebSocket Protocol Analysis

4. WebSocket协议分析

typescript
// User: "Analyze the WebSocket messages for this trading site"

// Step 1: List WebSocket connections
const wsData = await use_mcp_tool("js-reverse", "get_websocket_messages", {
  action: "list"
});

// Step 2: Analyze message patterns
const analysis = await use_mcp_tool("js-reverse", "get_websocket_messages", {
  action: "analyze",
  wsid: wsData.connections[0].wsid
});
// Returns: message type distribution, size stats, timing patterns

// Step 3: Inspect specific message
const message = await use_mcp_tool("js-reverse", "get_websocket_messages", {
  action: "get",
  wsid: wsData.connections[0].wsid,
  msgid: "msg_123"
});
// Returns: full payload, timestamp, direction (sent/received)
typescript
// 用户:"分析这个交易网站的WebSocket消息"

// 步骤1:列出WebSocket连接
const wsData = await use_mcp_tool("js-reverse", "get_websocket_messages", {
  action: "list"
});

// 步骤2:分析消息模式
const analysis = await use_mcp_tool("js-reverse", "get_websocket_messages", {
  action: "analyze",
  wsid: wsData.connections[0].wsid
});
// 返回:消息类型分布、大小统计、时序模式

// 步骤3:检查特定消息
const message = await use_mcp_tool("js-reverse", "get_websocket_messages", {
  action: "get",
  wsid: wsData.connections[0].wsid,
  msgid: "msg_123"
});
// 返回:完整负载、时间戳、方向(发送/接收)

5. Minified Code Debugging

5. 压缩代码调试

typescript
// User: "Set breakpoint on the obfuscated validation function"

// Step 1: Search for function signature in minified code
const results = await use_mcp_tool("js-reverse", "search_in_sources", {
  query: "validate.*password",
  isRegex: true
});

// Step 2: Get context around match
const source = await use_mcp_tool("js-reverse", "get_script_source", {
  scriptId: results[0].scriptId,
  startOffset: results[0].match.offset - 200,
  endOffset: results[0].match.offset + 200
});

// Step 3: Set breakpoint by text match (works in minified code)
await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
  searchText: results[0].match.line.trim(),
  scriptUrl: results[0].url,
  condition: "password.length > 0"  // optional conditional breakpoint
});
typescript
// 用户:"在混淆后的验证函数上设置断点"

// 步骤1:在压缩代码中搜索函数签名
const results = await use_mcp_tool("js-reverse", "search_in_sources", {
  query: "validate.*password",
  isRegex: true
});

// 步骤2:获取匹配内容的上下文
const source = await use_mcp_tool("js-reverse", "get_script_source", {
  scriptId: results[0].scriptId,
  startOffset: results[0].match.offset - 200,
  endOffset: results[0].match.offset + 200
});

// 步骤3:通过文本匹配设置断点(适用于压缩代码)
await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
  searchText: results[0].match.line.trim(),
  scriptUrl: results[0].url,
  condition: "password.length > 0"  // 可选条件断点
});

6. Scope Variable Inspection

6. 作用域变量检查

typescript
// After hitting breakpoint, inspect all accessible variables

const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});

// pausedInfo.scopeChain contains:
// - local variables
// - closure variables
// - global scope

// Evaluate complex expressions in current scope
const result = await use_mcp_tool("js-reverse", "evaluate_script", {
  expression: "Object.keys(this).filter(k => k.startsWith('_'))",
  callFrameId: pausedInfo.callFrames[0].callFrameId,
  returnByValue: true
});
typescript
// 断点命中后,检查所有可访问变量

const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});

// pausedInfo.scopeChain包含:
// - 局部变量
// - 闭包变量
// - 全局作用域

// 在当前作用域中执行复杂表达式
const result = await use_mcp_tool("js-reverse", "evaluate_script", {
  expression: "Object.keys(this).filter(k => k.startsWith('_'))",
  callFrameId: pausedInfo.callFrames[0].callFrameId,
  returnByValue: true
});

7. Save Large Script Sources

7. 保存大型脚本源码

typescript
// User: "Save this 5MB minified bundle for analysis"

const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});
const targetScript = scripts.find(s => s.url.includes("bundle.min.js"));

// Save to local file (more reliable than get_script_source for large files)
await use_mcp_tool("js-reverse", "save_script_source", {
  scriptId: targetScript.scriptId,
  outputPath: "/tmp/bundle.min.js"
});

// Now analyze with external tools or search within it
const matches = await use_mcp_tool("js-reverse", "search_in_sources", {
  query: "apiKey.*=.*['\"]([^'\"]+)['\"]",
  isRegex: true,
  scriptId: targetScript.scriptId
});
typescript
// 用户:"保存这个5MB的压缩包用于分析"

const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});
const targetScript = scripts.find(s => s.url.includes("bundle.min.js"));

// 保存到本地文件(对于大文件,比get_script_source更可靠)
await use_mcp_tool("js-reverse", "save_script_source", {
  scriptId: targetScript.scriptId,
  outputPath: "/tmp/bundle.min.js"
});

// 现在使用外部工具分析或在其中搜索
const matches = await use_mcp_tool("js-reverse", "search_in_sources", {
  query: "apiKey.*=.*['\"]([^'\"]+)['\"]",
  isRegex: true,
  scriptId: targetScript.scriptId
});

8. Multi-Page Debugging

8. 多页面调试

typescript
// User: "Debug login flow across multiple redirects"

// Step 1: List all open pages
const pages = await use_mcp_tool("js-reverse", "select_page", {});

// Step 2: Switch to login page
await use_mcp_tool("js-reverse", "select_page", {
  index: 0
});

// Step 3: Set breakpoint on form submit
await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
  searchText: "submitLogin"
});

// Step 4: After redirect, switch to new page
const updatedPages = await use_mcp_tool("js-reverse", "select_page", {});
await use_mcp_tool("js-reverse", "select_page", {
  index: updatedPages.length - 1
});

// Step 5: Continue debugging in new context
const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});
typescript
// 用户:"调试跨多个重定向的登录流程"

// 步骤1:列出所有已打开页面
const pages = await use_mcp_tool("js-reverse", "select_page", {});

// 步骤2:切换到登录页面
await use_mcp_tool("js-reverse", "select_page", {
  index: 0
});

// 步骤3:在表单提交函数上设置断点
await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
  searchText: "submitLogin"
});

// 步骤4:重定向后,切换到新页面
const updatedPages = await use_mcp_tool("js-reverse", "select_page", {});
await use_mcp_tool("js-reverse", "select_page", {
  index: updatedPages.length - 1
});

// 步骤5:在新上下文中继续调试
const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});

Troubleshooting

故障排查

Bot Detection / Access Denied

机器人检测/访问被拒绝

Symptoms: Site returns 403, Cloudflare challenge loops, Zhihu 40362 error
Solution 1: Try isolated profile first (rules out state pollution)
json
"args": ["js-reverse-mcp", "--isolated"]
Solution 2: Enable CloakBrowser (49 fingerprint patches)
Pre-download binary:
bash
npx cloakbrowser install
Configure:
json
"args": ["js-reverse-mcp", "--cloak"]
Solution 3: Clear persistent profile (loses login state)
bash
rm -rf ~/.cache/chrome-devtools-mcp/chrome-profile
症状: 网站返回403、Cloudflare验证循环、知乎40362错误
解决方案1: 先尝试使用隔离配置文件(排除状态污染问题)
json
"args": ["js-reverse-mcp", "--isolated"]
解决方案2: 启用CloakBrowser(49项指纹补丁)
预下载二进制文件:
bash
npx cloakbrowser install
配置:
json
"args": ["js-reverse-mcp", "--cloak"]
解决方案3: 清除持久化配置文件(会丢失登录状态)
bash
rm -rf ~/.cache/chrome-devtools-mcp/chrome-profile

or for cloak mode:

或针对cloak模式:

rm -rf ~/.cache/chrome-devtools-mcp/cloak-profile
undefined
rm -rf ~/.cache/chrome-devtools-mcp/cloak-profile
undefined

Breakpoint Not Hitting

断点未触发

  1. Check if script is loaded:
    typescript
    const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});
    // Verify target script is in list
  2. Use text-based breakpoint (works in minified code):
    typescript
    await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
      searchText: "unique_code_snippet",
      scriptUrl: "target.js"
    });
  3. List active breakpoints:
    typescript
    const breakpoints = await use_mcp_tool("js-reverse", "list_breakpoints", {});
  4. Check if execution is paused elsewhere:
    typescript
    const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});
  1. 检查脚本是否已加载:
    typescript
    const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});
    // 确认目标脚本在列表中
  2. 使用基于文本的断点(适用于压缩代码):
    typescript
    await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
      searchText: "unique_code_snippet",
      scriptUrl: "target.js"
    });
  3. 列出活跃断点:
    typescript
    const breakpoints = await use_mcp_tool("js-reverse", "list_breakpoints", {});
  4. 检查是否在其他位置暂停:
    typescript
    const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});

Cannot Find Script

无法找到脚本

If dynamic/lazy-loaded scripts don't appear:
  1. Navigate to trigger script load:
    typescript
    await use_mcp_tool("js-reverse", "navigate_page", {
      action: "goto",
      url: "https://example.com/trigger-page"
    });
  2. Wait for script load, then list:
    typescript
    // Give page time to load
    await new Promise(resolve => setTimeout(resolve, 2000));
    const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});
  3. Search across all sources:
    typescript
    const results = await use_mcp_tool("js-reverse", "search_in_sources", {
      query: "function_name"
    });
如果动态/懒加载的脚本未显示:
  1. 导航到触发脚本加载的页面:
    typescript
    await use_mcp_tool("js-reverse", "navigate_page", {
      action: "goto",
      url: "https://example.com/trigger-page"
    });
  2. 等待脚本加载完成后再列出:
    typescript
    // 给页面加载时间
    await new Promise(resolve => setTimeout(resolve, 2000));
    const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});
  3. 在所有源码中搜索:
    typescript
    const results = await use_mcp_tool("js-reverse", "search_in_sources", {
      query: "function_name"
    });

WebSocket Messages Not Captured

WebSocket消息未捕获

If
get_websocket_messages
returns empty:
  1. Ensure page is loaded and WebSocket is connected:
    typescript
    const wsData = await use_mcp_tool("js-reverse", "get_websocket_messages", {
      action: "list"
    });
    // Check if connections array is populated
  2. Trigger WebSocket traffic in browser (message capture is passive)
  3. List connections includes lifecycle events; messages are captured automatically once connection is established
如果
get_websocket_messages
返回空:
  1. 确保页面已加载且WebSocket已连接:
    typescript
    const wsData = await use_mcp_tool("js-reverse", "get_websocket_messages", {
      action: "list"
    });
    // 检查connections数组是否有内容
  2. 在浏览器中触发WebSocket流量(消息捕获是被动的)
  3. 连接列表包含生命周期事件;连接建立后会自动捕获消息

Evaluate Script Fails

脚本执行失败

Common issues:
  1. Execution context invalid — Make sure you're evaluating in the right frame:
    typescript
    // List frames first
    const frames = await use_mcp_tool("js-reverse", "select_frame", {});
    
    // Select target frame
    await use_mcp_tool("js-reverse", "select_frame", {
      index: 1  // switch to iframe
    });
    
    // Now evaluate
    await use_mcp_tool("js-reverse", "evaluate_script", {
      expression: "window.secretVar"
    });
  2. Paused in wrong call frame — Specify
    callFrameId
    :
    typescript
    const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});
    
    await use_mcp_tool("js-reverse", "evaluate_script", {
      expression: "localVar",
      callFrameId: pausedInfo.callFrames[0].callFrameId
    });
  3. Reference error — Variable not in scope; check
    scopeChain
    :
    typescript
    const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});
    // Inspect pausedInfo.scopeChain to see available variables
常见问题:
  1. 执行上下文无效 —— 确保在正确的框架中执行:
    typescript
    // 先列出框架
    const frames = await use_mcp_tool("js-reverse", "select_frame", {});
    
    // 选择目标框架
    await use_mcp_tool("js-reverse", "select_frame", {
      index: 1  // 切换到iframe
    });
    
    // 现在执行脚本
    await use_mcp_tool("js-reverse", "evaluate_script", {
      expression: "window.secretVar"
    });
  2. 在错误的调用帧中暂停 —— 指定
    callFrameId
    typescript
    const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});
    
    await use_mcp_tool("js-reverse", "evaluate_script", {
      expression: "localVar",
      callFrameId: pausedInfo.callFrames[0].callFrameId
    });
  3. 引用错误 —— 变量不在当前作用域;检查
    scopeChain
    typescript
    const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});
    // 查看pausedInfo.scopeChain了解可用变量

Anti-Detection Layer Details

反检测层详情

Protocol Layer (Always Active):
  • Patchright removes
    Runtime.enable
    ,
    Console.enable
    CDP calls
  • Script evaluation in isolated world
  • Automation launch flags stripped
Binary Layer (With
--cloak
):
  • 49 C++ patches:
    navigator.webdriver
    , canvas, WebGL, audio, GPU, fonts, screen, WebRTC, TLS
  • Custom Chromium build (no Google services, no Web Store)
  • Persistent fingerprint identity per profile
Navigation Layer (Always Active):
  • Silent CDP navigation (no early
    Network.enable
    /
    Debugger.enable
    )
  • Google referer on
    new_page
  • Real viewport (no fake 1280×720)
When to use
--cloak
:
Only when protocol-layer evasion fails. See project docs for details.
协议层(始终激活):
  • Patchright移除
    Runtime.enable
    Console.enable
    等CDP调用
  • 在隔离环境中执行脚本
  • 移除自动化启动参数
二进制层(启用
--cloak
时):
  • 49项C++补丁:
    navigator.webdriver
    、canvas、WebGL、音频、GPU、字体、屏幕、WebRTC、TLS
  • 自定义Chromium构建(无Google服务、无应用商店)
  • 每个配置文件保留持久化指纹标识
导航层(始终激活):
  • 静默CDP导航(不提前启用
    Network.enable
    /
    Debugger.enable
  • new_page
    时使用Google referer
  • 真实视口(不使用伪造的1280×720)
何时使用
--cloak
仅当协议层规避失败时使用。详见项目文档。

Best Practices

最佳实践

  1. Start simple: Use default mode; only add
    --cloak
    if blocked
  2. Persistent sessions: Default profile saves login state (use
    --isolated
    for clean state)
  3. Text-based breakpoints: More reliable than line numbers in minified/dynamic code
  4. Save large sources: Use
    save_script_source
    instead of
    get_script_source
    for big files
  5. Scope inspection: Always check
    get_paused_info().scopeChain
    before evaluating variables
  6. Network initiators: Use
    get_request_initiator
    to find where requests originate
  7. WebSocket analysis: Use
    analyze
    action first to understand message patterns before diving into individual messages
  1. 从简开始: 使用默认模式;仅在被拦截时添加
    --cloak
  2. 持久会话: 默认配置文件保存登录状态(使用
    --isolated
    获取干净状态)
  3. 基于文本的断点: 在压缩/动态代码中比行号更可靠
  4. 保存大型源码: 针对大文件,使用
    save_script_source
    而非
    get_script_source
  5. 作用域检查: 执行变量评估前,务必检查
    get_paused_info().scopeChain
  6. 网络发起者: 使用
    get_request_initiator
    查找请求的发起位置
  7. WebSocket分析: 先使用
    analyze
    操作了解消息模式,再深入单个消息

Security Warning

安全警告

This tool exposes browser content to MCP clients with full inspection/modification capabilities. Do not use on pages with sensitive information (passwords, payment details, private data).
本工具会将浏览器内容暴露给具备完整检查/修改权限的MCP客户端。请勿在包含敏感信息(密码、支付详情、私人数据)的页面上使用。