devtools-debugger-mcp-nodejs

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

devtools-debugger-mcp-nodejs

devtools-debugger-mcp-nodejs

Skill by ara.so — Devtools Skills collection.
An MCP (Model Context Protocol) server that exposes comprehensive Node.js debugging capabilities through the Chrome DevTools Protocol. Enables AI assistants to set breakpoints, step through code, inspect variables, evaluate expressions, analyze call stacks, and work with source maps — all programmatically.
ara.so开发的Skill——Devtools Skills系列。
这是一款MCP(Model Context Protocol)服务器,通过Chrome DevTools Protocol提供全面的Node.js调试能力。它允许AI助手以编程方式设置断点、单步执行代码、检查变量、计算表达式、分析调用栈以及处理源映射。

What It Does

功能介绍

This MCP server launches Node.js applications with the built-in inspector (
--inspect-brk=0
), connects via WebSocket to the Chrome DevTools Protocol, and exposes debugging operations as MCP tools. It handles:
  • Session management: Launch/stop Node.js processes with debugging enabled
  • Breakpoints: Set line breakpoints, conditional breakpoints, logpoints, and pause-on-exceptions
  • Execution control: Resume, step over/into/out, continue to location, restart frames
  • Inspection: Explore scopes (locals, closures,
    this
    ), drill into object properties
  • Evaluation: Execute JavaScript expressions in paused call frames
  • Console capture: Buffer and retrieve console output between pauses
  • Source maps: Full TypeScript and transpiled code debugging support
  • Script management: List loaded scripts, fetch sources, blackbox patterns
该MCP服务器启动带有内置检查器的Node.js应用(
--inspect-brk=0
),通过WebSocket连接到Chrome DevTools Protocol,并将调试操作作为MCP工具暴露出来。它支持以下功能:
  • 会话管理:启动/停止启用调试功能的Node.js进程
  • 断点设置:设置行断点、条件断点、日志断点以及异常暂停
  • 执行控制:恢复执行、单步跳过/进入/跳出、继续到指定位置、重启调用帧
  • 变量检查:探索作用域(局部变量、闭包、
    this
    )、深入查看对象属性
  • 表达式计算:在暂停的调用帧中执行JavaScript表达式
  • 控制台捕获:缓冲并检索暂停期间的控制台输出
  • 源映射:全面支持TypeScript和转译代码的调试
  • 脚本管理:列出已加载脚本、获取源码、设置黑盒模式

Installation

安装

bash
npm install devtools-debugger-mcp
Or globally:
bash
npm install -g devtools-debugger-mcp
bash
npm install devtools-debugger-mcp
或全局安装:
bash
npm install -g devtools-debugger-mcp

Configuration

配置

MCP Settings

MCP设置

Add to your MCP client configuration (e.g., Claude Desktop's
claude_desktop_config.json
):
json
{
  "mcpServers": {
    "devtools-debugger": {
      "command": "node",
      "args": ["/path/to/devtools-debugger-mcp/dist/index.js"]
    }
  }
}
Or if installed globally:
json
{
  "mcpServers": {
    "devtools-debugger": {
      "command": "devtools-debugger-mcp"
    }
  }
}
添加到你的MCP客户端配置中(例如Claude Desktop的
claude_desktop_config.json
):
json
{
  "mcpServers": {
    "devtools-debugger": {
      "command": "node",
      "args": ["/path/to/devtools-debugger-mcp/dist/index.js"]
    }
  }
}
如果是全局安装:
json
{
  "mcpServers": {
    "devtools-debugger": {
      "command": "devtools-debugger-mcp"
    }
  }
}

Output Format

输出格式

Set default response format (
text
,
json
, or
both
):
javascript
// Via set_output_format tool (defaults to 'text')
{
  "tool": "set_output_format",
  "params": { "format": "json" }
}
Individual tools can override with their own
format
parameter.
设置默认响应格式(
text
json
both
):
javascript
// 通过set_output_format工具设置(默认值为'text')
{
  "tool": "set_output_format",
  "params": { "format": "json" }
}
单个工具可以通过自身的
format
参数覆盖默认设置。

Core Debugging Workflow

核心调试工作流

1. Start Debug Session

1. 启动调试会话

javascript
// Launch Node.js script with inspector
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/absolute/path/to/app.js",
    "format": "text"  // optional: 'text' | 'json' | 'both'
  }
}
Returns initial pause at first line with
pauseId
and top frame info.
With arguments and environment:
javascript
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/path/to/server.js",
    "args": ["--port", "3000"],
    "env": {
      "NODE_ENV": "development",
      "DEBUG": "*"
    }
  }
}
javascript
// 启动带有检查器的Node.js脚本
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/absolute/path/to/app.js",
    "format": "text"  // 可选值: 'text' | 'json' | 'both'
  }
}
返回初始暂停状态(在第一行),包含
pauseId
和顶层调用帧信息。
带参数和环境变量的启动方式:
javascript
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/path/to/server.js",
    "args": ["--port", "3000"],
    "env": {
      "NODE_ENV": "development",
      "DEBUG": "*"
    }
  }
}

2. Set Breakpoints

2. 设置断点

File path + line (1-based):
javascript
{
  "tool": "set_breakpoint",
  "params": {
    "filePath": "/path/to/app.js",
    "line": 42
  }
}
Conditional breakpoint:
javascript
{
  "tool": "set_breakpoint_condition",
  "params": {
    "filePath": "/path/to/users.js",
    "line": 15,
    "condition": "user.age > 18"
  }
}
URL regex breakpoint (for modules/packages):
javascript
{
  "tool": "set_breakpoint_condition",
  "params": {
    "urlRegex": ".*express.*",
    "line": 100,
    "condition": "req.method === 'POST'"
  }
}
Logpoint (logs message without pausing):
javascript
{
  "tool": "add_logpoint",
  "params": {
    "filePath": "/path/to/api.js",
    "line": 28,
    "message": "Request received: {req.url}"
  }
}
文件路径 + 行号(从1开始计数):
javascript
{
  "tool": "set_breakpoint",
  "params": {
    "filePath": "/path/to/app.js",
    "line": 42
  }
}
条件断点:
javascript
{
  "tool": "set_breakpoint_condition",
  "params": {
    "filePath": "/path/to/users.js",
    "line": 15,
    "condition": "user.age > 18"
  }
}
URL正则断点(用于模块/包):
javascript
{
  "tool": "set_breakpoint_condition",
  "params": {
    "urlRegex": ".*express.*",
    "line": 100,
    "condition": "req.method === 'POST'"
  }
}
日志断点(仅记录消息不暂停):
javascript
{
  "tool": "add_logpoint",
  "params": {
    "filePath": "/path/to/api.js",
    "line": 28,
    "message": "Request received: {req.url}"
  }
}

3. Exception Breakpoints

3. 异常断点

javascript
{
  "tool": "set_exception_breakpoints",
  "params": {
    "state": "uncaught"  // 'none' | 'uncaught' | 'all'
  }
}
javascript
{
  "tool": "set_exception_breakpoints",
  "params": {
    "state": "uncaught"  // 'none' | 'uncaught' | 'all'
  }
}

4. Resume and Step

4. 恢复与单步执行

Resume to next breakpoint:
javascript
{
  "tool": "resume_execution",
  "params": {
    "includeScopes": true,
    "includeStack": true,
    "includeConsole": true,
    "format": "text"
  }
}
Step over current line:
javascript
{
  "tool": "step_over",
  "params": {
    "includeScopes": true,
    "includeConsole": true
  }
}
Step into function:
javascript
{
  "tool": "step_into",
  "params": {
    "includeStack": true
  }
}
Step out of current function:
javascript
{
  "tool": "step_out",
  "params": {
    "includeScopes": true
  }
}
Continue to specific location:
javascript
{
  "tool": "continue_to_location",
  "params": {
    "filePath": "/path/to/app.js",
    "line": 55,
    "column": 10  // optional
  }
}
恢复到下一个断点:
javascript
{
  "tool": "resume_execution",
  "params": {
    "includeScopes": true,
    "includeStack": true,
    "includeConsole": true,
    "format": "text"
  }
}
单步跳过当前行:
javascript
{
  "tool": "step_over",
  "params": {
    "includeScopes": true,
    "includeConsole": true
  }
}
单步进入函数:
javascript
{
  "tool": "step_into",
  "params": {
    "includeStack": true
  }
}
单步跳出当前函数:
javascript
{
  "tool": "step_out",
  "params": {
    "includeScopes": true
  }
}
继续到指定位置:
javascript
{
  "tool": "continue_to_location",
  "params": {
    "filePath": "/path/to/app.js",
    "line": 55,
    "column": 10  // 可选
  }
}

5. Inspect Variables and Scopes

5. 检查变量与作用域

Current scope (locals, closures, this):
javascript
{
  "tool": "inspect_scopes",
  "params": {
    "maxProps": 20,          // max properties per object
    "pauseId": "pause123",   // optional, defaults to current
    "frameIndex": 0,         // optional, defaults to 0 (top frame)
    "includeThisPreview": true,
    "format": "text"
  }
}
Drill into object properties:
javascript
// First get objectId from inspect_scopes or evaluate_expression
{
  "tool": "get_object_properties",
  "params": {
    "objectId": "object:123",
    "maxProps": 50
  }
}
当前作用域(局部变量、闭包、this):
javascript
{
  "tool": "inspect_scopes",
  "params": {
    "maxProps": 20,          // 每个对象的最大属性数
    "pauseId": "pause123",   // 可选,默认为当前暂停
    "frameIndex": 0,         // 可选,默认为0(顶层帧)
    "includeThisPreview": true,
    "format": "text"
  }
}
深入查看对象属性:
javascript
// 首先从inspect_scopes或evaluate_expression获取objectId
{
  "tool": "get_object_properties",
  "params": {
    "objectId": "object:123",
    "maxProps": 50
  }
}

6. Evaluate Expressions

6. 计算表达式

javascript
{
  "tool": "evaluate_expression",
  "params": {
    "expr": "user.profile.email",
    "pauseId": "pause123",     // optional
    "frameIndex": 0,           // optional, which frame to eval in
    "returnByValue": true,     // optional, serialize result
    "format": "json"
  }
}
Evaluate with side effects:
javascript
{
  "tool": "evaluate_expression",
  "params": {
    "expr": "items.push({ id: 5, name: 'test' }); items.length"
  }
}
javascript
{
  "tool": "evaluate_expression",
  "params": {
    "expr": "user.profile.email",
    "pauseId": "pause123",     // 可选
    "frameIndex": 0,           // 可选,在哪个调用帧中计算
    "returnByValue": true,     // 可选,序列化结果
    "format": "json"
  }
}
计算带副作用的表达式:
javascript
{
  "tool": "evaluate_expression",
  "params": {
    "expr": "items.push({ id: 5, name: 'test' }); items.length"
  }
}

7. Call Stack Inspection

7. 检查调用栈

javascript
{
  "tool": "list_call_stack",
  "params": {
    "depth": 10,              // optional, max frames
    "pauseId": "pause123",    // optional
    "includeThis": true,      // optional, include 'this' preview
    "format": "text"
  }
}
javascript
{
  "tool": "list_call_stack",
  "params": {
    "depth": 10,              // 可选,最大帧数量
    "pauseId": "pause123",    // 可选
    "includeThis": true,      // 可选,包含'this'预览
    "format": "text"
  }
}

8. Pause Information

8. 暂停信息

javascript
{
  "tool": "get_pause_info",
  "params": {
    "pauseId": "pause123",    // optional, defaults to current
    "format": "text"
  }
}
Returns pause reason (breakpoint, exception, step, etc.) and location.
javascript
{
  "tool": "get_pause_info",
  "params": {
    "pauseId": "pause123",    // 可选,默认为当前暂停
    "format": "text"
  }
}
返回暂停原因(断点、异常、单步执行等)和位置。

9. Console Output

9. 控制台输出

javascript
{
  "tool": "read_console",
  "params": {
    "format": "text"
  }
}
Retrieves console messages buffered since last step/resume. Console is also auto-included when
includeConsole: true
on step/resume tools.
javascript
{
  "tool": "read_console",
  "params": {
    "format": "text"
  }
}
检索自上次单步/恢复操作以来缓冲的控制台消息。当在单步/恢复工具中设置
includeConsole: true
时,控制台输出也会自动包含在内。

10. Stop Session

10. 停止会话

javascript
{
  "tool": "stop_debug_session"
}
Kills the Node.js process and cleans up CDP connection.
javascript
{
  "tool": "stop_debug_session"
}
终止Node.js进程并清理CDP连接。

Script Management

脚本管理

List Loaded Scripts

列出已加载脚本

javascript
{
  "tool": "list_scripts"
}
Returns all scripts loaded by Node.js (app files, node_modules, builtins).
javascript
{
  "tool": "list_scripts"
}
返回Node.js加载的所有脚本(应用文件、node_modules、内置模块)。

Get Script Source

获取脚本源码

javascript
// By scriptId
{
  "tool": "get_script_source",
  "params": {
    "scriptId": "42"
  }
}

// By URL
{
  "tool": "get_script_source",
  "params": {
    "url": "file:///path/to/app.js"
  }
}
javascript
// 通过scriptId获取
{
  "tool": "get_script_source",
  "params": {
    "scriptId": "42"
  }
}

// 通过URL获取
{
  "tool": "get_script_source",
  "params": {
    "url": "file:///path/to/app.js"
  }
}

Blackbox Scripts (Skip During Debugging)

黑盒脚本(调试时跳过)

javascript
{
  "tool": "blackbox_scripts",
  "params": {
    "patterns": [
      "node_modules/express/*",
      "internal/*"
    ]
  }
}
Frames matching these patterns won't pause during step-into.
javascript
{
  "tool": "blackbox_scripts",
  "params": {
    "patterns": [
      "node_modules/express/*",
      "internal/*"
    ]
  }
}
匹配这些模式的调用帧在单步进入时不会暂停。

Restart Frame

重启调用帧

Re-execute a specific call frame:
javascript
{
  "tool": "restart_frame",
  "params": {
    "frameIndex": 2,          // which frame to restart (0 = top)
    "pauseId": "pause123",    // optional
    "format": "text"
  }
}
重新执行指定的调用帧:
javascript
{
  "tool": "restart_frame",
  "params": {
    "frameIndex": 2,          // 要重启的调用帧索引(0 = 顶层)
    "pauseId": "pause123",    // 可选
    "format": "text"
  }
}

Advanced Patterns

高级用法

Debug TypeScript with Source Maps

使用源映射调试TypeScript

Source maps are automatically detected and used. Just launch your compiled JS:
javascript
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/path/to/dist/app.js"
  }
}

// Set breakpoints using original .ts file paths
{
  "tool": "set_breakpoint",
  "params": {
    "filePath": "/path/to/src/app.ts",
    "line": 42
  }
}
源映射会被自动检测和使用。只需启动编译后的JS文件:
javascript
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/path/to/dist/app.js"
  }
}

// 使用原始.ts文件路径设置断点
{
  "tool": "set_breakpoint",
  "params": {
    "filePath": "/path/to/src/app.ts",
    "line": 42
  }
}

Conditional Debugging Loop

条件调试循环

javascript
// 1. Start session
start_node_debug({ scriptPath: "/path/to/app.js" })

// 2. Set conditional breakpoint
set_breakpoint_condition({
  filePath: "/path/to/app.js",
  line: 25,
  condition: "count > 100"
})

// 3. Resume until condition met
resume_execution({ includeScopes: true, includeConsole: true })

// 4. Inspect when paused
inspect_scopes({ maxProps: 15 })
evaluate_expression({ expr: "count" })

// 5. Continue
resume_execution()
javascript
// 1. 启动会话
start_node_debug({ scriptPath: "/path/to/app.js" })

// 2. 设置条件断点
set_breakpoint_condition({
  filePath: "/path/to/app.js",
  line: 25,
  condition: "count > 100"
})

// 3. 恢复执行直到条件满足
resume_execution({ includeScopes: true, includeConsole: true })

// 4. 暂停时检查变量
inspect_scopes({ maxProps: 15 })
evaluate_expression({ expr: "count" })

// 5. 继续执行
resume_execution()

Capture All Console Output

捕获所有控制台输出

javascript
// Resume with console capture
const result = await resume_execution({ includeConsole: true });

// Or read explicitly
const consoleOutput = await read_console({ format: "text" });
javascript
// 恢复执行并捕获控制台输出
const result = await resume_execution({ includeConsole: true });

// 或显式读取
const consoleOutput = await read_console({ format: "text" });

Multi-Frame Inspection

多帧检查

javascript
// Get full call stack
list_call_stack({ depth: 20, includeThis: true })

// Inspect different frames
inspect_scopes({ frameIndex: 0 })  // Current frame
inspect_scopes({ frameIndex: 1 })  // Caller frame
inspect_scopes({ frameIndex: 2 })  // Caller's caller

// Evaluate in different frame context
evaluate_expression({ expr: "localVar", frameIndex: 1 })
javascript
// 获取完整调用栈
list_call_stack({ depth: 20, includeThis: true })

// 检查不同调用帧
inspect_scopes({ frameIndex: 0 })  // 当前帧
inspect_scopes({ frameIndex: 1 })  // 调用者帧
inspect_scopes({ frameIndex: 2 })  // 调用者的调用者帧

// 在不同帧上下文中计算表达式
evaluate_expression({ expr: "localVar", frameIndex: 1 })

Exception Debugging

异常调试

javascript
// Pause on all exceptions
set_exception_breakpoints({ state: "all" })

// Resume and wait for exception
const result = await resume_execution({ includeStack: true })

// When paused on exception:
get_pause_info()  // Shows exception details
list_call_stack({ depth: 10 })
inspect_scopes({ maxProps: 20 })
javascript
// 在所有异常处暂停
set_exception_breakpoints({ state: "all" })

// 恢复执行并等待异常
const result = await resume_execution({ includeStack: true })

// 在异常暂停时:
get_pause_info()  // 显示异常详情
list_call_stack({ depth: 10 })
inspect_scopes({ maxProps: 20 })

Real-World Example: Debug Express API

实战示例:调试Express API

javascript
// 1. Start debugging an Express server
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/path/to/server.js",
    "env": {
      "PORT": "3000",
      "NODE_ENV": "development"
    }
  }
}

// 2. Set breakpoint in route handler
{
  "tool": "set_breakpoint",
  "params": {
    "filePath": "/path/to/routes/users.js",
    "line": 15
  }
}

// 3. Set logpoint to track requests
{
  "tool": "add_logpoint",
  "params": {
    "filePath": "/path/to/middleware/auth.js",
    "line": 8,
    "message": "Auth check for user: {req.user.id}"
  }
}

// 4. Pause only on errors
{
  "tool": "set_exception_breakpoints",
  "params": { "state": "uncaught" }
}

// 5. Resume and make HTTP request (externally)
{
  "tool": "resume_execution",
  "params": {
    "includeScopes": true,
    "includeConsole": true
  }
}

// 6. When paused at breakpoint, inspect request
{
  "tool": "evaluate_expression",
  "params": {
    "expr": "req.body",
    "returnByValue": true
  }
}

{
  "tool": "evaluate_expression",
  "params": {
    "expr": "req.headers['authorization']"
  }
}

// 7. Check database query in scope
{
  "tool": "inspect_scopes",
  "params": { "maxProps": 30 }
}

// 8. Step into database function
{
  "tool": "step_into",
  "params": { "includeStack": true }
}

// 9. Continue execution
{
  "tool": "resume_execution"
}

// 10. Stop when done
{
  "tool": "stop_debug_session"
}
javascript
// 1. 启动Express服务器调试
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/path/to/server.js",
    "env": {
      "PORT": "3000",
      "NODE_ENV": "development"
    }
  }
}

// 2. 在路由处理器中设置断点
{
  "tool": "set_breakpoint",
  "params": {
    "filePath": "/path/to/routes/users.js",
    "line": 15
  }
}

// 3. 设置日志断点跟踪请求
{
  "tool": "add_logpoint",
  "params": {
    "filePath": "/path/to/middleware/auth.js",
    "line": 8,
    "message": "Auth check for user: {req.user.id}"
  }
}

// 4. 仅在错误时暂停
{
  "tool": "set_exception_breakpoints",
  "params": { "state": "uncaught" }
}

// 5. 恢复执行并发起HTTP请求(外部)
{
  "tool": "resume_execution",
  "params": {
    "includeScopes": true,
    "includeConsole": true
  }
}

// 6. 在断点暂停时检查请求
{
  "tool": "evaluate_expression",
  "params": {
    "expr": "req.body",
    "returnByValue": true
  }
}

{
  "tool": "evaluate_expression",
  "params": {
    "expr": "req.headers['authorization']"
  }
}

// 7. 检查作用域中的数据库查询
{
  "tool": "inspect_scopes",
  "params": { "maxProps": 30 }
}

// 8. 单步进入数据库函数
{
  "tool": "step_into",
  "params": { "includeStack": true }
}

// 9. 继续执行
{
  "tool": "resume_execution"
}

// 10. 调试完成后停止会话
{
  "tool": "stop_debug_session"
}

Real-World Example: Debug Async/Await

实战示例:调试Async/Await

javascript
// app.js
async function fetchUserData(userId) {
  const user = await db.findUser(userId);
  const posts = await db.findPosts(user.id);
  return { user, posts };
}

// Debugging session:

// 1. Start
start_node_debug({ scriptPath: "/path/to/app.js" })

// 2. Break at async function
set_breakpoint({ filePath: "/path/to/app.js", line: 2 })

// 3. Resume to breakpoint
resume_execution({ includeScopes: true })

// 4. Check userId parameter
evaluate_expression({ expr: "userId" })

// 5. Step over await (resumes until promise resolves)
step_over({ includeScopes: true, includeConsole: true })

// 6. Inspect resolved user object
evaluate_expression({ expr: "user" })
get_object_properties({ objectId: "object:user123", maxProps: 20 })

// 7. Continue
resume_execution()
javascript
// app.js
async function fetchUserData(userId) {
  const user = await db.findUser(userId);
  const posts = await db.findPosts(user.id);
  return { user, posts };
}

// 调试会话:

// 1. 启动调试
start_node_debug({ scriptPath: "/path/to/app.js" })

// 2. 在异步函数处设置断点
set_breakpoint({ filePath: "/path/to/app.js", line: 2 })

// 3. 恢复执行到断点
resume_execution({ includeScopes: true })

// 4. 检查userId参数
evaluate_expression({ expr: "userId" })

// 5. 单步跳过await(恢复执行直到Promise解析)
step_over({ includeScopes: true, includeConsole: true })

// 6. 检查解析后的user对象
evaluate_expression({ expr: "user" })
get_object_properties({ objectId: "object:user123", maxProps: 20 })

// 7. 继续执行
resume_execution()

File Path Handling

文件路径处理

  • Always use absolute paths for
    filePath
    parameters
  • Relative paths are NOT resolved automatically
  • Internal conversion: file paths →
    file://
    URLs for CDP
  • Line numbers are 1-based (CDP internally uses 0-based)
  • Column numbers are 1-based when specified
javascript
// ✅ Correct
set_breakpoint({ filePath: "/home/user/project/src/app.js", line: 42 })

// ❌ Wrong (relative path)
set_breakpoint({ filePath: "./src/app.js", line: 42 })
  • 始终使用绝对路径作为
    filePath
    参数
  • 相对路径不会自动解析
  • 内部转换:文件路径 →
    file://
    格式的URL用于CDP
  • 行号是从1开始计数(CDP内部使用从0开始计数)
  • 指定列号时也是从1开始计数
javascript
// ✅ 正确用法
set_breakpoint({ filePath: "/home/user/project/src/app.js", line: 42 })

// ❌ 错误用法(相对路径)
set_breakpoint({ filePath: "./src/app.js", line: 42 })

Troubleshooting

故障排除

Session Won't Start

会话无法启动

Problem:
start_node_debug
fails or hangs
Solutions:
  • Ensure
    scriptPath
    is an absolute path
  • Check that the script file exists and is readable
  • Verify Node.js is in PATH
  • Try with a simple script first (e.g.,
    console.log('test')
    )
javascript
// Test with minimal script
start_node_debug({ scriptPath: "/tmp/test.js" })
// test.js content: console.log('Hello');
问题
start_node_debug
执行失败或挂起
解决方案
  • 确保
    scriptPath
    是绝对路径
  • 检查脚本文件存在且可读
  • 验证Node.js已添加到PATH
  • 先尝试使用简单脚本测试(例如
    console.log('test')
javascript
// 使用最小脚本测试
start_node_debug({ scriptPath: "/tmp/test.js" })
// test.js内容: console.log('Hello');

Breakpoint Not Hit

断点未触发

Problem: Breakpoint set but execution doesn't pause
Solutions:
  • Verify file path matches exactly (use
    list_scripts
    to confirm)
  • Check line number is valid (1-based, not 0-based)
  • Ensure breakpoint isn't in unreachable code
  • Try URL regex if file path doesn't match
javascript
// List all scripts to find exact URL
list_scripts()

// Use URL regex instead of file path
set_breakpoint_condition({
  urlRegex: ".*app\\.js$",
  line: 42
})
问题:已设置断点但执行未暂停
解决方案
  • 验证文件路径完全匹配(使用
    list_scripts
    确认)
  • 检查行号有效(从1开始计数,不是从0开始)
  • 确保断点不在不可达代码中
  • 如果文件路径不匹配,尝试使用URL正则
javascript
// 列出所有脚本以找到准确URL
list_scripts()

// 使用URL正则代替文件路径
set_breakpoint_condition({
  urlRegex: ".*app\\.js$",
  line: 42
})

Source Maps Not Working

源映射不工作

Problem: Breakpoints in TypeScript sources don't work
Solutions:
  • Ensure source maps are generated (
    "sourceMap": true
    in tsconfig.json)
  • Check
    .map
    files exist alongside compiled JS
  • Verify source map paths are correct (relative or absolute)
  • Use compiled JS path if source map lookup fails
javascript
// If TypeScript breakpoints fail, use compiled JS path
set_breakpoint({ filePath: "/path/to/dist/app.js", line: 58 })
问题:TypeScript源码中的断点无效
解决方案
  • 确保已生成源映射(tsconfig.json中设置
    "sourceMap": true
  • 检查.map文件是否与编译后的JS文件共存
  • 验证源映射路径正确(相对或绝对)
  • 如果源映射查找失败,使用编译后的JS路径
javascript
// 如果TypeScript断点失败,使用编译后的JS路径
set_breakpoint({ filePath: "/path/to/dist/app.js", line: 58 })

Can't Inspect Large Objects

无法检查大型对象

Problem: Objects truncated or not showing all properties
Solutions:
  • Increase
    maxProps
    parameter
  • Use
    get_object_properties
    to drill down
  • Evaluate specific property paths with
    evaluate_expression
javascript
// Get more properties
inspect_scopes({ maxProps: 100 })

// Or drill into specific object
evaluate_expression({ expr: "largeObject.specificProperty" })
问题:对象被截断或未显示所有属性
解决方案
  • 增加
    maxProps
    参数
  • 使用
    get_object_properties
    深入查看
  • 使用
    evaluate_expression
    计算特定属性路径
javascript
// 获取更多属性
inspect_scopes({ maxProps: 100 })

// 或深入查看特定对象
evaluate_expression({ expr: "largeObject.specificProperty" })

Console Output Missing

控制台输出缺失

Problem: Console logs not captured
Solutions:
  • Use
    includeConsole: true
    on step/resume operations
  • Or call
    read_console
    explicitly after stepping
  • Console buffer is cleared after each read
javascript
// Include console in step
step_over({ includeConsole: true })

// Or read explicitly
read_console({ format: "text" })
问题:未捕获到控制台日志
解决方案
  • 在单步/恢复操作中设置
    includeConsole: true
  • 或在单步后显式调用
    read_console
  • 控制台缓冲区在每次读取后会被清空
javascript
// 在单步时包含控制台输出
step_over({ includeConsole: true })

// 或显式读取
read_console({ format: "text" })

Session Cleanup

会话清理

Problem: Zombie Node.js processes after debugging
Solutions:
  • Always call
    stop_debug_session
    when done
  • MCP server cleans up on disconnect, but explicit stop is better
  • Check for orphaned Node.js processes:
    ps aux | grep node
bash
undefined
问题:调试后存在僵尸Node.js进程
解决方案
  • 调试完成后始终调用
    stop_debug_session
  • MCP服务器会在断开连接时清理资源,但显式停止更稳妥
  • 检查孤立的Node.js进程:
    ps aux | grep node
bash
undefined

Kill orphaned debugger processes

终止孤立的调试器进程

pkill -f "node --inspect-brk"
undefined
pkill -f "node --inspect-brk"
undefined

Multiple Pauses

意外暂停

Problem: Execution pauses unexpectedly
Solutions:
  • Check for multiple breakpoints at same location
  • Review exception breakpoint settings (
    set_exception_breakpoints
    )
  • Use
    get_pause_info
    to understand why paused
  • Remove breakpoints: restart session or use CDP commands directly
javascript
// Check why paused
get_pause_info({ format: "text" })

// Disable exception breaks if too noisy
set_exception_breakpoints({ state: "none" })
问题:执行意外暂停
解决方案
  • 检查同一位置是否设置了多个断点
  • 查看异常断点设置(
    set_exception_breakpoints
  • 使用
    get_pause_info
    了解暂停原因
  • 移除断点:重启会话或直接使用CDP命令
javascript
// 检查暂停原因
get_pause_info({ format: "text" })

// 如果异常暂停过于频繁,禁用异常断点
set_exception_breakpoints({ state: "none" })

Tips and Best Practices

技巧与最佳实践

  1. Use absolute paths: Always provide absolute file paths for breakpoints
  2. Include context: Add
    includeScopes
    ,
    includeStack
    ,
    includeConsole
    on steps for richer debugging
  3. Blackbox dependencies: Skip node_modules during step-into with
    blackbox_scripts
  4. Conditional breakpoints: Use conditions to pause only when specific criteria met
  5. Logpoints over breakpoints: Use logpoints for non-intrusive logging without pausing
  6. Pause on uncaught only: Set
    state: 'uncaught'
    to avoid pausing on handled exceptions
  7. Clean up sessions: Always call
    stop_debug_session
    when done
  8. Test with simple scripts: Verify setup with minimal examples before complex debugging
  9. Check pauseId: After each pause, note the
    pauseId
    for context-specific operations
  10. Frame-aware evaluation: Use
    frameIndex
    to evaluate expressions in specific call frames
  1. 使用绝对路径:设置断点时始终提供绝对文件路径
  2. 包含上下文信息:在单步操作中添加
    includeScopes
    includeStack
    includeConsole
    以获取更丰富的调试信息
  3. 黑盒依赖项:使用
    blackbox_scripts
    在单步进入时跳过node_modules
  4. 使用条件断点:通过条件设置仅在特定条件满足时暂停
  5. 优先使用日志断点:使用日志断点进行非侵入式日志记录,无需暂停执行
  6. 仅在未捕获异常时暂停:设置
    state: 'uncaught'
    避免在已处理异常处暂停
  7. 清理会话:调试完成后始终调用
    stop_debug_session
  8. 用简单脚本测试:在调试复杂代码前先用最小示例验证设置
  9. 记录pauseId:每次暂停后记录
    pauseId
    用于上下文相关操作
  10. 帧感知计算:使用
    frameIndex
    在特定调用帧中计算表达式

Environment Variables

环境变量

The MCP server itself doesn't require environment variables, but your Node.js scripts may:
javascript
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/path/to/app.js",
    "env": {
      "DATABASE_URL": process.env.DATABASE_URL,
      "API_KEY": process.env.API_KEY,
      "NODE_ENV": "development"
    }
  }
}
Never hardcode secrets in debugging params — reference environment variables or use a
.env
file in your project.
MCP服务器本身不需要环境变量,但你的Node.js脚本可能需要:
javascript
{
  "tool": "start_node_debug",
  "params": {
    "scriptPath": "/path/to/app.js",
    "env": {
      "DATABASE_URL": process.env.DATABASE_URL,
      "API_KEY": process.env.API_KEY,
      "NODE_ENV": "development"
    }
  }
}
切勿在调试参数中硬编码机密信息——引用环境变量或在项目中使用
.env
文件。

License

许可证

MIT
MIT