DEV Community

Cover image for REA MCP server: how AI agents drive Ghidra and IDA, and where the loop breaks
Devirt
Devirt

Posted on AI-assisted

REA MCP server: how AI agents drive Ghidra and IDA, and where the loop breaks

The REA MCP server is the part of REA (Reverse Engineer Anything) that lets an AI coding agent call reverse engineering tools as structured tool calls. It ships in the morluto/rea project, created on April 14, 2026 under the MIT license, and it registers with Claude Code, Codex, Cursor, Gemini CLI, Grok Build or any agent that supports local MCP servers. Instead of guessing what a binary does, the agent asks the REA MCP server to run Hopper, Ghidra, IDA, JADX or a browser capture, and reasons over what comes back.

We work on the far end of this pipeline. Devirt (devirt.re) turns VM-protected code back into readable functions, which is precisely the input where the REA MCP loop runs dry. Here is how that loop works, where it shines, and the exact point where it runs out of road.

What the REA MCP server exposes

The REA MCP server exposes reverse engineering tasks as MCP tools with defined input and output schemas. The project keeps a generated tool catalog in its MCP contracts guide, and the tools cover native binaries, .NET assemblies, JavaScript and Electron apps, Android packages, firmware, websites and a long tail of formats such as WASM, EVM bytecode and Unity IL2CPP metadata.

Two configuration details matter if you run it inside an agent with a tight context window:

  • Input schemas are compact by default. Setting REA_MCP_INPUT_SCHEMA_PROFILE=full in the MCP registration restores the complete field guidance and nested validation details.
  • Output schemas are complete by default. If your client caps the size of the tools/list response, REA_MCP_OUTPUT_SCHEMA_PROFILE=compact shrinks them. Both profiles keep the full tool set.

How the REA MCP loop works

The REA MCP loop is ask, inspect, read evidence, ask again. A typical investigation runs like this:

  1. The agent receives a question, for example "how does search work in this desktop app?"
  2. It calls an REA tool, say listing modules and imports of an Electron app or decompiling a native function through the configured provider.
  3. REA runs the underlying tool locally and returns findings with their evidence: code, references, and the unknowns it could not resolve.
  4. The agent forms a hypothesis and calls the next tool to confirm or reject it.
  5. When the evidence is strong enough, the agent explains the behavior or writes an implementation of its own.

The design choice that makes this work is that REA returns unknowns explicitly. An agent that can see "this call target could not be resolved" asks a better follow-up than one handed a confident but incomplete summary.

Setting up the REA MCP server

REA's setup command registers the MCP server and installs matching workflow instructions for each agent you pick:

npx rea-agents setup
Enter fullscreen mode Exit fullscreen mode

Setup shows its proposed changes, backs up your existing agent configuration, and asks for approval before writing. Restart the agent afterwards. For manual MCP registration, provider configuration and the Claude Code or Codex plugin route, the project points to its installation guide.

Things to have in place first:

Requirement Detail
Node.js 22, 24 or 26
Native provider An existing Hopper, Ghidra or IDA install (setup can install Hopper with approval)
Commercial tools IDA, Hopper and JEB need their own licenses; REA provides none
Linux A procps-compatible ps on the path for Ghidra, JADX and some static analysis
Sources Only the morluto/rea repo, rea.tools and the rea-agents npm package are official

What the REA MCP loop is good at

The REA MCP loop is strongest where the underlying tools already produce readable output. That covers most of the targets developers care about day to day:

  • Electron and JavaScript apps, where modules, source maps and IPC routes give an agent a lot to reason over.
  • Ordinary native binaries, where Ghidra or IDA pseudocode is readable and an agent can follow calls across functions.
  • Android apps, where JADX output is close to source.
  • Formats nobody has a decompiler habit for, such as IL2CPP metadata or EVM bytecode, where built-in parsers save real setup time.

Analysis runs on your machine. Keep in mind that the agent still forwards tool results to its model provider, so "local" describes where the tools run, not where the findings end up.

Where the REA MCP loop breaks: VM-protected binaries

The REA MCP loop breaks on code protected by a virtualizing protector, because every tool in the chain sees the protection instead of the program. VMProtect, Themida and Code Virtualizer replace selected functions with bytecode for a private virtual machine and add an interpreter that executes it. The virtual machine can differ from one protected file to the next.

Ask the REA MCP server to decompile a virtualized function and the provider dutifully returns the interpreter: a dispatcher loop, handler routines, and bytecode tables. The agent can describe that machinery accurately and still learn nothing about what the original function did. More tool calls won't fix it. The information the agent needs isn't in any listing the tools can produce. As of October 2026 the REA README does not mention obfuscation, packing or virtualizing protectors at all.

On a VM-protected function, the tools REA drives show the protector's interpreter, not the program

The fix sits upstream of the agent. Devirtualization rebuilds the virtual machine's state and control flow and turns that behavior back into native-shaped functions, so the decompiler, and the agent reading its output, has real code to work with.

Adding devirtualization in front of the REA MCP loop

Devirtualization is what Devirt does. Devirt (devirt.re) recovers the logic behind VMProtect, Themida and Code Virtualizer automatically, and handles Enigma Protector, Obsidium, Loki-based virtual machines, JavaScript VM obfuscation and custom VMs after a free assessment of the file. Two of its outputs fit straight back into an agent workflow:

  • An IDA database, which opens in IDA, one of the providers the REA MCP server can drive.
  • Structured JSON, which an agent can read directly.

Each recovered function carries a label in Devirt's coverage ledger: proven, runtime-dependent, unresolved or permanently bounded. That is the same idea as REA's explicit unknowns, applied to recovered code, and it tells the agent which functions to trust. Devirt only analyzes software that customers own or are authorized to examine. The How It Works page shows the process end to end.

If you want the non-technical overview of REA first, our Substack post on REA covers what it is and why "anything" has limits.

Top comments (0)