MCP server for x64dbg debugger integration, providing tools for debugging control, register manipulation, memory access, breakpoints, and code analysis
This x64dbg MCP server provides 21 well-organized debugging tools with explicit schemas and descriptions. Tool naming follows verb_noun conventions consistently (debug_*, register_*, memory_*). However, several definition quality gaps prevent a higher score: (1) Many parameter descriptions lack specificity about format constraints, allowed ranges, or when to use each tool instead of similar ones. (2) No output schemas are documented, LLMs cannot predict what fields to expect from tool responses, blocking downstream tool chaining. (3) No error handling guidance is visible, tools lack recovery instructions if calls fail. (4) Tool descriptions are adequate (100-300 chars) but some lack 'when to use' context. (5) Parameter descriptions are present but often minimal (15-40 chars), missing format/range guidance. Example: 'register_get' returns a register value but the output structure is undocumented. The server demonstrates solid baseline quality with clear naming and present-but-sparse documentation, landing in the 'Fair' range (60-69) typical of community servers.
Assemble x86/x64 instructions into machine code
Attach debugger to an already-running process by PID. Uses DbgCmdExec(attach) + WaitForPause + DbgIsDebugging check. Prefer over script_execute('attach'). For PonPon: LEProc start + inject first, x32dbg already open.
Get current debugger state (stopped/running/paused) and instruction pointer
Start a new debug session by loading an executable (equivalent to x64dbg/x32dbg's 'Run' button). Works regardless of current debug state — use this to relaunch the target after a crash, exit, or manual stop. If 'path' is omitted, falls back to the most recently observed debuggee path.
Pause program execution
Restart debugging session. Works even after the debuggee has exited/crashed as long as the target path has been observed in the current plugin session.
No output schemas documented. Tools like register_get, memory_read, function.list lack documented return structures. LLMs cannot predict field names/types for downstream chaining.
No error handling guidance. Tools provide no recovery instructions if they fail (e.g., 'Address not found, try memory_read at a nearby address' or 'PID does not exist, check process list with system tools'). Agents cannot self-recover.
Parameter descriptions too sparse. Many parameters (e.g., 'address', 'size', 'data') lack format/constraint detail. 'address' appears in 7 tools with identical vague description; should specify 'hex format (0x…), 1 - 8 chars for x64' or similar. Agents hallucinate invalid formats.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 68 | <=2025-11-25 | v2 |
| 2026-03-09 | D | 53 | 2024-11-05+ | v1 |
Continue execution until next breakpoint or exception
Run until reaching specified address
Execute single instruction (step into calls)
Execute until return from current function
Execute single instruction (step over calls)
Stop debugging and close target process
Get function information for a specific address
List all functions with their metadata
Read memory from specified address
Write data to memory
Read value of a single register
Read multiple registers at once
List all registers with their current values
Write value to a register
Get cross-references for an address
Dot notation in tool names (xref.get, function.list, function.get) is non-standard. Should be xref_get, function_list, function_get. Dots can confuse command-line parsing and tool routers.
No 'when to use' guidance in descriptions. Similar tools (debug_step_into vs debug_step_over, register_get vs register_list, function.get vs function.list) lack context distinguishing them. LLMs may pick wrong tool.
No batch operation limits documented. register_get_batch and memory_read accept arrays/sizes with no stated upper limit. Large requests could timeout or exhaust memory.
State dependencies undocumented. Many tools (debug_step_into, debug_run_to, memory_write) require the debugger to be in a specific state (paused, attached). Calling them with wrong state silently fails or returns misleading errors.
No mutual exclusion documented for debug_init vs debug_attach_pid. Both start a debug session; guidance on when to use each is missing.