An MCP server that provides remote debugging capabilities for x64dbg, enabling programmatic control of a debugger instance via HTTP and SSE transports.
This is a well-intentioned debugger MCP server with 28 tools covering a complex domain (x64dbg automation). Strengths: all tools have descriptions (10 - 100+ chars, reasonable length); all tools have schemas with parameter types; clear registration in ToolDef struct. Weaknesses: descriptions are functional but terse (avg ~80 chars, below production baseline of 194); several parameter descriptions are bare or generic ('text to echo', 'number of events'); output schemas are not documented for agents to understand return structures; error handling and recovery guidance are absent; no tool annotations (readOnlyHint, destructiveHint) despite clear semantic distinction between read-only, write, and destructive tools; some parameter design issues (e.g., 'byteString' in WriteMemToAddress is space-separated hex, format not stated); composition is reasonable but some tools could be combined (e.g., run + WaitForPause overlap). The codebase shows care in organization and the debugger domain is specialized, but production tooling would require richer descriptions, documented output schemas, and clearer error recovery paths.
Attaches the debugger to a running process by PID.
Clears the event log ring buffer.
Adds a comment or a label at a specific address in the disassembly.
Removes a breakpoint at an address or API symbol.
Disassembles instructions at an address. Returns instruction mnemonics with addresses. Default: 10 instructions from current IP.
Echoes the input back to the client.
Evaluates an x64dbg expression (address, register, arithmetic, symbol) and returns the result in hex and decimal.
Output schemas not documented. Agents cannot understand what fields each tool returns, forcing them to guess response structure and leading to misaligned downstream tool calls. Production tools must document return types with field names and types.
Tool annotations missing. The ToolDef struct includes 'read_only' and 'debug_only' flags but these are not surfaced as MCP toolAnnotations (readOnlyHint, destructiveHint, idempotentHint). This prevents agents and clients from reasoning about tool safety without parsing descriptions.
Terse parameter descriptions. Many parameters lack actionable context: 'text to echo' (Echo), 'number of events to return' (GetEventLog), 'text to search for' (SearchForStrings). Baseline is 72 chars; these are 15 - 25 chars. LLMs need constraints, format hints, and use-case guidance.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | <=2025-11-25 | v2 |
Executes a native x64dbg command string (like 'erun', 'analr', 'graph'). This is for x64dbg-internal commands ONLY — do NOT pass MCP tool names here. MCP tools (WaitForEvent, GetDebugState, Disassemble, etc.) must be called directly as tools.
Returns the current values of all general-purpose registers. Takes no arguments.
Returns the current thread's call stack. Takes no arguments.
Returns the current instruction pointer (EIP/RIP), the module it belongs to, and its label/comment. Takes no arguments.
Returns the current debugger state: whether a binary is loaded, whether it is running or paused, the PID, current instruction pointer, and current module. Always available. Takes no arguments.
Returns the last N debugger events (exceptions, breakpoints, DLL loads, thread events, etc.). Keeps the last 64 events in a ring buffer. Use this to see what happened in x64dbg.
Lists the available MCP tools, optionally filtered to a single category.
Loads an executable into the debugger for a new debugging session. Equivalent to File > Open in the GUI. If a session is already active it is terminated first. The debuggee pauses at the system breakpoint.
Pauses (suspends) the running debuggee, equivalent to Debug > Pause (F12). Takes no arguments.
Reads raw bytes from the target process memory and returns a hex dump with ASCII. Example: ReadMemory address=0x7FF600001000, size=128
Restarts the current debugging session from the beginning. Takes no arguments.
Searches process memory for a specific text string and returns the addresses where it occurs.
Sets a software execution breakpoint (INT3) at an address or API symbol.
Executes a single instruction, stepping INTO any call encountered (F7). Takes no arguments.
Runs until the current function returns to its caller (Ctrl+F9). Takes no arguments.
Executes a single instruction, stepping OVER any call/subroutine entirely (F8). Takes no arguments.
Terminates the current debugging session and closes the debuggee process. Takes no arguments.
Blocks until a debugger event fires (breakpoint hit, paused, resumed, exception, session start/stop) or timeout. Returns all events that occurred. Use this to monitor debugger state changes in real-time over HTTP — call it after 'run' or while waiting for the user to interact with the debugger.
Blocks until the debuggee stops running (hits a breakpoint, exception, or exits). Returns the reason for the pause and the current address. Use after 'run' to wait for the target to break.
Patches memory by writing raw hex bytes to an address. WARNING: this modifies the live process. Example: WriteMemToAddress address=0x12345678, byteString=0F FF 90
Resumes execution and waits for the target to pause (breakpoint, exception, or exit). Blocks until a pause event occurs or timeout. Use timeoutMs to control how long to wait (default 120s). Always returns the reason for the pause and current state.
No error recovery guidance. Tools like LoadBinary, AttachProcess, and SetBreakpoint perform state-changing operations but descriptions do not explain what can go wrong or how to recover. Error responses should guide the agent on retry strategy.
Bare tool name 'run' lacks verb clarity. Naming baseline is to start with action verbs (get_, create_, update_, etc.). 'run' is vague, does it execute code, run a query, or run a test? Rename to 'run_target' or 'resume_execution' for clarity.
Parameter format not specified. WriteMemToAddress accepts 'byteString' as 'space-separated hex bytes' but the description does not state the format explicitly. Agents may pass '0F,FF,90' or '0FFF90' instead of '0F FF 90', causing failures.
Overlapping tool semantics. WaitForPause and run both block until the debuggee stops, and WaitForEvent overlaps with both. Descriptions do not explain when to choose one over the other, forcing agents to reason about subtle differences.