| name | jsreverser-mcp-javascript-reverse-engineering |
| description | MCP server for JavaScript reverse engineering in real browser environments with hooks, breakpoints, network tracing, deobfuscation, and environment reconstruction. |
| triggers | ["reverse engineer this JavaScript","analyze encrypted request parameters","hook JavaScript functions in browser","deobfuscate minified code","extract API signature logic","trace network request initiator","debug obfuscated frontend code","recreate JavaScript runtime environment"] |
JSReverser-MCP JavaScript Reverse Engineering
Skill by ara.so — MCP Skills collection.
JSReverser-MCP is a specialized MCP server for JavaScript reverse engineering that operates in real browser environments. It helps locate frontend core logic by integrating script retrieval, breakpoint debugging, function hooking, network request tracing, call chain analysis, deobfuscation, and risk assessment into unified MCP tools. Perfect for API analysis, security research, frontend debugging, and understanding encrypted/signed request parameters.
Core Methodology
The project follows these principles:
- Observe-first: Confirm requests, scripts, functions in browser before intervention
- Hook-preferred: Use minimal hooks for runtime sampling before breakpoints
- Breakpoint-last: Only pause execution when hooks are insufficient
- Rebuild-oriented: Export evidence and reconstruct in Node.js environment
- Evidence-first: Record all findings as task artifacts, not just in conversation
- Pure-extraction-after-pass: Extract pure algorithm only after environment passes
Installation
1. Install and Build
git clone https://github.com/NoOne-hub/JSReverser-MCP.git
cd JSReverser-MCP
npm install
npm run build
The build output is at build/src/index.js.
2. Quick Start
npm run start
3. Configure MCP Client
Claude Code
claude mcp add js-reverse node /ABSOLUTE/PATH/JSReverser-MCP/build/src/index.js
Cursor Settings
{
"mcpServers": {
"js-reverse": {
"command": "node",
"args": ["/ABSOLUTE/PATH/JSReverser-MCP/build/src/index.js"]
}
}
}
Codex (config.toml)
[mcp_servers.js-reverse]
command = "node"
args = ["/ABSOLUTE/PATH/JSReverser-MCP/build/src/index.js"]
4. Connect to Existing Browser (Optional)
Launch Chrome with remote debugging:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
google-chrome --remote-debugging-port=9222
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
Then configure with --browserUrl:
[mcp_servers.js-reverse]
command = "node"
args = [
"/ABSOLUTE/PATH/JSReverser-MCP/build/src/index.js",
"--browserUrl=http://localhost:9222"
]
External AI Configuration
JSReverser-MCP can integrate external LLMs for enhanced analysis:
[mcp_servers.js-reverse]
command = "node"
args = ["/ABSOLUTE/PATH/JSReverser-MCP/build/src/index.js"]
[mcp_servers.js-reverse.env]
DEFAULT_LLM_PROVIDER = "anthropic"
ANTHROPIC_API_KEY = "your_anthropic_key_here"
ANTHROPIC_MODEL = "claude-3-5-sonnet-20241022"
AI-dependent features:
understand_code (required)
detect_crypto (optional with useAI=true)
deobfuscate_code (enhanced quality)
analyze_target (optional with useAI=true)
Key Tool Categories
1. Page Observation & Script Location
Identify which scripts exist and where target code lives:
list_scripts({ includeSourceMaps: false })
get_script_source({
scriptId: "123",
url: "https://example.com/app.js"
})
find_in_script({
scriptId: "123",
searchText: "encrypt",
maxResults: 10
})
search_in_scripts({
searchText: "signature",
maxResults: 20
})
2. Runtime Hooks & Sampling
Observe runtime behavior with minimal intrusion:
hook_function({
functionPath: "window.crypto.subtle.encrypt",
options: {
captureArgs: true,
captureReturn: true,
captureStack: true
}
})
create_hook({
hookId: "crypto-monitor",
code: `
const original = crypto.subtle.encrypt;
crypto.subtle.encrypt = function(...args) {
console.log('[HOOK] encrypt called:', args);
return original.apply(this, args);
};
`
})
inject_hook({ hookId: "crypto-monitor" })
get_hook_data({ hookId: "crypto-monitor" })
trace_function({
functionName: "generateSignature",
captureStack: true
})
3. Breakpoints & Debug Control
Pause execution when hooks aren't enough:
set_breakpoint({
scriptUrl: "https://example.com/sign.js",
lineNumber: 42
})
set_breakpoint_on_text({
scriptUrl: "https://example.com/sign.js",
searchText: "return signature",
lineOffset: 0
})
resume({ mode: "continue" })
pause()
step_over()
step_into()
step_out()
4. Network Analysis & Request Tracing
Locate target requests and their initiators:
list_network_requests({
filterUrl: "api.example.com",
filterMethod: "POST"
})
get_network_request({
requestId: "12345.67"
})
get_request_initiator({
requestId: "12345.67"
})
break_on_xhr({
urlPattern: "*sign*"
})
5. Code Analysis & Deobfuscation
Understand and clean obfuscated code:
collect_code({
priority: ["inline", "webpack", "vendor"],
maxSize: 500000
})
understand_code({
source: "function _0x1234(){...}",
context: "encryption signature generation"
})
deobfuscate_code({
source: "var _0x1a2b=['push','length'];...",
options: {
renameVariables: true,
removeDeadCode: true,
simplifyExpressions: true
}
})
detect_crypto({
source: "...",
useAI: true
})
risk_panel({
useAI: true,
includeNetworkRisk: true
})
6. WebSocket Monitoring
Track WebSocket connections and message patterns:
list_websocket_connections()
analyze_websocket_messages({
wsId: "ws-123",
groupBy: "opcode"
})
get_websocket_messages({
wsId: "ws-123",
group: "binary-frames",
limit: 50
})
7. Local Rebuild & Environment Reconstruction
Export evidence and recreate runtime in Node.js:
export_rebuild_bundle({
taskId: "jd-h5st-20240517",
includeScripts: true,
includeNetwork: true,
includeStorage: true
})
diff_env_requirements({
currentEnv: { navigator: true, document: false },
requiredEnv: { navigator: true, document: true, XMLHttpRequest: true }
})
record_reverse_evidence({
taskId: "jd-h5st-20240517",
evidence: {
type: "hook-capture",
functionName: "h5st",
args: [...],
returnValue: "..."
}
})
8. Session & Login State Management
Save and restore browser sessions:
save_session_state({
snapshotId: "logged-in-state"
})
restore_session_state({
snapshotId: "logged-in-state"
})
dump_session_state({
snapshotId: "logged-in-state",
outputPath: "artifacts/tasks/my-task/session.json"
})
load_session_state({
source: "artifacts/tasks/my-task/session.json"
})
9. Page Automation
Minimal automation to trigger target behavior:
navigate_page({ url: "https://example.com/login" })
query_dom({ selector: "button.submit" })
click_element({ selector: "button.submit" })
type_text({
selector: "input[name='username']",
text: "testuser"
})
take_screenshot({
outputPath: "artifacts/tasks/my-task/screenshot.png"
})
Standard Workflow Example
Scenario: Reverse Engineer API Signature Parameter
check_browser_health()
navigate_page({ url: "https://example.com/api-page" })
const requests = list_network_requests({
filterUrl: "*api*",
filterMethod: "POST"
})
const targetRequest = get_network_request({
requestId: requests[0].id
})
const searchResults = search_in_scripts({
searchText: "sign:",
maxResults: 10
})
hook_function({
functionPath: "window.generateSign",
options: {
captureArgs: true,
captureReturn: true,
captureStack: true
}
})
click_element({ selector: "button.load-data" })
const hookData = get_hook_data({
hookId: "auto-hook-generateSign"
})
scriptSource = ({
: hookData.[].
})
cleaned = ({
: scriptSource,
: { : , : }
})
({
: ,
: ,
: ,
:
})
({
: ,
: {
: ,
: ,
: hookData.[].,
: hookData.[].
}
})
Task Artifact Structure
Tasks are stored in artifacts/tasks/<task-id>/:
artifacts/tasks/my-reverse-task/
├── task.json # Task metadata
├── runtime-evidence.jsonl # Hook/trace data
├── network.jsonl # Network requests
├── scripts.jsonl # Script sources
├── env/
│ ├── env.js # Base environment shims
│ ├── polyfills.js # Proxy diagnostics, watch
│ ├── entry.js # Entry point for local rebuild
│ └── capture.json # Runtime captures
├── run/ # Test runs
└── report.md # Analysis report
Git Safety: Only artifacts/tasks/_TEMPLATE/ is committed. Real task directories stay local.
Pre-Indexed Parameter Cases
Existing reverse-engineered parameter cases (abstracted, no sensitive data):
- JD h5st:
scripts/cases/jd-h5st-pure-node.mjs
- Kuaishou falcon:
scripts/cases/ks-hxfalcon-pure-node.mjs
- Douyin a-bogus:
scripts/cases/douyin-a-bogus-pure-node.mjs
See scripts/cases/README.md for methodology and templates.
Common Patterns
Pattern 1: Find Encryption Function
search_in_scripts({ searchText: "CryptoJS.AES" })
hook_function({
functionPath: "CryptoJS.AES.encrypt",
options: { captureArgs: true, captureReturn: true }
})
get_hook_data({ hookId: "auto-hook-CryptoJS.AES.encrypt" })
Pattern 2: Trace Request Parameter Generation
break_on_xhr({ urlPattern: "*api.example.com*" })
resume()
hook_function({ functionPath: "window.buildParams" })
get_hook_data({ hookId: "auto-hook-buildParams" })
Pattern 3: Deobfuscate and Understand
const script = get_script_source({ scriptId: "123" })
const cleaned = deobfuscate_code({
source: script.source,
options: {
renameVariables: true,
removeDeadCode: true,
simplifyExpressions: true
}
})
understand_code({
source: cleaned.code,
context: "API signature generation"
})
Pattern 4: Export and Recreate Locally
export_rebuild_bundle({
taskId: "my-api-20240517",
includeScripts: true,
includeNetwork: true,
includeStorage: true
})
diff_env_requirements({
currentEnv: {},
requiredEnv: {}
})
Troubleshooting
Browser Connection Issues
Problem: check_browser_health fails
Solution:
- Ensure Chrome is launched with
--remote-debugging-port=9222
- Check
--browserUrl matches (default http://localhost:9222)
- Verify no firewall blocking localhost:9222
Hook Not Capturing Data
Problem: get_hook_data returns empty
Solution:
- Confirm hook was injected: check
inject_hook response
- Ensure target function was actually called (trigger page action)
- Check console for hook errors:
list_console_messages()
- Verify function path is correct (check
window.functionName exists)
Deobfuscation Produces Invalid Code
Problem: Deobfuscated code doesn't run
Solution:
- Start with minimal options:
{ renameVariables: false }
- Incrementally enable transformations
- Use
understand_code to identify why code fails
- Some VM-based obfuscation requires manual extraction
Environment Reconstruction Fails
Problem: Local rebuild throws errors
Solution:
- Review
runtime-evidence.jsonl for missing globals
- Use
diff_env_requirements to identify gaps
- Add shims to
env/env.js one at a time
- Use
watch and diagnostics in env/polyfills.js
- Aim for "first divergence" — find exact point where behavior differs
AI Provider Not Working
Problem: understand_code fails with "provider not configured"
Solution:
- Set
DEFAULT_LLM_PROVIDER in MCP server env config
- Set corresponding API key (
ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.)
- Verify key is valid and has API access
- Check
ANTHROPIC_BASE_URL if using proxy
Session State Not Restoring
Problem: restore_session_state doesn't preserve login
Solution:
- Ensure cookies domain matches current page
- Save session while still on target domain
- Check if site uses
httpOnly cookies (not accessible to JS)
- Some sites require additional localStorage/sessionStorage
Reference Documentation
- Full tool reference:
docs/reference/tool-reference.md
- Workflow guide:
docs/reference/reverse-workflow.md
- Case safety policy:
docs/reference/case-safety-policy.md
- Environment patching:
docs/reference/env-patching.md
- Reverse artifacts:
docs/reference/reverse-artifacts.md
- Browser connection:
docs/guides/browser-connection.md
- Client configuration:
docs/guides/client-configuration.md
Security & Ethics
- Never commit sensitive task directories (real credentials, keys, tokens)
- Respect target site's terms of service
- Use only for authorized testing, research, or debugging your own applications
- Abstracted cases in
scripts/cases/ must be sanitized and educational
This tool is for legitimate reverse engineering, security research, and debugging — not for bypassing security controls on third-party services without permission.