Loading...
Loading...
Compare original and translation side by side
Object.definePropertyObject.defineProperty{
"mcpServers": {
"js-reverse": {
"command": "npx",
"args": ["js-reverse-mcp"]
}
}
}claude mcp add js-reverse npx js-reverse-mcpcodex mcp add js-reverse -- npx js-reverse-mcp{
"mcpServers": {
"js-reverse": {
"command": "npx",
"args": ["js-reverse-mcp"]
}
}
}claude mcp add js-reverse npx js-reverse-mcpcodex mcp add js-reverse -- npx js-reverse-mcpgit clone https://github.com/zhizhuodemao/js-reverse-mcp.git
cd js-reverse-mcp
npm install
npm run build{
"mcpServers": {
"js-reverse": {
"command": "node",
"args": ["/path/to/js-reverse-mcp/build/src/index.js"]
}
}
}git clone https://github.com/zhizhuodemao/js-reverse-mcp.git
cd js-reverse-mcp
npm install
npm run build{
"mcpServers": {
"js-reverse": {
"command": "node",
"args": ["/path/to/js-reverse-mcp/build/src/index.js"]
}
}
}--cloak--isolated--browserUrl, -uhttp://127.0.0.1:9222--logFileDEBUG=*--cloak--isolated--browserUrl, -uhttp://127.0.0.1:9222--logFileDEBUG=*{
"mcpServers": {
"js-reverse": {
"command": "npx",
"args": ["js-reverse-mcp"]
}
}
}npx cloakbrowser install{
"mcpServers": {
"js-reverse-cloak": {
"command": "npx",
"args": ["js-reverse-mcp", "--cloak"]
}
}
}{
"mcpServers": {
"js-reverse": {
"command": "npx",
"args": ["js-reverse-mcp"]
},
"js-reverse-cloak": {
"command": "npx",
"args": ["js-reverse-mcp", "--cloak"]
}
}
}# 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"{
"mcpServers": {
"js-reverse": {
"command": "npx",
"args": ["js-reverse-mcp", "--browserUrl", "http://127.0.0.1:9222"]
}
}
}{
"mcpServers": {
"js-reverse": {
"command": "npx",
"args": ["js-reverse-mcp"]
}
}
}npx cloakbrowser install{
"mcpServers": {
"js-reverse-cloak": {
"command": "npx",
"args": ["js-reverse-mcp", "--cloak"]
}
}
}{
"mcpServers": {
"js-reverse": {
"command": "npx",
"args": ["js-reverse-mcp"]
},
"js-reverse-cloak": {
"command": "npx",
"args": ["js-reverse-mcp", "--cloak"]
}
}
}# 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"{
"mcpServers": {
"js-reverse": {
"command": "npx",
"args": ["js-reverse-mcp", "--browserUrl", "http://127.0.0.1:9222"]
}
}
}| Tool | Purpose |
|---|---|
| List open pages or switch debugging context by index |
| Create new page and navigate to URL |
| Navigate, back, forward, or refresh |
| List/select iframe execution context |
| Capture page screenshot |
| 工具 | 用途 |
|---|---|
| 列出已打开页面或通过索引切换调试上下文 |
| 创建新页面并导航到指定URL |
| 执行导航、后退、前进或刷新操作 |
| 列出/选择iframe执行上下文 |
| 捕获页面截图 |
| Tool | Purpose |
|---|---|
| List all loaded JavaScript files |
| Fetch script source (supports line ranges, character offsets) |
| Save full script to local file (large/minified/WASM) |
| Search all scripts for string/regex |
| 工具 | 用途 |
|---|---|
| 列出所有已加载的JavaScript文件 |
| 获取脚本源码(支持行范围、字符偏移量) |
| 将完整脚本保存到本地文件(支持大文件、压缩文件、WASM) |
| 在所有脚本中搜索字符串/正则表达式 |
| Tool | Purpose |
|---|---|
| Set breakpoint by searching code text (works in minified code) |
| Set XHR/Fetch breakpoint by URL pattern |
| Remove by ID, URL, or all; auto-resumes execution |
| List all active breakpoints |
| Get pause state, call stack, scope variables |
| Toggle pause/resume |
| Step over/into/out, returns location + source context |
| 工具 | 用途 |
|---|---|
| 通过搜索代码文本设置断点(适用于压缩代码) |
| 根据URL模式设置XHR/Fetch断点 |
| 通过ID、URL删除断点或清除所有断点;自动恢复执行 |
| 列出所有活跃断点 |
| 获取暂停状态、调用栈、作用域变量 |
| 切换暂停/恢复状态 |
| 执行单步跳过/进入/退出操作,返回位置及源码上下文 |
| Tool | Purpose |
|---|---|
| List requests or get single request details by reqid |
| Get JavaScript call stack for network request |
| List connections, analyze message patterns, get message details |
| 工具 | 用途 |
|---|---|
| 列出请求或通过reqid获取单个请求详情 |
| 获取网络请求的JavaScript调用栈 |
| 列出连接、分析消息模式、获取消息详情 |
| Tool | Purpose |
|---|---|
| Execute JavaScript (supports breakpoint context, main world, save results/binary to file) |
| List console messages or get single message by msgid |
| 工具 | 用途 |
|---|---|
| 执行JavaScript(支持断点上下文、主环境、将结果/二进制数据保存到文件) |
| 列出控制台消息或通过msgid获取单个消息详情 |
// 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"
});// 用户:"调试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"
});// 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
});// 用户:"找出这个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
});// 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
});// 用户:"拦截所有指向/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
});// 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)// 用户:"分析这个交易网站的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"
});
// 返回:完整负载、时间戳、方向(发送/接收)// 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
});// 用户:"在混淆后的验证函数上设置断点"
// 步骤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" // 可选条件断点
});// 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
});// 断点命中后,检查所有可访问变量
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
});// 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
});// 用户:"保存这个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
});// 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", {});// 用户:"调试跨多个重定向的登录流程"
// 步骤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", {});"args": ["js-reverse-mcp", "--isolated"]npx cloakbrowser install"args": ["js-reverse-mcp", "--cloak"]rm -rf ~/.cache/chrome-devtools-mcp/chrome-profile"args": ["js-reverse-mcp", "--isolated"]npx cloakbrowser install"args": ["js-reverse-mcp", "--cloak"]rm -rf ~/.cache/chrome-devtools-mcp/chrome-profileundefinedundefinedconst scripts = await use_mcp_tool("js-reverse", "list_scripts", {});
// Verify target script is in listawait use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
searchText: "unique_code_snippet",
scriptUrl: "target.js"
});const breakpoints = await use_mcp_tool("js-reverse", "list_breakpoints", {});const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});
// 确认目标脚本在列表中await use_mcp_tool("js-reverse", "set_breakpoint_on_text", {
searchText: "unique_code_snippet",
scriptUrl: "target.js"
});const breakpoints = await use_mcp_tool("js-reverse", "list_breakpoints", {});const pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});await use_mcp_tool("js-reverse", "navigate_page", {
action: "goto",
url: "https://example.com/trigger-page"
});// Give page time to load
await new Promise(resolve => setTimeout(resolve, 2000));
const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});const results = await use_mcp_tool("js-reverse", "search_in_sources", {
query: "function_name"
});await use_mcp_tool("js-reverse", "navigate_page", {
action: "goto",
url: "https://example.com/trigger-page"
});// 给页面加载时间
await new Promise(resolve => setTimeout(resolve, 2000));
const scripts = await use_mcp_tool("js-reverse", "list_scripts", {});const results = await use_mcp_tool("js-reverse", "search_in_sources", {
query: "function_name"
});get_websocket_messagesconst wsData = await use_mcp_tool("js-reverse", "get_websocket_messages", {
action: "list"
});
// Check if connections array is populatedget_websocket_messagesconst wsData = await use_mcp_tool("js-reverse", "get_websocket_messages", {
action: "list"
});
// 检查connections数组是否有内容// 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"
});callFrameIdconst 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
});scopeChainconst pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});
// Inspect pausedInfo.scopeChain to see available variables// 先列出框架
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"
});callFrameIdconst 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
});scopeChainconst pausedInfo = await use_mcp_tool("js-reverse", "get_paused_info", {});
// 查看pausedInfo.scopeChain了解可用变量Runtime.enableConsole.enable--cloaknavigator.webdriverNetwork.enableDebugger.enablenew_page--cloakRuntime.enableConsole.enable--cloaknavigator.webdriverNetwork.enableDebugger.enablenew_page--cloak--cloak--isolatedsave_script_sourceget_script_sourceget_paused_info().scopeChainget_request_initiatoranalyze--cloak--isolatedsave_script_sourceget_script_sourceget_paused_info().scopeChainget_request_initiatoranalyze