Files
RE-AI/docs/ARCHITECTURE.md
T
John Smith 8cfd2b3745 chore(release): v2.1.0 hygiene — sync counts, fix verify.sh, document re-il2cpp
PR #3 added a 9th MCP server (re-il2cpp) and a 13th skill
(re-il2cpp-decompile) on top of v2.0.0, but the surrounding project state
was not updated to match: counts disagreed across docs, the new
server/skill were absent from every user-facing index, and verify.sh
would fail on a clean checkout because it asserted on a top-level
'len(d)==8' of a dict whose top-level key is 'mcpServers' (so 'len(d)==1').

This is a pure-hygiene follow-up — no code logic changes, no new tests,
no server/skill code edits:

- Fix verify.sh and verify.bat stale assertion: now check the
  'mcpServers' key, assert 9 entries, require the 8 originals as a
  subset, and require 're-il2cpp' to be present.
- Bump pyproject.toml and .claude-plugin/plugin.json to 2.1.0
  (matches .claude-plugin/plugin.json which was already at 2.1.0).
- Add [2.1.0] entry to CHANGELOG.md with Added / Changed /
  Known limitations sections.
- Update counts (8 -> 9 servers, 12/10/9 -> 13 skills) and add
  re-il2cpp + re-il2cpp-decompile to: README.md, docs/SKILLS.md,
  docs/MCP_SERVERS.md, docs/ARCHITECTURE.md, docs/MIGRATION_FROM_V1.md,
  docs/TROUBLESHOOTING.md, .claude-plugin/plugin.json.
- Add new 'Companion data' section to README.md describing
  data/drm-indicators.yaml and data/ksy/unityfs.ksy (were not
  documented before).
- Add new TROUBLESHOOTING entry: 're-il2cpp: Unity 6 / 2023+ metadata
  not supported'.

All 26 existing pytest tests still pass; 'bash verify.sh' reports 7/7 PASS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 14:57:54 -04:00

6.4 KiB

Architecture

RE-AI v2 is a Claude Code plugin. The architecture is deliberately minimal: it doesn't try to be the agent. Claude Code is the agent. The plugin just gives Claude Code a deep toolbox (MCP servers) and a deep playbook (skills).

High-level shape

┌─────────────────────────────────────────────────────────────┐
│  Claude Code                                                │
│  (the agent — owns the conversation, the context, the user) │
│                                                              │
│   ┌────────────┐    ┌──────────────────────────────────┐    │
│   │  Skills    │    │  MCP servers                     │    │
│   │  (prompt   │    │  (processes that expose tools    │    │
│   │  context)  │    │   via stdio JSON-RPC)            │    │
│   │            │    │                                  │    │
│   │13 SKILL.md │    │ re-rizin     re-capa             │    │
│   │ files in   │    │ re-lief      re-llm-decompile    │    │
│   │ skills/    │    │ re-mitm2swagger  re-kaitai       │    │
│   │            │    │ re-gdb       re-triton           │    │
│   │            │    │ re-il2cpp                         │    │
│   └────────────┘    └──────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
                          │
                          │ (Claude invokes tools)
                          ▼
                Tool results in conversation

When you ask Claude Code "analyze /usr/bin/ls", Claude:

  1. Reads the re-static-triage skill (the body of skills/re-static-triage/SKILL.md is loaded into context)
  2. Plans the tool calls: re-lief.parse_binary, re-lief.get_sections, re-rizin.list_imports_exports, re-capa.detect_capabilities, re-lief.extract_strings
  3. Spawns the MCP server processes (or uses already-running ones) via the stdio JSON-RPC transport
  4. Aggregates the results
  5. Writes a Markdown report

Plugin manifest

.claude-plugin/plugin.json is the marketplace manifest. It tells Claude Code:

  • Plugin name and version
  • Where to find skills (./skills/)
  • Where to find the MCP server registry (./.mcp.json)

This is the single source of truth. Marketplace install copies the whole plugin directory and reads this manifest.

MCP server registry

.mcp.json declares the 9 MCP servers. Each entry has:

  • command: the binary to run (typically uv with --directory ${CLAUDE_PLUGIN_ROOT}/servers/<name> run <name>)
  • args: command-line arguments
  • env: optional env vars (with ${CLAUDE_PLUGIN_ROOT} expansion so paths work regardless of install location)

${CLAUDE_PLUGIN_ROOT} is a Claude Code convention: it's expanded at load time to the absolute path of the plugin root.

Skill format

Each skill is a directory under skills/ containing a single SKILL.md file. The format is:

---
name: <kebab-case-name>
description: <one-sentence activation hint — Claude uses this to decide when to load the skill>
---

# <Skill title>

## When to use
<paragraph>

## Workflow
<numbered steps with the actual MCP tool calls>

## Tips / pitfalls / limitations
...

The description field is critical — Claude Code uses it to decide whether to activate the skill for a given user prompt. A vague description means Claude will never pick the skill up. The plugin enforces a 40-character minimum on descriptions (see tests/test_skills_frontmatter.py).

MCP server pattern

Every server follows the same shape:

servers/<name>/
├── pyproject.toml         # standard Python packaging
├── README.md
└── src/<name>/
    ├── __init__.py
    ├── __main__.py        # python -m <name> entry point
    ├── server.py          # the FastMCP instance + @mcp.tool() defs
    └── ...                # any helpers

The server module exposes:

  • A FastMCP("<name>") instance named mcp
  • A main() that calls mcp.run(transport="stdio") (this is the standard Claude Code transport)
  • One or more @mcp.tool() decorated functions

The pyproject.toml declares a console-script entry point: <name> = "<name>.server:main". This lets install.sh run pip install -e . and have a working <name> command.

Cross-platform install

install.sh (POSIX) and install.bat (Windows) do roughly the same thing:

  1. Check Python ≥ 3.11
  2. Install uv (preferred package runner) if missing
  3. Create a virtualenv (default) or install into system Python (RE_AI_SYSTEM=1)
  4. Discover system tools (rizin, gdb, kaitai-struct-compiler) and try to install via apt/brew/winget/scoop
  5. Download GEF to ~/.gdb/gef.py if gdb is installed
  6. pip install -e each server package
  7. pip install flare-capa mitmproxy mitmproxy2swagger kaitaistruct (shared Python deps)
  8. Run scripts/check_deps.py and report

Both scripts are idempotent — running them twice does no harm.

Verification

verify.sh / verify.bat run the test suite plus a few manifest sanity checks. pytest is the actual test runner.

What's intentionally NOT here

  • No database. The plugin is stateless; Claude Code owns the conversation history.
  • No custom agent loop. Claude Code's tool-use loop is the loop.
  • No frontend. The terminal is the UI.
  • No encrypted config store. Env vars (set in the shell or in .mcp.json env blocks) are the config.
  • No WebSocket protocol. The MCP stdio JSON-RPC is the wire protocol.

Why this design

RE-AI v1 was a FastAPI + React + SQLite + ChromaDB app with its own agent loop. The author spent 90% of their time on infrastructure (FastAPI routes, React state, WebSocket protocol, ChromaDB persistence) and 10% on the actual RE tools.

RE-AI v2 flips that: 100% of the code is RE tools. The agent, the UI, the protocol — all of it is Claude Code, which is already shipping for free.

This is the entire architectural insight of v2: don't build an agent, use one.