MCP server that forwards a 32-bit x96dbg debugger session to MCP-aware clients, enabling debugger tooling access from editors like Cursor and VS Code without leaving the editor
Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
X96Dbg MCP Server provides 21 debugger-oriented tools with reasonable naming conventions and basic descriptions. However, the implementation exhibits significant gaps in parameter documentation, output schema clarity, and error handling guidance. While tool names follow verb-first conventions (readMemory, writeMemory, listModules, getRegisters), many parameter descriptions are minimal or absent. Output schemas are not explicitly documented in the visible source code, responses are wrapped in a generic envelope with 'content' and 'structured' fields, but the actual return types for each tool are not clearly specified. Error handling is minimal: there is no guidance for recovery, no categorization of error types (retryable vs. fatal), and no actionable error messages. The code shows basic structure and covers a coherent domain (32-bit debugger introspection), but falls short of production-grade tool quality. Average tool score: 58/100.
Tools (21)
deleteBreakpointwritesource verified62/100
Delete a breakpoint.
disableBreakpointwritesource verified62/100
Disable a breakpoint.
enableBreakpointwritesource verified62/100
Enable a breakpoint.
getDisassemblyread onlysource verified70/100
Disassemble up to 64 instructions from an address.
Many parameter descriptions are missing or minimal. Tools like getExports, getImports, getRegisters, getThreads lack detailed input documentation. LLMs cannot infer whether 'module' accepts base address hex format, module name string, or both.
Output schemas are not documented for any tool. The code wraps responses in a generic envelope with 'content' and 'structured' fields, but what fields does listModules return? What is the structure of getThreads output? LLMs need documented return types to plan downstream calls.
Add detailed parameter descriptions to every tool. For 'address' parameters, specify: 'Hex string (with 0x prefix) or decimal integer. 32-bit address space only (0x00000000 to 0xFFFFFFFF).' For 'module' parameters, clarify: 'Module name (string, e.g. 'kernel32.dll') or base address (hex string, e.g. 0x00400000). The tool resolves either format.'
Document output schemas explicitly. For each tool, add a 'Returns' or 'Output' section describing field types. Example for listModules: 'Returns: array of {moduleName: string, baseAddress: string (hex), size: integer, entryPoint: string (hex), sections: array of {name: string, virtualAddress: string (hex), virtualSize: integer}}'.
Add error handling guidance to all tools. Example for readMemory: 'Error: AddressInvalid, address is outside the debuggee address space. Verify the address is within the module bounds returned by listModules(). Retryable: yes, with a corrected address. Error: ProcessNotPaused, the debuggee is running. Pause it in x96dbg and retry. Retryable: yes.'
Convert the 'type' parameter of setBreakpoint to a formal enum constraint in the JSON Schema. Declare: {'type': 'string', 'enum': ['normal', 'hardware', 'memory', 'dll', 'exception'], 'description': 'Breakpoint type. Choose from: normal (standard code breakpoint), hardware (CPU-assisted breakpoint), memory (page protection breakpoint), dll (module load breakpoint), exception (exception breakpoint)'}.
Add pagination to list-style tools. Extend listModules, listBreakpoints, getExports, getImports with optional parameters 'limit' (default 50, max 200) and 'offset' (default 0). Return a 'totalCount' field so the agent knows if more results exist.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Score history
Overall score trend
↑ 50 points across a rubric change (v1 → v2)
50/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
D
50
<=2025-11-25
v2
2026-03-09
F
0
-
v1
Snapshot general, debug, and flag registers.
getThreadsread onlysource verified47/100
Inspect debugger threads, priorities, wait reasons, and CIP.
getTraceRecordread onlysource verified53/100
Retrieve trace record data.
listBreakpointsread onlysource verified50/100
List all x96dbg breakpoints.
listModulesread onlysource verified53/100
Enumerate loaded modules with base, size, entry, and sections.
memBpSizeread onlysource verified47/100
Helper for memory-breakpoint diagnostics.
memIsCodePageread onlysource verified57/100
Query whether an address is a code page.
patternScanread onlysource verified73/100
Binary pattern search with wildcard support.
pingread onlysource verified43/100
Lightweight health check.
readMemoryread onlysource verified76/100
Dump bytes from the target address space (max 4 KB per call).
runTracewritesource verified40/100
Helper for trace and memory-breakpoint diagnostics.
setBreakpointwritesource verified70/100
Set a breakpoint at an address.
setPageRightswritesource verified62/100
Modify memory protections.
writeMemorywritesource verified73/100
Patch bytes with optional temporary page-rights escalation.
No error handling guidance. Tools do not document what errors can occur, whether they are retryable, or what the LLM should do next. Example: if readMemory fails with 'address out of bounds', should the agent retry, ask the user, or abandon the plan?
Parameter 'address' is used in many tools (readMemory, writeMemory, getDisassembly, setBreakpoint, etc.) but its acceptable format is not clearly documented. The description says 'hex string or integer' but does not specify endianness, prefix format (0x vs bare hex), or bit width (32-bit only per the overview).
Ambiguous tool names: memBpSize, runTrace, getTraceRecord do not clearly convey their purpose. 'memBpSize' appears to be 'memory breakpoint size' but that is unclear. 'runTrace' vs 'getTraceRecord' suggests duplicate responsibility without clear distinction.
No pagination documented for list-style tools. listModules, listBreakpoints, and getImports/getExports may return large result sets, but there is no mention of limit/offset parameters or result counts. Without pagination, large results can exhaust the LLM context window.
The 'type' parameter in setBreakpoint (accepts 'normal, hardware, memory, dll, exception') is an enum but not declared as such in the schema. Free-form string input invites invalid values. The description should list allowed enum values and declare the parameter as type:string with enum constraint.
No documentation of prerequisites or dependencies. Many tools require the debuggee to be paused (mentioned in overview resource but not in tool descriptions). Tools should state 'Requires: debuggee paused' or 'Requires: breakpoint set' in descriptions so LLMs know when to call them.
No confirmation pattern for destructive operations. writeMemory, deleteBreakpoint, and setPageRights modify state but do not support dry-run or confirmation. Agents can accidentally corrupt memory or delete critical breakpoints without verification.
writeMemorydeleteBreakpointsetPageRights
Rename ambiguous tools for clarity. Rename 'memBpSize' to 'getMemoryBreakpointSize' (action + target). Distinguish 'runTrace' and 'getTraceRecord': if runTrace starts a trace and getTraceRecord retrieves results, describe both clearly. If they overlap, merge them into one 'queryTraceData' tool or split them into non-overlapping concerns.
Document prerequisites in every tool description. Add: 'Prerequisites: debuggee is paused in x96dbg. If you need to pause the debuggee, call a separate 'pause' or 'break' tool first (if exposed by the server).'
Implement a 'dry-run' or 'confirm' pattern for destructive tools. Add optional parameter 'dryRun: boolean (default false)' to writeMemory, deleteBreakpoint, setPageRights. When true, return what would happen without executing. Pair with an explicit confirmation step before execution.
Add 'readable' parameter to readMemory to enforce alignment and size constraints: 'size must be 1 - 4096 bytes; address should be aligned to word boundary (multiples of 4).' Return actionable error if violated: 'Invalid size: 5000 > max 4096. Retry with size ≤ 4096 bytes.'
Provide chaining IDs in list responses. When listModules returns modules, include 'baseAddress' (hex) so agent can immediately call getExports/getImports with that address without a second lookup. Similarly, listBreakpoints should return 'address' (hex) for setBreakpoint follow-ups.