MCP Chrome调试器协议
](https://www.npmjs.com/package/@vitalyostanin/mcp-chrome-debugger-protocol) ](https://github.com/VitalyOstanin/mcp-chrome-debugger-protocol/actions/workflows/node.js.yml)  ](https://nodejs.org)
MCP服务器,允许AI编码工具通过chrome devtools协议(CDP)和轻量级调试适配器协议(DAP)桥控制和观察正在运行的Node.js进程。
使用Claude Code CLI进行测试。
特性
- 连接/控制:通过端口、WebSocket URL或PID连接到Node.js进程;暂停、继续并逐步执行代码。
- 断点和日志点:设置/删除经典断点和日志点(带
{expr}插值)在TS或JS上。 - 源地图:解析TS↔JS使用自动发现
*.js.map具有LEAST_UPPER_BOUND偏置,可实现可靠放置。 - 状态和事件:观察暂停/恢复、自定义日志点点击和基本线程/堆栈检查。
- 安全插值:表达式
{expr}被防御性地评估;错误永远不会中断执行(返回undefined).
高级图表
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]工作原理(功能描述)
- MCP服务器:在模型上下文协议上公开一组调试工具(附加、断点、步进、检查)。
- DAP桥:服务器使用进程内DAP客户端和直接与CDP通信的自定义Node.js调试适配器。
- CDP传输:适配器启用CDP域(
Runtime,Debugger,Console)并安装一个名为的绑定__mcpLogPoint. - 日志点:日志点只是一个断点,其条件调用
__mcpLogPoint(JSON.stringify(...))并返回false所以执行永远不会停顿。 - 事件流:适配器发送自定义DAP事件
mcpLogpointDAP客户端存储命中数据,MCP服务器通过工具和日志记录将其显示出来。
调试器交互(文本方案)
- 附加/初始化
- MCP客户端呼叫 attach;服务器创建适配器并连接到CDP(通过URL/port/PID)。 - 适配器: Runtime.enable, Debugger.enable, Console.enable那么 Runtime.addBinding 为了 __mcpLogPoint (以及每个执行上下文)。
- 设置日志点/断点
- MCP客户端呼叫 setBreakpoints 相对于TS或JS源路径和坐标(基于1的行/列)。 - 对于TS输入,服务器通过源映射解析生成的JS位置(或自动发现它们)。 - 适配器放置CDP断点(Debugger.setBreakpointByUrl 或通过scriptId)。对于日志点,条件评估 {expr} 安全地调用绑定。
- 执行并收集
- 当代码到达站点时,CDP会触发 Runtime.bindingCalled 使用JSON有效载荷。 - 适配器发出DAP自定义事件 mcpLogpoint 使用原始有效载荷和上下文id。 - DAP客户端解析/存储命中并发出 logpointHit;MCP服务器通过以下方式公开它 getLogpointHits 以及日志记录。
演示
带有源代码映射的TypeScript演示
可用格式:
需求
- Node.js>=22(匹配项
engines.node在package.json;CI运行节点22和24,以及.nvmrc固定推荐的本地版本)。 - npm>=11(仅适用于
npm publish;日常开发工作在npm 10+上)。
安装
使用Claude MCP CLI进行安装:
claude mcp add --scope user chrome-debugger-protocol npx @vitalyostanin/mcp-chrome-debugger-protocol范围选项:
--scope user:为当前用户安装--scope project:仅为当前项目安装
移除
卸下MCP服务器:
claude mcp remove chrome-debugger-protocol --scope user范围选项:
--scope user:从用户配置中删除--scope project:从项目配置中删除
安全模型
仅在受信任的本地环境(开发人员工作站、IDE、您拥有的CI沙箱)中运行此服务器。它是 不 设计用于坐在公共代理后面或在相互不信任的客户端之间共享。
MCP客户端连接后可以做什么:
evaluate,setBreakpoints随着condition,和logpoint{expr}占位符在调试进程中运行任意JavaScript。任何可以与此服务器通信的人都是目标Node.js进程内的根用户。attach可以通过主机名请求连接。默认情况下,服务器拒绝非环回主机;集MCP_CDP_ALLOW_REMOTE=1只有当你控制了两端,并且有理由这样做的时候。- 日志点点击被缓冲(最多10000个条目),并按需返回。避免放置以下日志点
{expr}在长期调试会话中引用secrets/PII——稍后getLogpointHits在缓冲区被清除或条目被逐出FIFO之前,仍将看到它们。
操作指南:
node --inspect约束检查员127.0.0.1默认情况下(从Node 7+开始)。永远不要把它当作--inspect=0.0.0.0在多租户或网络暴露的主机上:V8检查器暴露Runtime.evaluate,这是对被调试对象执行的未经身份验证的任意代码。- MCP服务器通过WebSocket连接到
localhost.要调试远程进程,请通过SSH隧道(ssh -L 9229:127.0.0.1:9229 host)而不是向网络开放端口9229。
快速开始
- 使用调试器启动Node.js应用程序:
node --inspect your-app.js- 在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提示:使用 attach 连接工具;通过以下方式设置日志点 setBreakpoints (通过断点 logMessage),然后使用以下命令检查命中率 getLogpointHits.
需要目标应用程序吗?该回购在 tests/fixtures/test-app 带着一个 /test1 您可以在其下启动的端点 --inspect 按照上面的提示进行端到端操作。
发展
贡献者的本地工作流程:
npm install
npm run build # tsc -> dist/
npm run typecheck # tsc -p tsconfig.json (src + tests)
npm run lint # eslint .
npm run lint:fix # eslint . --fix
npm test # vitest unit tests
npm run test:coverage # vitest unit tests with coverage report
npm run test:integration # vitest integration tests (real Node debugger)
npm run test:all # unit + integration sequentially
npm run dev # tsc --watch (incremental compile only)
npm run dev:server # build + run MCP server (stdio)
npm run dev:test # launch the test-app fixture under --inspect for manual attach30秒内完成端到端循环:运行 npm run dev:test 在一个终端中(它在下面启动测试应用程序夹具 --inspect=9229),然后在另一个终端中运行MCP服务器(npm run dev:server)并使用 attach 您的客户提供的工具。
格式化:此项目依赖ESLint plus .editorconfig。没有单独的 prettier 配置,没有 npm run format 脚本--运行 npm run lint:fix 应用样式修复。如果编辑器插入了冲突的格式,请将其配置为遵从ESLint。
看 代理商.md 了解详细的贡献者规则和项目约定。
可用工具
- 连接:
attach,disconnect,restart,terminate - 断点:
setBreakpoints(支持logMessage),removeBreakpoint,getBreakpoints,setExceptionBreakpoints,breakpointLocations - 执行控制:
continue,pause,next(跳过),stepIn,stepOut,goto,restartFrame - 检查:
evaluate,stackTrace,variables,scopes,setVariable,threads,loadedSources,exceptionInfo - 监控:
getLogpointHits,clearLogpointHits,getDebuggerEvents,clearDebuggerEvents,getDebuggerState - 源地图:
resolveOriginalPosition,resolveGeneratedPosition
日志点
- 放置:通过以下方式创建日志点
setBreakpoints通过提供断点条目logMessage现场。 - 插值:使用
{expr}内部占位符logMessage在目标上下文中安全地计算表达式;错误被接受并屈服undefined. - 传输:日志点通过CDP实现
Runtime.addBinding并通过以下方式捕获Runtime.bindingCalled--不使用控制台输出前缀。 - 有效载荷:每次命中都会产生一个结构化的有效载荷,由
getLogpointHits.
放置日志点的请求示例:
{
"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}" }
]
}
}例子 getLogpointHits 响应内容(简化):
{
"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
}
}笔记:
payload.vars包含“配对”表达式→ “为所有人”{expr}在logMessage.- 为了可靠地放置日志点,请使用真正可执行的行和正确的列(基于1)。
TypeScript断点和源映射
使用TypeScript源代码的两种推荐方法:
- TS‑first断点和日志点(推荐)
- 直接在TS文件路径上设置断点/日志点——适配器会自动解析源映射。
{
"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}" }
]
}
}- 自动解析生成的位置(回退)
- 如果需要显式映射,请调用
resolveGeneratedPosition无需手动传递地图路径,只需提供originalSourcePath。服务器自动发现以下地图dist|build|out|lib相对于项目根和TS文件。
{
"name": "resolveGeneratedPosition",
"arguments": {
"originalSource": "src/index.ts",
"originalSourcePath": "/abs/path/to/project/tests/fixtures/test-app/src/index.ts",
"originalLine": 96,
"originalColumn": 1
}
}笔记:
- 当
originalSourcePath如果提供,服务器会自动在项目的构建目录中以及TS文件位置附近搜索映射——否sourceMapPaths需要。 - 集成脚本
scripts/mcp-logpoint-check.mjs遵循TS优先流,并验证对数点插值在TS线上有效;它还确保了Node检查器端口9229完成后免费。
故障排除
- 项目根检测:对于自动源映射发现,服务器会查找最近的
package.json从提供的TS路径向上扫描dist,build,out,以及lib。确保您的构建能够发出*.js.map到其中一个文件夹。 - 如果找不到地图:通过
originalSourcePath到resolveGeneratedPosition,或从项目根目录运行MCP服务器,以便当前工作目录的回退扫描成功。 - 坐标:所有MCP/DAP坐标都是基于1的线和列。使用
column >= 1设置断点/日志点时。 - 日志点命中:如果您没有看到任何命中,请将日志点移动到实际可执行的行(例如,处理程序中的赋值或表达式),或触发执行该行的端点/函数。在TS测试应用程序中,可靠的线路包括
index.ts:96(响应对象)和index.ts:92(theprocessor.processData()地区)。 - WebSocket连接:您可以通过
attach随着 `{ "url": "ws://127.0.0.1:
/" },或通过以下方式启用正在运行的进程 attach 随着 { "processId": } (发送 SIGUSR1`).
- PID连接端口发现:使用时
attach随着processId,服务器自动发现检查器端口port此路径的参数被忽略。在Linux上,它试图通过以下方式检测激活strace否则,它将进行民意调查 `http://127.0.0.1:
/json/version` 跨公共端口(9229..9250),如果找不到任何内容,则回退到9229。
建筑
详细流程
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项目创建
这个项目是由我的专业知识设计的,并使用人工智能辅助编码实现。
支持
如果你觉得这个项目有用,可以考虑支持它的开发: 捐款
