MCP Debugger
# mcp-debugger
<div align="center">
<img src="assets/logo.png" alt="MCP Debugger Logo - A stylized circuit board with debug breakpoints" width="400" height="400">
</div>
**A headless, agentic debugger over MCP โ let your AI agents debug running programs in ten languages.**
[](https://github.com/debugmcp/mcp-debugger/actions/workflows/ci.yml)
[](https://codecov.io/gh/debugmcp/mcp-debugger)
[](https://www.npmjs.com/package/@debugmcp/mcp-debugger)
[](https://hub.docker.com/r/debugmcp/mcp-debugger)
[](./LICENSE)
[](https://scorecard.dev/viewer/?uri=github.com/debugmcp/mcp-debugger)
[](https://www.bestpractices.dev/projects/13543)
## ๐ฏ 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](https://github.com/microsoft/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 (`redefine_classes`) | โ
| โ |
| Debuggee output as subscribable MCP resource | โ
| โ |
| In-IDE debugging UX alongside the agent | โ
read-only IDE mirror ([`expose_session`](docs/tool-reference.md#expose_session)) โ the IDE joins the *agent's* live session | โ
native |
| Logpoints without pausing (prod-safe value watching) | โ
[`logMessage` breakpoints](docs/tool-reference.md#set_breakpoint) | โ
via VS Code |
| Content/function-addressed breakpoints (`statement:`, `function:`, `expectedContent`) | โ
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) | โ
[`kubectl debug` flow](docs/kubernetes.md) | โ |
| 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 to `127.0.0.1` with 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](./CHANGELOG.md) 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](docs/rust-debugging-windows.md))
- ๐น **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`/`.cbl` sources (auto-compiled with `cobc`) 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](docs/cobol/README.md))
- ๐ฆ **Dart/Flutter debugging via the SDK's own debug adapters** โ Launch Dart programs and `package:test` files (`dart debug_adapter`) or Flutter apps and tests (`flutter debug-adapter`), the runner auto-detected from `pubspec.yaml` and the program path; attach to a running VM by service URI or service-info file; conditional breakpoints, logpoints, `Unhandled`/`All` exception 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](docs/dart/README.md))
- ๐งช **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_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](docs/kubernetes.md), [turnkey manifests](examples/kubernetes/))
- ๐ **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](./docs/tool-reference.md#secret-redaction); 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](https://github.com/debugmcp/mcp-debugger/actions/workflows/ci.yml))
## ๐ง Agent Skill
Tools tell an agent *what* it can do; a skill teaches it *how to debug well*. This repo ships an [agent skill](skills/debugging/) covering the session golden path, root-cause discipline (bisection over line-by-line stepping), attach/remote recipes, and per-language quirks:
```bash
# 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](skills/debugging/README.md) for details.
## ๐ฌ See It In Action
- **[Auto-debug failing CI tests](.github/actions/debug-failing-test/)** โ a composite GitHub Action that launches mcp-debugger + an agent on a test failure and posts the root-cause analysis
- **[Sick pod walkthrough](examples/sick-pod/)** โ attach to a misbehaving Python service in Kubernetes via port-forward ([tutorial](docs/jit-diagnostics/README.md))
- **[Native sick pod](examples/sick-pod-cpp/)** โ 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, 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? 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](https://github.com/vadimcn/codelldb/releases) binary instead, or use the Docker image.
### For MCP Clients (Claude Desktop, etc.)
Add to your MCP settings configuration:
```json
{
"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:
```bash
codex mcp add mcp-debugger -- npx -y @debugmcp/mcp-debugger stdio
codex mcp list
```
Codex 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](https://developers.openai.com/codex/mcp) for configuration and
troubleshooting details.
Developing mcp-debugger itself? Use the restartable [source dev proxy](tools/dev-proxy/README.md#codex-cli-desktop-and-ide)
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](https://claude.ai/code) for installation instructions.
```bash
# 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](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:
```bash
pi install npm:@debugmcp/mcp-debugger # the mcp-debugger skill, and the server via pi's built-in MCP
pi list # shows the package
```
The 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](tools/dev-proxy/README.md).
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
```bash
docker run -i --rm -v $(pwd):/workspace debugmcp/mcp-debugger:latest
```
> The 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 --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](./docs/docker-support.md).
### Using npm
```bash
npm install -g @debugmcp/mcp-debugger
mcp-debugger --help
```
Or use without installation via npx:
```bash
npx @debugmcp/mcp-debugger --help
```
### Over 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:
```bash
mcp-debugger http --port 3001 # or: node dist/index.js http -p 3001
```
and point the client at it:
```json
{
"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:
```json
// 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](docs/tool-reference.md) for parameters and response shapes.
| Tool | Description | Status |
|------|-------------|--------|
| `create_debug_session` | Create a new debugging session | โ
Implemented |
| `list_debug_sessions` | List all active sessions | โ
Implemented |
| `list_supported_languages` | Show available language adapters | โ
Implemented |
| `set_breakpoint` | Set a breakpoint in a file | โ
Implemented |
| `list_breakpoints` | List a session's breakpoints with verified state | โ
Implemented |
| `remove_breakpoint` | Remove a breakpoint by id or file+line | โ
Implemented |
| `clear_breakpoints` | Remove all breakpoints (optionally per file) | โ
Implemented |
| `start_debugging` | Start debugging a script | โ
Implemented |
| `restart_debugging` | Relaunch with the same config, breakpoints re-applied | โ
Implemented |
| `attach_to_process` | Attach debugger to a running process | โ
Implemented |
| `detach_from_process` | Detach debugger from a process | โ
Implemented |
| `expose_session` | Open a read-only DAP mirror endpoint so an IDE can attach and inspect | โ
Implemented |
| `unexpose_session` | Close the mirror endpoint and disconnect IDE clients | โ
Implemented |
| `get_stack_trace` | Get the current stack trace | โ
Implemented |
| `list_threads` | List all threads in the debug session | โ
Implemented |
| `get_scopes` | Get variable scopes for a frame | โ
Implemented |
| `get_variables` | Get variables in a scope | โ
Implemented |
| `get_local_variables` | Get local variables in current frame | โ
Implemented |
| `step_over` | Step over the current line | โ
Implemented |
| `step_into` | Step into a function | โ
Implemented |
| `step_out` | Step out of a function | โ
Implemented |
| `continue_execution` | Continue running | โ
Implemented |
| `wait_for_stop` | Block until the session next pauses or ends | โ
Implemented |
| `pause_execution` | Pause running execution | โ
Implemented |
| `evaluate_expression` | Evaluate expressions in debug context | โ
Implemented |
| `get_source_context` | Get source code context | โ
Implemented |
| `get_output` | Read captured debuggee output (stdout/stderr) | โ
Implemented |
| `close_debug_session` | Close a session | โ
Implemented |
| `redefine_classes` | 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](./docs/architecture/adapter-development-guide.md)!
## ๐ก Example: Debugging Python Code
Here's a complete debugging session example:
```python
# 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
```json
// 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
```json
// 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
```json
// 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:
```json
// 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:
```json
// 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](./ROADMAP.md) โ Path to 1.0: stability criteria, near-term themes, non-goals
- ๐ [Tool Reference](./docs/tool-reference.md) โ Complete API documentation
- ๐ฆ [Getting Started Guide](./docs/getting-started.md) โ First-time setup
- ๐๏ธ [Architecture Overview](./docs/architecture/README.md) โ Multi-language design
- ๐ง [Adapter Development](./docs/architecture/adapter-development-guide.md) โ Add new languages
- ๐ [Dynamic Loading Architecture](./docs/architecture/dynamic-loading-architecture.md) โ Runtime discovery, lazy loading, caching
- ๐งฉ [Adapter API Reference](./docs/architecture/adapter-api-reference.md) โ Adapter, factory, loader, and registry contracts
- ๐ [CHANGELOG](./CHANGELOG.md) โ Release history and upgrade notes
- ๐ [Python Debugging Guide](./docs/python/README.md) โ Python-specific features
- ๐ [Ruby Debugging Guide](./docs/ruby/README.md) โ Ruby debugging with `rdbg`, including remote attach
- ๐ฌ [Case Study: the initialize response that never came](./docs/case-studies/rdbg-initialize-response-stall.md) โ mcp-debugger debugging itself to root-cause a Ruby launch stall
- ๐ฌ [Case Study: attaching the debugger to itself](./docs/case-studies/self-attach-fork-release-and-the-500ms-ack-window.md) โ 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](./docs/case-studies/js-attach-pause-and-the-smart-stepper.md) โ 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](./docs/case-studies/trace-that-couldnt-name-its-socket.md) โ measure-fix-measure on the diagnostics themselves: one scripted attach run, before and after, as the acceptance test
- ๐จ [JavaScript Debugging Guide](./docs/javascript/README.md) โ JavaScript/TypeScript features
- ๐น [Go Debugging Guide](./docs/go/README.md) โ Go debugging with Delve
- โ [Java Debugging Guide](./docs/java/README.md) โ Java debugging with JDI bridge
- ๐ท [.NET Debugging Guide](./docs/dotnet/README.md) โ .NET/C# debugging with netcoredbg
- โ๏ธ [C/C++ Debugging Guide](./docs/cpp/README.md) โ CodeLLDB launch, auto-compile, attach-by-PID, core dumps, remote stubs
- ๐งฎ [COBOL Debugging Guide](./docs/cobol/README.md) โ GnuCOBOL + CodeLLDB: auto-compile, COBOL-shaped variables, runtime-error stops, the mainframe migration recipe
- ๐ฆ [Dart/Flutter Debugging Guide](./docs/dart/README.md) โ the SDK's own debug adapters: runner selection, `dart test`/`flutter test`, attach by VM-service URI, Flutter devices
- ๐ฆ [Rust Debugging Guide](./docs/rust-debugging.md) โ CodeLLDB setup ([Windows specifics](docs/rust-debugging-windows.md))
- ๐ณ [Docker Support](./docs/docker-support.md) โ Container languages, attach modes, host-binary source mapping
- โธ๏ธ [Kubernetes Debugging](./docs/kubernetes.md) โ Turnkey attach recipes: registry-free manifests, per-language presets, ephemeral debug sidecar
- ๐ [JIT Diagnostics Tutorial](./docs/jit-diagnostics/README.md) โ Debug live services in Kubernetes, incl. the ephemeral-sidecar flow for compiled code
- ๐ค [Agent Debugging Guide](./docs/agent-debugging-guide.md) โ Correct tool usage patterns for AI agents
- โ ๏ธ [Known Issues](./docs/KNOWN_ISSUES.md) โ Current caveats and workarounds
- ๐ฉบ [Diagnostics](./docs/diagnostics.md) โ `mcp-debugger doctor`, per-language prerequisites, failure signatures, env-var reference
- ๐ง [Troubleshooting](./docs/troubleshooting.md) โ Common issues & solutions
## ๐ค Contributing
We welcome contributions! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
```bash
# 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: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++ & 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 build
- **CI Environment**: Set `SKIP_ADAPTER_VENDOR=true` to skip vendoring
To manually manage adapters:
```bash
# 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](https://github.com/nektos/act) to run GitHub Actions workflows locally:
```bash
# 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](./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](./ROADMAP.md) for the path to 1.0
## ๐๏ธ Who Maintains This
mcp-debugger is stewarded by **Sycamore LLC** and led by John Franklin ([@debugmcpdev](https://github.com/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](./MAINTAINERS.md), [GOVERNANCE.md](./GOVERNANCE.md), and [SUPPORT.md](./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](https://scorecard.dev/viewer/?uri=github.com/debugmcp/mcp-debugger) score we actively maintain โ details in [SUPPLY-CHAIN-SECURITY.md](./SUPPLY-CHAIN-SECURITY.md). Report vulnerabilities via [SECURITY.md](./SECURITY.md).
## ๐ License
MIT License - see [LICENSE](./LICENSE) for details.
## ๐ฅ Contributors
- [@Poyraxx](https://github.com/Poyraxx) โ Ruby adapter (rdbg)
- [@swinyx](https://github.com/swinyx) โ Go adapter (Delve)
- [@roofpig95008](https://github.com/roofpig95008) โ Java adapter (JDI bridge)
## ๐ Acknowledgments
Built with:
- [Model Context Protocol](https://github.com/anthropics/model-context-protocol) by Anthropic
- [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) by Microsoft
- [debugpy](https://github.com/microsoft/debugpy) for Python debugging
- [debug](https://github.com/ruby/debug) for Ruby debugging
---
**Give your AI agents a real debugger โ in any language.**
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.