← Discover MCPs and Agents
w
MCPAI & MLGitHub

windbg-mcp

C# MCP server for kernel & user-mode Windows debugging — DbgEng COM, KDNET, Frida, dbgsrv, TTD, and integrated VM control. 29 tools for LLM agents.

Links

README

From the repo.

WinDbg MCP Server

A Model Context Protocol (MCP) server that gives AI agents complete control over a Windows VM for kernel debugging, reverse engineering, malware analysis, and vulnerability research.

Built in C# (.NET 8), it wraps the Windows Debugger Engine (DbgEng COM), VMware Workstation, Frida, and dbgsrv into 29 MCP tools that any MCP-compatible LLM client can call.

Architecture Platform VMware License

Why this project?

Other WinDbg MCP servers exist — most are Python wrappers that launch cdb.exe or windbg.exe as a subprocess and drive it over stdin/stdout. That's easy to prototype but fragile in practice: the child debugger crashes, hangs on modal dialogs, deadlocks its own pipes, or dies mid-session and takes the agent's context with it.

This project takes a different approach:

  • Direct DbgEng COM — calls the Windows Debugger Engine natively through its COM interface. No subprocess to babysit, no stdout parsing, no hung pipes. Commands execute inside the server process on a dedicated MTA COM thread with an event pump — so the debugger can't drag the whole MCP server down with it.
  • Kernel debugging is the primary use case, not an afterthought — full KDNET integration: attach to a running kernel, set breakpoints, step, run any WinDbg command while the target is halted, wait for events with hard timeouts, detect BSODs, and pass first-chance exceptions through so Windows keeps running normally. Execution-control commands (g/t/p) are blocked in kd_execute so the LLM can't accidentally run away from a breakpoint — it has to use the explicit kd_continue/kd_step tools, which always return.
  • User-mode is covered too — Frida (with eternalized hooks for persistent instrumentation across sessions), dbgsrv for noninvasive process inspection with full WinDbg command access, and TTD (Time Travel Debugging) — all behind the same server.
  • VM lifecycle is integrated with the debug session — snapshot restore cleanly tears down KD/Frida/dbgsrv before reverting the VM; guest commands, file transfer, and process control are all gated on VM power state so the agent never trips on "wrong state" errors. vm_set_target lets a running server switch to a different VM at runtime.
  • Designed for LLM agents — every tool has a hard timeout (nothing blocks forever), every error message explicitly tells the LLM what to do next, and get_system_state gives the model a single "where am I?" snapshot on demand. A StateCoordinator validates preconditions before every call so the agent gets useful feedback instead of silent failures.

What Can It Do?

An LLM connected to this server can autonomously:

  • Control a VM — start, stop, pause, resume, snapshot, restore, screenshot
  • Kernel debug — connect via KDNET, set breakpoints, step, execute any WinDbg command, wait for events
  • Run commands in the guest — execute programs, transfer files, list/kill processes
  • User-mode debug — attach Frida to hook functions, inspect processes via dbgsrv, record TTD traces

All without the LLM ever needing direct access to WinDbg, a terminal, or the VM itself.

Quick Start

Prerequisites

RequirementPurpose
.NET 8 SDKBuild & run the server
VMware Workstation ProVM management (vmrun)
Windows Guest VMTarget for debugging
KDNET enabled in guestKernel debugging (see Setup)
frida-tools (optional)User-mode instrumentation
WinDbg Preview (optional)Provides dbgsrv.exe for remote user-mode debugging

1. Clone & Build

git clone https://github.com/memoryforensics1/windbg-mcp.git
cd windbg-mcp
dotnet build src/WinDbgMCP.Server/WinDbgMCP.Server.csproj

2. Configure (optional)

Everything in appsettings.json is just a default — the LLM can change VM target, credentials, KDNET key, and more at runtime via vm_set_target. Expand only if you want to set a starting config.

Copy src/WinDbgMCP.Server/appsettings.example.json to appsettings.json and edit:

{
  "Vm": {
    "VmxPath": "C:\\path\\to\\your\\vm.vmx",
    "VmrunPath": "C:\\Program Files (x86)\\VMware\\VMware Workstation\\vmrun.exe",
    "VmPassword": "",
    "GuestUsername": "YourUser",
    "GuestPassword": "YourPass"
  },
  "KernelDebug": {
    "Transport": "kdnet",
    "Kdnet": {
      "Port": 50000,
      "Key": "your.kdnet.key.here"
    },
    "SymbolPath": "srv*C:\\Symbols*https://msdl.microsoft.com/download/symbols"
  },
  "Guest": {
    "FridaPort": 27042,
    "DbgsrvPort": 5064
  }
}

3. Add to Your MCP Client

Claude Code (.mcp.json in project root):

{
  "mcpServers": {
    "windbg-mcp": {
      "command": "dotnet",
      "args": ["run", "--project", "C:\\path\\to\\windbg-mcp\\src\\WinDbgMCP.Server\\WinDbgMCP.Server.csproj"]
    }
  }
}

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "windbg-mcp": {
      "command": "C:\\Program Files\\dotnet\\dotnet.exe",
      "args": ["run", "--project", "C:\\path\\to\\windbg-mcp\\src\\WinDbgMCP.Server\\WinDbgMCP.Server.csproj"]
    }
  }
}

4. Run

The server starts automatically when your MCP client connects. It communicates over stdio.

# Or run standalone for testing
dotnet run --project src/WinDbgMCP.Server/WinDbgMCP.Server.csproj

Tool Catalog (29 tools)

Meta

ToolDescription
get_system_stateFull state overview — VM power, KD, guest ops, UMD. Always allowed.

VM Tools (8)

ToolDescription
vm_startPower on the VM
vm_stopShut down (graceful or hard)
vm_pauseFreeze entire VM
vm_resumeUnpause a paused VM
vm_snapshot_restoreRestore a named snapshot (debug sessions are cleanly torn down and can reconnect after)
vm_snapshot_listList available snapshots
vm_screenshotCapture VM display as PNG
vm_set_targetSwitch the active VM target at runtime (VMX path + credentials)

Kernel Debug Tools (7)

ToolDescription
kd_connectAttach to kernel via KDNET. Target breaks on connect.
kd_disconnectDetach from kernel. Resumes target so VM keeps running.
kd_breakHalt running target (Ctrl+Break)
kd_continueResume target execution
kd_stepStep one instruction (into or over)
kd_executeRun any WinDbg command (k, r, lm, !process 0 0, !analyze -v, etc.)
kd_wait_for_eventWait for breakpoint/exception with timeout. Always returns.

Guest Tools (5)

ToolDescription
guest_run_commandExecute command in guest OS, capture stdout/stderr
guest_transfer_to_vmCopy file from host to guest
guest_transfer_from_vmCopy file from guest to host
guest_list_processesList running processes with PIDs
guest_kill_processKill a process by PID

User-Mode Debug Tools (8)

ToolDescription
umd_frida_attachAttach Frida to a guest process
umd_fridaInject JS, eval expressions, list processes, detach
umd_frida_skillFrida best practices and API reference for LLMs
umd_dbgsrv_connectConnect to remote dbgsrv in guest
umd_dbgsrv_executeAttach to PID, run WinDbg commands, detach
umd_dbgsrv_skilldbgsrv best practices and WinDbg command reference for LLMs
umd_ttdTime Travel Debugging — record, stop, retrieve, list traces
umd_ttd_queryQuery TTD traces (not yet implemented)

Example Workflows

Inspect a Running Kernel

get_system_state
kd_connect
kd_execute("lm")                    # list loaded modules
kd_execute("!process 0 0")          # list all processes
kd_execute("vertarget")             # target version info
kd_disconnect

Set Breakpoint and Catch It

kd_connect
kd_execute("bp nt!NtCreateFile")    # set breakpoint
kd_continue                          # let target run
kd_wait_for_event(30)               # wait up to 30s for hit
kd_execute("k")                     # show call stack
kd_execute("r")                     # show registers
kd_disconnect

Deploy and Debug a Driver

guest_transfer_to_vm("MyDriver.sys", "C:\\Windows\\System32\\drivers\\MyDriver.sys")
guest_run_command("sc create MyDrv type= kernel binPath= C:\\Windows\\System32\\drivers\\MyDriver.sys")
guest_run_command("sc start MyDrv")
kd_connect
kd_execute("lm m MyDrv")            # verify driver loaded
kd_execute("bp MyDrv!DriverEntry")
kd_disconnect

Hook a Function with Frida

umd_frida_skill                      # read best practices first
umd_frida_attach(processName="target.exe")
umd_frida(action="eval", code="Process.enumerateModules().map(m=>m.name)")
umd_frida(action="inject", code="""
  Interceptor.attach(Module.getExportByName('kernel32.dll','CreateFileW'), {
    onEnter(args) { console.log('CreateFileW: ' + args[0].readUtf16String()); }
  });
  console.log('Hook installed');
""", timeoutSeconds=10)
umd_frida(action="detach")

Inspect a Process with dbgsrv

umd_dbgsrv_skill                     # read best practices first
guest_run_command("start /b C:\\Tools\\DbgSrv\\dbgsrv.exe -t tcp:port=5064")
umd_dbgsrv_connect(vmIpAddress="192.168.x.x")
umd_dbgsrv_execute(action="attach", argument="<PID>")
umd_dbgsrv_execute(action="command", argument="lm")
umd_dbgsrv_execute(action="command", argument="!peb")
umd_dbgsrv_execute(action="command", argument="~*k")
umd_dbgsrv_execute(action="detach")
umd_dbgsrv_execute(action="disconnect")

Crash Analysis

kd_connect                           # connect after BSOD
kd_execute("!analyze -v")           # automated crash analysis
kd_execute("k")                     # faulting stack
kd_execute("r")                     # registers at crash
kd_execute(".trap")                 # switch to trap frame
kd_disconnect

Architecture

┌─────────────────────────────────────────────────────────────┐
│                      MCP Client (LLM)                       │
│                  Claude Code / Claude Desktop                │
└──────────────────────────┬──────────────────────────────────┘
                           │ stdio (JSON-RPC)
┌──────────────────────────▼──────────────────────────────────┐
│                    WinDbgMCP.Server                          │
│                                                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐  │
│  │  VM Tools    │  │  KD Tools    │  │  Guest Tools     │  │
│  │  (vmrun)     │  │  (DbgEng)    │  │  (vmrun guest)   │  │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────────┘  │
│         │                 │                  │               │
│  ┌──────▼───────┐  ┌──────▼───────┐  ┌──────▼───────────┐  │
│  │ VmwareManager│  │ DbgEngManager│  │ GuestExecManager │  │
│  └──────────────┘  └──────┬───────┘  └──────────────────┘  │
│                           │                                  │
│  ┌────────────────────────▼─────────────────────────────┐   │
│  │              StateCoordinator                         │   │
│  │   (precondition gate — validates every tool call)     │   │
│  └───────────────────────────────────────────────────────┘   │
│                                                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐  │
│  │ UMD: Frida   │  │ UMD: dbgsrv  │  │ UMD: TTD         │  │
│  │ (frida CLI)  │  │ (DbgEng COM) │  │ (TTD.exe)        │  │
│  └──────────────┘  └──────────────┘  └──────────────────┘  │
└──────────────────────────────────────────────────────────────┘
         │                    │                    │
         ▼                    ▼                    ▼
┌─────────────────────────────────────────────────────────────┐
│                   Windows Guest VM                           │
│              (VMware Workstation Pro)                         │
│                                                              │
│  KDNET (:50000)  │  frida-server (:27042)  │  dbgsrv (:5064)│
└─────────────────────────────────────────────────────────────┘

Key Design Principles

  1. Every tool validates preconditionsStateCoordinator checks VM power, KD state, guest ops availability before any operation executes
  2. Every operation has a timeout — no blocking calls, ever. The LLM never hangs.
  3. Error messages are prompts — every error tells the LLM exactly what to do next
  4. Execution-control commands are blockedg, t, p are blocked in kd_execute; use kd_continue/kd_step instead
  5. DbgEng COM thread affinity — all COM calls marshaled to a dedicated MTA thread with an event pump
  6. BSOD detection — bugchecks are detected and handled differently from normal breakpoints
  7. Snapshot restore resets everything — KD, Frida, dbgsrv sessions are all cleaned up

VM Setup

Enable KDNET (Kernel Debugging)

In the guest VM (elevated cmd):

bcdedit /debug on
bcdedit /dbgsettings net hostip:<HOST_IP> port:50000 key:<YOUR_KEY>
shutdown /r /t 0

Generate a key with kdnet.exe from the Windows SDK, or use any dotted-quad format key.

Install Frida Server (Optional)

On the host:

pip install frida-tools

Download frida-server-<version>-windows-x86_64.exe from Frida releases, deploy to guest as C:\Tools\frida-server.exe, and run:

frida-server.exe -l 0.0.0.0:27042

Install dbgsrv (Optional)

Copy dbgsrv.exe, dbgeng.dll, and dbghelp.dll from WinDbg Preview (or Windows SDK) to the guest, then run:

dbgsrv.exe -t tcp:port=5064

Firewall

The host firewall must allow:

  • UDP port 50000 inbound (KDNET)
  • TCP port 27042 outbound (Frida)
  • TCP port 5064 outbound (dbgsrv)

Project Structure

src/WinDbgMCP.Server/
├── Program.cs                    # Entry point, MCP server setup, DI
├── appsettings.json              # Configuration (VM creds, KDNET, timeouts)
├── Configuration/
│   └── ServerConfig.cs           # Typed configuration model
├── State/
│   ├── SystemState.cs            # State model + enums
│   ├── StateCoordinator.cs       # Precondition gate (heart of system)
│   ├── ErrorMessages.cs          # LLM-friendly error catalog
│   └── ToolResult.cs             # Result type
├── Vmware/
│   └── VmwareManager.cs          # vmrun wrapper
├── KernelDebug/
│   ├── DbgEngThread.cs           # Dedicated MTA thread for COM
│   ├── DbgEngManager.cs          # Kernel debug session manager
│   ├── DebugEventCallbacks.cs    # Breakpoint/exception/module events
│   ├── OutputCapture.cs          # Command output capture
│   └── Interop/                  # P/Invoke, constants
├── Guest/
│   └── GuestExecManager.cs       # Guest command execution + file transfer
├── UserModeDebug/
│   ├── FridaManager.cs           # Frida CLI wrapper
│   ├── DbgsrvManager.cs          # Remote user-mode debugging via dbgsrv
│   └── TtdManager.cs             # Time Travel Debugging
└── Tools/
    ├── VmTools.cs                # vm_* tools
    ├── KernelDebugTools.cs       # kd_* tools
    ├── GuestTools.cs             # guest_* tools
    ├── UserModeDebugTools.cs     # umd_* tools
    └── MetaTools.cs              # get_system_state

src/WinDbgMCP.Tests/              # Unit tests (126 tests)

Running Tests

dotnet test src/WinDbgMCP.Tests/WinDbgMCP.Tests.csproj

Tech Stack

ComponentTechnology
Runtime.NET 8 (C#)
MCP SDKModelContextProtocol 0.1.0-preview.12
DbgEngNative COM interop (dbgeng.dll)
VM ControlVMware vmrun CLI
User-Mode HookingFrida (frida-tools Python CLI)
Remote Debuggingdbgsrv.exe (WinDbg component)
TTDTTD.exe (Time Travel Debugging)

License

MIT

Collected info

  • 40 stars
  • 7 forks
  • Language: C#
  • Source updated: 8/19/2026

Config for your environment

Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.

Tool

OS

Config file: ~/.cursor/mcp.json

{
  "mcpServers": {
    "mcp-server": {
      "url": "{MCP_ENDPOINT_URL}"
    }
  }
}

Paste into mcpServers in the config file. Restart Cursor after saving.

If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.