← All reviews

Repo review · Tested October 9, 2026

rea wants your coding agent to read programs without the source

rea gives a coding agent local tools to take apart a compiled program or a packaged app without its source. On small programs an agent with ordinary shell tools already explained the code almost perfectly, so rea added cost and no accuracy.

Verdict: adopt with care
View repository ↗
A slate-blue pigeon wearing a watchmaker's loupe stands on a workbench and peers at an opened pocket watch, with its gears, spring, screws and back plate laid out in a row on green felt beside a blank sheet of paper and a pencil.
rea lets a coding agent open up a shipped program and see how the parts fit, with no blueprint on the bench.

rea gives a coding agent local tools for taking apart software it has no source for. It is an MCP server (a way for a coding agent to call tools) and a CLI that drive Ghidra (the NSA’s open-source decompiler) and hand back readable code, plus a list of what is inside a packaged app. We tested it on four small stripped binaries (compiled programs with their function and variable names removed) and three shipped Electron apps. rea’s decompiled code was readable, and it matched the source where we compared it. On programs this small the agent did not need rea: reading raw machine instructions from objdump (a standard tool that prints them), the agent already explained almost everything correctly, and rea added cost.

Tested: commit a64851f2592cd353600d54864b38524705341dd1, tag rea-agents-6.2.0, on October 9, 2026. Scope: Claude Code 2.1.295 with claude-sonnet-5-5 at medium effort, on four small stripped binaries up to 264 KB and three shipped Electron apps. Result: on the native binaries the agent scored 74 of 75 checklist points with ordinary tools and 73 of 75 with rea, and rea used about 2.5 times the tokens (about 1.5 times the computed cost). 92 of 95 rea calls returned usable output. On Electron apps the full analysis is too large to return in one tool call. Verdict: adopt with care: small programs your agent can already read do not need it.

Set up rea with your coding agent

Paste this into a coding agent that can run commands. rea’s setup asks which agent to register and shows its plan before writing.

1. Check Node.js is 22.19+, 24.11+, or 26+; otherwise stop.
2. Only for native binaries: install Ghidra 12.1.x and a JDK 21 or newer, set GHIDRA_INSTALL_DIR and JAVA_HOME, then run npx -y rea-agents@latest doctor --provider ghidra --json. On Linux arm64, first build Ghidra's decompiler with gradle --no-daemon buildNatives in its support/gradle folder (needs Gradle and a C/C++ compiler).
3. Preview with npx -y rea-agents@latest setup --dry-run --json, show me the plan, and run npx -y rea-agents@latest setup once I approve it. Ask before using sudo.
4. Restart the agent. If it does not pick up rea's skill (its instruction file for the agent), check where setup wrote it against the folder your agent reads skills from.

This review tested 6.2.0, and @latest may be a newer release. In this review setup wrote the skill to ~/.agents/skills, and the arm64 build in step 2 was needed because Ghidra’s release has no decompiler for Linux on arm64.

What rea covers and what it competes with

The README lists a wide scope: native binaries through Hopper, Ghidra or IDA; JavaScript and Electron apps; websites and saved network captures; .NET assemblies; Android APKs; firmware; and more. This review covers two of those paths: native binaries through Ghidra, and JavaScript and Electron apps.

The project is MIT-licensed, was created in April 2026, and is developed quickly, mostly by one maintainer. Its server adds 139 tools to the agent’s tool list. The closest alternatives are @electron/asar (the tool that unpacks an Electron app’s code) plus a text search tool such as rg for Electron apps, and other MCP servers that connect an agent to a decompiler, such as GhidraMCP or ida-pro-mcp, for native work.

How rea was tested

Each session was a fresh agent with no memory of any other session, asked one question about one program it had no source for.

  • Electron questions traced a feature, such as “How does the app find out whether pandoc is available and which pandoc binary an export would use?” The apps were Electron Fiddle (a code playground), MarkText (a Markdown editor) and VSCodium (a build of VS Code).
  • Native questions were about one function, such as “How is a record’s length encoded in the file, and which encodings does the program reject?” The programs were md2html (a Markdown converter), jtool (a JSON tool), gtpack (a checker for a small archive file format) and gtvm (a bytecode interpreter). md2html and jtool are built on the open-source md4c and yyjson libraries; gtpack and gtvm were written for this test.

Every question ran under three conditions:

  • Shell tools only: ordinary command-line tools such as rg (text search) and objdump.
  • rea: the agent was told to use rea, with the project’s own skill available.
  • Free choice: rea was available and nothing told the agent to use it.

Scoring used a checklist. For each question, five facts were written from the program’s real source before any session answered it, and an answer earned a point for each fact it got right. That makes 75 points for the 15 native questions and 60 for the 12 Electron questions. Three more questions in each test asked about a feature that does not exist; every session, under every condition, correctly said so. For five native questions the agent also rewrote the function in C, and its version was run against the original on 7,092 inputs in total.

rea decompiled the binaries; its Electron analysis is too large for one tool call

On the native path, tested on Linux on arm64, rea drove Ghidra 12.1.4 on the four stripped binaries. Ghidra’s release had no decompiler for that platform, so it had to be built first. rea’s calls returned usable output in 92 of 95 cases. About a quarter of the calls asked for decompiled code. The rest opened and closed the binary or looked up text strings, where a function is called from, and similar details. Here is the decompiled checksum routine of gtpack:

uint FUN_00400c70(long param_1,ulong param_2,uint param_3)
{
  param_3 = (int)param_2 * -0x61c8864f ^ param_3;
  ...
  param_3 = (param_3 >> 0x13 | param_3 << 0xd) * 5 + 0xe6546b64;
  ...
}

The negative constant -0x61c8864f is 0x9E3779B1 printed as a negative number, and 0xE6546B64 is in the original too, so the decompiled code uses the same constants as the source it was compiled from.

On the Electron path, rea’s command-line analysis completed on Electron Fiddle and MarkText in full and on VSCodium’s main code directory. An Electron app’s code is usually packed into one file, an asar archive. Run on Electron Fiddle’s 22 MB archive, rea’s analyze-javascript-application command parsed 71 JavaScript files and wrote a 692 MB document.

A document that size cannot be returned to an agent in one tool call, so through MCP rea sends back an error that says so. rea’s documentation offers two ways around this: a summary call, inspect_analysis_view, or writing the full result to a file. Start with the summary call. For Electron Fiddle it returned about 11,000 characters and reported 20 windows, 9 preload scripts, 4 contextBridge APIs with 56 members, and 84 IPC operations, 64 of them on a channel name rea could not resolve to a fixed string.

Preload scripts and contextBridge APIs are the parts of an Electron app that let a window call into the main process. IPC (inter-process communication) is how the two exchange messages. The list is the start of an IPC map: which window talks to which process, and over which channel. For anyone trying to reverse engineer an Electron app, it says where to look next without running the app.

In our Electron sessions the agent did not take the summary route. It answered by searching the unpacked app itself and scored 57 of 60 with or without rea, so those sessions say nothing about what the summary is worth to an agent.

rea also passed three smaller checks. It only linked a sender to a receiver when the channel name was written out in the code, and labelled the rest as unresolved. Asked to trace a feature it could not find, it said that this does not prove the feature is absent. Given an archive we had tampered with, it stopped and named the file. It made no network connection on either path.

rea did not raise the agent’s score, and it cost more

Native run Shell tools only rea Free choice
Checklist items correct 74/75 73/75 71/75
Rebuilt functions matching every input 5/5 5/5 4/5
Sessions that called rea 0/18 18/18 3/18
rea calls with usable output not applicable 92/95 4/4
Median tokens per session 94,663 233,951 119,869
Median session time 54.5 s 63 s 48 s

The one-to-three point differences between columns are too small for the scoring to tell apart. rea multiplied median tokens by about 2.5 and median time by about 1.2; most of the extra tokens are cached reads, so the computed cost rose by about 1.5 times. Part of the token cost is fixed: rea adds 139 tools to the agent’s tool list, and a session with rea started with about 11,000 tokens of context against about 5,000 without. Free-choice sessions paid about 1.3 times the tokens while calling rea in 3 of 18. With ordinary tools the agent was already at or near the top of the checklist, which leaves rea little room to help on programs this size.

Decompiling Minesweeper

As a demonstration outside the scored test, we pointed the agent at a program most readers know: Minesweeper from Windows XP (version 5.1.2600.0), which is closed source. The question was why the first click is never a mine.

rea’s Ghidra route listed the program’s unnamed functions and returned decompiled code for the click routine. This is the part that runs when no square has been revealed yet. DAT_01005340 is the board and 0x80 is the bit that marks a mine:

do {
  if ((puVar3[iVar2] & 0x80) == 0) {
    (&DAT_01005340)[param_1 + param_2 * 0x20] = 0xf;
    (&DAT_01005340)[iVar2 + iVar1 * 0x20] = (&DAT_01005340)[iVar2 + iVar1 * 0x20] | 0x80;
    FUN_01003084(param_1,param_2);
    return;
  }
  iVar2 = iVar2 + 1;
} while (iVar2 < DAT_01005334);

The loop walks the board from the top-left looking for a square with no mine. When it finds one, it clears the clicked square, sets the mine bit on the square it found, and reveals the square you clicked. So the mines are placed before you click, and nothing steers them away from your first square. If you hit one, the game quietly moves it.

The agent without rea reached the same explanation from the raw disassembly. The explanation matches a public write-up of the game’s first-click behaviour.

Adopt rea with care: small programs do not need it

Adopt rea with care if you want decompiled code on hand for your coding agent: on small programs the agent already explains the code almost perfectly without it, so rea adds cost and no accuracy. With rea the answers on the native binaries were no more correct, and it used about 2.5 times the tokens. Left to choose, the agent picked rea in 3 of 18 sessions.

It suits a reader who wants a decompiler their agent can call, or rea’s summary of an Electron app’s windows and message channels, and who accepts the token cost. Skip it when the agent already answers your question from the disassembly or the unpacked app.