MCP Debugger
mcp-debugger is a headless MCP server that lets AI agents run full step-through debugging sessions on running programs across nine languages (Python, JavaScript/TypeScript, Ruby, Rust, Go, Java, .NET/C#, C/C++, COBOL, plus a mock adapter).
Session management — create, list, and close debug sessions; discover which languages/adapters are available.
Launch or attach — start a script under the debugger (args, stop-on-entry, exception breaking, adapter-specific launch config) or attach to a running process by host/port or PID, then detach without terminating it.
Breakpoints — set by line, by content (
statement:), or by symbol (function:), with conditions,expectedContentassertions,nearLinedisambiguation, suspend policy, and logpoints (logMessage) that log without pausing; list, remove, and clear them live mid-run.Execution control — step over/into/out, continue, pause, and restart the debuggee with the same config and breakpoints automatically re-applied.
State inspection — list threads, get stack traces (with optional internal/framework frames), scopes, scoped or local variables, and evaluate expressions in the paused context.
Source and output — fetch source context around a line, and read buffered debuggee stdout/stderr through a cursor (
since/nextSince).IDE mirror — expose a session as a read-only, token-gated DAP endpoint so a human's IDE can inspect the agent's live session without taking control; unexpose to close it.
Java hot-swap — redefine changed
.classfiles into a running JVM and re-resolve statement-anchored breakpoints.
Enables step-through debugging for JavaScript applications with tools for managing breakpoints, stack traces, and variable scopes.
Supports debugging of Node.js applications, providing tools to control execution and inspect program state through the Debug Adapter Protocol.
Provides debugging capabilities for Python code, including setting breakpoints, inspecting variables, and stepping through execution using debugpy.
Supports debugging Rust programs and Cargo projects, enabling variable inspection and source context tracking via CodeLLDB.
Provides debugging support for TypeScript projects, allowing for interactive code execution and inspection within the MCP environment.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Debuggerdebug this Python script and show me the variables at line 15"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-debugger
A headless, agentic debugger over MCP — let your AI agents debug running programs in ten languages.
🎯 Overview
mcp-debugger is a Model Context Protocol (MCP) server that exposes step-through debugging as structured tool calls. It lets AI agents set breakpoints, inspect variables, evaluate expressions, and step through running programs across ten languages — driving real language debuggers through the Debug Adapter Protocol (DAP).
No IDE required. mcp-debugger runs anywhere Node.js runs: CI runners, Docker containers, Kubernetes pods, SSH boxes, and the sandboxes that cloud coding agents live in. It's the debugger for where IDEs can't go.
When to use mcp-debugger vs an IDE-bound debug server
Microsoft's DebugMCP exposes VS Code's debugger over MCP and is a good choice when your agent works inside a running VS Code. The two projects make different structural trade-offs:
mcp-debugger | microsoft/DebugMCP | |
Runs headless (CI, containers, k8s, cloud agents) | ✅ standalone Node process | ❌ requires a running VS Code |
Transports | stdio + Streamable HTTP | Streamable HTTP (localhost) |
Distribution | npx, npm, Docker image | VS Code Marketplace extension |
Remote attach without an IDE | ✅ debugpy / rdbg / JDWP, incl. pods via port-forward | ❌ |
Per-session process isolation | ✅ one proxy process per session | shares the VS Code instance |
Java hot-swap ( | ✅ | ❌ |
Debuggee output as subscribable MCP resource | ✅ | ❌ |
In-IDE debugging UX alongside the agent | ✅ read-only IDE mirror ( | ✅ native |
Logpoints without pausing (prod-safe value watching) | ✅ via VS Code | |
Content/function-addressed breakpoints ( | ✅ agent-native addressing that survives edits | — |
Secret redaction on by default | ✅ variable/evaluate/output masking + least-privilege mode | — |
Kubernetes ephemeral debug sidecar (native attach-by-PID) | ❌ | |
C/C++ | ✅ via CodeLLDB (launch + attach-by-PID) | ✅ via VS Code extensions |
COBOL | ✅ via GnuCOBOL + CodeLLDB (launch + attach-by-PID, COBOL-shaped variables) | — |
Dart/Flutter | ✅ via the SDK's own debug adapters (launch + attach by VM-service URI; Dart now, Flutter runners wired and shipping in the next milestones) | — |
PHP | ❌ | ✅ via VS Code extensions |
Languages | Python, JS/TS, Ruby, Rust, Go, Java, .NET, C/C++, COBOL, Dart/Flutter | Python, JS/TS, Ruby, Rust, Go, Java, .NET, C/C++, PHP |
If your agent runs in a terminal, a pipeline, or a cloud sandbox — or needs to attach to a process on another machine — you want mcp-debugger.
🆕 v0.25.0 — COBOL debugging lands (GnuCOBOL + CodeLLDB, with COBOL-shaped variables, PERFORM-aware stepping and paragraph breakpoints), and Rust and C/C++ work out of the box on every platform npm installs now that CodeLLDB ships as per-platform packages. Also new:
mcp-debugger doctor, a Kubernetes debugging recipe, an HTTP transport locked to127.0.0.1with Host/Origin checks, launch responses that say how a run ended, exit codes for Go and Docker JavaScript, and a lighter startup. See the CHANGELOG for the full release history.
Related MCP server: cdp-tools-mcp
✨ Key Features
🌐 Multi-language support – Clean adapter pattern for any language
🐍 Python debugging via debugpy – Full DAP protocol support
💎 Ruby debugging via rdbg – Launch and attach workflows, including remote attach to containers and Kubernetes pods
🟨 JavaScript (Node.js) debugging via js-debug – VSCode's proven debugger
🦀 Rust debugging via CodeLLDB – Debug Rust & Cargo projects (Linux/macOS; Windows needs the GNU toolchain — see Rust on Windows)
🐹 Go debugging via Delve – Full DAP support for Go programs
☕ Java debugging via JDI bridge – Launch and attach modes with JDK 21+
🔷 .NET/C# debugging via netcoredbg – Debug .NET applications with full DAP support
⚙️ C/C++ debugging via CodeLLDB – Launch prebuilt binaries or lone source files (auto-compiled), attach by PID; core dumps and gdbserver/rr targets via config pass-through
🧮 COBOL debugging via GnuCOBOL + CodeLLDB – Launch
.cob/.cblsources (auto-compiled withcobc) or prebuilt executables, attach by PID; WORKING-STORAGE / LOCAL-STORAGE / LINKAGE scopes with DISPLAY, COMP, COMP-3 and 88-level values decoded, breakpoints in copybooks, statement-granular stepping, and a pause on libcob runtime errors (the S0C7/SSRANGE analogues) — built for mainframe-to-GnuCOBOL migrations (guide)🐦 Dart/Flutter debugging via the SDK's own debug adapters – Launch Dart programs and
package:testfiles (dart debug_adapter) or Flutter apps and tests (flutter debug-adapter), the runner auto-detected frompubspec.yamland the program path; attach to a running VM by service URI or service-info file; conditional breakpoints, logpoints,Unhandled/Allexception filters,noDebug. Nothing is vendored — the Dart or Flutter SDK on the machine is the debugger. Dart now; the Flutter runners are wired, measured on Windows desktop and the Android emulator in the spike, and ship in the next milestones (guide)🧪 Mock adapter for testing – Test without external dependencies
🛰️ Out-of-IDE & remote attach – Attach over host/port to a process on another machine or inside a container (Python via debugpy, Ruby via rdbg, JavaScript via the V8 inspector, Java via JDWP, Dart/Flutter via the VM-service URI) with source-path mapping, or by PID for native code (C/C++, COBOL) and for a local Node.js process, whose inspector mcp-debugger opens for you (JavaScript). Python and Ruby attach direct-connect — the debug engine already runs inside the target, so no local Python or Ruby is needed; JavaScript, Java, .NET, C/C++, COBOL and Dart/Flutter spawn a local adapter instead; of those, only Java (a JDK), .NET (netcoredbg) and Dart/Flutter (the Dart or Flutter SDK, whose own debug adapter does the work) need a toolchain you install, since the JavaScript, C/C++ and COBOL debug engines ship with the package.
list_supported_languagesreports per-mode availability with reasons🎯 Breakpoints that survive edits – Address by content (
statement: "total = sum(prices)"), by symbol (function: "main"), or assert line content withexpectedContent; anchors re-resolve acrossrestart_debuggingand weak matches warn loudly🪵 Logpoints –
set_breakpointwithlogMessage: "x={x}"streams interpolated values intoget_outputwithout pausing — prod-safe value watching on hot paths🧰 Full breakpoint lifecycle –
list_breakpoints/remove_breakpoint/clear_breakpointswork live mid-run;restart_debuggingrelaunches with the same config and re-applies everything in one call📡 Buffered program output –
get_outputreturns debuggee stdout/stderr with a cursor, and each session exposes its transcript as a subscribable MCP resource💥 Crash-state debugging by default – Launch sessions pause on uncaught exceptions with stack and locals live (
breakOnExceptions; exception class/message surfaced vialastStop)🪞 Read-only IDE mirror –
expose_sessionopens a loopback, token-gated DAP endpoint so a human's IDE can inspect the agent's live session without taking control☸️ Kubernetes debugging – port-forward attach for interpreted runtimes,
kubectl debug --target+ attach-by-PID for native processes (recipe, turnkey manifests)🔌 STDIO and Streamable HTTP transports – Works with any MCP client (legacy SSE transport is deprecated)
📦 Zero-runtime dependencies – Self-contained bundles via esbuild + tsup
⚡ npx ready – Run directly with
npx @debugmcp/mcp-debugger- no installation needed🐳 Docker and npm packages – Deploy anywhere
🤖 Built for AI agents – Structured JSON responses for easy parsing
🔒 Secret redaction on by default – Credential-shaped values (API keys, tokens, private keys) are masked as labeled placeholders in variable, evaluate, and output results before they reach the agent (details; opt out with
DEBUG_MCP_NO_REDACT=1)🛡️ Path validation – Prevents crashes from non-existent files
📝 AI-aware line context – Intelligent breakpoint placement with code context
✅ Comprehensive test suite – unit, integration, and end-to-end coverage across every adapter (CI status)
🧠 Agent Skill
Tools tell an agent what it can do; a skill teaches it how to debug well. This repo ships an agent skill covering the session golden path, root-cause discipline (bisection over line-by-line stepping), attach/remote recipes, and per-language quirks:
# Claude Code (user-level)
cp -r skills/debugging ~/.claude/skills/mcp-debugger
# Cross-agent directories (Copilot CLI and friends)
cp -r skills/debugging ~/.agents/skills/mcp-debuggerThe server also serves condensed guidance in-band: MCP instructions on connect, plus a debugging-workflow prompt any MCP client can request. See skills/debugging/README.md for details.
🎬 See It In Action
Auto-debug failing CI tests – a composite GitHub Action that launches mcp-debugger + an agent on a test failure and posts the root-cause analysis
Sick pod walkthrough – attach to a misbehaving Python service in Kubernetes via port-forward (tutorial)
Native sick pod – same story for compiled code: ephemeral debug sidecar + attach-by-PID, no in-process agent required
🚀 Quick Start
Requirements: Node.js 22+ for the server. Each language you debug also needs its own toolchain installed (Python + debugpy, Ruby + the
debuggem /rdbg, Node.js, Go + Delve, JDK 21+, .NET SDK, the Rust toolchain, a C/C++ compiler — g++/clang++, only needed for source-file launch — GnuCOBOL 3.1.2+ for COBOL source launch, or the Dart SDK — Flutter bundles one — for Dart/Flutter). Not sure what's installed? Runnpx @debugmcp/mcp-debugger doctorfor a per-adapter toolchain report.CodeLLDB platform note (npx/npm installs): the CodeLLDB debug engine ships as per-platform optional dependencies (
@debugmcp/codelldb-win32-x64,-darwin-x64,-darwin-arm64,-linux-x64,-linux-arm64) — npm installs exactly the one matching your platform, so Rust and C/C++ debugging work out of the box everywhere npm serves. If you install with--omit=optional, setCODELLDB_PATHto a CodeLLDB release binary instead, or use the Docker image.
For MCP Clients (Claude Desktop, etc.)
Add to your MCP settings configuration:
{
"mcpServers": {
"mcp-debugger": {
"command": "node",
"args": ["C:/path/to/mcp-debugger/dist/index.js", "stdio", "--log-level", "debug", "--log-file", "C:/path/to/logs/debug-mcp-server.log"],
"disabled": false,
"autoApprove": ["create_debug_session", "set_breakpoint", "get_variables"]
}
}
}For Codex CLI, desktop, and IDE
Register the published stdio server with the Codex CLI:
codex mcp add mcp-debugger -- npx -y @debugmcp/mcp-debugger stdio
codex mcp listCodex stores this entry in ~/.codex/config.toml. The ChatGPT desktop app, Codex CLI,
and Codex IDE extension share that configuration when they run on the same Codex host.
Restart the active desktop client or IDE extension (or start a new CLI session), then use
/mcp to confirm that mcp-debugger is connected. See the official
Codex MCP documentation for configuration and
troubleshooting details.
Developing mcp-debugger itself? Use the restartable source dev proxy instead of the published package.
For Claude Code CLI
For Claude Code users, we provide an automated installation script:
Prerequisite: The Claude CLI must be installed and available on your PATH before running the installation script. See Claude Code documentation for installation instructions.
# Clone the repository
git clone https://github.com/debugmcp/mcp-debugger.git
cd mcp-debugger
# Run the installation script
./scripts/install-claude-mcp.sh
# Verify the connection (use 'claude mcp list' if claude is on your PATH)
claude mcp listImportant: The stdio argument is required to prevent console output from corrupting the JSON-RPC protocol. See CLAUDE.md for detailed setup and troubleshooting.
For the pi coding agent
pi 0.99 and later has built-in MCP support. The published @debugmcp/mcp-debugger package is
also a pi package: one install adds the mcp-debugger agent skill and an extension that registers
the server with pi's MCP support:
pi install npm:@debugmcp/mcp-debugger # the mcp-debugger skill, and the server via pi's built-in MCP
pi list # shows the packageThe extension runs the CLI that pi install put on disk, so the server matches the skill and
starts without an npx download. It registers with deferred exposure: pi lists the debugger in
its system prompt, and the model loads the tools it needs with tool_search, named
mcp__mcp_debugger__<tool>. /mcp shows the server and changes its exposure for a session. A
mcp-debugger entry in ~/.pi/agent/mcp.json replaces the registration, for example to debug a
source build through the dev proxy.
To add only the server, without the skill: pi mcp add mcp-debugger -- npx -y @debugmcp/mcp-debugger stdio.
pi older than 0.99 has no built-in MCP support; the extension then does nothing, so upgrade pi.
Using Docker
docker run -i --rm -v $(pwd):/workspace debugmcp/mcp-debugger:latestThe Docker image debugs Python, JavaScript, Java, Rust, C/C++, COBOL, and Dart natively (toolchains — GnuCOBOL and the Dart SDK included — plus a shared vendored CodeLLDB), plus the mock adapter. Flutter is host-only: the image carries no Flutter SDK. Ruby is attach-only in the image (the adapter ships without a Ruby runtime — attach to any
rdbg --openprocess, local or remote). Only Go and .NET are disabled in the container — run those via npm/npx next to your local toolchain. Host-built Rust/C++ binaries debugged in the container get an auto-derived source map back to/workspace.list_supported_languagesreports per-mode availability (modes.launch/modes.attach) with reasons. See Docker support.
Using npm
npm install -g @debugmcp/mcp-debugger
mcp-debugger --helpOr use without installation via npx:
npx @debugmcp/mcp-debugger --helpOver the network (Streamable HTTP)
stdio is the default and is what most clients want. When the server has to run somewhere else
— a CI runner, a container, a Kubernetes pod — start it on a port instead:
mcp-debugger http --port 3001 # or: node dist/index.js http -p 3001and point the client at it:
{
"mcpServers": {
"mcp-debugger": {
"type": "http",
"url": "http://127.0.0.1:3001/mcp"
}
}
}Each HTTP client gets its own isolated server: debug sessions are never visible to another
client. A client that disconnects without DELETE /mcp keeps its debug sessions — and any
paused attach target — alive until the server reaps it: 2 minutes after its SSE stream
dropped (MCP_HTTP_STREAM_LOST_SESSION_MS), or 30 minutes idle if it never opened one
(MCP_HTTP_STALE_SESSION_MS). GET /health lists what each session is holding.
The port defaults to 3001, and the server listens on 127.0.0.1 only. --bind 0.0.0.0 (or
MCP_HTTP_BIND=0.0.0.0) listens on every interface — pair it with --allowed-host for the names other
machines will use; --bind localhost means 127.0.0.1, and only IP addresses are accepted. GET /health
on the same port answers a liveness check and reports the bound address and port under listening. The
legacy sse subcommand still exists but is deprecated — use http.
The server accepts only loopback Host headers by default — localhost, 127.0.0.1, [::1] —
as DNS-rebinding protection for an unauthenticated endpoint that can spawn processes and attach to
PIDs. A client on another machine reaches it through a port-forward or an SSH tunnel
(ssh -L 3001:127.0.0.1:3001 user@server, then http://127.0.0.1:3001/mcp), or you bind an
interface with --bind; any other Host gets a 403 that says so. To accept a service name directly — http://mcp-debugger:3001/mcp on a
container network — start the server with --allowed-host mcp-debugger (repeatable) or
MCP_HTTP_ALLOWED_HOSTS=mcp-debugger (comma-separated). That opt-in means another access control
fronts the server; there is no wildcard. Browser clients are checked against the same list by
their Origin, so a cross-site page cannot drive the debugger. The deprecated sse subcommand
applies the same allowlist and accepts the same flag.
📚 How It Works
mcp-debugger exposes debugging operations as MCP tools that can be called with structured JSON parameters:
// Tool: create_debug_session
// Request:
{
"language": "python", // or "ruby", "javascript", "rust", "go", "java", "dotnet", "cpp", "cobol", "dart", or "mock" for testing
"name": "My Debug Session"
}
// Response:
{
"success": true,
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"message": "Created python debug session: My Debug Session"
}🛠️ Available Tools
All 29 tools below are implemented — see the tool reference for parameters and response shapes.
Tool | Description | Status |
| Create a new debugging session | ✅ Implemented |
| List all active sessions | ✅ Implemented |
| Show available language adapters | ✅ Implemented |
| Set a breakpoint in a file | ✅ Implemented |
| List a session's breakpoints with verified state | ✅ Implemented |
| Remove a breakpoint by id or file+line | ✅ Implemented |
| Remove all breakpoints (optionally per file) | ✅ Implemented |
| Start debugging a script | ✅ Implemented |
| Relaunch with the same config, breakpoints re-applied | ✅ Implemented |
| Attach debugger to a running process | ✅ Implemented |
| Detach debugger from a process | ✅ Implemented |
| Open a read-only DAP mirror endpoint so an IDE can attach and inspect | ✅ Implemented |
| Close the mirror endpoint and disconnect IDE clients | ✅ Implemented |
| Get the current stack trace | ✅ Implemented |
| List all threads in the debug session | ✅ Implemented |
| Get variable scopes for a frame | ✅ Implemented |
| Get variables in a scope | ✅ Implemented |
| Get local variables in current frame | ✅ Implemented |
| Step over the current line | ✅ Implemented |
| Step into a function | ✅ Implemented |
| Step out of a function | ✅ Implemented |
| Continue running | ✅ Implemented |
| Block until the session next pauses or ends | ✅ Implemented |
| Pause running execution | ✅ Implemented |
| Evaluate expressions in debug context | ✅ Implemented |
| Get source code context | ✅ Implemented |
| Read captured debuggee output (stdout/stderr) | ✅ Implemented |
| Close a session | ✅ Implemented |
| Hot-swap changed Java classes into a running JVM (Java only) | ✅ Implemented |
🏗️ Architecture: Dynamic Adapter Loading
Version 0.10.0 introduces a clean adapter pattern that separates language-agnostic core functionality from language-specific implementations:
┌─────────────┐ ┌────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ MCP Client │────▶│ DebugMcpServer │────▶│SessionManager│────▶│ AdapterRegistry │
└─────────────┘ └────────────────┘ └──────────────┘ └─────────────────┘
│ │
▼ ▼
┌──────────────┐ ┌─────────────────┐
│ ProxyManager │◀─────│ Language Adapter│
└──────────────┘ └─────────────────┘
│
┌───────────┬───────────┬───────────┼───────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┐
│ │ │ │ │ │ │ │ │ │ │
┌─────▼────┐┌─────▼────┐┌─────▼────┐┌─────▼────┐┌─────▼────┐┌─────▼────┐┌─────▼────┐┌─────▼────┐┌─────▼────┐┌─────▼────┐┌─────▼────┐
│Python ││Ruby ││JavaScript││Rust ││Go ││Java ││.NET ││C/C++ ││COBOL ││Dart ││Mock │
│Adapter ││Adapter ││Adapter ││Adapter ││Adapter ││Adapter ││Adapter ││Adapter ││Adapter ││Adapter ││Adapter │
└──────────┘└──────────┘└──────────┘└──────────┘└──────────┘└──────────┘└──────────┘└──────────┘└──────────┘└──────────┘└──────────┘Adding Language Support
Want to add debugging support for your favorite language? Check out the Adapter Development Guide!
💡 Example: Debugging Python Code
Here's a complete debugging session example:
# buggy_swap.py
def swap_variables(a, b):
a = b # Bug: loses original value of 'a'
b = a # Bug: 'b' gets the new value of 'a'
return a, bStep 1: Create a Debug Session
// Tool: create_debug_session
// Request:
{
"language": "python",
"name": "Swap Bug Investigation"
}
// Response:
{
"success": true,
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"message": "Created python debug session: Swap Bug Investigation"
}Step 2: Set Breakpoints
// Tool: set_breakpoint
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"file": "C:\\path\\to\\buggy_swap.py",
"line": 2
}
// Response:
{
"success": true,
"breakpointId": "28e06119-619e-43c0-b029-339cec2615df",
"file": "C:\\path\\to\\buggy_swap.py",
"line": 2,
"verified": false,
"message": "Breakpoint set at C:\\path\\to\\buggy_swap.py:2"
}Step 3: Start Debugging
// Tool: start_debugging
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"scriptPath": "C:\\path\\to\\buggy_swap.py"
}
// Response:
{
"success": true,
"state": "paused",
"message": "Debugging started for C:\\path\\to\\buggy_swap.py. Current state: paused",
"data": {
"message": "Debugging started for C:\\path\\to\\buggy_swap.py. Current state: paused",
"reason": "breakpoint"
}
}Step 4: Inspect Variables
First, get the scopes:
// Tool: get_scopes
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"frameId": 3
}
// Response:
{
"success": true,
"scopes": [
{
"name": "Locals",
"variablesReference": 5,
"expensive": false,
"presentationHint": "locals",
"source": {}
},
{
"name": "Globals",
"variablesReference": 6,
"expensive": false,
"source": {}
}
]
}Then get the local variables:
// Tool: get_variables
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"scope": 5
}
// Response:
{
"success": true,
"variables": [
{"name": "a", "value": "10", "type": "int", "variablesReference": 0, "expandable": false},
{"name": "b", "value": "20", "type": "int", "variablesReference": 0, "expandable": false}
],
"count": 2,
"variablesReference": 5
}📖 Documentation
🗺️ Roadmap – Path to 1.0: stability criteria, near-term themes, non-goals
📘 Tool Reference – Complete API documentation
🚦 Getting Started Guide – First-time setup
🏗️ Architecture Overview – Multi-language design
🔧 Adapter Development – Add new languages
🔌 Dynamic Loading Architecture – Runtime discovery, lazy loading, caching
🧩 Adapter API Reference – Adapter, factory, loader, and registry contracts
🔄 CHANGELOG – Release history and upgrade notes
🐍 Python Debugging Guide – Python-specific features
💎 Ruby Debugging Guide – Ruby debugging with
rdbg, including remote attach🔬 Case Study: the initialize response that never came – mcp-debugger debugging itself to root-cause a Ruby launch stall
🔬 Case Study: attaching the debugger to itself – live-patching a running mcp-debugger through its own
evaluate_expressionto catch a race strace couldn't see🔬 Case Study: the pause that always succeeded – reading js-debug's own CDP trace to catch its smart-stepper eating user pauses on idle servers
🔬 Case Study: the trace that couldn't name its socket – measure-fix-measure on the diagnostics themselves: one scripted attach run, before and after, as the acceptance test
🟨 JavaScript Debugging Guide – JavaScript/TypeScript features
🐹 Go Debugging Guide – Go debugging with Delve
☕ Java Debugging Guide – Java debugging with JDI bridge
🔷 .NET Debugging Guide – .NET/C# debugging with netcoredbg
⚙️ C/C++ Debugging Guide – CodeLLDB launch, auto-compile, attach-by-PID, core dumps, remote stubs
🧮 COBOL Debugging Guide – GnuCOBOL + CodeLLDB: auto-compile, COBOL-shaped variables, runtime-error stops, the mainframe migration recipe
🐦 Dart/Flutter Debugging Guide – the SDK's own debug adapters: runner selection,
dart test/flutter test, attach by VM-service URI, Flutter devices🦀 Rust Debugging Guide – CodeLLDB setup (Windows specifics)
🐳 Docker Support – Container languages, attach modes, host-binary source mapping
☸️ Kubernetes Debugging – Turnkey attach recipes: registry-free manifests, per-language presets, ephemeral debug sidecar
🚑 JIT Diagnostics Tutorial – Debug live services in Kubernetes, incl. the ephemeral-sidecar flow for compiled code
🤖 Agent Debugging Guide – Correct tool usage patterns for AI agents
⚠️ Known Issues – Current caveats and workarounds
🩺 Diagnostics –
mcp-debugger doctor, per-language prerequisites, failure signatures, env-var reference🔧 Troubleshooting – Common issues & solutions
🤝 Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
# Development setup
git clone https://github.com/debugmcp/mcp-debugger.git
cd mcp-debugger
# Install dependencies and vendor debug adapters
pnpm install
# Vendored debug engines (Microsoft's js-debug; CodeLLDB, shared by Rust, C/C++ and COBOL)
# are downloaded automatically and verified against committed SHA-256 digest pins
# Build the project
pnpm build
# Run tests
pnpm test
# Check adapter vendoring status
pnpm vendor:status
# Force re-vendor all adapters (if needed)
pnpm vendor:forceDebug Adapter Vendoring
The project automatically vendors debug adapters during pnpm install:
JavaScript: Downloads Microsoft's js-debug from GitHub releases
Rust, C/C++ & COBOL: Download a single shared copy of CodeLLDB for the current platform (
packages/codelldb-common)Integrity: Every download is verified against the pinned SHA-256 digests in the packages'
vendor-manifest.json; mismatches fail the buildCI Environment: Set
SKIP_ADAPTER_VENDOR=trueto skip vendoring
To manually manage adapters:
# Check current vendoring status
pnpm vendor:status
# Re-vendor all adapters
pnpm vendor
# Clean and re-vendor (force)
pnpm vendor:force
# Clean vendor directories only
pnpm clean:vendorRunning Container Tests Locally
We use Act to run GitHub Actions workflows locally:
# Build the Docker image first
docker build -t mcp-debugger:local .
# Run tests with Act (use WSL2 on Windows)
act -j build-and-test --matrix os:ubuntu-latestSee tests/README.md for detailed testing instructions.
📊 Project Status
✅ Production Ready: ten language adapters, 29 tools, and polished multi-language distribution
✅ Clean architecture with a dynamic adapter pattern
✅ Python · Ruby · JavaScript/TypeScript · Go · Java · .NET/C#: Full step-through debugging
🦀 Rust: Full support on Linux/macOS/Windows (Windows requires the GNU toolchain; MSVC is not supported by CodeLLDB)
⚙️ C/C++: Full step-through debugging via CodeLLDB (launch + attach-by-PID; on Windows prefer MinGW/DWARF — MSVC PDB fidelity is partial)
🧮 COBOL: Step-through debugging via GnuCOBOL + CodeLLDB (launch + attach-by-PID; verified with GnuCOBOL 3.1.2/3.2 on Linux and Windows/MSYS2; PERFORM-aware stepping, paragraph breakpoints and
{WS-NAME}logpoints)🐦 Dart/Flutter: Step-through debugging through the SDK's own debug adapters (
dart debug_adapter,flutter debug-adapter; launch + attach by VM-service URI). Dart now; the Flutter runners are wired, measured on Windows desktop and the Android emulator in the spike, and ship in the next milestones🟢 Runtime: Node.js 22+
📈 Active Development: Regular updates and improvements — see the Roadmap for the path to 1.0
🏛️ Who Maintains This
mcp-debugger is stewarded by Sycamore LLC and led by John Franklin (@debugmcpdev). The project uses an agent-first development model with human accountability: AI agents write most of the code; a human maintainer makes every merge, release, and security decision. See MAINTAINERS.md, GOVERNANCE.md, and SUPPORT.md (including commercial support).
Supply-chain posture: pinned CI actions, OIDC trusted publishing, sigstore provenance on every npm package, SBOMs attached to releases, and an OpenSSF Scorecard score we actively maintain — details in SUPPLY-CHAIN-SECURITY.md. Report vulnerabilities via SECURITY.md.
📄 License
MIT License - see LICENSE for details.
👥 Contributors
@Poyraxx — Ruby adapter (rdbg)
@swinyx — Go adapter (Delve)
@roofpig95008 — Java adapter (JDI bridge)
🙏 Acknowledgments
Built with:
Model Context Protocol by Anthropic
Debug Adapter Protocol by Microsoft
debugpy for Python debugging
debug for Ruby debugging
Give your AI agents a real debugger — in any language.
Available Tools
28 toolsattach_to_processB
Attach to a running process for debugging. After the handshake the target is verified by polling for threads; if none are reported within verifyTimeout (~20s default) the attach fails and the proxy is torn down. When a requested post-attach pause is accepted but no stopped event arrives within its bounded wait, returns state "running" with pending:true; the late event alone changes the session to "paused"
| Name | Required | Description | Default |
|---|---|---|---|
| host | No | Host to attach to (default: localhost) | |
| port | No | Debug port to attach to | |
| timeout | No | Connection timeout in milliseconds (default: 30000) | |
| processId | No | Process ID (for local attach, language-specific) | |
| sessionId | Yes | Debug session ID | |
| justMyCode | No | Only debug user code (skip library code) | |
| sourcePaths | No | Source paths for code mapping | |
| stopOnEntry | No | Pause the target after attaching. Default true when omitted (thread verification, then a pause request; if the stop lands after the response you get pending:true and the target still freezes on its next dispatch). Pass false to attach without stopping — required when attaching to a live service | |
| adapterConfig | No | Adapter-specific attach configuration merged into the attach config before the adapter transforms it (e.g. C/C++/LLDB: program — the binary path for symbol resolution when /proc/<pid>/maps paths are not openable, as in a kubectl-debug ephemeral container — or initCommands like "settings set target.exec-search-paths /proc/<pid>/root"). Reserved keys request/__attachMode are ignored; set stopOnEntry via the top-level parameter. Keys the adapter does not recognize are still forwarded to the debugger and named in the response warning — a near-miss of a supported key gets a did-you-mean suggestion. js-debug pins its attach orchestration keys (address/port/continueOnAttach/attachExistingChildren) over caller values; its autoAttachChildProcesses defaults to false on attach — child processes the target forks run undebugged (set it true to auto-attach children; only one child can be adopted at a time, further children are resumed undebugged) | |
| verifyTimeout | No | How long to wait (ms) for the debugger to report at least one thread after attaching before failing the attach (default: 20000, max: 600000). Decrease for fast failure-by-design probes; increase for targets that are exceptionally slow to become debuggable | |
| breakOnExceptions | No | Break when exceptions are thrown: "uncaught" pauses at uncaught exceptions at the crash site; "all" also pauses on caught/raised exceptions (language-dependent). Default "none" — attach sessions never apply a language default (unlike launch) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose real behavior: a thread-polling handshake, attach failure plus proxy teardown on verifyTimeout, and the async pending:true pause semantics. However, it omits other behavioral essentials for a mutation-style session tool, such as required permissions or what the response object contains. Solid partial disclosure, not complete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is correctly front-loaded in a short first sentence. The second sentence, however, is a dense run-on with nested clauses ('accepted but no stopped event arrives within its bounded wait... pending:true; the late event alone changes the session...') that is hard to parse for what is essentially a two-state edge case. Informative but structurally heavy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with a nested adapterConfig object, the description plus the very rich schema entries cover most of what an agent needs, and no output schema exists so return-state description (running/paused, pending) is a genuine plus. The gap is that overall response shape and side-effect scope are not summarized, leaving it just short of fully self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 11 parameters in depth. The description's mentions of verifyTimeout (~20s default) and post-attach pause duplicate what the schema says rather than adding syntax or meaning beyond it. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Attach to a running process for debugging.' That clearly separates it from siblings like launch-oriented tools and from detach_from_process. It stops short of naming which sibling to use instead (e.g. create_debug_session or start_debugging), so it is clear but not differentiating.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance in the description itself: no prerequisites, no statement of when attaching is preferable to launching, and no named alternative. The useful conditional advice ('required when attaching to a live service') lives in the stopOnEntry schema entry, not the description. An agent gets context only by reading the schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_breakpointsA
Remove all breakpoints in a session, or all breakpoints in one file. Clearing zero breakpoints is success. Takes effect immediately while the program is running or paused
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Optional: only clear breakpoints in this file | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose two genuinely useful behavioral traits: idempotency ('Clearing zero breakpoints is success') and immediate effect regardless of run state ('Takes effect immediately while the program is running or paused'). It omits error conditions, required session state, and return shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the core action and scope, followed by the two behavioral notes. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations and no output schema, the description covers purpose, scope, idempotency, and timing adequately. It stops short of stating error cases or whether the session must be active, which would complete the picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50%: the 'file' parameter is already documented in the schema, while the required 'sessionId' has no schema description. The description only vaguely covers session scope ('in a session') and adds little beyond the schema, so it only partially compensates for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (remove all breakpoints) plus the scope options (entire session vs one file). The word 'all' implicitly distinguishes it from the singular remove_breakpoint sibling, but it never names that sibling explicitly, so an agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The scope phrasing ('all breakpoints in a session, or all breakpoints in one file') implies when this bulk-clear is appropriate versus the singular remove_breakpoint, but there is no explicit when-to-use/when-not guidance or named alternative. Usage is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
close_debug_sessionC
Close a debugging session
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description bears full responsibility for behavioral disclosure. It states the action but fails to mention side effects, error conditions, or any impact on the session state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise (one sentence, four words) and front-loaded. However, it may be too terse for completeness, but conciseness itself is a strength.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple interface (1 required param, no output schema), the description lacks enough context to be fully self-contained. With many sibling tools, additional usage context would be helpful.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'sessionId' has 0% schema description coverage, and the tool description adds no explanation about its meaning, source, or format. The schema only specifies type and requiredness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (close) and the resource (a debugging session), directly distinguishing it from sibling tools like create_debug_session or list_debug_sessions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool, prerequisites (e.g., session must exist), or alternatives. The agent is given no context for appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
continue_executionA
Continue execution. Returns immediately after the adapter acknowledges; does not wait for the next stop. When the program stops again the session state becomes "paused" — check list_debug_sessions or get_stack_trace, whose lastStop/stopReason tells you why it stopped (e.g. "breakpoint" vs "exception"). Use get_output to read the program's stdout/stderr
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does real work: it discloses the asynchronous, non-blocking return ('returns immediately after the adapter acknowledges; does not wait'), and the state transition to 'paused' on the next stop. It omits error/failure behavior and any permission requirements, so it is not fully complete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core verb and the crucial non-blocking caveat, then follow-up guidance. The get_output sentence is slightly tangential but still useful, and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no annotations and no output schema, the description covers behavior (async return, pause state) and next-step tooling well. The main gap is the undocumented sessionId, which for a stateful debug control tool is a meaningful omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single sessionId parameter has 0% schema description coverage and the description never mentions it or its format/origin. Nothing compensates for the schema's silence, leaving the most important input semantically undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (continue execution) on an implicit debug session resource, which maps cleanly onto a debugger resume. The contrast with sibling step_over/step_into/pause_execution is implied by the non-blocking resume semantics rather than named explicitly, so an agent can mostly but not fully distinguish it from the schema alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear usage flow: returns immediately, does not wait for the next stop, and directs the agent to list_debug_sessions/get_stack_trace on the following pause and to get_output for stdout/stderr. It lacks an explicit when-not statement (e.g. versus step_over for single-instruction stepping), keeping it below a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_debug_sessionA
Create a new debugging session. Provide host and port to attach to a running process; omit them for launch mode. Attaching pauses the target unless stopOnEntry is false
| Name | Required | Description | Default |
|---|---|---|---|
| host | No | Host to attach to for remote debugging (optional, triggers attach mode) | |
| name | No | Optional session name | |
| port | No | Debug port to attach to for remote debugging (optional, triggers attach mode) | |
| timeout | No | Connection timeout in milliseconds for attach mode (default: 30000) | |
| language | Yes | Programming language for debugging | |
| stopOnEntry | No | Attach mode only: same as attach_to_process.stopOnEntry — omitted means true, the target is paused after attach (possibly late, reported as pending:true). Pass false to attach to a live service without stopping it | |
| adapterConfig | No | Attach mode only: adapter-specific attach configuration merged into the attach config (see attach_to_process) | |
| verifyTimeout | No | Attach mode only: how long to wait (ms) for the debugger to report at least one thread after attaching before failing the attach (default: 20000, max: 600000) | |
| executablePath | No | Path to language executable (optional, will auto-detect if not provided) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that attaching pauses the target unless stopOnEntry is false, but says nothing about what the session creation returns (session id?), permission requirements, or failure behavior on connect timeout — meaningful gaps for a stateful tool with 9 parameters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, zero filler, with the highest-value information (the two modes) front-loaded and the pause behavior trailing. Nothing to trim.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description never indicates what a created session yields or how to reference it in later calls (e.g., list_debug_sessions, close_debug_session). Given 9 parameters, nested adapterConfig, and no annotations, the behavioral surface is only partially covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds cross-parameter semantics (host+port jointly trigger attach mode), but the schema already labels each of those fields as 'triggers attach mode', so the incremental value is modest.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Create a new debugging session') and immediately distinguishes two operating modes (attach vs launch). It does not, however, differentiate itself from close siblings like start_debugging and attach_to_process, which appear to overlap with its functionality.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear intra-tool rule: supply host/port to attach, omit them to launch. What it never says is when to pick this tool over start_debugging or attach_to_process, which is exactly the ambiguity an agent faces with 27 sibling tools on offer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detach_from_processA
Detach from the debugged process without terminating it
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes | Debug session ID | |
| terminateProcess | No | Whether to terminate the process on detach (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. States the key behavioral trait (no termination) but does not disclose other effects (e.g., session validity, resource cleanup). Adequate but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no redundant words, front-loaded with action and key constraint. Highly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Simple tool with 2 params and no output schema. Description covers core action but lacks pre/post-conditions (e.g., must be attached) and return value. Acceptable for a straightforward operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%; both parameters documented. Description adds minimal new meaning beyond confirming the 'without terminating it' behavior aligns with default of terminateProcess. Baseline score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses a specific verb ('Detach') and resource ('debugged process') with a clarifying condition ('without terminating it'). Clearly distinguishes from sibling tools like terminate or close.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use versus alternatives like close_debug_session or terminate. The condition 'without terminating it' is present but not framed as a decision rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
evaluate_expressionA
Evaluate expression in the current debug context. Without frameId, uses the same adopted top frame as stack and locals — at a breakpoint or step that is the frame the program stopped in even when the stack display would hide it — and discloses an automatic thread switch or a hidden paused frame in anchorNote; frame names the frame that was used, on success and on failure. Expressions can read and modify program state. Waits up to 30s by default
| Name | Required | Description | Default |
|---|---|---|---|
| frameId | No | Optional authoritative stack frame ID from get_stack_trace. When provided, no automatic frame/thread selection occurs | |
| timeout | No | Max time (ms) to wait for the evaluation to complete (default: 30000, max: 600000). On expiry the request fails but the expression may keep executing in the debuggee. Note: your MCP client may enforce its own overall request timeout | |
| sessionId | Yes | ||
| expression | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and largely meets it: it warns that expressions can read and modify program state, discloses automatic thread switches or hidden paused frames via anchorNote, and states frame naming on both success and failure. It does not cover error semantics beyond the frame name or any permission/authorization context, so a 5 is not warranted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in one sentence, and each following clause adds distinct information (frame adoption, anchorNote disclosure, frame naming, wait default). The embedded em-dash aside about breakpoints and hidden frames is convoluted enough to slow parsing, costing it the top score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter, no-output-schema, no-annotation tool, the description compensates well by describing anchorNote, frame naming, and side-effect capability that an output schema would otherwise convey. Missing detail on failure modes other than frame naming and on timeout-expiry behavior (which is only in the schema) keeps it from 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: frameId and timeout are already documented in the schema. The description usefully restates the no-frameId fallback behavior and the default wait, but adds nothing for sessionId or expression. Against the coverage baseline this lands at 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Evaluate expression in the current debug context') and immediately distinguishes itself from sibling read tools by explaining that absent a frameId it adopts the same top frame as stack and locals. An agent can tell it apart from get_variables/get_stack_trace without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the key routing decision: pass an authoritative frameId from get_stack_trace to suppress automatic frame/thread selection, otherwise the adopted top frame is used. It implies but never explicitly says 'use this instead of locals when you need to compute or mutate an expression,' so it stops short of a full when/when-not statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
expose_sessionA
Expose a debug session as a read-only DAP mirror endpoint on 127.0.0.1 so an IDE (e.g. VS Code) can attach as a second debug client and inspect live state: threads, stack, scopes, variables, evaluate. Returns host, port, and a session token the IDE must include as "mirrorToken" in its attach configuration. The mirror never drives execution — continue/step/pause and breakpoint changes are rejected; control stays with this MCP session. Requires an active session (launched or attached); works while running or paused. Calling it again returns the same endpoint. The endpoint closes on unexpose_session, close_debug_session, restart, or debuggee exit
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: read-only enforcement, idempotency ('calling it again returns the same endpoint'), token requirement, and the full closure lifecycle (unexpose_session, close_debug_session, restart, debuggee exit). This is unusually complete behavioral disclosure for a mutation-adjacent tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is longer than most descriptions but every sentence carries distinct information (capability, token, rejection semantics, lifecycle). The core purpose is front-loaded, though the density is high for a single-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even without an output schema, the description explains the return values (host, port, session token) and the attach configuration requirement, and it covers lifecycle and control restrictions. An agent has everything needed to invoke and reason about the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one required sessionId parameter at 0% schema coverage, so the description must compensate. It implies an active session is needed and describes the returned token/host/port, but never states which session identifier to pass or how to obtain it, leaving the single parameter under-specified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Expose) and resource (a debug session) and defines the concrete output form: a read-only DAP mirror endpoint on 127.0.0.1. It clearly distinguishes itself from siblings like unexpose_session and close_debug_session by naming the lifecycle boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the exact use case (let an IDE attach as a second debug client), prerequisites (requires an active launched/attached session), and the when-not case (the mirror never drives execution; continue/step/pause and breakpoint changes are rejected). It also names the counterpart tool unexpose_session.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_local_variablesA
Get local variables for the shared inspection anchor. If the stopped thread is frameless, a sibling with policy-recognized user frames is preferred, adopted, and disclosed in note. At a breakpoint or step inside a frame the stack display hides as internal (a node_modules dependency), the anchor is that frame — the one the program stopped in — and note says so. A JavaScript frame with no Local/block scope returns empty with guidance instead of mislabeling Global bindings. Responses are size-guarded; pass names:[...] to fetch specific variables in full
| Name | Required | Description | Default |
|---|---|---|---|
| names | No | Only return variables with these exact names (case-sensitive). Requested names missing from the scope are listed in the response's notFound. | |
| sessionId | Yes | ||
| includeSpecial | No | Include special/internal variables like this, __proto__, __builtins__, etc. Default: false |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does substantively: it discloses frameless-thread handling, sibling preference/adoption with disclosure in a note, anchor semantics at breakpoints, and the empty-with-guidance fallback for JS frames. It omits error cases, permissions, and pagination specifics, but the edge-case disclosure is above average.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the purpose in the first sentence, which is good, but the following sentences are long and built on undefined jargon ('shared inspection anchor', 'note'), which reduces readability. Every sentence is doing work, but the density hurts comprehension.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations and no output schema, the description should explain the response shape and key concepts, yet 'anchor' and 'note' are never defined and the return structure is only partially implied. It covers edge cases adequately but leaves the agent guessing on core semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, with names and includeSpecial already documented in the schema. The description adds one genuine insight beyond the schema — that names:[...] is the workaround for size-guarded responses — but does not clarify sessionId or the broader fetch semantics. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (get local variables) and adds a distinguishing scope concept ('shared inspection anchor') that separates it from the sibling get_variables/get_scopes. However, it never names or contrasts those siblings explicitly, so differentiation is implied rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives behavioral context for specific situations (frameless thread, pause inside an internal frame, JS frame with no Local scope), which is useful guidance. But it never says when to call this tool versus get_variables or get_scopes, so routing to alternatives is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_outputA
Get debuggee output (stdout/stderr/console) captured for a session. Buffered per launch (last 1000 entries; adapter telemetry and known adapter-internal diagnostics — e.g. LLDB DWARF-parser noise — filtered out). Works while the program is running and after it finishes, until the session is closed. Pass since=nextSince from the previous response to fetch only new output
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum entries to return (default: 100, max: 1000). hasMore:true in the response means more entries are available | |
| since | No | Only return entries with seq greater than this cursor (use nextSince from the previous response). Default: 0 = from the start of the buffer | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses per-launch buffering, the 1000-entry cap, telemetry/DWARF-noise filtering, and lifecycle limits. It omits permission or concurrency considerations, but the behavioral picture is otherwise rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each earning its place: purpose first, then buffering behavior, then lifecycle window, then the pagination how-to. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by naming the cursor field (nextSince) used for continuation and implying the entry-list return. Combined with the limit/hasMore schema text, an agent has enough to call and page correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, and the description meaningfully compensates by explaining the cursor contract ('pass since=nextSince from the previous response to fetch only new output'), which ties into the pagination semantics. limit and sessionId remain schema-documented only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Get) and resource (debuggee output: stdout/stderr/console) scoped to a session. Clearly distinguished from siblings like get_variables or get_stack_trace, which retrieve different data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the temporal window ('works while running and after it finishes, until the session is closed') and how to page with since=nextSince, but gives no explicit when-not guidance or named alternative. Usage is implied by the output-retrieval framing rather than stated as a choice among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scopesC
Get scopes for a stack frame
| Name | Required | Description | Default |
|---|---|---|---|
| frameId | Yes | The ID of the stack frame from a stackTrace response | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description should disclose behavior, but it only states 'Get scopes'. It does not mention side effects, authentication needs, rate limits, or what the return value represents. The tool's read-only nature is implied but not confirmed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short (one sentence) and concise, but it is too brief to be informative. It is not verbose, but the minimalism comes at the cost of completeness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a debugging tool with no output schema and no annotations, the description is insufficient. It does not explain prerequisites (e.g., having a stack trace), return values, or how it differs from similar tools. The complexity of the debugging context demands more detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50% with only frameId having a description. The tool description adds no extra meaning to the parameters, and sessionId remains undocumented. The description does not compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (Get) and resource (scopes) with a specific context (for a stack frame), distinguishing it from sibling tools like get_stack_trace or get_variables. However, it does not explicitly differentiate itself from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like get_local_variables or get_variables. The description lacks any context about prerequisites or typical usage scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_source_contextB
Get source context around a specific line in a file
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Path to the source file. Use absolute paths or paths relative to your current working directory | |
| line | Yes | Line number to get context for | |
| sessionId | Yes | ||
| linesContext | No | Number of lines before and after to include (default: 5) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description must bear the full burden of behavioral disclosure. It does not state whether the tool is read-only, what happens on invalid file/line, or what errors occur. The behavior is minimally implied but not explicitly described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that is front-loaded and clear. It is concise but at the expense of missing important details like output format and usage context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description does not mention what the tool returns (e.g., source lines, snippet). It also does not explain how it fits with sibling debug tools or any session requirements beyond the required sessionId parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 75%, so baseline is 3. The tool description adds no additional meaning beyond the schema; it does not elaborate on sessionId or clarify parameter interactions. However, the schema already provides good descriptions for file, line, and linesContext.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Get source context around a specific line in a file' clearly states the action (get) and the resource (source context) with specificity. It distinguishes from sibling debug tools, which focus on session management, breakpoints, stepping, etc., by focusing on source code retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like get_local_variables or evaluate_expression. There is no mention of prerequisites (e.g., active debug session) or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_stack_traceA
Get stack trace. The response includes stopReason — why the session is paused. For an implicit frameless stopped thread, a sibling with policy-recognized user frames is preferred and adopted, with the switch disclosed in note. Internal/runtime frames are filtered by default; when any are hidden the response carries hiddenFrames and a note. When the frame the program is paused in is itself internal, pausedFrame names it (kept: whether it was retained as stackFrames[0]) and the note says so
| Name | Required | Description | Default |
|---|---|---|---|
| threadId | No | Inspect this exact thread (ids from list_threads). Explicit selection is authoritative and is never silently switched | |
| sessionId | Yes | ||
| includeInternals | No | Include internal/framework frames (e.g., Node.js internals, node_modules dependencies, async separators). Default: false for cleaner output. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it discloses substantial behavior beyond the input schema: automatic adoption of a sibling thread when frameless, default filtering of internal frames, and the hiddenFrames/pausedFrame/note signaling. Missing is any mention of permissions or error behavior, but the response-contract disclosure is strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose statement, and each sentence conveys contract detail. However, the sentences are long, comma-chained, and jargon-heavy, making the disclosure harder to parse than it needs to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must explain return values, and it does so thoroughly (stopReason, hiddenFrames, pausedFrame, kept, note). The gap is that it does not ground the tool in the debugging workflow, but for a read tool it is substantially complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, so the schema largely documents threadId and includeInternals. The description reinforces threadId's authoritative, never-silently-switched semantics but adds little on sessionId or the exact meaning of includeInternals' frame categories. Baseline 3 fits.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a clear verb+resource ("Get stack trace") and immediately scopes what the response contains (stopReason, frameless-thread handling, filtered frames). It never explicitly distinguishes itself from siblings like get_source_context or get_variables, so it loses the top mark, but the purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the reader infers this is the tool for inspecting a paused session's call stack. It describes thread-selection behavior (explicit threadId is authoritative, implicit threads may be swapped) but gives no explicit when-to-use versus alternatives and no prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_variablesA
Get variables (scope is variablesReference: number). Responses are size-guarded: oversized values are cut (truncated:true) and very large scopes return a capped list with a truncation notice — pass names:[...] to fetch specific variables in full
| Name | Required | Description | Default |
|---|---|---|---|
| names | No | Only return variables with these exact names (case-sensitive). Requested names missing from the scope are listed in the response's notFound. | |
| scope | Yes | The variablesReference number from a StackFrame or Variable | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and discloses important traits: responses are size-guarded, oversized values are cut with truncated:true, and very large scopes return a capped list with a truncation notice. It stops short of documenting permissions, error cases, or the notFound behavior that only appears in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences with no filler; the core purpose and scope come first, followed by the truncation behavior and the names escape hatch. The em-dash-heavy phrasing is compact but still readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read tool with no annotations and no output schema, the description covers the key operational risk (truncation) and the mitigation (names), which is exactly what an agent needs to avoid misreading results. The undocumented sessionId and lack of explicit sibling routing are minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, and the schema itself documents names (including notFound) and scope thoroughly; the description largely restates scope and the names workaround. sessionId remains undocumented in both, so the description does not fully compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ("Get variables") and pins the scope to a variablesReference number, so an agent knows exactly what is retrieved. It does not, however, distinguish itself from close siblings like get_local_variables or get_scopes, which also return variable data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a concrete usage hint — pass names:[...] to fetch specific variables in full when the scope is capped — which tells the agent how to work around truncation. It gives no explicit when-to-use/when-not guidance versus the sibling variable tools (get_local_variables, get_scopes, evaluate_expression), leaving tool selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_breakpointsA
List all breakpoints in a session with their verified state and adapter-assigned ids. Session-global function breakpoints appear separately as functionBreakpoints (omitted when filtering by file). Works before launch (queued, verified=false), while running or paused, and after the program exits
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Optional: only list breakpoints in this file | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses that unverified/queued breakpoints report verified=false, that function breakpoints surface separately as functionBreakpoints, and that they are omitted when filtering by file. It stops short of error or auth behavior, but the return-shape disclosure is valuable given no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, no filler, and the core purpose plus return contents are front-loaded before the state/edge-case details. Every clause carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read tool with no output schema and no annotations, the description covers what is returned, how function breakpoints are grouped, and the session states in which it works. Error handling is not covered, but the operational picture is otherwise complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The 'file' parameter is documented in the schema, and the description adds useful behavior around it (functionBreakpoints omitted under file filtering). 'sessionId' is undocumented in both places, matching the 50% coverage; the description implies session scoping but adds no format detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (list) and resource (breakpoints) scoped to a session, and adds what is returned (verified state, adapter-assigned ids). It is clearly distinguishable from siblings like set_breakpoint, remove_breakpoint, and clear_breakpoints.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the temporal context in which it is valid (before launch, while running/paused, after exit) and notes the file-filtering mode. It does not explicitly name alternatives, but the read-vs-mutate distinction against the breakpoint siblings is clear from the name and description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_debug_sessionsA
List all active debugging sessions. Paused sessions include lastStop with the reason for the most recent stop (e.g. "breakpoint" vs "exception")
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries the behavioral burden. It discloses an important trait: paused sessions include lastStop with a reason (breakpoint vs exception), which is useful non-obvious context. However, it doesn't state whether this is a read-only operation, pagination behavior, or how it interacts with session lifecycle.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the purpose, then a detail about paused session shape. No waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-param, no-output-schema list tool, the description covers what it returns (including lastStop for paused sessions) adequately. Lacks only pagination/activation caveats, but those are minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so baseline is 4. No parameter info is needed or provided, and the description correctly stays silent on parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (list) and resource (active debugging sessions, with detail on paused sessions). Clear enough to distinguish from sibling create_debug_session or close_debug_session, but doesn't explicitly contrast with other list_* tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use guidance or alternatives. Usage is implied by 'List all active debugging sessions' — an agent would infer this is for enumerating sessions, but there's no mention of when to prefer this over create_debug_session or other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_supported_languagesA
List all supported debugging languages with metadata
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It only states the tool lists languages but discloses nothing about side effects (e.g., it is read-only, non-destructive), data freshness, or performance. For a simple list, this is a notable gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, which is maximally concise. It is front-loaded with the verb 'List' to immediately convey the action. Every word earns its place, with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters, no output schema), the description is minimally adequate. However, it lacks details on the return format or what 'metadata' includes, which would help an agent understand the output. It is complete enough for basic usage but not rich.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and schema coverage is 100% (empty). Per guidelines, baseline for 0 params is 4. The description does not need to add parameter information since there are none, so this score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'List all supported debugging languages with metadata' clearly states the action (list), the resource (supported debugging languages), and that metadata is included. It distinguishes from sibling tools, which are all action-oriented debugging operations, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. With 20 sibling tools like 'start_debugging' or 'create_debug_session', it would be helpful to mention that this tool is useful before initiating debugging sessions to discover available languages, but no such context is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_threadsB
List all threads in the debugged process
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description indicates a read-only listing operation. With no annotations, it provides minimal behavioral insight but does not contradict any known traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no unnecessary words. It efficiently conveys the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the description is adequate for a simple list operation, it lacks information about the output format (no output schema) and does not elaborate on what a 'thread' means in this context, which could be helpful given the absence of annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'sessionId' is not described beyond the schema. Schema description coverage is 0%, and the description adds no meaning about its purpose or format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'list' and the resource 'all threads in the debugged process'. It is specific and distinguishable from sibling tools like set_breakpoint or step_into.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like get_stack_trace or get_variables. There is no mention of context or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pause_executionA
Pause a running program. Waits briefly for the stop; if the program cannot stop within ~5s (e.g. blocked in native code, or an idle server waiting for input), returns success with pending:true and the session reports "paused" the next time the program runs code. Fails with an actionable error if the session has no debuggable target to pause (e.g. a js attach whose target session was never adopted or has ended)
| Name | Required | Description | Default |
|---|---|---|---|
| threadId | No | Thread ID to pause. If omitted or 0, pauses all threads. | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so richly: it discloses the ~5s grace period, the pending:true success fallback for programs blocked in native code or idle servers, the deferred 'paused' state, and an actionable failure mode when no debuggable target exists. This is exactly the behavioral context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly packed sentences: the action first, then the async/pending semantics, then the failure mode. Every clause earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a pause tool with no annotations and no output schema, the description covers runtime behavior and failure modes thoroughly, including the pending:true return. The one notable gap is that sessionId is undocumented and the description doesn't explain how to identify a valid debuggable session.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: threadId is well documented in the schema ('omitted or 0 pauses all threads'), but sessionId has no description anywhere. The description adds no parameter-level meaning to compensate for that gap, so it fails to help the agent understand the required sessionId.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Pause a running program.' This cleanly separates it from continue_execution and the step_* siblings by name implication. It doesn't explicitly name which sibling to prefer, but the purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (pause a running program), and it describes the error condition when there is no debuggable target. However, it never states when to choose pause over step_over or continue_execution, nor any explicit exclusions. Usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
redefine_classesA
Hot-swap changed Java classes into a running JVM. Scans a classes directory for .class files modified after sinceTimestamp, matches them against loaded classes in the target JVM, and redefines them using JDI. Returns which classes were redefined and the newest file timestamp (pass as sinceTimestamp on next call for incremental updates). Statement-anchored breakpoints are re-resolved against the new source after the swap (anchorResolution reports moved/stale). Only works with Java debug sessions.
| Name | Required | Description | Default |
|---|---|---|---|
| timeout | No | Max time (ms) to wait for the redefinition to complete (default: 30000, max: 600000). Increase when hot-swapping many classes at once | |
| sessionId | Yes | ||
| classesDir | Yes | Absolute path to compiled classes directory (e.g. build/classes/java/main/) | |
| sinceTimestamp | No | Unix timestamp (ms). Only redefine .class files modified after this time. 0 or omitted = all files. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full load, and it does well: it discloses the scan/match/redefine mechanism, the return payload, and an important side effect (statement-anchored breakpoints are re-resolved with moved/stale reporting via anchorResolution). It does not mention failure modes such as JDI's inability to change class schemas or permission requirements, which leaves a gap for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences, front-loaded with the core action before mechanism and side effects. Each sentence carries information (mechanism, return value, breakpoint side effect, constraint) with no filler, though the middle sentences are packed tightly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description fills the gaps well by enumerating return values (redefined classes, newest timestamp) and behavior after the swap (anchorResolution moved/stale). It falls short only on failure conditions and environment requirements beyond 'Java debug sessions'.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75%, and the description adds real meaning beyond it by explaining the incremental pattern for sinceTimestamp (newest returned timestamp feeds the next call). timeout and classesDir are left to the schema, and sessionId is undescribed in both places, but the added semantics for the key parameter are valuable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (hot-swap/redefine) and resource (changed Java .class files into a running JVM) and describes the mechanism (scan directory, match loaded classes, redefine via JDI). No sibling in the list does anything comparable, so an agent can distinguish it immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly states the prerequisite audience ('Only works with Java debug sessions') and explains the incremental-update workflow (pass the returned newest timestamp as sinceTimestamp on the next call). It lacks explicit when-not guidance, but no sibling tool overlaps in function, so the routing context is effectively clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_breakpointA
Remove a breakpoint by breakpointId (returned by set_breakpoint / list_breakpoints), by function name, or by file + line (removes all breakpoints at that location). Takes effect immediately while the program is running or paused; also works after the program exits, before a relaunch
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Alternative addressing: source file path (use together with line) | |
| line | No | Alternative addressing: line number (use together with file) | |
| function | No | Alternative addressing: remove all function breakpoints with this symbol name. Applies the same per-language rewrite as set_breakpoint (e.g. a bare Go "main" matches the stored "main.main"); the response reports the effective name as functionName and, when rewritten, the original as requestedName | |
| sessionId | Yes | ||
| breakpointId | No | Breakpoint id from set_breakpoint or list_breakpoints. Takes precedence over file + line |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does meaningful work: it discloses the destruction scope ('removes all breakpoints at that location') and the lifecycle window in which the removal is honored. It omits failure behavior, e.g. what happens when no matching breakpoint exists or the id is stale.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences with zero filler; the primary addressing mechanism and the immediate-effect semantics are front-loaded before the secondary lifecycle note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations and no output schema, the definition covers targeting and effect timing well enough to call it correctly. The remaining gap is the absence of error/confirmation behavior when no breakpoint matches.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 80%, so the schema already documents each addressing field, including the function-name rewrite details and breakpointId precedence. The description restates the three modes but adds no syntax or edge-case detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (remove a breakpoint) and enumerates three distinct addressing modes with their resolution sources, so an agent knows exactly what the call does. It references siblings set_breakpoint and list_breakpoints as id sources but never distinguishes itself from clear_breakpoints, which is the closest alternative for bulk removal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational context: the removal takes effect immediately while running or paused, and also works after the program exits but before a relaunch. It does not say when to prefer this over clear_breakpoints or how to choose among the three targeting modes when more than one applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
restart_debuggingA
Restart the debuggee: terminate the current program (if still running) and relaunch it with the same configuration as the last start_debugging. All current breakpoints are re-applied automatically. The get_output buffer starts fresh — read from since=0 after a restart. Works while running, paused, or after the program has exited. Not available for attach sessions or sessions never launched. Answers like start_debugging, including "running" with pending:true when the relaunch has not stopped within its readiness window
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the destructive terminate step, automatic breakpoint re-application, get_output buffer reset ('read from since=0'), and the readiness-window return contract ('running' with pending:true). It omits permission/auth requirements, but behavioral coverage is otherwise strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, then constraints, then return contract. Every sentence earns its place — breakpoints, buffer reset, valid states, and exclusions are each distinct operational facts, not padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description explains the return shape ('Answers like start_debugging... running with pending:true'), which is what an agent needs to interpret the result. Combined with the state and exclusion rules, it is complete enough to call correctly; only sessionId semantics are unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
One parameter (sessionId) with 0% schema description coverage, so the description must compensate and largely does not — sessionId semantics (which kind of session, relation to create/attach) are left to inference. The reference to sessions via exclusions implies context but adds no field-level meaning. Baseline 3 for a single obvious param.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Restart the debuggee') and immediately scopes it as 'terminate the current program... and relaunch it with the same configuration as the last start_debugging.' This distinguishes it from siblings like start_debugging (fresh config), continue_execution (resume), and attach_to_process (attach, which it explicitly excludes).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-it-works ('Works while running, paused, or after the program has exited') and when-not ('Not available for attach sessions or sessions never launched'). The reader knows exactly when to reach for this tool versus start_debugging or continue_execution.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_breakpointB
Set a breakpoint. Setting breakpoints on non-executable lines (structural, declarative) may lead to unexpected behavior
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Path to the source file or Java FQCN. For Java, passing a fully-qualified class name (e.g. "com.example.MyClass" or "com.example.Outer$Inner") is preferred — it works reliably with all classloaders including custom classloaders. Alternatively, use absolute file paths. | |
| line | No | Line number where to set breakpoint. Executable statements (assignments, function calls, conditionals, returns) work best. Structural lines (function/class definitions), declarative lines (imports), or non-executable lines (comments, blank lines) may cause unexpected stepping behavior | |
| function | No | Address by symbol name instead of file location: break on entry to this function/method (DAP function breakpoint). No file or line needed — names survive edits better than both. Composes with condition only. Supported by Python, Go, Rust, C/C++, .NET, Java, JavaScript and COBOL (paragraph, section or PROGRAM-ID names, e.g. "1000-INIT" or "1000-INIT OF PAYROLL") adapters; not by Ruby (rdbg ignores the request). JavaScript names are dotted runtime paths (e.g. "handler" or "obj.method") bound to the current function value: top-level function declarations of the main module bind at launch; functions in modules loaded later bind at the next pause | |
| nearLine | No | With statement only: when the statement text appears on multiple lines, bind to the match closest to this line | |
| condition | No | Optional expression: only break (or log) when it evaluates truthy | |
| sessionId | Yes | ||
| statement | No | Address by content instead of line number: the text of the target line, like an Edit-tool match — a distinctive substring is enough (leading/trailing whitespace and trailing //- or #-comments are ignored; an exact whole-line match always wins over substring matches). Preferred over line — it can only land on a line containing your text (an inexact or multi-candidate match adds a warning to the response) and survives file edits across restart_debugging. If the text appears on multiple lines, the error lists every match; add nearLine to pick one. Provide statement OR line, not both | |
| logMessage | No | Create a logpoint: instead of pausing, log this message when the line is hit. Expressions in {curly braces} are interpolated (e.g. "order={orderId} total={total}"). Messages arrive in get_output while the program runs at full speed. Supported by the Python, JavaScript, Go, Rust, C/C++, COBOL ({WS-NAME} data references) and mock adapters; not by Java, .NET, or Ruby | |
| suspendPolicy | No | Suspend policy when breakpoint is hit: "all" suspends all threads (default), "thread" only suspends the event thread. Only supported by the Java/JDI adapter. | |
| expectedContent | No | Optional assertion: text you expect on the target line — a distinctive substring is enough (leading/trailing whitespace and trailing //- or #-comments are ignored). If it does not match, the breakpoint is NOT set and the error shows the actual content of that line and its neighbors — use this to catch stale or off-by-one line numbers before they cause confusing behavior |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden, and it does volunteer one real behavioral trait: breakpoints on structural/declarative lines cause unexpected stepping behavior. Beyond that caveat it says nothing about idempotency, persistence across restart_debugging, permission needs, or what the response contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, and the core action is front-loaded ahead of the hazard warning. It is arguably too terse for a 10-parameter tool, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter mutation-adjacent tool with no annotations and no output schema, the description covers only one hazard. It omits session prerequisites, whether breakpoints persist, and what a successful call returns or how failures are reported.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 90%, so the schema already documents all 10 parameters in detail (statement, function, logMessage, expectedContent, suspendPolicy, etc.). The description adds no parameter-level meaning beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource ("Set a breakpoint"), which cleanly separates it from siblings like remove_breakpoint, clear_breakpoints, and list_breakpoints. It does not explicitly differentiate itself from create_debug_session or explain the line/function/statement addressing modes, but the core action is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The caveat about non-executable lines functions as an implicit "when not to / watch out" rule, so usage is implied rather than stated. There is no guidance on prerequisites (an active session), no mention of alternatives such as condition vs logMessage vs suspendPolicy, and no explicit routing against sibling breakpoint tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_debuggingB
Start debugging a script. Answers with the session as it is after the program's first stop, its exit, or a readiness window: "paused" with a reason (a launch with breakpoints answers at the first one), "stopped" with the exit code, or "running" with pending:true when the program is still running — after ~5s when nothing is armed to stop it (no breakpoints, no entry stop, no caught-exception filter; the "uncaught" default does not count), after 30s when something is; the message says what was or was not reached. A later stop shows in list_debug_sessions as the state flips to "paused"
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | ||
| sessionId | Yes | ||
| scriptPath | Yes | Path to the script to debug. Use absolute paths or paths relative to your current working directory | |
| dryRunSpawn | No | ||
| dapLaunchArgs | No | ||
| breakOnExceptions | No | Break when exceptions are thrown: "uncaught" pauses at uncaught exceptions at the crash site instead of terminating the session; "all" also pauses on caught/raised exceptions (language-dependent). Launch sessions default to "uncaught" (Ruby is the exception — rdbg has no uncaught-only filter, so it stays "none"); pass "none" to opt out and let crashing scripts run to termination | |
| adapterLaunchConfig | No | Optional adapter-specific launch configuration overrides |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and largely delivers: it discloses the three terminal states of the first stop, the ~5s vs 30s readiness windows, the condition that selects each, and that debuggerDisabled can be set via nested launch args. It omits auth/permission needs and whether the session persists, but the return-state and timing disclosure is substantive context beyond any structured data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in sentence one, which is good, but the remainder is a single dense, em-dash-heavy paragraph that buries the 5s/30s distinction and the debuggerDisabled caveat mid-sentence. Every clause conveys real information, but the lack of structure hurts readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does describe return states and timing well, covering the main post-call expectation. But it leaves the multi-param surface (7 params, 2 required) unexplained and gives no routing relative to the many sibling session tools, so it is adequate but not complete for a launch tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 43% and the description adds no parameter meaning at all — args, sessionId, dryRunSpawn, and adapterLaunchConfig are undocumented in both places. All parameter detail lives in nested schema descriptions the top-level text never references, so it does not compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb+resource ("Start debugging a script"), so an agent knows the operation. However, it never distinguishes itself from close siblings like create_debug_session, restart_debugging, or attach_to_process, so the agent cannot confidently choose between them from the description alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the description explains what happens once launched (paused/stopped/running), which indirectly signals this is the launch entry point. It never states when to prefer this over create_debug_session or attach_to_process, nor any prerequisites, so guidance is inferential rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
step_intoA
Step into the current call. Waits briefly for the program to stop; if the step is still executing after ~5s, returns success with state "running" and pending:true — the session becomes "paused" when the step completes
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose key runtime behavior: it waits briefly, times out after ~5s, returns state 'running' with pending:true, and later flips the session to 'paused'. It omits error/permission cases and whether a paused session is required, so it is not fully complete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense sentence that front-loads the action, then the async/timeout semantics. No wasted words, though the em-dash clause packs several facts together and slightly hurts scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description appropriately explains the return state ('running', pending:true) and the eventual 'paused' transition. What remains missing is prerequisite/error context, but for a one-parameter step tool this is largely sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single sessionId parameter, and the description never explains it. However, sessionId is self-evident from the debug-session sibling family, so the gap is minor rather than crippling.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific debugger verb ('Step into') plus the target ('the current call'), which is directly distinguishable from the sibling step_over and step_out tools. It is clear what the tool does, though it doesn't explicitly name those alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the description assumes the agent knows step_into means descend into the called function. There is no explicit when-to-use vs step_over/step_out guidance, nor any stated prerequisite that a session must be paused.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
step_outA
Step out of the current function. Waits briefly for the program to stop; if the step is still executing after ~5s (e.g. the rest of the function is long-running), returns success with state "running" and pending:true — the session becomes "paused" when the step completes
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load and does well: it discloses the ~5s wait, the timeout outcome (success with state 'running' and pending:true), and the eventual transition of the session to 'paused'. It omits error cases and whether a specific session state is required beforehand, but the async/timeout behavior is genuinely valuable information not available elsewhere.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the action ('Step out of the current function') before the timing behavior, and every clause earns its place. The second sentence is dense but conveys distinct, decision-relevant facts about the wait and return states.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations and no output schema, the description supplies the return-state and timing behavior an agent needs to interpret results. What is missing is the precondition (session must be stopped/paused) and any failure modes, but for a one-parameter step action it is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the single required sessionId parameter is never mentioned in the description. The parameter name is largely self-evident in this debugging-session toolset, so the gap is minor, but the description contributes no parameter semantics beyond the obvious.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Step out of the current function' with precise step-debugging semantics. An agent can distinguish it from step_over, step_into, and continue_execution purely from the description without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the step-debugging vocabulary and the returned state semantics, but the description never states the prerequisite (e.g. a paused/stopped session) or when to prefer step_out over step_over/step_into/continue_execution. No explicit when/when-not guidance is offered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
step_overB
Step over the current line. Waits briefly for the program to stop; if the step is still executing after ~5s (e.g. stepping over a long-running call), returns success with state "running" and pending:true — the session becomes "paused" when the step completes (check list_debug_sessions, or call pause_execution to interrupt)
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: it discloses the ~5s wait, the success-with-state="running" and pending:true outcome, the eventual transition to "paused", and the recovery paths (list_debug_sessions or pause_execution). It omits error/precondition behavior (e.g. what happens if the session is not paused or sessionId is invalid), keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first four words, and the subsequent clauses all earn their place by describing the non-obvious async semantics. The long em-dash clause is dense but not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, no-output-schema tool, the description covers the critical operational nuance (pending/running state, recovery via pause_execution). Missing only precondition and failure-mode detail, which is a modest gap rather than a blocking one.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single sessionId parameter, and the description never explains it. The indirect reference to list_debug_sessions hints at where a session ID comes from, but the description does not compensate for the coverage gap with any format, origin, or validity detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Step over the current line" states a specific debugger verb and its target, and the term "step over" carries conventional meaning distinct from step_into/step_out. However, the description never explicitly contrasts itself with those sibling tools, so the differentiation rests on the reader's prior debugger knowledge rather than on the text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what happens during execution but gives no when-to-use guidance relative to the obvious alternatives (step_into, step_out, continue_execution). The mention of a long-running call is an example of the async behavior, not a selection criterion for choosing this tool over its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unexpose_sessionA
Close a session's DAP mirror endpoint and disconnect any attached IDE clients. Succeeds as a no-op if the session is not exposed
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does meaningfully disclose idempotent behavior ('succeeds as a no-op if not exposed') and an important destructive side effect (disconnecting IDE clients). It does not cover permissions, error cases, or return behavior, so it stops short of full transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the primary action before the idempotency caveat. Every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with no annotations and no output schema, the effect and no-op guarantee are covered, but parameter meaning and error/return behavior are absent. Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description never mentions sessionId or its expected format/source. It must compensate for the coverage gap and does not, leaving the single parameter entirely defined by the bare schema type.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (close) and resource (the session's DAP mirror endpoint), plus a concrete side effect (disconnecting attached IDE clients). It is implicitly the inverse of the sibling expose_session, so an agent can place it immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the no-op note tells you it is safe to call regardless of state, but there is no explicit when-to-use framing or reference to expose_session as the counterpart. It does not state prerequisites or when to prefer an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
16 tool updates
v0.25.1- Changed
attach_to_process4 fields changed- added
Input schema / properties / adapterConfigAdded value: +{ + "additionalProperties": true, + "description": "Adapter-specific attach configuration merged into the attach config before the adapter transforms it (e.g. C/C++/LLDB: program — the binary path for symbol resolution when /proc/<pid>/maps paths are not openable, as in a kubectl-debug ephemeral container — or initCommands like \"settings set target.exec-search-paths /proc/<pid>/root\"). Reserved keys request/__attachMode are ignored; set stopOnEntry via the top-level parameter. Keys the adapter does not recognize are still forwarded to the debugger and named in the response warning — a near-miss of a supported key gets a did-you-mean suggestion. js-debug pins its attach orchestration keys (address/port/continueOnAttach/attachExistingChildren) over caller values; its autoAttachChildProcesses defaults to false on attach — child processes the target forks run undebugged (set it true to auto-attach children; only one child can be adopted at a time, further children are resumed undebugged)", + "type": "object" +} - added
Input schema / properties / breakOnExceptionsAdded value: +{ + "description": "Break when exceptions are thrown: \"uncaught\" pauses at uncaught exceptions at the crash site; \"all\" also pauses on caught/raised exceptions (language-dependent). Default \"none\" — attach sessions never apply a language default (unlike launch)", + "enum": [ + "uncaught", + "all", + "none" + ], + "type": "string" +} - changed
Input schema / properties / stopOnEntry / descriptionPrevious value: -"Stop on entry after attaching"New value: +"Pause the target after attaching. Default true when omitted (thread verification, then a pause request; if the stop lands after the response you get pending:true and the target still freezes on its next dispatch). Pass false to attach without stopping — required when attaching to a live service" - added
Input schema / properties / verifyTimeoutAdded value: +{ + "description": "How long to wait (ms) for the debugger to report at least one thread after attaching before failing the attach (default: 20000, max: 600000). Decrease for fast failure-by-design probes; increase for targets that are exceptionally slow to become debuggable", + "type": "number" +}
- Added
clear_breakpoints - Changed
create_debug_session4 fields changed- added
Input schema / properties / adapterConfigAdded value: +{ + "additionalProperties": true, + "description": "Attach mode only: adapter-specific attach configuration merged into the attach config (see attach_to_process)", + "type": "object" +} - changed
Input schema / properties / language / enumPrevious value: -[ - "mock", - "python", - "javascript", - "rust", - "go", - "java", - "dotnet" -]New value: +[ + "mock", + "python", + "javascript", + "ruby", + "rust", + "go", + "java", + "dotnet", + "cpp", + "cobol" +] - added
Input schema / properties / stopOnEntryAdded value: +{ + "description": "Attach mode only: same as attach_to_process.stopOnEntry — omitted means true, the target is paused after attach (possibly late, reported as pending:true). Pass false to attach to a live service without stopping it", + "type": "boolean" +} - added
Input schema / properties / verifyTimeoutAdded value: +{ + "description": "Attach mode only: how long to wait (ms) for the debugger to report at least one thread after attaching before failing the attach (default: 20000, max: 600000)", + "type": "number" +}
- Changed
evaluate_expression2 fields changed- changed
Input schema / properties / frameId / descriptionPrevious value: -"Optional stack frame ID for evaluation context. Must be a frame ID from a get_stack_trace response. If not provided, uses the current (top) frame automatically"New value: +"Optional authoritative stack frame ID from get_stack_trace. When provided, no automatic frame/thread selection occurs" - added
Input schema / properties / timeoutAdded value: +{ + "description": "Max time (ms) to wait for the evaluation to complete (default: 30000, max: 600000). On expiry the request fails but the expression may keep executing in the debuggee. Note: your MCP client may enforce its own overall request timeout", + "type": "number" +}
- Added
expose_session - Changed
get_local_variables1 field changed- added
Input schema / properties / namesAdded value: +{ + "description": "Only return variables with these exact names (case-sensitive). Requested names missing from the scope are listed in the response's notFound.", + "items": { + "type": "string" + }, + "type": "array" +}
- Added
get_output - Changed
get_stack_trace2 fields changed- changed
Input schema / properties / includeInternals / descriptionPrevious value: -"Include internal/framework frames (e.g., Node.js internals). Default: false for cleaner output."New value: +"Include internal/framework frames (e.g., Node.js internals, node_modules dependencies, async separators). Default: false for cleaner output." - added
Input schema / properties / threadIdAdded value: +{ + "description": "Inspect this exact thread (ids from list_threads). Explicit selection is authoritative and is never silently switched", + "type": "number" +}
- Changed
get_variables1 field changed- added
Input schema / properties / namesAdded value: +{ + "description": "Only return variables with these exact names (case-sensitive). Requested names missing from the scope are listed in the response's notFound.", + "items": { + "type": "string" + }, + "type": "array" +}
- Added
list_breakpoints - Changed
redefine_classes1 field changed- added
Input schema / properties / timeoutAdded value: +{ + "description": "Max time (ms) to wait for the redefinition to complete (default: 30000, max: 600000). Increase when hot-swapping many classes at once", + "type": "number" +}
- Added
remove_breakpoint - Added
restart_debugging - Changed
set_breakpoint7 fields changed- added
Input schema / properties / condition / descriptionAdded value: +"Optional expression: only break (or log) when it evaluates truthy" - added
Input schema / properties / expectedContentAdded value: +{ + "description": "Optional assertion: text you expect on the target line — a distinctive substring is enough (leading/trailing whitespace and trailing //- or #-comments are ignored). If it does not match, the breakpoint is NOT set and the error shows the actual content of that line and its neighbors — use this to catch stale or off-by-one line numbers before they cause confusing behavior", + "type": "string" +} - added
Input schema / properties / functionAdded value: +{ + "description": "Address by symbol name instead of file location: break on entry to this function/method (DAP function breakpoint). No file or line needed — names survive edits better than both. Composes with condition only. Supported by Python, Go, Rust, C/C++, .NET, Java, JavaScript and COBOL (paragraph, section or PROGRAM-ID names, e.g. \"1000-INIT\" or \"1000-INIT OF PAYROLL\") adapters; not by Ruby (rdbg ignores the request). JavaScript names are dotted runtime paths (e.g. \"handler\" or \"obj.method\") bound to the current function value: top-level function declarations of the main module bind at launch; functions in modules loaded later bind at the next pause", + "type": "string" +} - added
Input schema / properties / logMessageAdded value: +{ + "description": "Create a logpoint: instead of pausing, log this message when the line is hit. Expressions in {curly braces} are interpolated (e.g. \"order={orderId} total={total}\"). Messages arrive in get_output while the program runs at full speed. Supported by the Python, JavaScript, Go, Rust, C/C++, COBOL ({WS-NAME} data references) and mock adapters; not by Java, .NET, or Ruby", + "type": "string" +} - added
Input schema / properties / nearLineAdded value: +{ + "description": "With statement only: when the statement text appears on multiple lines, bind to the match closest to this line", + "type": "number" +} - added
Input schema / properties / statementAdded value: +{ + "description": "Address by content instead of line number: the text of the target line, like an Edit-tool match — a distinctive substring is enough (leading/trailing whitespace and trailing //- or #-comments are ignored; an exact whole-line match always wins over substring matches). Preferred over line — it can only land on a line containing your text (an inexact or multi-candidate match adds a warning to the response) and survives file edits across restart_debugging. If the text appears on multiple lines, the error lists every match; add nearLine to pick one. Provide statement OR line, not both", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "sessionId", - "file", - "line" -]New value: +[ + "sessionId" +]
- Changed
start_debugging4 fields changed- added
Input schema / properties / breakOnExceptionsAdded value: +{ + "description": "Break when exceptions are thrown: \"uncaught\" pauses at uncaught exceptions at the crash site instead of terminating the session; \"all\" also pauses on caught/raised exceptions (language-dependent). Launch sessions default to \"uncaught\" (Ruby is the exception — rdbg has no uncaught-only filter, so it stays \"none\"); pass \"none\" to opt out and let crashing scripts run to termination", + "enum": [ + "uncaught", + "all", + "none" + ], + "type": "string" +} - added
Input schema / properties / dapLaunchArgs / properties / justMyCode / descriptionAdded value: +"Only debug user code (default true). JavaScript launch: true blackboxes node_modules via skipFiles and keeps js-debug's smart-stepper on, so a pause or step that lands in skipped code (Node internals, node_modules) is stepped through and may never land; false drops node_modules from skipFiles and turns the stepper off, so pauses and steps land inside dependencies" - added
Input schema / properties / dapLaunchArgs / properties / noDebugAdded value: +{ + "description": "DAP's launch-without-debugging flag (default false). Where the adapter honours it (js-debug, debugpy, Delve and CodeLLDB) no breakpoint binds, no exception filter arms, no entry stop lands and no breakpoint, exception or entry stop ever arrives (a pause may still land where the runtime allows one) — the response warns when breakpoints, an explicit breakOnExceptions or stopOnEntry are set alongside it, and while the launch runs the session reports debuggerDisabled and every later surface says the debugger is off. rdbg, netcoredbg and the Java bridge ignore the flag, and the rust launch never forwards it: their debugger stays on and the response says so", + "type": "boolean" +} - added
Input schema / properties / dapLaunchArgs / properties / stopOnEntry / descriptionAdded value: +"Pause at the first line before running. Default false — the opposite of attach, which pauses unless stopOnEntry is false"
- Added
unexpose_session
7 tool updates
v0.20.0- Added
attach_to_process - Changed
create_debug_session4 fields changed- added
Input schema / properties / hostAdded value: +{ + "description": "Host to attach to for remote debugging (optional, triggers attach mode)", + "type": "string" +} - changed
Input schema / properties / language / enumPrevious value: -[ - "mock", - "python", - "javascript", - "rust" -]New value: +[ + "mock", + "python", + "javascript", + "rust", + "go", + "java", + "dotnet" +] - added
Input schema / properties / portAdded value: +{ + "description": "Debug port to attach to for remote debugging (optional, triggers attach mode)", + "type": "number" +} - added
Input schema / properties / timeoutAdded value: +{ + "description": "Connection timeout in milliseconds for attach mode (default: 30000)", + "type": "number" +}
- Added
detach_from_process - Added
list_threads - Changed
pause_execution1 field changed- added
Input schema / properties / threadIdAdded value: +{ + "description": "Thread ID to pause. If omitted or 0, pauses all threads.", + "type": "number" +}
- Added
redefine_classes - Changed
set_breakpoint2 fields changed- changed
Input schema / properties / file / descriptionPrevious value: -"Path to the source file. Use absolute paths or paths relative to your current working directory"New value: +"Path to the source file or Java FQCN. For Java, passing a fully-qualified class name (e.g. \"com.example.MyClass\" or \"com.example.Outer$Inner\") is preferred — it works reliably with all classloaders including custom classloaders. Alternatively, use absolute file paths." - added
Input schema / properties / suspendPolicyAdded value: +{ + "description": "Suspend policy when breakpoint is hit: \"all\" suspends all threads (default), \"thread\" only suspends the event thread. Only supported by the Java/JDI adapter.", + "enum": [ + "all", + "thread" + ], + "type": "string" +}
17 tool updates
- First observed
close_debug_session - First observed
continue_execution - First observed
create_debug_session - First observed
evaluate_expression - First observed
get_local_variables - First observed
get_scopes - First observed
get_source_context - First observed
get_stack_trace - First observed
get_variables - First observed
list_debug_sessions - First observed
list_supported_languages - First observed
pause_execution - First observed
set_breakpoint - First observed
start_debugging - First observed
step_into - First observed
step_out - First observed
step_over
TDQS
Scored across 28 tools
Most tools have clearly distinct purposes (e.g., step_over vs step_into vs continue_execution, get_scopes vs get_variables). However, create_debug_session, attach_to_process, and start_debugging overlap in session attachment/launch semantics, which could cause an agent to hesitate between them. Descriptions help but do not fully resolve the boundary.
All 28 tools follow a consistent snake_case verb_noun pattern (e.g., set_breakpoint, list_breakpoints, get_stack_trace, close_debug_session). Even the few exceptions like step_over and step_into fit the same naming family. No mixed conventions or chaotic naming.
28 tools is on the heavy side for an MCP server, and some features are convenience layers (get_local_variables) or advanced/niche (expose_session, redefine_classes). The debugger domain legitimately requires many operations, so it is borderline rather than clearly excessive, but a few tools could be merged or omitted.
The surface covers core debugger lifecycle: session management, breakpoints, stepping, inspection (variables, stack, scopes, threads), evaluation, output, and session teardown. Minor gaps exist (e.g., no explicit conditional breakpoint or logpoint update tool, no watch expression management), but agents can work around most of these.
Maintenance
Related MCP Connectors
Agent Replay Debugger MCP — record every agent step + deterministic replay. Step-debugger for
Live browser debugging for AI assistants — DOM, console, network via MCP.
Shared debugging memory for AI coding agents
Persistent cloud workspaces for AI agents: run commands, edit files, use git and a browser.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables 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.1810 npm2Apache 2.0
- AlicenseBqualityAmaintenanceEnables AI agents to debug code and automate browsers using Chrome DevTools Protocol, supporting breakpoints, variable inspection, and replayable interaction recording.35619 npm16MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to debug code inside VS Code by setting breakpoints, stepping through execution, inspecting variables, and evaluating expressions across multiple languages.551MIT
- AlicenseBqualityDmaintenanceEnables AI agents to debug C/C++ programs with GDB or LLDB, supporting breakpoints, stepping, variable inspection, and function calls.20MIT