mcp-debugger
A headless, agentic debugger over MCP — let your AI agents debug running programs in eight 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 eight 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:
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.24.0 — C/C++ debugging lands (CodeLLDB: prebuilt binaries, auto-compiled single sources, attach by PID), alongside statement/function-addressed breakpoints, logpoints, restart_debugging, breakpoint management tools, buffered get_output, break-on-uncaught-exceptions by default, a read-only IDE mirror (expose_session), default-on secret redaction, and a multi-language Docker image (Python, JS, Java, Rust, C/C++ native; Ruby attach). See the CHANGELOG for the full release history.
✨ 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
- 🧪 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, Java via JDWP) with source-path mapping, or by PID for native code (C/C++) — direct-connect attach needs no local toolchain, and
list_supported_languages reports per-mode availability with reasons
- 🎯 Breakpoints that survive edits – Address by content (
statement: "total = sum(prices)"), by symbol (function: "main"), or assert line content with expectedContent; anchors re-resolve across restart_debugging and weak matches warn loudly
- 🪵 Logpoints –
set_breakpoint with logMessage: "x={x}" streams interpolated values into get_output without pausing — prod-safe value watching on hot paths
- 🧰 Full breakpoint lifecycle –
list_breakpoints / remove_breakpoint / clear_breakpoints work live mid-run; restart_debugging relaunches with the same config and re-applies everything in one call
- 📡 Buffered program output –
get_output returns 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 via lastStop)
- 🪞 Read-only IDE mirror –
expose_session opens 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-debugger
The 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 debug gem / rdbg, Node.js, Go + Delve, JDK 21+, .NET SDK, the Rust toolchain, or a C/C++ compiler — g++/clang++, only needed for source-file launch). Not sure what's installed? Run npx @debugmcp/mcp-debugger doctor for 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, set CODELLDB_PATH to 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 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 list
Important: The stdio argument is required to prevent console output from corrupting the JSON-RPC protocol. See CLAUDE.md for detailed setup and troubleshooting.
Using Docker
docker run -v $(pwd):/workspace debugmcp/mcp-debugger:latest
The Docker image debugs Python, JavaScript, Java, Rust, and C/C++ natively (toolchains + a shared vendored CodeLLDB are included), plus the mock adapter. Ruby is attach-only in the image (the adapter ships without a Ruby runtime — attach to any rdbg --open process, 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_languages reports per-mode availability (modes.launch / modes.attach) with reasons. See Docker support.
Using npm
npm install -g @debugmcp/mcp-debugger
mcp-debugger --help
Or use without installation via npx:
npx @debugmcp/mcp-debugger --help
📚 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", 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"
}
All 28 tools below are implemented — see the tool reference for parameters and response shapes.
🏗️ 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++ ││Mock │
│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, b
Step 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": "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": "buggy_swap.py"
}
// Response:
{
"success": true,
"state": "paused",
"message": "Debugging started for buggy_swap.py. Current state: paused",
"data": {
"message": "Debugging started for 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
- 🔄 Migration Guide – Upgrading to v0.15.0 (dynamic loading)
- 🐍 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_expression to 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
- 🦀 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 and C/C++)
# 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:force
Debug Adapter Vendoring
The project automatically vendors debug adapters during pnpm install:
- JavaScript: Downloads Microsoft's js-debug from GitHub releases
- Rust & C/C++: 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 build
- CI Environment: Set
SKIP_ADAPTER_VENDOR=true to 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:vendor
Running 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-latest
See tests/README.md for detailed testing instructions.
📊 Project Status
- ✅ Production Ready: v0.24.0 with eight language adapters, 28 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)
- 🟢 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
🙏 Acknowledgments
Built with:
Give your AI agents a real debugger — in any language.