MCP server wrapping kd.exe for Windows kernel debugging over KDNET.
kd-mcp defines 16 tools with complete input schemas and descriptions. Naming follows verb_noun convention (kernel_attach, breakpoint_set, memory_read). Descriptions are detailed (100-300 chars) and explain WHAT the tool does and WHEN to use it. However, output schemas are not documented, tools return {status, output, data} but the structure and field types are not formally specified. Error handling is minimal; tools raise RuntimeError or TimeoutError without recovery guidance. No tool annotations (readOnlyHint, destructiveHint) despite clear risk classifications. Parameter descriptions are good but lack format constraints (e.g., 'hex string' should specify format). No pagination support for list-like operations.
Clear a breakpoint by ID or address. Args: id_or_addr: Breakpoint ID (e.g. "0") or address (e.g. "nt!NtCreateFile") Returns: {status, output}
List all active breakpoints ("bl" command).
Set a breakpoint at an address or symbol. Args: address: Address or symbol name (e.g. "nt!NtCreateFile", "0xfffff800deadbeef") type: "e" (execute, default), "r" (read), "w" (write), "io" (I/O) size: Breakpoint size in bytes (default 1) Returns: {status, output}
Disassemble code at an address ("u" command). Args: address: Address to disassemble from (e.g. "nt!NtCreateFile" or "0xfffff800deadbeef") length: Number of bytes to disassemble (default 64) Returns: {status, output}
Send an arbitrary kd.exe command and return the output. Args: command: Raw kd.exe command (e.g. "!process 0 0", "dt nt!_EPROCESS") timeout: Command timeout in seconds (default 20) Returns: {status, output}
Launch kd.exe and connect to a kernel over KDNET. kd.exe may exit immediately if the target is unreachable; this tool will respawn it until the full timeout expires so it catches the KDNET hello packet whenever the target becomes ready (e.g. after a VM reboot).
Output schemas not documented. Tools return {status, output, data} but field types, structure, and when 'data' is populated are not specified. LLMs cannot plan downstream operations or extract structured results.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk classifications. Tools marked DESTRUCTIVE (memory_write, register_write) should carry destructiveHint=true to signal irreversibility to agents.
Error handling lacks recovery guidance. RuntimeError and TimeoutError are raised but do not tell the LLM what to do next (retry? check connection? call a different tool?). No categorization of errors as retryable vs fatal.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 57 | 2026-07-28+ | v2 |
Send Ctrl+Break to the kernel debugger, halting execution. Useful when the kernel is running and you need to inspect state or set breakpoints. On KDNET, this sends a break-in packet over the network.
Resume kernel execution ("g" command).
Detach from the kernel and close kd.exe.
Single-step the kernel ("t" command).
Read memory from the kernel. Args: address: Address to read from (e.g. "0xfffff800deadbeef" or "nt!NtCreateFile") size: Number of bytes to read (default 256) format: "hex" (default), "ascii", "unicode", "dword", "qword" Returns: {status, output, data}
Write data to kernel memory. Args: address: Address to write to (e.g. "0xfffff800deadbeef") data: Hex string or ASCII string (e.g. "41 42 43" or "ABC") format: "hex" (default) or "ascii" Returns: {status, output}
Read CPU registers ("r" command). Args: filter: Optional register name filter (e.g. "rax", "r*", or empty for all) Returns: {status, output}
Write a CPU register. Args: register: Register name (e.g. "rax", "rcx") value: New value (e.g. "0x1234" or "1234") Returns: {status, output}
Print the stack trace ("k" command). Args: frames: Number of frames to show (default 10, 0 = all) Returns: {status, output}
Resolve a symbol to an address ("x" command). Args: symbol: Symbol pattern (e.g. "nt!NtCreateFile", "nt!*Create*") Returns: {status, output}
Parameter format constraints missing. 'format' parameters (hex, ascii, unicode, dword, qword) lack enum constraints; 'address' parameters accept symbols or hex but no regex/pattern is specified. LLMs may pass invalid values.
kd_command is a generic pass-through tool that accepts arbitrary kd.exe commands. This violates single-responsibility principle and makes it hard for LLMs to reason about what the tool does. Consider removing or restricting to a whitelist of safe commands.