VitalyOstanin/mcp-chrome-debugger-protocol
If you are the rightful owner of mcp-chrome-debugger-protocol and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
MCP Chrome Debugger Protocol is a server for debugging Node.js applications using the Chrome DevTools Protocol.
MCP Chrome Debugger Protocol
MCP server that lets AI coding tools control and observe a running Node.js process through the chrome devtools protocol (CDP), via a lightweight Debug Adapter Protocol (DAP) bridge.
Tested with Claude Code CLI.
Features
- Attach/Control: Attach to a Node.js process by port, WebSocket URL, or PID; pause, continue, and step through code.
- Breakpoints & Logpoints: Set/remove classic breakpoints and logpoints (string templates with
{expr}interpolation) on TS or JS. - Source Maps: Resolve TS↔JS using auto-discovered
*.js.mapwith LEAST_UPPER_BOUND bias for reliable placement. - State & Events: Observe pause/resume, custom logpoint hits, and basic thread/stack inspection.
- Safe Interpolation: Expressions in
{expr}are evaluated defensively; errors never break execution (returnundefined).
High-Level Diagram
flowchart LR
C[MCP client] <--> S[MCP server]
S --> A["DAP node.js adapter (debug adapter protocol)"]
A <--> I["CDP (chrome devtools protocol)"]
I <--> N[node.js app]
How It Works (Functional Description)
- MCP server: Exposes a set of debugging tools (attach, breakpoints, stepping, inspection) over the Model Context Protocol.
- DAP bridge: The server uses an in-process DAP client and a custom Node.js debug adapter that talks directly to CDP.
- CDP transport: The adapter enables CDP domains (
Runtime,Debugger,Console) and installs a binding named__mcpLogPoint. - Logpoints: A logpoint is just a breakpoint whose condition calls
__mcpLogPoint(JSON.stringify(...))and returnsfalseso execution never pauses. - Event flow: The adapter sends a custom DAP event
mcpLogpoint; the DAP client stores the hit and the MCP server surfaces it via tools and logging.
Debugger Interaction (Textual Scheme)
-
Attach/initialize
- MCP client calls
attach; server creates the adapter and connects to CDP (by URL/port/PID). - Adapter:
Runtime.enable,Debugger.enable,Console.enable, thenRuntime.addBindingfor__mcpLogPoint(and per execution context).
- MCP client calls
-
Set logpoint / breakpoint
- MCP client calls
setBreakpointsagainst a TS or JS source path and coordinates (1-based line/column). - For TS inputs, the server resolves the generated JS location through source maps (or auto-discovers them).
- Adapter places a CDP breakpoint (
Debugger.setBreakpointByUrlor by scriptId). For logpoints, the condition evaluates{expr}safely and invokes the binding.
- MCP client calls
-
Execute and collect
- When code hits the site, CDP fires
Runtime.bindingCalledwith the JSON payload. - Adapter emits a DAP custom event
mcpLogpointwith the raw payload and context id. - DAP client parses/stores the hit and emits
logpointHit; MCP server exposes it viagetLogpointHitsand logging.
- When code hits the site, CDP fires
Demo
TypeScript with Source Maps Demo
Available formats:
Installation
Install using Claude MCP CLI:
claude mcp add --scope user chrome-debugger-protocol npx @vitalyostanin/mcp-chrome-debugger-protocol
Scope Options:
--scope user: Install for current user--scope project: Install for current project only
Removal
Remove the MCP server:
claude mcp remove chrome-debugger-protocol --scope user
Scope Options:
--scope user: Remove from user configuration--scope project: Remove from project configuration
Quick Start
-
Start your Node.js application with debugger:
node --inspect your-app.js -
Try this practical example prompt in Claude Code:
* Connect to the already running Node.js debugger
* Set a logpoint INSIDE the function handler for HTTP endpoint test1 to show only requests with query parameter logme=1. Make sure that logpoint is installed on the executable code.
* Immediately show the logpoint with marker
* Execute requests to http://localhost:3000/test1 with this parameter and without it
* Show the triggered log
Tip: use the attach tool to connect; set a logpoint via setBreakpoints (pass a breakpoint with logMessage), then inspect hits with getLogpointHits.
Available Tools
- Connection:
attach,disconnect,restart,terminate - Breakpoints:
setBreakpoints(supportslogMessage),removeBreakpoint,getBreakpoints,setExceptionBreakpoints,breakpointLocations - Execution Control:
continue,pause,next(step over),stepIn,stepOut,goto,restartFrame - Inspection:
evaluate,stackTrace,variables,scopes,setVariable,threads,loadedSources,exceptionInfo - Monitoring:
getLogpointHits,clearLogpointHits,getDebuggerEvents,clearDebuggerEvents,getDebuggerState - Source Maps:
resolveOriginalPosition,resolveGeneratedPosition
Logpoints
- Placement: logpoints are created via
setBreakpointsby providing a breakpoint entry with thelogMessagefield. - Interpolation: use
{expr}placeholders insidelogMessage. Expressions are evaluated safely in the target context; errors are swallowed and yieldundefined. - Transport: logpoints are implemented through CDP
Runtime.addBindingand captured viaRuntime.bindingCalled— no console output prefixing is used. - Payload: every hit produces a structured payload that is stored and returned by
getLogpointHits.
Example request to place a logpoint:
{
"name": "setBreakpoints",
"arguments": {
"source": { "path": "/abs/path/to/project/tests/fixtures/test-app/src/index.ts" },
"breakpoints": [
{ "line": 96, "column": 1, "logMessage": "fib={fibResult} sum={breakpointResult}" }
]
}
}
Example of getLogpointHits response content (simplified):
{
"success": true,
"data": {
"hits": [
{
"timestamp": "2025-08-12T12:34:56.789Z",
"executionContextId": 1,
"message": "fib=5 sum=15",
"payloadRaw": "{\"message\":\"fib=5 sum=15\",\"vars\":{\"fibResult\":5,\"breakpointResult\":15},\"time\":1734000000000}",
"payload": {
"message": "fib=5 sum=15",
"vars": { "fibResult": 5, "breakpointResult": 15 },
"time": 1734000000000
},
"level": "info"
}
],
"totalCount": 1
}
}
Notes:
payload.varscontains pairs "expression → value" for all{expr}inlogMessage.- For reliable logpoint placement, use a truly executable line and the correct column (1‑based).
TypeScript Breakpoints and Source Maps
Two recommended ways to work with TypeScript sources:
- TS‑first breakpoints and logpoints (recommended)
- Set breakpoints/logpoints directly on the TS file path — the adapter automatically resolves source maps.
{
"name": "setBreakpoints",
"arguments": {
"source": { "path": "/abs/path/to/project/tests/fixtures/test-app/src/index.ts" },
"breakpoints": [
{ "line": 96, "column": 1, "logMessage": "fib={fibResult} sum={breakpointResult}" }
]
}
}
- Auto‑resolve generated position (fallback)
- If you need an explicit mapping, call
resolveGeneratedPositionwithout manually passing map paths by providingoriginalSourcePath. The server auto‑discovers maps underdist|build|out|librelative to the project root and the TS file.
{
"name": "resolveGeneratedPosition",
"arguments": {
"originalSource": "src/index.ts",
"originalSourcePath": "/abs/path/to/project/tests/fixtures/test-app/src/index.ts",
"originalLine": 96,
"originalColumn": 1
}
}
Notes:
- When
originalSourcePathis provided, the server automatically searches for maps in the project’s build directories and near the TS file location — nosourceMapPathsneeded. - The integration script
scripts/mcp-logpoint-check.mjsfollows the TS‑first flow and verifies that logpoint interpolation works on TS lines; it also ensures the Node inspector port9229is free after completion.
Troubleshooting
- Project root detection: for auto source map discovery the server looks for the nearest
package.jsonupward from the provided TS path and scansdist,build,out, andlib. Ensure your build emits*.js.mapto one of these folders. - If maps aren’t found: pass
originalSourcePathtoresolveGeneratedPosition, or run the MCP server from the project root so the fallback scan of the current working directory succeeds. - Coordinates: all MCP/DAP coordinates are 1‑based for both lines and columns. Use
column >= 1when setting breakpoints/logpoints. - Logpoint hits: if you see no hits, move the logpoint to an actually executable line (e.g., assignment or expression within the handler), or trigger the endpoint/function that executes that line. In the TS test app, reliable lines include
index.ts:96(response object) andindex.ts:92(theprocessor.processData()region). - WebSocket attach: you can attach via
attachwith{ "url": "ws://127.0.0.1:<port>/<id>" }, or enable a running process viaattachwith{ "processId": <pid> }(sendsSIGUSR1). - PID attach port discovery: when using
attachwithprocessId, the server auto‑discovers the inspector port — theportargument is ignored for this path. On Linux, it attempts to detect activation viastrace; otherwise it pollshttp://127.0.0.1:<port>/json/versionacross common ports (9229..9250) and falls back to 9229 if nothing is found.
Architecture
Detailed Flow
sequenceDiagram
autonumber
participant C as Client
participant S as Server
participant A as Adapter
participant I as CDP
participant N as App
C->>S: attach
S->>A: start
A->>I: connect
A->>I: Runtime.enable
A->>I: Debugger.enable
A->>I: Console.enable
A->>I: Runtime.addBinding (__mcpLogPoint)
Note over C,S: set logpoint
C->>S: setBreakpoints
S->>A: setBreakpoints
A->>I: setBreakpointByUrl
Note over N,S: execute and collect
N->>I: hits line
I-->>A: bindingCalled (__mcpLogPoint)
A-->>S: event mcpLogpoint
C->>S: getLogpointHits
S-->>C: hits list
Project Creation
This project was designed by my expertise and implemented with AI assistant coding.
Support
If you find this project useful, consider supporting its development: