MCP server for .NET debugging via netcoredbg.
Enables AI agents (Claude, etc.) to set breakpoints, step through code, and inspect variables in .NET applications.
┌─────────┐ MCP ┌─────────────────┐ DAP ┌─────────────┐
│ Claude │ ──────────► │ mcp-netcoredbg │ ──────────► │ netcoredbg │
│ │ (tools) │ (this repo) │ (stdio) │ (Samsung) │
└─────────┘ └─────────────────┘ └──────┬──────┘
│
▼
┌─────────────┐
│ .NET App │
└─────────────┘
| Tool | Description |
|---|---|
list_sessions |
List all active debug sessions |
select_session |
Set the default session for commands |
terminate_session |
Terminate a specific session |
| Tool | Description |
|---|---|
launch |
Start debugging a .NET application (DLL path) |
launch_watch |
Start debugging with hot reload via dotnet watch |
stop_watch |
Stop hot reload debugging mode |
attach |
Attach to a running .NET process |
invoke |
Invoke a specific method in an assembly (with optional debugging) |
restart |
Restart the debugged program (for launch mode) |
terminate |
Stop debugging session |
| Tool | Description |
|---|---|
set_breakpoint |
Set breakpoint at file:line (supports conditions) |
remove_breakpoint |
Remove a breakpoint |
list_breakpoints |
List all active breakpoints |
| Tool | Description |
|---|---|
continue |
Continue execution |
pause |
Pause execution |
step_over |
Step over current line |
step_into |
Step into function call |
step_out |
Step out of current function |
| Tool | Description |
|---|---|
stack_trace |
Get current call stack |
scopes |
Get variable scopes for a stack frame |
variables |
Get variables from a scope |
evaluate |
Evaluate expression in debug context |
threads |
List all threads |
output |
Get recent program output |
status |
Get debugger status |
Note: All tools accept an optional sessionId parameter to target a specific session. If omitted, the default session is used.
Version 2.0 introduces support for multiple simultaneous debug sessions. This allows you to debug multiple .NET applications concurrently - for example, an API and a background worker.
When you launch a debug session without specifying a sessionId, one is automatically derived from the project/program name:
TopServer.Service.Api→ session ID:apiTopServer.Service.Worker→ session ID:workerMyApp.Web→ session ID:web- Custom: specify
sessionIdparameter explicitly
# Start API debugging
launch_watch projectPath=/path/to/MyApp.Api launchProfile=https
→ Session 'api' created
# Start Worker in a second session
launch_watch projectPath=/path/to/MyApp.Worker launchProfile=default
→ Session 'worker' created
# List all sessions
list_sessions
→ api (default): watch - /path/to/MyApp.Api [running]
worker: watch - /path/to/MyApp.Worker [running]
# Set breakpoint in API
set_breakpoint file=/path/to/ApiController.cs line=42 sessionId=api
# Set breakpoint in Worker
set_breakpoint file=/path/to/WorkerService.cs line=100 sessionId=worker
# Continue API execution
continue sessionId=api
# Check Worker status
status sessionId=worker
# Switch default session
select_session sessionId=worker
# Now commands without sessionId go to worker
continue # continues worker
| Command | Description |
|---|---|
list_sessions |
Show all active sessions with status |
select_session |
Change which session receives commands by default |
terminate_session |
Stop a specific session |
If you only use one session, the behavior is unchanged from v1.x - no sessionId parameter needed.
The invoke tool lets you run a specific method from a .NET assembly without launching the full application. This is useful for:
- Testing individual methods in isolation
- Running utility functions
- Debugging specific code paths without going through the whole app
| Parameter | Type | Required | Description |
|---|---|---|---|
assembly |
string | Yes | Path to the .NET DLL |
type |
string | Yes | Fully qualified type name (e.g., MyApp.Services.Calculator) |
method |
string | Yes | Method name to invoke |
args |
array | No | Method arguments as JSON array |
ctorArgs |
array | No | Constructor arguments (for instance methods) |
debug |
boolean | No | Launch under debugger for breakpoint support (default: false) |
cwd |
string | No | Working directory |
Static method:
{
"assembly": "/path/to/MyApp.dll",
"type": "MyApp.StringUtils",
"method": "FormatName",
"args": ["John", "Doe"]
}Instance method with constructor arguments:
{
"assembly": "/path/to/MyApp.dll",
"type": "MyApp.Calculator",
"method": "Add",
"args": [5],
"ctorArgs": [10]
}With debugging (breakpoints supported):
{
"assembly": "/path/to/MyApp.dll",
"type": "MyApp.Calculator",
"method": "Add",
"args": [5],
"debug": true
}- Static methods: Just provide type, method, and args
- Instance methods: Automatically constructs the type (provide
ctorArgsif needed) - Auto ILogger injection:
ILogger<T>parameters are automatically resolved - Async support: Automatically awaits Task-returning methods
- Console capture: Captures
Console.WriteLineoutput - Log capture: Captures
ILoggercalls made during execution - Rich errors: On failure, shows available constructors/methods to help you fix the call
The tool returns a structured JSON result:
{
"success": true,
"method": "MyApp.StringUtils.FormatName",
"args": ["John", "Doe"],
"returnType": "string",
"returnValue": "Doe, John",
"durationMs": 2.5,
"logs": [
{"level": "Information", "message": "Processing..."}
],
"stdout": ""
}On error, it provides helpful diagnostics:
{
"success": false,
"error": "Method not found",
"errorDetails": {
"type": "MyApp.StringUtils",
"reason": "Method 'DoSomething' not found",
"methods": [
{"name": "FormatName", "params": ["string firstName", "string lastName"], "returnType": "string", "isStatic": true}
]
}
}The launch_watch tool enables debugging with hot reload support via dotnet watch. When you make code changes, the app automatically restarts and the debugger reconnects - preserving your breakpoints.
| Parameter | Type | Required | Description |
|---|---|---|---|
projectPath |
string | Yes | Path to the .NET project directory (containing .csproj) |
launchProfile |
string | No | Name of a launch profile from Properties/launchSettings.json |
args |
array | No | Additional arguments to pass to dotnet watch |
Basic usage:
{
"projectPath": "/path/to/MyApp"
}With launch profile (recommended for ASP.NET apps):
{
"projectPath": "/path/to/MyApp.Api",
"launchProfile": "https"
}The launch profile is important for ASP.NET applications as it sets:
ASPNETCORE_ENVIRONMENT(e.g., Development)applicationUrl(e.g., https://localhost:7179)- Other environment variables needed for proper operation
- Starts
dotnet watch runwith the specified project - Waits for the app to build and start
- Automatically attaches the debugger to the running process
- When you edit code and save,
dotnet watchrebuilds and restarts - The debugger detects the restart and reconnects automatically
- Breakpoints are preserved across restarts
Use stop_watch to cleanly terminate both the debugger and the dotnet watch process.
Use status to see hot reload specific information:
- Watch process PID
- Child app PID
- Whether the debugger is currently reconnecting
- netcoredbg installed and in PATH
- Node.js 18+
- .NET SDK 8.0+ (for building the harness and target applications)
# Install netcoredbg (example for Linux x64)
curl -sLO https://github.com/Samsung/netcoredbg/releases/download/3.1.3-1062/netcoredbg-linux-amd64.tar.gz
tar xzf netcoredbg-linux-amd64.tar.gz
sudo mv netcoredbg /opt/netcoredbg
sudo ln -sf /opt/netcoredbg/netcoredbg /usr/local/bin/netcoredbg
# Build this MCP server
npm install
npm run build
# The method invocation harness is auto-built on first useQuick install:
# Clone and build
git clone https://github.com/AerialByte/mcp-netcoredbg.git
cd mcp-netcoredbg && npm install && npm run build
# Add to Claude Code
claude mcp add netcoredbg -- node $(pwd)/dist/index.jsOr manually add to your Claude Code MCP settings:
{
"mcpServers": {
"netcoredbg": {
"command": "node",
"args": ["/path/to/mcp-netcoredbg/dist/index.js"]
}
}
}This tool launches and controls a debugger. By design, it can:
- Execute arbitrary .NET applications
- Evaluate expressions within the debugged process
- Inspect memory and variables
Only use this with code you trust. Do not debug untrusted applications.
- Build your .NET app with debug symbols:
dotnet build --configuration Debug - Launch debugger:
launchwith the DLL path - Set breakpoints:
set_breakpointat file:line - Continue/step through code
- Inspect variables with
scopesandvariables - Evaluate expressions with
evaluate - Terminate when done
- Build the target assembly:
dotnet build - Use
invokewith the type and method name - If it fails, check the error for available constructors/methods
- For debugging: set breakpoints first, then use
invokewithdebug: true
When using this MCP server as an AI agent:
- Use
invokewhen you want to test a specific method in isolation - Use
launchwhen you need to run the full application or debug complex scenarios
-
Start simple: Try without
ctorArgsfirst - the harness will use parameterless constructors or auto-injectILogger<T> -
Handle errors iteratively: If invocation fails, the error response includes available methods/constructors. Use this to correct your call.
-
For debugging specific methods:
1. Set breakpoints in the source files first 2. Call invoke with debug: true 3. Use continue/step_over/step_into to navigate 4. Use output to see the final result -
Arguments are JSON: Pass args as a JSON array. The harness handles type conversion:
- Strings:
"hello" - Numbers:
42,3.14 - Booleans:
true,false - Null:
null - Objects:
{"name": "Alice", "age": 30}
- Strings:
Testing a utility method:
invoke assembly=/path/to.dll type=MyApp.Utils method=Parse args=["input"]
Testing with constructor injection:
invoke assembly=/path/to.dll type=MyApp.Service method=Process ctorArgs=[100] args=["data"]
Debugging a failing method:
1. set_breakpoint file=/path/to/Service.cs line=42
2. invoke assembly=/path/to.dll type=MyApp.Service method=Process args=["bad-input"] debug=true
3. (breakpoint hits)
4. variables variablesReference=1
5. continue
6. output
MIT