REA: Multi-Tool Reverse Engineering Through MCP Orchestration A developer released REA (Reverse Engineer Anything), an open-source Model Context Protocol server that orchestrates reverse-engineering tools such as Ghidra, Hopper, and dynamic tracers behind a single stateful API for agents. The server maintains a shared investigation graph across static and dynamic analysis, handles tool lifecycle and credential injection server-side, and ships 33 "Parseltongue" input-perturbation techniques for testing agent robustness. The project has reached 14,029 stars and ranks first among trending TypeScript repositories, targeting Claude Code, Codex, Cursor, Gemini, and Grok. Reverse engineering typically requires juggling multiple specialized tools: Ghidra for decompilation, Hopper for disassembly, dynamic tracers for runtime behavior. Each tool has its own CLI, API surface, and session management. REA Reverse Engineer Anything exposes all of them through a single Model Context Protocol MCP server, letting agents coordinate static analysis, dynamic tracing, and binary inspection without managing tool-specific state. The project sits at 14,029 stars and ranks 1 in trending TypeScript repos. It targets Claude Code, Codex, Cursor, Gemini, and Grok through a skills framework that abstracts vendor differences. The interesting part is not the agent frontend but the MCP server that maintains investigation state across tool boundaries. REA treats reverse engineering as a multi-phase investigation. An agent might: The MCP server holds the investigation context. When an agent calls analyze binary , the server decides whether to invoke Ghidra, Hopper, or both based on the query. When the agent requests runtime behavior, the server spawns a tracer and merges its output with prior static analysis. This is not a simple tool wrapper. The server maintains a shared investigation graph: functions discovered in static analysis become targets for dynamic tracing. Symbols resolved at runtime feed back into the decompiler's type inference. The agent sees a unified API; the server handles tool coordination. The MCP server runs on Node.js 22+ and exposes a catalog of tools: Each tool runs in a subprocess. The server manages lifecycle spawn, attach, teardown and serializes results into a common schema. Agents call MCP methods like decompile function or trace syscalls ; the server routes to the appropriate backend and caches results in the investigation context. The server maintains three state layers: | Layer | Scope | Persistence | |---|---|---| | Investigation context | Cross-tool results, symbol maps, call graphs | In-memory, serialized to JSON on request | | Tool sessions | Ghidra project files, Hopper database handles | Ephemeral, cleaned up on investigation close | | Agent checkpoints | Intermediate findings, hypotheses, next steps | Stored in MCP resource URIs for resume | When an agent requests analyze binary , the server: If the agent later calls trace function with a function ID, the server: The agent never manages Ghidra project files or frida script lifecycles. It sees a stateful investigation that spans tools. The server uses heuristics to decide which tool to invoke: file and objdump for basic metadata These rules live in the server's investigation planner. The agent can override by calling specific tools directly, but the default flow minimizes redundant analysis. For example, if Ghidra already decompiled a function, the server skips Hopper disassembly unless the agent explicitly requests a second opinion. REA includes wrappers for vendor CLIs like stripe and gh . These tools often require OAuth tokens or API keys. The MCP server handles credential injection server-side: Agents call invoke cli with a tool name and arguments. The server injects credentials, runs the command, and returns stdout. The agent never sees raw tokens. This keeps the MCP interface tool-agnostic while supporting authenticated workflows. REA ships with 33 Parseltongue techniques for testing agent robustness. These are input perturbations across three intensity tiers: The MCP server can apply Parseltongue transforms to any tool input before passing it to the backend. This lets agents test how decompilers, disassemblers, and tracers handle malformed or malicious inputs. For example, an agent might: This is useful for evaluating tool brittleness and finding edge cases in binary parsers. The MCP server logs every tool invocation with: Logs are structured JSON, queryable with jq or ingested into observability platforms. When a tool crashes, the server: Common failure modes: | Failure | Cause | Mitigation | |---|---|---| | Ghidra timeout | Large binary, complex control flow | Server kills subprocess after 5 minutes, returns partial results | | Frida attach failure | Target process protected by SIP or ptrace restrictions | Server falls back to passive tracing dtrace, strace | | Hopper license error | Commercial license expired or not found | Server skips Hopper, uses Ghidra only | | Memory exhaustion | Decompiler allocates too much RAM | Server enforces per-tool memory limits via cgroups Linux or ulimit | The agent sees a unified error interface. It can retry with different tools or adjust the investigation scope. REA runs as a single MCP server process. Typical deployment: js // server.ts import { MCPServer } from 'rea-agents/mcp'; import { GhidraBackend, HopperBackend, FridaBackend } from 'rea-agents/tools'; const server = new MCPServer { tools: new GhidraBackend { headless: true, timeout: 300000 } , new HopperBackend { license: process.env.HOPPER LICENSE } , new FridaBackend { spawn: true, attach: true } , , investigation: { persistTo: './investigations', maxConcurrent: 4, }, observability: { logLevel: 'debug', metricsPort: 9090, }, } ; server.listen 3000 ; The server exposes: Agents connect via MCP clients Claude Desktop, Cursor, custom scripts . Multiple agents can share the same server, but each investigation is isolated. The server enforces concurrency limits to prevent resource exhaustion. The MCP server runs tool subprocesses with restricted privileges: ulimit macOS Agents cannot execute arbitrary code on the server. They can only invoke predefined MCP tools. The server validates all inputs against a schema before passing them to backends. This prevents command injection and path traversal attacks. Credential storage uses OS-level keychains. Tokens are encrypted at rest and never logged. The server rotates tokens on a schedule and revokes them when an investigation closes. js // agent.ts import { MCPClient } from 'rea-agents/client'; const client = new MCPClient { serverUrl: 'http://localhost:3000' } ; // Start investigation const investigation = await client.createInvestigation { target: './suspicious-binary', goals: 'identify obfuscation', 'find network calls' , } ; // Static analysis const functions = await client.call 'analyze binary', { investigationId: investigation.id, binary: './suspicious-binary', tools: 'ghidra', 'hopper' , } ; // Filter for network-related functions const networkFuncs = functions.filter f = f.name.includes 'socket' || f.calls.some c = c.includes 'connect' ; // Dynamic tracing for const func of networkFuncs { const trace = await client.call 'trace function', { investigationId: investigation.id, functionId: func.id, duration: 10000, // 10 seconds } ; console.log ${func.name} called with: , trace.arguments ; console.log Returned: , trace.returnValue ; } // Export investigation const report = await client.call 'export investigation', { investigationId: investigation.id, format: 'markdown', } ; console.log report ; The agent sees a high-level API. The MCP server coordinates Ghidra, Hopper, and frida under the hood. Use REA when: Avoid REA when: The MCP server architecture works well for agent-driven workflows where the agent decides what to investigate and the server handles tool coordination. It does not replace manual reverse engineering but automates the plumbing between tools.