# Chrome Debugger MCP (npm · chrome-debugger-mcp)

Chrome breakpoint debugging MCP server for inspecting runtime values and stepping through code

- Trust score: 62/100 (medium)
- Change this week: +16
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- npm · `chrome-debugger-mcp`: 62/100 (this document), [markdown](https://verifymcp.io/servers/bitepro-chrome-debugger-mcp/chrome-debugger-mcp.md), [page](https://verifymcp.io/servers/bitepro-chrome-debugger-mcp/chrome-debugger-mcp)

## Channel facts

- Registry: `npm`
- Package: `chrome-debugger-mcp`
- Version: `1.0.4`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Supply Chain Security**: 87/100
  - No malware found by supply-chain analysis.
  - Only part of the dependency tree could be resolved (98 of 102), so this covers what we could see, not the whole tree.
  - No install/post-install scripts declared.
  - Only part of the dependency tree could be resolved (98 of 102), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 140 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 40/100
  - AI-judged instruction clarity (poor).
  - Context-footprint check failed: tool/resource definitions use about 2107 tokens (~117/item across 18 items; 18 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add bitepro-chrome-debugger-mcp -- npx -y chrome-debugger-mcp
```

### Codex

```bash
codex mcp add bitepro-chrome-debugger-mcp -- npx -y chrome-debugger-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "bitepro-chrome-debugger-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "chrome-debugger-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add bitepro-chrome-debugger-mcp --command npx --arg -y --arg chrome-debugger-mcp
```

### Hermes

```yaml
mcp_servers:
  bitepro-chrome-debugger-mcp:
    command: "npx"
    args: ["-y", "chrome-debugger-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "bitepro-chrome-debugger-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "chrome-debugger-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-02 (score 62, +57)

- [security regression] Provenance: unverified → fail
- [security improvement] Install scripts: unverified → pass
- [security improvement] Known CVEs: unverified → partial
- [security improvement] Malware scan: unverified → pass
- [functional regression] Security disclosure: fail → unverified
- [functional improvement] Tool coverage: unverified → 100
- [functional improvement] License: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Stability: unverified → 0.23
- [functional improvement] Schema quality: unverified → poor
- [functional] Licence: MIT

### 2026-08-01 (score 5, −15)

- [functional regression] Tool coverage: 100 → unverified
- [functional] First check of Schema quality: unverified

### 2026-07-31 (score 20, −8)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 28, −18)

- [security regression] Malware scan: pass → unverified

### 2026-07-27 (score 46)

First indexed and scored.

## MCP tools (18)

### `startDebuggingSession` (~107 tokens)

CALL THIS FIRST whenever browser-side debugging is needed — before any other tool.

Auto-trigger when user mentions any of:
  debug, breakpoint, debugger, inspect, trace, step through, runtime value,
  variable value, why is this, implement based on API response, bug, error,
  unexpected behavior, not working, check this, confirm this.

Returns the complete debugging workflow and critical rules.
The response contains a "_ui" field — relay it to the user verbatim.

### `launchChrome` (~262 tokens)

[STEP 1] Launch a dedicated Chrome instance with remote debugging enabled (default port 9222).
Uses --user-data-dir=~/.chrome-debug-profile so your normal Chrome keeps running (dual-instance).
Auto-detects if the debug port is already active and skips launch (alreadyRunning=true).
Use dryRun=true to preview the command — show it to the user and ask for confirmation before executing.
Set openDevTools=true to automatically open DevTools panel for every new tab.
If automatic launch does not succeed, relay the returned command to the user and ask them to run it manually.
Relay the "_ui" field from the response to the user.

Input parameters:

- `chromePath` (string): Chrome executable path. Overrides platform defaults and CHROME_PATH/GOOGLE_CHROME_BIN.
- `dryRun` (boolean): If true, return the launch command without executing it
- `openDevTools` (boolean): If true, adds --auto-open-devtools-for-tabs so DevTools opens automatically for every new tab
- `port` (integer): Remote debugging port (default 9222)
- `url` (string): URL to open immediately after launch
- `userDataDir` (string): Profile directory for the debug instance (default ~/.chrome-debug-profile)

### `listTargets` (~100 tokens)

[STEP 2] List all open Chrome tabs available for debugging.
MANDATORY: show the full list to the user and ask "Which URL do you want to debug?"
NEVER skip this step, NEVER guess — even if only one tab is open.
Wait for the user's explicit reply before proceeding to connect().
Relay the "_ui" field from the response to the user.

Input parameters:

- `port` (integer): Chrome remote debugging port (default 9222)

### `connect` (~154 tokens)

[STEP 3] Connect the debugger to a specific Chrome tab.
MANDATORY: call listTargets first, show the list to the user, wait for their explicit URL confirmation, then call this.
NEVER guess the URL. NEVER skip user confirmation — even if only one tab is visible.
targetUrl must be a unique substring of the tab URL the user confirmed (e.g. "localhost:5173").
Relay the "_ui" field from the response to the user.

Input parameters:

- `port` (integer): Chrome remote debugging port (default 9222)
- `targetUrl` (string, required): Unique substring of the tab URL confirmed by the user (e.g. 'localhost:5173'). REQUIRED — always obtain from user confirmation.

### `disconnect` (~32 tokens)

Disconnect the current Chrome debugging session and clear in-memory pause state. Use this to explicitly end a debug session before connecting again.

### `setBreakpoint` (~129 tokens)

Set a breakpoint at a specific script URL and line number via CDP — no source code modification needed.
  Use a full URL (https://...) for exact match, or a partial filename/keyword for regex match.
  Alternative to inserting debugger; when you cannot modify the source file.
  After setting, call reloadPage() to ensure the breakpoint resolves correctly.

Input parameters:

- `column` (integer): 0-based column number
- `condition` (string): Conditional breakpoint expression
- `line` (integer, required): 0-based line number
- `url` (string, required): Script URL or URL pattern to match

### `removeBreakpoint` (~39 tokens)

Remove a previously set CDP breakpoint by its ID (returned by setBreakpoint).

Input parameters:

- `breakpointId` (string, required): The breakpoint ID returned by setBreakpoint

### `waitForPause` (~175 tokens)

[STEP 5b — FALLBACK] BLOCKING call — waits until ANY debugger pause occurs (breakpoint, debugger; statement, or exception).
  Before blocking, sends a notification to the user to trigger the page action.
  Must be called IMMEDIATELY after reloadPage() in the SAME AI turn — do NOT end your turn before calling this.
  Prefer waitForSpecificPause when you know the exact file and line — it uses smarter two-tier matching.
  Use this only when the target location is unknown or when setBreakpoint is used without a specific line.

Input parameters:

- `actionHint` (string): Optional hint to tell the user what action to perform on the page (e.g. 'click the button', 'submit the form').
- `timeout` (integer): Timeout in milliseconds (default 30000)

### `waitForSpecificPause` (~357 tokens)

[STEP 5b — PREFERRED] BLOCKING call — waits for the next debugger pause, then checks if it matches the target location.
  
  ⚠️ NO AUTO-RESUME: execution stays paused after this returns, regardless of matched value.
  You decide what to do based on the "matched" field in the response:
    matched=true  → call getScopeVariables() immediately to read variables
    matched=false → the wrong breakpoint fired; call resume() to continue,
                    then call waitForSpecificPause() again if you need to wait for the next pause.
  
  Must be called IMMEDIATELY after reloadPage() in the SAME AI turn.
  Before blocking, sends a notification to the user to trigger the page action.
  Editor line N → pass line=N-1 (CDP uses 0-based line numbers).
  Relay the "_ui" field from the response to the user once it returns.

Input parameters:

- `actionHint` (string): Describe the page action to trigger the breakpoint (e.g. 'click the Search button'). Shown in the waiting notification to the user.
- `line` (integer, required): 0-based line number where debugger; was inserted. Editor line N → pass N-1.
- `lineTolerance` (integer): ±line tolerance for Tier 1 matching (default 10). Increase to 20+ for heavily bundled code.
- `timeout` (integer): Timeout in ms to wait for any pause (default 90000). Increase for slow interactions.
- `urlFragment` (string, required): Substring of the script URL where debugger; was added (e.g. 'LoginForm.vue', 'utils.ts'). Does NOT need to be the full URL.

### `getScopeVariables` (~103 tokens)

[STEP 6a] Read all scope variables (local, closure, module) at the currently paused call frame.
  Call this immediately after waitForSpecificPause or waitForPause returns.
  Results are grouped by scope type; global scope is skipped.
  Use frameIndex=1, 2, ... to inspect variables in parent call frames up the stack.

Input parameters:

- `frameIndex` (integer): Call frame index (default 0, the topmost frame)

### `evaluate` (~100 tokens)

[STEP 6b] Evaluate any JavaScript expression in the context of the currently paused call frame.
  Use this to inspect nested objects, call methods, compute derived values, or verify conditions at runtime.
  Complements getScopeVariables for values not directly visible in scope (e.g. this.state, JSON.stringify(obj)).

Input parameters:

- `expression` (string, required): JavaScript expression to evaluate
- `frameIndex` (integer): Call frame index (default 0)

### `resume` (~60 tokens)

[STEP 8] Resume script execution after collecting all needed variable data — ends the current pause.
  After calling resume, remove all temporary debugger; statements added to source code during this session.
  Relay the "_ui" field from the response to the user.

### `stepInto` (~64 tokens)

[STEP 7] BLOCKING: step into the next function call, then wait until the debugger pauses again. Follow with getScopeVariables() to observe inner-function state.

Input parameters:

- `timeout` (integer): Timeout in milliseconds to wait for the next pause (default 30000)

### `stepOver` (~68 tokens)

[STEP 7] BLOCKING: step over the current statement without entering function calls, then wait until the debugger pauses again. Follow with getScopeVariables() to observe how local variables change.

Input parameters:

- `timeout` (integer): Timeout in milliseconds to wait for the next pause (default 30000)

### `stepOut` (~68 tokens)

[STEP 7] BLOCKING: step out of the current function and wait until the debugger pauses again in the caller. Use to observe the return value and the state of the calling context.

Input parameters:

- `timeout` (integer): Timeout in milliseconds to wait for the next pause (default 30000)

### `getStatus` (~73 tokens)

Non-blocking: return current connection and pause state immediately without waiting.
  Use this to poll for pause instead of waitForPause when the MCP client has a short request timeout (e.g. MCP Inspector ~10s).
  Returns: connected, paused, targetUrl, pauseReason, hitBreakpoints, callStack.

### `reloadPage` (~177 tokens)

[STEP 5a] Reload the connected page via Chrome DevTools Protocol.
  More reliable than manual browser refresh — maintains the CDP connection and ensures debugger; statements and setBreakpoint() calls resolve correctly when scripts reload.
  Always call this after inserting debugger; in source code or after setBreakpoint(), before waitForSpecificPause/waitForPause.
  
  ⚠️ CRITICAL TURN RULE: After this tool returns, you MUST immediately call waitForSpecificPause (or waitForPause) in the SAME AI turn — do NOT end your turn here.
  waitForSpecificPause is a blocking call that will notify the user to trigger the page action and wait for the breakpoint internally.
  If you end your turn after reloadPage, the session will break.

Input parameters:

- `ignoreCache` (boolean): Hard reload ignoring cache (default false)

### `forcePause` (~39 tokens)

Force the debugger to pause at the very next JavaScript statement. Useful when you cannot modify source code to add debugger; and setBreakpoint is not feasible.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/bitepro-chrome-debugger-mcp/chrome-debugger-mcp#diagnostics

## Score history

- 2026-08-03: 62
- 2026-08-02: 62
- 2026-08-01: 5
- 2026-07-31: 20
- 2026-07-30: 28
- 2026-07-28: 46
- 2026-07-27: 46

## Links

- npm package: https://www.npmjs.com/package/chrome-debugger-mcp
- Socket report: https://socket.dev/npm/package/chrome-debugger-mcp
- Repository: https://github.com/BitePro/chrome-debugger-mcp
- Changelog RSS feed: https://verifymcp.io/servers/bitepro-chrome-debugger-mcp/chrome-debugger-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/bitepro-chrome-debugger-mcp/chrome-debugger-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/bitepro-chrome-debugger-mcp/chrome-debugger-mcp
