mcp server
ReverseMCP
Native C++23 MCP server for PE analysis, process memory, Zydis disassembly, and Win32 debugging.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 25, 2026ReverseMCP
ReverseMCP is a native C++23 Model Context Protocol server for reverse-engineering work on Windows. It gives an MCP client structured access to PE files, game-engine installations, Unity IL2CPP metadata, live process memory, x86/x64 disassembly, breakpoints, thread state, stack traces, and persistent analyst annotations.
The repository contains both parts of the system:
- a native execution layer with 49 bounded MCP tools;
- a knowledge layer with focused skills for native binaries, debuggers, protected code, managed runtimes, and popular game engines.
The executable and internal C++ namespace retain the name reverseplugin for compatibility. ReverseMCP is the project and distribution name.
At a glance
- 49 MCP tools with explicit input and output JSON Schemas.
- 12 focused analysis Skills.
- Static PE analysis, Zydis-backed x86/x64 disassembly, and SSA-backed C-like pseudocode.
- Unity IL2CPP metadata v38/v39 with token-to-native-RVA mapping.
- Installation discovery for seven engine families.
- Validated process-memory access and a native Windows debugger.
- Content-addressed analysis cache and persistent annotations.
- No IDA Pro, Python runtime, injected DLL, or game launch required for static workflows.
Download
Prebuilt Windows releases contain the MCP executable, plugin manifest, Skills, documentation, and third-party notices:
Extract the archive and point the MCP client at build/release/Release/reverseplugin-mcp.exe. Build from source when changing the SDK or native tools.
Why this exists
General-purpose shell tools force an agent to parse unstable text output and repeatedly reconstruct analysis state. ReverseMCP exposes addresses, instructions, operands, references, registers, memory regions, and debugger events as typed JSON. Static results are keyed by the binary SHA-256, so an unchanged file can reuse previous function discovery, xrefs, strings, CFGs, names, comments, and types.
ReverseMCP is intended for agent-driven investigations where a graphical disassembler is unavailable or unnecessary. It replaces the common IDA MCP loop for PE triage, navigation, call-graph traversal, structured disassembly, function-level data flow, annotation, live memory, and native debugging. It does not claim feature parity with IDA Pro or Hex-Rays. The native decompiler does not recover original source or guarantee source-level types, structured exception constructs, switch reconstruction, or complete vector and floating-point semantics. GUI database import, ELF/Mach-O loading, ARM decoding, and an IDB bridge remain outside the current contract.
Capabilities
Static PE analysis
- PE32 and PE32+ validation without executing the input file.
- Sections, imports, exports, ordinals, forwarded exports, image layout, and entry point.
- File-backed reads and Zydis disassembly by RVA or virtual address.
- Structured instructions: exact bytes, mnemonic, operands, categories, branch type, relative targets, and register access.
- Wildcard AOB scans over file-backed sections.
- ASCII and UTF-16LE string indexing.
- Direct call, jump, immediate, and RIP-relative data references.
- Function discovery from the entry point, exports, x64 unwind records, and recursively reached direct calls.
- Bounded control-flow graphs, typed edges, basic blocks, and call graph data.
- x86/x64 semantic lifting with canonical register slices, pruned inter-block SSA, memory SSA alias sets, phi nodes, natural-loop and conditional-region recovery, normalized stack variables, ABI parameter candidates, type and field evidence, and per-statement confidence.
- PE exception-directory boundaries prevent x64 tail calls and neighboring functions from being merged into one CFG; import and export symbols are propagated into call targets.
- Unsupported semantics remain visible as address-linked intrinsics instead of being silently guessed.
- Persistent names, comments, and type declarations isolated by content hash and overlaid on cached decompilation results without invalidating deterministic analysis.
Runtime memory
- Process discovery and cached read-only process handles.
- Loaded module inventory with exact base addresses and image sizes.
- Virtual memory maps with normalized permissions.
- Validated reads that reject unreadable, guarded, or uncommitted pages.
- Writes restricted to already writable committed pages, with old-byte capture and optional read-back verification.
- Pointer-chain traversal with signed offsets and x86/x64 pointer widths.
- Chunked wildcard AOB scans with cross-chunk matching.
- Typed unknown-value snapshots with iterative changed, unchanged, increased, and decreased filters.
- Live structured disassembly in Intel or AT&T syntax.
Native debugger
- Win32 attach and detach without terminating the target.
- Managed
INT3software breakpoints with original-byte restoration and reinsertion. - Per-thread DR0–DR3 execute, write, and read/write hardware breakpoints.
- Asynchronous debugger events; waiting never blocks the MCP input loop.
- Register contexts, thread enumeration, ownership-tracked suspend/resume, and single-step.
- DbgHelp stack walking with modules, symbols, displacements, instruction pointers, stack pointers, and frame pointers.
Unity IL2CPP
- Compact
global-metadata.datv38/v39 parsing with strict section and record validation. - Static x86-64
GameAssembly.dllcode-registration discovery without loading or executing the game. - Managed image, namespace, type, field, method, parameter, token, flag, and slot records.
- Method-token resolution through per-image code-generation modules to native RVA and preferred VA.
- Bounded filtered queries for interactive work and atomic JSONL export for complete dumps.
- In-process workspace reuse keyed by canonical paths, sizes, and modification times; SHA-256 identities are returned for both inputs.
Game-engine workspaces
- Evidence-ranked detection for Unity, Unreal Engine, Godot, Source, Source 2, CRYENGINE, and Cocos2d-x.
- Read-only bounded traversal with explicit depth, examined-file, and retained-artifact limits.
- Structured indexes for native modules, managed assemblies, containers, cooked assets, metadata, symbols, scripts, shaders, and configuration.
- Header validation for PE, Valve VPK, and standalone or executable-embedded Godot PCK files.
- Explicit PAK and Unreal IoStore classification without pretending to decrypt or enumerate protected container indexes.
- Engine-specific Skills route the artifact inventory into reflection, runtime, and static-binary workflows.
Engine coverage
| Engine | Native support | Current boundary |
|---|---|---|
| Unity | Mono/IL2CPP detection, module and asset inventory, IL2CPP v38/v39 metadata dump, method RVA mapping | Native mapping currently targets matching Windows x86-64 GameAssembly.dll files |
| Unreal Engine | UE4/UE5 layout detection, module/PDB inventory, cooked assets, PAK and IoStore classification | Encrypted indexes and runtime UObject reflection require authorized keys or live analysis |
| Godot | Godot 3/4 detection, scripts, extensions, standalone and embedded PCK header parsing | Encrypted PCK directories are identified but not decrypted |
| Source / Source 2 | Generation-specific module evidence, VPK validation, compiled-resource inventory | Entity tables and SchemaSystem layouts are recovered from the target build rather than assumed |
| CRYENGINE | CrySystem/GameSDK detection, module, configuration, shader, level, and CryPak inventory | Signed or encrypted PAK content is not bypassed |
| Cocos2d-x | Native module, script, shader, asset, and binding-oriented inventory | Statically linked builds require corroborating strings, symbols, or runtime evidence |
Knowledge skills
The native server performs deterministic work. Skills describe how an agent should combine those primitives and how to validate version-sensitive assumptions.
reverse-analysis— router, evidence rules, and shared operating procedure.native-binary-triage— loader-first PE, ELF, and Mach-O triage and toolchain recognition.decompiler-guided-analysis— ABI, data-flow, types, vtables, and indirect calls.runtime-debugging— reproducible breakpoint-driven investigations.protected-binary-analysis— packers, anti-debugging, self-modification, control-flow flattening, and virtualized code.unity-il2cpp-analysis— Mono and IL2CPP metadata, registrations, objects, methods, and assets.unreal-engine-analysis— UObject reflection, names, object arrays, functions, Blueprints, PAK, and IoStore.godot-engine-analysis— ClassDB, Object/Variant, GDScript, GDExtension, resources, and PCK.source-engine-analysis— Source and Source 2 interfaces, entities, network metadata, schemas, BSP, and VPK.cryengine-analysis— CrySystem, gEnv subsystems, entities, plugins, configuration, levels, and CryPak.cocos2d-x-analysis— Cocos2d-x native scenes, Ref ownership, resources, and Lua/JavaScript bindings.managed-runtime-analysis— CLI metadata, .NET and Mono JIT, ReadyToRun, trimming, single-file applications, and NativeAOT.
See the knowledge-base design for the source and extension policy.
Requirements
- Windows 10 or 11, x64 host.
- Visual Studio 2022 with the Desktop development with C++ workload.
- CMake 3.25 or newer.
- Python 3 for knowledge-skill validation.
- Git, required by CMake when fetching Zydis.
The first configure downloads pinned versions of Zydis 4.1.1 and JSON for Modern C++ 3.11.3. Later builds reuse CMake's dependency checkout.
Build and test
From a Visual Studio developer shell or PowerShell with MSVC available:
git clone https://github.com/Stingeer01/ReverseMCP.git
Set-Location ReverseMCP
./scripts/build.ps1
The server is written to:
build/release/Release/reverseplugin-mcp.exe
Run the complete test suite independently with:
ctest --preset release
The test preset covers MCP framing and schemas, PE parsing, cache round-trips, CFG recovery, semantic lifting, memory access, Zydis decoding, stack walking, a real child-process debugger integration test, all twelve skills, and the stress suite.
The engine suite also validates Unity IL2CPP, Source 2, and Godot PCK detection using isolated fixtures.
Connect an MCP client
The repository is already a Codex plugin. Its .mcp.json starts the release executable through ${CURSOR_PLUGIN_ROOT}. For another MCP client, use the equivalent absolute path:
{
"mcpServers": {
"reverseplugin": {
"type": "stdio",
"command": "C:/absolute/path/to/ReverseMCP/build/release/Release/reverseplugin-mcp.exe",
"args": [],
"cwd": "C:/absolute/path/to/ReverseMCP"
}
}
}
Transport is newline-delimited JSON-RPC 2.0 over standard input and output. Diagnostics go to standard error so they cannot corrupt protocol frames. The server implements MCP initialization, ping, tool discovery, and tool calls. Tool work runs on a fixed worker pool rather than the input thread.
After connecting, call get_server_info to confirm the server version and compiled modules. Use MCP tools/list as the canonical contract; the prose reference intentionally omits low-level schema repetition.
Typical workflows
Analyze a binary without running it
- Call
open_binarywith the executable or DLL path. - Read sections, imports, and exports with
get_binary_index. - Run
discover_binary_functionsandfind_binary_strings. - Follow targets with
find_binary_xrefsandanalyze_binary_function. - Call
decompile_binary_function; use SSA values, phi nodes, memory alias sets, control regions, and type/field evidence before reading the rendered pseudocode. Inspect everypartialorunmodeledstatement against its source instruction. - Save conclusions through
set_binary_annotation. - Call
close_binarywhen the in-memory workspace is no longer needed.
All stable identities are RVAs. Virtual addresses are also returned for display. Addresses are serialized as hexadecimal strings to avoid JSON and model precision loss.
Dump a Unity IL2CPP build
- Call
open_il2cpp_workspacewithglobal-metadata.datand the matchingGameAssembly.dll. - Select an image, namespace, or type with
dump_il2cpp_types. - Use each method's
native_rvafor static reads, xrefs, CFG recovery, and annotations in the ordinary PE workspace. - Use
export_il2cpp_jsonlfor a complete streaming dump that does not retain a second JSON tree in memory. - Call
close_il2cpp_workspacewhen the metadata buffers are no longer needed.
Native addresses are reported only when the code-generation module contains a file-backed pointer. Runtime-initialized pointers remain null; the server does not invent an address.
Identify and inventory another engine
- Call
open_engine_workspacewith the game installation root. - Review every candidate and its evidence instead of trusting the top label in isolation.
- Filter modules, packages, metadata, scripts, or symbols with
list_engine_artifacts. - Validate a selected file with
inspect_engine_artifact; pass PE modules toopen_binaryfor code analysis. - Continue through the matching engine Skill, then release the index with
close_engine_workspace.
Inspect a running process
- Narrow
list_processesby executable name. - Call
attach_process; this requests query and memory-read rights only. - Use
list_modulesandquery_memory_regionsto establish a valid range. - Read, scan, follow pointers, or disassemble within that range.
- Call
detach_processto release the cached handle.
write_memory is explicit and separate. It never changes page protection and can only write to committed pages that are already writable.
Debug a process
- Call
debug_attachto create an independent debugger session. - Set a software or hardware breakpoint.
- Use
wait_debug_eventuntil the target pauses. - Inspect registers, threads, the stack trace, and nearby instructions.
- Call
continue_debug_eventorsingle_step. - Always finish with
debug_detach.
Read-only session_id values and debugger debug_session_id values have different lifecycles. They cannot be used interchangeably.
Tool reference
ReverseMCP exposes 49 tools. TOOLS.md groups them by lifecycle and documents their limits, mutability, and expected use. Every tool also publishes its exact input and output JSON Schemas through MCP tools/list; those runtime schemas are the canonical machine-readable contract.
The four main state scopes are intentionally separate:
binary_idfor immutable PE analysis;workspace_idfor engine or IL2CPP indexes, within the tool family that created it;session_idfor read-only process access;debug_session_idfor debugger-owned execution state.
Architecture
flowchart LR
Client[MCP client] -->|JSON-RPC over stdio| Server[MCP server]
Server --> Pool[Fixed worker pool]
Pool --> Tools[Tool registry]
Tools --> Static[Immutable PE workspaces]
Tools --> Memory[Validated process sessions]
Tools --> Debugger[Dedicated debugger event loop]
Tools --> IL2CPP[IL2CPP metadata and code registration]
Tools --> Engines[Engine artifact workspaces]
Static --> Zydis[Zydis decoder]
Zydis --> Lifter[Semantic lifter and pseudocode]
Memory --> Zydis
Static --> Cache[SHA-256 persistent cache]
Skills[Focused analysis skills] -. guide .-> Client
The boundaries are deliberate:
src/mcpowns framing, JSON-RPC dispatch, schema discovery, and result envelopes.src/toolstranslates MCP requests into typed domain operations.src/analysisowns immutable images, discovery, CFG recovery, semantic lifting, annotations, and persistent cache records.src/processandsrc/memoryown Win32 handles, page validation, scans, and snapshots.src/debugowns the debugger thread, breakpoints, register state, and stack walking.src/disasmis the Zydis adapter.src/il2cppowns compact metadata parsing, PE registration discovery, module tables, and token-to-RVA mapping.src/engineowns bounded installation scanning, evidence-ranked detection, artifact classification, and signature inspection.skillscontains no native execution code.
Read ARCHITECTURE.md for ownership, concurrency, caching, and failure semantics.
Caching and local data
An open image is reused in memory when its canonical path, size, and modification time have not changed. Deterministic results are stored under:
%LOCALAPPDATA%/ReversePlugin/analysis-cache-v1/<binary-sha256>/
The cache contains derived analysis and user annotations, not a copy of the input binary. Records are replaced atomically. A different binary hash receives a separate directory, even when the filename is the same. Delete analysis-cache-v1 while the server is stopped to clear all persistent analysis.
Resource and safety boundaries
- Input files are opened read-only and capped at 2 GiB.
- Expensive scans, result counts, CFGs, snapshots, and individual memory operations have explicit limits.
- Runtime reads validate every covered memory region.
- Runtime writes require existing write permission and support verification.
- Debug detach restores managed software breakpoints and suspensions owned by the session.
- Unknown exceptions can be passed back to the target instead of being swallowed.
- Tool failures return structured MCP errors; invalid JSON, addresses, session identifiers, or ranges do not terminate the server.
Use ReverseMCP only on software and systems you own or are authorized to inspect. The project does not include workflows for bypassing licensing, anti-cheat systems, access controls, or third-party security enforcement. Vulnerability reports belong in the private process described in SECURITY.md.
Performance tests
reverseplugin-stress-tests exercises work volume rather than publishing a hardware-independent score:
- 1 GiB of wildcard AOB scanning;
- 512 MiB of typed snapshot comparisons;
- 200,000 concurrent
ReadProcessMemoryoperations; - 1.2 million decoded instructions across eight threads;
- 256 concurrent function decompilations across eight threads;
- concurrent static-image cache reuse;
- 20,000 MCP requests across eight workers.
The test prints local throughput and fails on lost results or invalid state. Numbers depend on CPU, memory, target layout, compiler, and security software; the project does not use a single developer machine as a performance claim.
Releases
./scripts/release.ps1
The release script performs a clean Release build, runs every CTest target, stages the executable, manifest, skills, documentation, and licenses, then writes a ZIP and SHA-256 checksum under dist/. Pushing a v* tag runs the same path in GitHub Actions and attaches both files to a GitHub release.
See RELEASE.md for the version 1.2 compatibility contract.
Contributing
Bug reports, focused tools, additional loaders, architecture backends, cache migrations, and well-sourced engine knowledge are welcome. Changes to runtime code need tests; changes to skills need authoritative references and must pass the knowledge validator. Start with CONTRIBUTING.md.
License
ReverseMCP is available under the MIT License. Zydis, Zycore, and JSON for Modern C++ retain their own MIT copyright notices in THIRD_PARTY_NOTICES.md.