Skip to main content
Glama

JS Reverse MCP

English | 中文

An AI-first / AI-native JavaScript reverse engineering MCP Server that lets your AI coding assistant (such as Claude, Cursor, Copilot) continuously debug, locate, save, and review JavaScript behavior in web pages like an analyst.

It doesn't hand the Chrome DevTools API to the model as-is. Instead, it reorganizes scripts, breakpoints, network, WebSocket, browser state, and local file I/O into tools suited for an AI Agent's continuous reasoning and operation. Anti-detection is part of that capability: by default it uses a Patchright fork that is recompiled, published, and independently maintained for this MCP to provide protocol-level stealth, with an optional CloakBrowser source-level fingerprint mode for heavily anti-scraping sites.

☁️ 赞助 · Sponsored by IPWO

IPWO residential proxies support flexible proxy configuration, letting developers choose the appropriate network environment for different tasks, for web access, request testing, region-specific content analysis, and automated workflows.

For projects involving JS reverse engineering, browser debugging, and web network analysis, residential proxies can also serve as a supplementary network environment option, helping developers more flexibly meet access and testing needs across different regions.

👉 Free trial entry, 10% discount code: 0204

Related MCP server: MCP JS Debugger

☁️ 赞助 · Sponsored by Infistar.cc 无限星河

js-reverse-mcp × Infistar.cc 无限星河|All-model API · Stable AI-assisted debugging

Thanks to Infistar.cc 无限星河 for sponsoring and providing model service support for js-reverse-mcp!

  • ⚡ Stably handles complex debugging tasks: enterprise-grade high-concurrency channels and multi-node redundancy, priced as low as 10% of official channels, reducing rate limits, 429s, and long-task disconnects.

  • 🧠 One API Key for mainstream models: supports ChatGPT, Claude, Gemini, Kimi, GLM, DeepSeek and more, compatible with AI coding tools such as Claude Code, Codex, and Cursor.

  • 🔎 Supports authorized debugging and security research: suitable for multi-step tasks such as script retrieval, breakpoint analysis, network request tracing, call stack inspection, and code logic understanding.

  • 📦 Exclusive benefit for project users: register via the exclusive referral link and complete your first call to receive $5 worth of test credits / first-recharge exclusive discount.

Positioning: model API configuration support for Claude Code / Codex.

Features

  • AI-native tool design: tool granularity, output boundaries, and error messages are all designed around Agent decision-making, avoiding pushing the model toward invalid next steps

  • Reviewable workflow: script source code, raw network data, and binary results can all be exported to local files and then used as input for subsequent analysis

  • Breakpoint context execution: while paused, you can evaluate directly in the call frame, inspect scope variables, step through execution, and get source context back

  • Script analysis: list all loaded JS, search code, fetch/save source, auto-format large minified scripts

  • Network and WebSocket analysis: request call stacks, XHR breakpoints, Set-Cookie identification, raw body/header export, WebSocket message grouping

  • Browser state replay: clear the current site's cookies / cache / storage / sessionStorage, combined with reload to reproduce cookie and risk-control flows

  • Headed by default + persistent login state: you can see the browser, and cookies / localStorage persist across sessions

  • Dedicated Patchright kernel: by default depends on a Patchright fork independently maintained by this project, continuously fixing known shared implementation fingerprints from upstream

  • Optional anti-detection layer: dedicated Patchright protocol-level stealth is enabled by default; for heavily anti-scraping sites you can add --cloak to use the CloakBrowser binary

Dedicated Patchright fork

js-reverse-mcp no longer depends directly on Patchright's public distribution package. Instead, it uses @zhizhuodemao/patchright, compiled and published specifically for this MCP. This fork is continuously maintained in a separate repository and evolves with this MCP's actual detection samples.

  • No longer depends directly on Patchright's public distribution package

  • Protocol-level adjustments for confirmed upstream shared implementation fingerprints, recompiled and republished

  • Anti-detection adjustments do not rely on page-level JS injection

  • Retains original capabilities such as evaluate, locator, and page control

  • The fork is continuously maintained in a dedicated repository for this MCP

The public documentation only describes design boundaries and does not go into internal detection samples or implementation details. The goal of the dedicated fork is to reduce confirmed shared implementation fingerprints, not to promise that browser automation is absolutely undetectable.

System Requirements

Quick Start (npx)

No installation needed. Just add the following to your MCP client configuration:

{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp"]
    }
  }
}

Claude Code

claude mcp add js-reverse npx js-reverse-mcp

If you don't have a usable model API yet, or need to configure a custom API address, see: Claude Code / Codex third-party model API configuration tutorial.

Codex

codex mcp add js-reverse -- npx js-reverse-mcp

If you don't have a usable model API yet, or need to configure a custom API address, see: Claude Code / Codex third-party model API configuration tutorial.

Cursor

Go to Cursor Settings -> MCP -> New MCP Server and use the configuration above.

VS Code Copilot

code --add-mcp '{"name":"js-reverse","command":"npx","args":["js-reverse-mcp"]}'

Local Installation (Optional)

git clone https://github.com/zhizhuodemao/js-reverse-mcp.git
cd js-reverse-mcp
npm install
npm run build

Then use the local path in your MCP configuration:

{
  "mcpServers": {
    "js-reverse": {
      "command": "node",
      "args": ["/你的路径/js-reverse-mcp/build/src/index.js"]
    }
  }
}

AI-first Design

The core goal of this project is not "being able to operate a browser," but letting an AI Agent reliably complete a full round of real JS reverse engineering tasks: open the page, pass risk control, locate the script, save the source, set breakpoints, trigger behavior, inspect runtime state, export network materials, reproduce state, and then continue reasoning.

Several design orientations run through the code:

  • Tools are Agent primitives, not DevTools menu mappings: list_network_requests can list an index, look up details by reqid, and export precise materials via outputFile; evaluate_script can execute in the page, execute in a breakpoint call frame, and accept a localFilePath input.

  • Output must guide the next step: list output stays short and scannable; detail output has boundaries; long results prompt for export; pending requests explicitly prompt to resume execution first, so the Agent doesn't wait for a response that will never complete.

  • Local files are the analysis workbench: save_script_source, list_network_requests(..., outputFile), and evaluate_script(..., localFilePath) let the Agent move back and forth between the browser, network, and local files, instead of stuffing large code blocks or binary data into the chat context.

  • State can be cleaned, flows can be replayed: the default profile preserves login state; --isolated provides a one-time clean environment; clear_site_data only clears state related to the current site, used to repeatedly reproduce cookie generation, risk-control initialization, and request chains.

  • Anti-detection serves the debugging chain: CDP silent navigation, real viewport, Google referer, the dedicated Patchright fork, and CloakBrowser all aim to let the Agent enter the target page and continue analysis, rather than turning the project into a general-purpose crawler framework.

Anti-detection Mechanisms (Supporting Capability)

Anti-detection is one of js-reverse-mcp's underlying supporting capabilities. The wrapper layer (this MCP itself) does zero JS injection and no Object.defineProperty hacks (those are detection signals in themselves). All anti-detection lives in two non-overlapping layers:

Layer

Default mode

--cloak mode

Protocol layer (CDP)

Dedicated Patchright fork: doesn't call Runtime.enable / Console.enable, executes evaluate in an isolated world, removes automation launch flags, and continuously fixes known shared implementation fingerprints

Same

Source layer (C++ binary patch)

None — uses the system Google Chrome directly

CloakBrowser binary (platform-specific source-level fingerprint patches covering navigator.webdriver, canvas, WebGL, audio, GPU, fonts, screen, WebRTC, TLS)

Profile directory

~/.cache/chrome-devtools-mcp/chrome-profile (persistent login state)

~/.cache/chrome-devtools-mcp/cloak-profile (physically isolated from default)

Actual browser

Your installed Google Chrome (with Web Store, extensions, sync)

Custom Chromium build (no Google services, no Web Store)

A few additional navigation-level measures (active in both modes):

  • CDP silent navigation — Network.enable / Debugger.enable are not activated when the page loads; request/console collection only goes through Playwright listeners until a tool explicitly needs CDP

  • Google Referer — new_page defaults to referer: https://www.google.com/

  • Real viewport — Playwright's default fake 1280×720 viewport is disabled; the browser shows the real screen size

When to enable --cloak: only when the above isn't enough and you're being blocked by site fingerprinting. See docs/cloak.md for details.

Tool List (24 tools)

Page & Navigation

Tool

Description

select_page

List open pages, or select the debugging context by index

new_page

Create a new page and navigate to a URL

navigate_page

Navigate, go back, go forward, or refresh the page

select_frame

List all frames (iframes), or select the execution context

click_element

Strictly match and click a single visible element in the current frame

take_screenshot

Take a page screenshot

Script Analysis

Tool

Description

list_scripts

List all JavaScript scripts loaded in the page

get_script_source

Get a script source snippet, supporting line ranges or character offsets

save_script_source

Save the full script source to a local file (for large/minified/WASM files)

search_in_sources

Search all scripts for a string or regular expression

Breakpoints & Execution Control

Tool

Description

set_breakpoint_on_text

Automatically set a breakpoint by searching code text (for minified code)

break_on_xhr

Set XHR/Fetch breakpoints by URL pattern

remove_breakpoint

Remove breakpoints by ID, URL, or all, with an explicit action

list_breakpoints

List all active breakpoints

get_paused_info

Get paused state, call stack, and scope variables

pause_or_resume

Pause or resume execution with an explicit action

step

Step through debugging (over/into/out), returning position and source context

Network & WebSocket

Tool

Description

list_network_requests

List network requests, view details, or export raw materials such as header/body/query

clear_network_requests

Clear collected requests and body cache for the current page after explicit confirmation

get_request_initiator

Get the JavaScript call stack for a network request

get_websocket_messages

List WebSocket connections, analyze message patterns, or get message details

Browser State

Tool

Description

clear_site_data

Clear cookies, origin storage, and sessionStorage related to the current site; can explicitly choose to clear the global HTTP cache

Inspection Tools

Tool

Description

evaluate_script

Execute JavaScript in the page or breakpoint context, supporting the main world, saving results, and reading one local input file

list_console_messages

List console messages, or get a single message's details by msgid

Usage Examples

Basic JS Reverse Engineering Flow

  1. Open the target page

打开 https://example.com 并列出所有加载的 JS 脚本
  1. Find the target function

在所有脚本中搜索包含 "encrypt" 的代码
  1. Set a breakpoint

在加密函数入口处设置断点
  1. Trigger and analyze

在页面上触发操作,断点命中后检查参数、调用栈和作用域变量

WebSocket Protocol Analysis

列出 WebSocket 连接,分析消息模式,查看特定类型的消息内容

Because the navigation phase deliberately keeps CDP silent, the Network / Debugger domains are not opened immediately when first entering the target page. The recommended flow is to pass risk control first, then refresh to capture:

1. new_page 打开目标页
2. 调用 list_network_requests 激活 collectors
3. navigate_page(type="reload") 刷新页面
4. 再次 list_network_requests 查看完整请求
5. 对关键 reqid 使用 outputFile 导出原始材料
1. clear_site_data(confirm=true) 清理当前站点状态
2. navigate_page(type="reload") 重新触发初始化
3. list_network_requests 找到设置 cookie 或提交 sensor 的请求
4. 导出 requestBody / responseHeaders / responseBody
5. 用 evaluate_script + localFilePath 在页面上下文中复算或验证

Configuration Options

The CLI stays minimal; all flags are optional. The defaults work for 99% of scenarios. When local files are involved, it's recommended to use --allowedRoots to limit the directories the Agent can read and write.

Option

Description

Default

--cloak

Switch to the CloakBrowser stealth binary (replacing system Chrome). Enables platform-specific C++ source-level fingerprint patches. First launch auto-downloads a ~200MB binary; the fingerprint identity persists per profile. See docs/cloak.md.

false

--isolated

Use a temporary user-data-dir (cookies/localStorage not preserved, auto-cleaned on close)

false

--browserUrl, -u

Connect to an already-running Chrome instance (CDP HTTP endpoint, e.g. http://127.0.0.1:9222). The MCP auto-detects the WebSocket debugger URL. How to get this endpoint for local Chrome, AdsPower, BitBrowser, etc. is in docs/cdp-endpoint.md.

–

--logFile

MCP debug log written to a 0600 regular file; detailed logging only via DEBUG=mcp:*. Don't use DEBUG=* — browser protocol logs can leak pages, cookies, scripts, and credentials.

–

--allowedRoots

Repeatable; local directories the Agent is allowed to read and write. Resolves real paths and rejects symlink escapes. When enabled, disables file:, view-source:file:, and filesystem:file: browser pages. When unspecified, local file access is not directory-restricted, and a security warning is printed at startup.

–

Example Configurations

Default — system Chrome + persistent login state (recommended for most debugging scenarios):

{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp"]
    }
  }
}

--cloak — heavily anti-scraping sites (Cloudflare Turnstile / DataDome / FingerprintJS protection):

Strongly recommended: pre-download the binary first (one-time, ~30–60 seconds). If you skip this, the first launch with --cloak will silently download ~200MB, which looks like the MCP is stuck:

npx cloakbrowser install

(The cloakbrowser package is already installed via optionalDependencies; this command just triggers its built-in binary download logic, with a progress bar)

{
  "mcpServers": {
    "js-reverse-cloak": {
      "command": "npx",
      "args": ["js-reverse-mcp", "--cloak"]
    }
  }
}

Two parallel instances — two MCP instances with physically isolated profiles, switch based on the target site:

{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp"]
    },
    "js-reverse-cloak": {
      "command": "npx",
      "args": ["js-reverse-mcp", "--cloak"]
    }
  }
}

--isolated — a fresh profile every time (cookies/localStorage not preserved):

{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp", "--isolated"]
    }
  }
}

Connecting to a Running Chrome / Third-Party Fingerprint Browser

--browserUrl only accepts a CDP endpoint (an HTTP endpoint that responds to /json/version), not vendor-private Local APIs. How to get the CDP port for local Chrome, AdsPower, BitBrowser, etc. is in the dedicated document:

📖 docs/cdp-endpoint.md — How to get the CDP debugging port

Shortest path (local Chrome):

# 先关掉所有 Chrome 窗口,然后
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug
{
  "mcpServers": {
    "js-reverse": {
      "command": "npx",
      "args": ["js-reverse-mcp", "--browserUrl", "http://127.0.0.1:9222"]
    }
  }
}

For fingerprint browsers (AdsPower, BitBrowser, etc.), the CDP port changes randomly on every launch; you must start the browser via the vendor's Local API and then extract it. The steps and example scripts are in the document above.

Troubleshooting

Blocked by Anti-Scraping Systems

If you're blocked on certain sites (e.g., Zhihu returns 40362, Cloudflare challenge loops):

  1. Try --isolated first — use a fresh profile to rule out residual state pollution:

    "args": ["js-reverse-mcp", "--isolated"]
  2. If that doesn't work, enable --cloak — enable platform-specific source-level fingerprint patches:

    "args": ["js-reverse-mcp", "--cloak"]
  3. As a last resort, manually clear the persistent profile (this loses login state):

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

When you should and shouldn't enable --cloak, see docs/cloak.md.

Agent Routing Evaluation (Maintainers)

npm run eval:routing:validate offline-validates the actual MCP tools/list, server instructions, and the 30 tool-selection contracts in evals/tool-routing.json; this command does not hit model endpoints and is part of presubmit.

Real model evaluation is explicitly opt-in and calls the OpenAI-compatible Chat Completions endpoint per item, which may incur costs:

MCP_ROUTING_EVAL_ENDPOINT=https://api.example.com/v1/chat/completions \
MCP_ROUTING_EVAL_MODEL=model-name \
MCP_ROUTING_EVAL_API_KEY=secret \
npm run eval:routing

MCP_ROUTING_EVAL_API_KEY can be omitted for local endpoints that don't require authentication; remote endpoints with credentials must use HTTPS, and HTTP is only allowed on loopback. Use MCP_ROUTING_EVAL_TIMEOUT_MS to adjust the per-request timeout. 100% pass is required by default; when comparing across models, use MCP_ROUTING_EVAL_MIN_PASS_RATE to set a (0, 1] threshold. The evaluation does not output API keys, endpoints, or endpoint error response bodies.

Security Notice

This tool exposes browser content to the MCP client, allowing inspection, debugging, and modification of any data in the browser. Do not use it on pages containing sensitive information.

evaluate_script.localFilePath and various outputFile/filePath options allow the MCP process to read or write host machine files. In production or shared environments, one or more --allowedRoots should be used to narrow access to a dedicated working directory; when not configured, the access scope is unrestricted. When --allowedRoots is enabled, file:, view-source:file:, and filesystem:file: browser pages are also rejected, preventing directory boundary bypass through browser navigation; when local pages need to be debugged, this option can only be left unconfigured in sessions that explicitly accept the risk of local file exposure.

License

Apache-2.0

Available Tools

24 tools
break_on_xhrA

Sets a URL-substring breakpoint for a future XHR/Fetch when runtime request arguments, local variables, or payload construction must be inspected. For an already captured request, call get_request_initiator first because it is non-pausing; use this only when that evidence is insufficient. Set it before reproducing the user action—it does not inspect past traffic—then call get_paused_info/evaluate_script and finally step or resume. The URL pattern identifies this breakpoint for list_breakpoints and remove_breakpoint(action="remove_xhr").

Inputs: url (required). Returns: ok, data, tool, error, +1 more

clear_network_requestsA
DestructiveIdempotent

Discard captured HTTP(S) evidence for the currently selected page after confirm=true. Use this immediately before reproducing an action when a clean network capture window is needed; do not use it to reset login, cookies, cache, or other browser state. It irreversibly clears the in-memory request queue, cached response bodies, and initiator maps only. Browser cookies, HTTP cache, origin storage, console messages, and WebSocket connections/messages are unchanged; use clear_site_data for cookie and storage reset. New captures continue above the previous reqid high-water mark because reqids are never reused.

Inputs: confirm. Returns: ok, data, tool, error, +1 more

clear_site_dataA
DestructiveIdempotent

Irreversibly clear browser state after confirm=true to create a clean replay environment for the selected page. Use this before replaying login, session creation, storage initialization, or other state-dependent flows; do not use it to inspect cookies or determine which response set one. For cookie provenance, including HttpOnly, Secure, and SameSite attributes, use list_network_requests with cookieName first. Cleanup covers cookies affecting the selected page's HTTP(S) frames—including HttpOnly and Secure cookies through the browser context—persistent storage for those frame origins, and each HTTP(S) frame's sessionStorage. It does not reload the page. The browser HTTP cache is global and is preserved by default; set clearBrowserCache=true only when that wider cross-page effect is explicitly intended.

Inputs: confirm, clearBrowserCache. Returns: ok, data, tool, error, +1 more

click_elementA
Destructive

Performs one verified, auditable click in the currently selected frame. Use it when the task requires activating a known button, link, or control after selecting the correct page/frame and identifying a CSS selector; it is the preferred minimal interaction primitive over arbitrary evaluate_script code. It does not discover elements, type text, or silently guess among matches: the selector must resolve to exactly one element unless index is explicit, and the chosen element must be visible. A click can submit data, navigate, or trigger external effects, so confirm=true is required and the result reports the exact resolved element.

Inputs: selector (required), index, button, confirm, +2 more. Returns: ok, data, tool, error, +1 more

evaluate_scriptA
Destructive

Evaluates one focused JavaScript function for DOM/page state, web storage, page-defined globals, a paused-frame expression, or browser-side processing of one local file. Use it when those runtime values are the goal and no narrower evidence tool applies. Do not use document.cookie or page evaluation to investigate HttpOnly/Secure cookies, Set-Cookie provenance, or captured HTTP evidence; use list_network_requests with cookieName/reqid, and use search_in_sources/get_script_source for source discovery. While running, evaluation uses the selected frame's isolated world by default or its page main world with mainWorld=true; while paused, it always uses the chosen call frame and ignores mainWorld. Call get_paused_info before paused evaluation, then step or resume when finished. Arbitrary code can change page/external state and requires confirm=true; inline results are bounded, so use outputFile for exact large or binary results.

Inputs: function (required), confirm, mainWorld, frameIndex, +3 more. Returns: ok, data, tool, error, +1 more

get_paused_infoA
Read-only

Inspects the current call stack, source locations, and selected call-frame scopes after a code/XHR breakpoint or explicit pause has stopped execution. It neither creates a pause nor resumes one. Returned frameIndex values and callFrameIds belong only to the current pause and expire after any step or resume; use evaluate_script with frameIndex for a focused expression, then step or pause_or_resume(action="resume").

Inputs: frameIndex, includeScopes, maxScopeDepth. Returns: ok, data, tool, error, +1 more

get_request_initiatorA
Read-only

Non-pausing first action for tracing which JavaScript initiated a retained HTTP request when CDP initiator evidence was active. Pass the reqid from list_network_requests; because initiator capture starts lazily and is not retroactive, an older request may have no stack—in that case reproduce the action and inspect the new reqid, or set break_on_xhr before reproduction when runtime values are required. If the captured stack identifies the code, inspect its URL/location with get_script_source. If arguments, locals, or a dynamically built payload are still needed, use break_on_xhr, reproduce, then call get_paused_info or evaluate_script before stepping or resuming. This tool only reads retained evidence and does not pause or reproduce the request.

Inputs: requestId (required). Returns: ok, data, tool, error, +1 more

get_script_sourceA
Read-only

Reads a small source region around a search match, paused location, or known statement without executing or pausing the page. Select by URL when available because URL-backed scripts can be resolved again after navigation; use the debugger-context-scoped scriptId only for current inline/eval scripts. Use line ranges for normal source and offset/length for minified single-line bundles. For a whole, minified, or WASM source, use save_script_source; to observe runtime values next, call set_breakpoint_on_text against the original loaded source.

Inputs: url, length, offset, endLine, +2 more. Returns: ok, data, tool, error, +1 more

get_websocket_messagesA
Read-only

Inspect captured bidirectional WebSocket connections and frame payloads for the selected page. Use this for WebSocket, socket, live-update, push, streaming, or realtime message flows; use list_network_requests for ordinary HTTP/XHR/fetch traffic and WebSocket upgrade request headers. WebSocket capture starts lazily on this tool's first use and is not retroactive: if the relevant socket already connected or exchanged frames, call this tool once to initialize capture, then reload or reproduce the flow. Without wsid it lists connections so you can choose one. With wsid it lists paginated sent/received frames; add show_content=true for payload previews. With wsid and analyze=true it groups frames by payload pattern and returns group IDs and sample frame indices; then use groupId to inspect one pattern. With wsid and frameIndex it returns one retained frame's detailed payload using the stable index shown in frame tables or analysis samples.

Inputs: wsid, analyze, groupId, pageIdx, +6 more. Returns: ok, data, tool, error, +1 more

list_breakpointsA
Read-only

Inspects code and XHR/Fetch breakpoints managed by this MCP session before reproducing an action or cleaning up debugger state. Returns current code breakpointIds and the exact XHR URL patterns needed by remove_breakpoint; URL-backed definitions are restored after navigation when possible, but a rebuilt debugger session may assign new IDs. This does not show why or where execution is currently paused—use get_paused_info for the active call stack.

Inputs: pageIdx, pageSize. Returns: ok, data, tool, error, +1 more

list_console_messagesA
Read-only

Inspects console messages and uncaught page errors captured for the selected page. Use it to diagnose runtime failures, warnings, application logs, or values already emitted by page code; use search_in_sources for source text and list_network_requests for HTTP evidence instead. Without msgid it lists messages 20 per page by default, optionally filtered by type or retained navigation history. With msgid it returns one message by its stable ID for focused inspection. Capture begins when this MCP attaches and is not retroactive, so reload or reproduce code that logged before attachment.

Inputs: msgid, types, pageIdx, pageSize, +1 more. Returns: ok, data, tool, error, +1 more

list_network_requestsA

Inspect captured HTTP(S) traffic for the currently selected page. Use this for API calls, request or response headers and bodies, redirects, authentication/session flows, replay or signing inputs, and determining which response created, refreshed, rotated, overwritten, or deleted a cookie. Without reqid it lists and filters requests; with cookieName it traces exact response Set-Cookie updates oldest-first, including cookies with HttpOnly, Secure, or SameSite attributes that page JavaScript cannot fully inspect; with reqid it returns bounded request details; with reqid plus outputFile it exports exact data. To inspect complete Set-Cookie values and attributes, export outputPart="responseHeaders" for a reqid returned by cookieName mode. cookieName never searches outbound Cookie request headers. Use get_websocket_messages for WebSocket frame payloads; this tool only represents the HTTP upgrade request. Capture begins when this MCP attaches and is not retroactive, so reload or reproduce traffic that occurred earlier. Captures then survive navigation in a 5000-request FIFO queue. List and cookie-flow modes default to 20 items per page; filters combine with AND and multiple values inside one filter combine with OR.

Inputs: reqid, methods, pageIdx, pageSize, +6 more. Returns: ok, data, tool, error, +1 more

list_scriptsA
Read-only

Discovers JavaScript currently loaded in the selected debugger context—the main frame by default, or the frame chosen with select_frame. Use select_frame first for iframe-specific source/debugger work. Includes external, inline, and eval scripts in that context; if you already know a function name, endpoint, or code literal, use search_in_sources instead. Each result includes a context-scoped scriptId that expires on reload, navigation, or debugger target change and, for external scripts, a URL that is the preferred selector for get_script_source or save_script_source.

Inputs: filter, pageIdx, pageSize. Returns: ok, data, tool, error, +1 more

new_pageA

Opens a separate browser page for a URL, reusing an existing about:blank startup tab when available. Use this when the task needs another tab or should preserve the currently selected page; use navigate_page to change the URL in the existing selected page instead. It waits for DOMContentLoaded, not every background resource, and then makes the opened page the target for later tools. It preserves cookies, storage, cache, and other browser state; use clear_site_data separately when a clean replay is required.

Inputs: url (required), timeout. Returns: ok, data, tool, error, +1 more

pause_or_resumeA

Explicitly requests an immediate pause or resumes an existing paused execution; it never toggles implicitly. Use a code breakpoint or break_on_xhr instead when a specific statement/request should stop, and use get_paused_info before resuming if evidence must be collected. Resuming invalidates current callFrameIds and frame indices.

Inputs: action (required). Returns: ok, data, tool, error, +1 more

remove_breakpointA
DestructiveIdempotent

Removes a known code breakpoint, XHR/Fetch breakpoint, or every MCP-managed breakpoint after explicit confirmation. Use breakpointId from set_breakpoint_on_text/list_breakpoints for remove_code, or reuse the exact URL pattern from break_on_xhr/list_breakpoints for remove_xhr. Removal does not resume an already paused page; call pause_or_resume(action="resume") separately after inspection.

Inputs: action (required), url, confirm, breakpointId. Returns: ok, data, tool, error, +1 more

save_script_sourceA

Saves one complete JavaScript or WASM source for local inspection when an inline snippet is insufficient, especially for large or minified bundles. Prefer get_script_source for a small known region and search_in_sources to locate text across loaded scripts first. With format=true, destinations using a supported JavaScript/TypeScript extension are formatted by default; other extensions preserve raw source, and formatted line numbers may differ from the live page. Use distinctive text plus the original URL with set_breakpoint_on_text for runtime debugging. The returned filename is the resolved local path, while scriptId remains scoped to the current debugger context.

Inputs: filePath (required), url, format, scriptId, +1 more. Returns: ok, data, tool, error, +1 more

search_in_sourcesA
Read-only

Finds a known function name, endpoint, string literal, token, or code pattern in JavaScript loaded by the selected debugger context—the main frame by default, or the frame chosen with select_frame. It searches external, inline/eval, and minified sources in that context without executing or pausing the page, returning 1-based lines plus context-scoped scriptIds; URLs are the preferred selectors for URL-backed matches. Use select_frame first for iframe-specific source work, get_script_source for nearby context, save_script_source for a whole bundle, or set_breakpoint_on_text when runtime values are needed. For a known captured request, prefer get_request_initiator before a broad source search.

Inputs: query (required), isRegex, urlFilter, maxResults, +3 more. Returns: ok, data, tool, error, +1 more

select_frameA

Lists or selects frames, including iframes, within the current page. Use it when the target element, page-defined global, script, or execution context may live in an iframe: first list frames, then pass frameIdx before click_element or evaluate_script. Omitting frameIdx lists 20 frames per page without changing context; passing frameIdx changes the shared frame target, with 0 restoring the main frame. It does not switch browser tabs or navigate—use select_page or navigate_page for those actions—and listPageIdx only paginates this listing.

Inputs: frameIdx, pageSize, listPageIdx. Returns: ok, data, tool, error, +1 more

select_pageA

Lists or selects open browser pages. Use it without pageIdx to identify the active page or choose the correct tab before inspecting network traffic, scripts, frames, or console output; pass pageIdx to make one listed page the shared target for later tools. It does not navigate or create pages: use navigate_page to change the selected page's URL and new_page when a separate tab is required. listPageIdx only paginates the page listing and never changes selection.

Inputs: pageIdx, pageSize, listPageIdx. Returns: ok, data, tool, error, +1 more

set_breakpoint_on_textA

Sets a restorable URL-backed breakpoint when distinctive code text is known and its runtime values must be observed. Call it directly when the user already supplies precise text plus any URL/occurrence disambiguation; use search_in_sources/get_script_source first only when the location is unknown or ambiguous. For an API with no known code location, start with list_network_requests and get_request_initiator or use break_on_xhr. On a hit, call get_paused_info, optionally evaluate_script, then step or resume. Returns the current breakpointId for remove_breakpoint; list breakpoints again after a rebuilt debugger session, and note that unnamed inline/eval scripts cannot use this URL breakpoint.

Inputs: text (required), condition, urlFilter, occurrence. Returns: ok, data, tool, error, +1 more

stepA

Advances JavaScript execution by one debugger operation from an existing pause and returns the next stopped call frame with concise source context. Use after get_paused_info or evaluate_script when control flow still needs tracing; it cannot start from running execution. Each advance invalidates prior callFrameIds, so inspect the new pause again as needed, then use pause_or_resume(action="resume") to finish.

Inputs: direction (required). Returns: ok, data, tool, error, +1 more

take_screenshotA

Captures the visual state of the currently selected page. Use it to verify page layout, visible UI state, selector targets, in-page dialogs/modals, or the effect of a navigation/click; it is not a substitute for DOM values, network evidence, or script inspection. By default it returns the visible viewport, while fullPage=true captures the whole document; oversized captures may be saved as a temporary artifact instead of attached. Pass filePath for a reusable local artifact; existing files require confirmOverwrite=true and remain subject to --allowedRoots.

Inputs: format, quality, filePath, fullPage, +1 more. Returns: ok, data, tool, error, +1 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.3/5.0

    Scored across 24 tools

    Disambiguation3/5

    Tools are organized around specific debugging actions, but many overlap in purpose (e.g., multiple breakpoint and pause/resume tools, multiple request inspection tools). While descriptions are precise, an agent could easily confuse which tool to use for a given step, especially with 24 tools.

    Naming Consistency4/5

    Most tools follow a verb_noun pattern in snake_case (e.g., clear_network_requests, click_element). A few deviate slightly (e.g., 'break_on_xhr', 'get_paused_info'), but overall the naming is predictable and readable.

    Tool Count3/5

    24 tools is on the higher side for a focused reverse engineering server. The set is comprehensive but some tools could be merged (e.g., clear_network_requests and clear_site_data are distinct but very similar). Still, each tool has a clear role, so the count is borderline but acceptable.

    Completeness4/5

    The tool surface covers all major aspects of JavaScript reverse engineering: network interception, source inspection, breakpoint management, page control, and evaluation. Minor gaps exist (e.g., no direct DOM query tool), but the set is largely complete for its purpose.

    Maintenance

    ActivityStale
    ResponsivenessMixed handling

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI assistants to debug frontend applications by providing direct access to browser DevTools, React state, DOM inspection, and runtime debugging capabilities. Bridges the gap between AI and complex web applications for autonomous debugging and issue resolution.
      1
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Enables AI assistants to debug JavaScript and TypeScript applications by connecting to Chrome DevTools Protocol-compatible debuggers, allowing them to set breakpoints, step through code, inspect variables, and evaluate expressions with full source map support.
      18
      8 npm
      2
      Apache 2.0