Give an AI agent a real .NET debugger: breakpoints, stepping, locals, expression evaluation.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
An MCP server that lets an AI assistant debug .NET programs: launch or attach to a process, set breakpoints, step through code, inspect variables and evaluate expressions. It also carries a searchable reference on how .NET debuggers work internally.
Published on NuGet as DotnetDebugger.Mcp.
Built on clrdbg, driven over the Debug Adapter Protocol. The
debugger travels inside the package and runs as a child process, so a crash in native debugging code
costs the debug session rather than the server.
Origin. A fork of decriptor/SharpDbg.MCP, now far enough from it to carry its own name: the debugger layer speaks the Debug Adapter Protocol instead of calling a debugger's internal API, the debugger underneath has since changed from SharpDbg to clrdbg, launching a program under the debugger is new, and the two have not shared a commit since. This repository was called
SharpDbg.MCPuntil the first release; GitHub redirects the old name, and the project files andSHARPDBG_*settings still carry it.
Some of these need changes in the underlying debugger rather than here.
exit_code is null there. The debugger
reads the code off a process it started itself and has none for one it was pointed at, so for an
attached process there is nothing to report β and the protocol cannot say "unknown", only 0,
which would be a number this server made up. A program started with launch_program does report
its real code.CORDBG_E_DEBUG_COMPONENT_MISSING (0x80131C3C), reported as
Attempting to register for runtime startup failed: -2146231236. Self-contained on its own works,
and single-file on its own works; only the combination does not.One package carries the debugger and its native shims for every platform, so the same configuration works everywhere. There is nothing to clone or build.
Claude Code, for the current project:
Add --scope user to make it available in every project, or --scope project to write a .mcp.json
that is committed and shared with your team.
Claude Desktop, by editing ~/.config/Claude/claude_desktop_config.json on macOS and Linux, or
%APPDATA%\Claude\claude_desktop_config.json on Windows:
dnx DotnetDebugger.Mcp --yes is the shorter equivalent, and the form NuGet.org suggests. Prefer
dotnet tool exec in a client launched from a desktop environment rather than from a shell: dnx
lives in the SDK directory, which such a client often does not have on its PATH, while dotnet
reliably is.
A client only connects its MCP servers when a session starts, so restart it after changing the
configuration. To confirm the server is there, run claude mcp list or ask the client to list .NET
processes.
Installing the tool once avoids the resolution step on every start and keeps the version fixed until you change it:
The command is then dotnet-debugger-mcp, with no arguments. This needs ~/.dotnet/tools on your
PATH, which is why it is not the default suggestion: a client that cannot find the command fails
the same way a wrong path does.
dotnet tool exec can keep running a version it has already downloaded, even after a newer one is
published and indexed. Nothing looks wrong when it does: the server starts, the client reports it as
connected, and the only sign is that the new release's tools are missing.
Measured while releasing 0.1.1. With only 0.1.0 in the local package folder, the unpinned command kept running 0.1.0, and clearing the NuGet HTTP cache did not change that. Naming the version once fetched the new package, after which the unpinned command used it too:
Installing the tool avoids the question entirely, because then upgrading is explicit:
To see which version is actually running, ask the client to list this server's tools, or read the first line the server writes to stderr β it names the version at startup. A client's own health check reports only that the process started, not what it is.
Catching a program before it has run a single line, which is the case attaching cannot reach:
| Tool | What it does |
|---|---|
list_dotnet_processes | List the .NET processes running on this machine |
attach_to_process | Attach the debugger to a running .NET process |
launch_program | Prepare a program to run under the debugger, stopped before it starts |
start_program | Run the program prepared by launch_program |
get_process_status | Report whether the session is running, stopped, and where |
wait_for_stop | Block until the debuggee stops, instead of polling |
get_program_output | Read what the debuggee wrote to stdout and stderr |
detach_from_process | Detach, leaving the process running |
list_sessions | List open sessions and what each is debugging |
close_session | Close a session, detaching first if needed |
| Tool | What it does |
|---|---|
set_breakpoint | Set or update a breakpoint at a file and line, with an optional condition or hit count |
set_function_breakpoint | Set a breakpoint on a method by name, when the file and line are not known |
remove_breakpoint | Remove a breakpoint of either kind |
list_breakpoints | List this session's breakpoints and whether each is verified |
set_exception_break_mode | Choose which exceptions stop the program: all, unhandled, or named types |
| Tool | What it does |
|---|---|
continue_execution | Resume until the next breakpoint or exit |
pause_execution | Break into the debugger where the program currently is |
step_over, step_into, step_out | Step by line, into a call, or out of the current method |
get_threads | List the threads in the debuggee |
get_stack_trace | Read the call stack for a thread |
get_variables | Read the locals of a stack frame |
expand_variable | Expand an object into its members, which may expand further |
evaluate_expression | Evaluate a C# expression in the context of a frame |
get_exception_info | Read the type, message, HResult, source and stack trace of what was thrown |
| Tool | What it does |
|---|---|
search_debugging_concepts | Search the embedded documentation |
explain_icordebug_interface | Explain a specific ICorDebug interface |
get_debugging_flow | Walk through a debugging operation step by step |
list_debugging_concepts | Browse the concept catalogue by category |
A breakpoint binds through the target's symbols, so the debuggee must be built with portable PDBs
sitting next to its assembly. A missing or mismatched PDB is the most common reason set_breakpoint
answers verified: false with No symbols have been loaded for this document.
Debug builds already do this. For a Release build, or any project that changes the defaults:
Optimized code also moves locals out of reach, so get_variables is only fully useful with
<Optimize>false</Optimize>.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/net-debugger-for-mcp)<a href="https://allmcps.com/mcp/net-debugger-for-mcp"><img src="https://allmcps.com/api/badge/net-debugger-for-mcp?style=directory" alt=".NET Debugger for MCP on AllMCPs" /></a>