A secure, headless Model Context Protocol (MCP) server for automated retro-reversing and bare-metal firmware triage. Utilizes PyGhidra for in-process P-code micro-emulation and multi-generation console ROM auto-triage (Nintendo, PlayStation, Sega) over secure stdio transport
claude mcp add ghidra-retro-mcp -- python -m -e{
"mcpServers": {
"ghidra-retro-mcp": {
"command": "python",
"args": ["-m", "-e"]
}
}
}MCP Servers overview
# Ghidra Retro MCP
MCP (Model Context Protocol) server that exposes Ghidra's headless analysis capabilities to AI assistants via pyhidra.
> **GBA ROMs**: If analyzing Game Boy Advance ROMs, install [pudii/gba-ghidra-loader](https://github.com/pudii/gba-ghidra-loader) in your Ghidra installation for proper ROM header parsing, mirrored memory regions, and I/O register maps. The loader repository has pre-built `.gpa` files for Ghidra 11.x.
## Security Model
This server communicates **exclusively over standard process stdio** — there is no HTTP socket, no TCP listener, and no network interface exposed. It is inherently immune to LAN/WAN exposure, SSRF, and unauthenticated API attacks. The only way to interact with it is for an MCP client to launch it as a subprocess and communicate via stdin/stdout.
## Hardware & Retro Ecosystem Integration
`ghidra-retro-mcp` includes native out-of-the-box support for retro-reversing automation pipelines. The server container bundles pre-compiled execution dependencies for:
- **Nintendo Entertainment System (NES)** via `GhidraNes`
- **Super Nintendo Entertainment System (SNES)** via native 65816 memory maps
- **Game Boy Advance (GBA)** via `gba-ghidra-loader`
- **Nintendo DS (NDS)** via `NTRGhidra`
- **Nintendo Switch** via `ghidra-switch-loader`
- **PlayStation 1 (PSX)** via `ghidra_psx_ldr`
- **Sega Genesis / Mega Drive** via native 68000 memory maps
- **Sega Master System / Game Gear** via `Ghidra-SegaMasterSystem-Loader`
- **Sega Dreamcast** via native SuperH4 memory maps
### Zero-Input Triage — Worked Example (GBA)
The primary entry point is `triage_and_load_retro_rom`. Call it with any ROM path and the server handles the rest:
```python
# Auto-detect platform, map language, provision session
triage_and_load_retro_rom(rom_path="/data/game.gba")
# → platform: "Game Boy Advance (GBA)"
# → loader: "GBA ROM Loader"
# → arch: "ARM:LE:32:v4t"
# Decompile the main entry point on the same session
decompile_function(address="0x00001c2c")
# → decompiled C code for the GBA ROM entry routine
# Search for a known pattern (e.g. 32-bit ARM store-multiple)
search_bytes(pattern="09 08 00 01")
# → matching addresses labelled "gba_ram_start"
```
### Execution Chaining Flow
Instead of forcing your AI agent to spend cycles manually identifying architecture maps, register layouts, or memory segments, chain the automated ingestion pipeline:
1. Invoke `triage_and_load_retro_rom` with a target file path.
2. The server headlessly parses the binary file structure (`NES\x1a`, `NTR`, `NSO0`, `GBA`, SNES title vectors, `PS-X EXE`, `SEGA`, `TMR SEGA`, `SEGA ENTERPRISES`), binds the matching Ghidra language module (`6502:LE:16`, `ARM:LE:32:v4t`, `AARCH64:LE:64`, `65816:LE:24`, `MIPS:LE:32`, `68000:BE:32`, `Z80:16`, `SuperH4:LE:32`), loads standard address memory blocks, and links automated signature cache arrays.
3. Use the integrated `emulate_slice` or `emulate_slice_with_taint` tools to analyze localized console loops — no physical console hardware or open GDB networking ports needed.
### Triage Tool
| Tool | Description |
|---|---|
| `triage_and_load_retro_rom` | Reads raw file magic bytes to detect NES, SNES, GBA, NDS, Switch, PSX, Genesis, SMS, or Dreamcast ROMs. Provisions a correctly-language-mapped Ghidra session and auto-restores cached function signatures. Returns platform, loader, architecture tag, and mapped memory blocks. |
## Quick Start
### Local
```bash
pip install -e .
set GHIDRA_INSTALL_DIR=C:\path\to\ghidra # Windows
ghidra-retro-mcp
```
### Docker
```bash
docker build -t ghidra-retro-mcp .
docker run -i --rm -v /path/to/binaries:/data ghidra-retro-mcp
```
The container bundles JDK 17, Ghidra 11.2, and the server — no host dependencies beyond Docker.
## Claude Desktop config
```json
{
"mcpServers": {
"ghidra-headless": {
"command": "ghidra-retro-mcp",
"args": ["--ghidra-dir", "C:\\path\\to\\ghidra"],
"env": {}
}
}
}
```
## Tools
### Session management
| Tool | Description |
|---|---|
| `analyze_binary` | Import + analyze a binary, returns a `session_id`. Reuses the ID if provided, otherwise auto-generates. |
| `list_sessions` | List all active workspaces with their session IDs, binary paths, and load times. |
| `close_session` | Close a session and free its Ghidra project resources. |
Most tools accept an optional `session_id` parameter — omit it to use the most recently loaded session.
### Read / Analysis
| Tool | Description |
|---|---|
| `decompile_function` | Decompile a function by name or address. |
| `decompile_function_paginated` | Decompile with `line_start`, `line_end`, `max_tokens` (token-budget truncation), and `summarize` (strips boilerplate locals + collapsing blank lines). Prevents context-window exhaustion. |
| `get_data_types` | List all data types defined in the program. |
| `get_cross_references` | Cross-references to/from an address. |
| `get_call_graph` | Recursive call graph + callers for a function. |
| `analyze_and_decompile_entrypoints` | Composite — bulk decompile all entry points (program entry, exports, `main`, `_start`, etc.) in one call. |
| `generate_workspace_report` | Produce a Markdown summary of the active workspace — entry points, function count, custom symbols, recovered structures, renamed functions, comments. Replaces a GUI CodeBrowser window. |
### Write / Mutation
| Tool | Description |
|---|---|
| `rename_symbol` | Rename a function or label. Stored in the Ghidra project DB. |
| `add_comment` | Attach a comment (`plate`, `pre`, `post`, `eol`, `repeatable`). |
| `create_struct` | Create a custom structured data type from a JSON member layout `[{offset, name, type}, ...]`. Offsets are optional. |
| `retype_variable` | Re-type a local variable or function parameter (e.g. `undefined4*` → `MyStruct*`). |
### Assembly-level
| Tool | Description |
|---|---|
| `disassemble_range` | Disassemble N raw instructions at an address — returns mnemonic, operands, hex bytes, and length for precise lower-level inspection. |
| `get_listing_range` | Raw hex + ASCII dump for a byte range, equivalent to Ghidra's Listing panel. Complements `disassemble_range` for data regions. |
### Byte-sequence search
| Tool | Description |
|---|---|
| `search_bytes` | Search the entire binary for a hex byte pattern (e.g. `09 08 00 01` or `F86D0003`). Returns matching addresses with context bytes and any string label at the hit. |
### Binary diffing
| Tool | Description |
|---|---|
| `diff_binaries` | Compare two loaded sessions by function name and body size. Returns functions unique to each side and changed functions. |
## Workspace Sessions
Each `analyze_binary` call creates a named session. Sessions keep their Ghidra project open independently, so multiple binaries can be loaded concurrently:
```python
# Load two binaries into separate sessions
s1 = analyze_binary(binary_path="/bin/a.out") # auto session_id
s2 = analyze_binary(binary_path="/bin/b.out", session_id="my_session")
# Operate on a specific session
decompile_function(function_name="main", session_id=s1.session_id)
# Diff them
diff_binaries(session_a=s1.session_id, session_b="my_session")
```
## Deployment
### Docker (multi-user / CI)
```bash
docker build -t ghidra-retro-mcp .
# Run as an MCP subprocess
docker run -i --rm \
-v /data/binaries:/data \
ghidra-retro-mcp \
--ghidra-dir /opt/ghidra
```
The `Dockerfile` bundles Ghidra 11.2 and JDK 17 in a slim Python 3.11 image. Bind-mount your binaries directory at runtime.
### P-code micro-emulation
| Tool | Description |
|---|---|
| `emulate_slice` | Headlessly execute N instructions. Seed register state and get a step-by-step trace of register mutations. |
| `emulate_slice_with_taint` | Same as `emulate_slice` but with automated taint tracking — specify a taint register (e.g. `r0`) and the tool flags exactly when its value is modified or propagates to other registers. |
| `emulate_slice_with_breakpoints` | Execute until a condition is met or the count expires. Condition syntax: `R0==0`, `R1>0xFF`, `R2!=R3`, `PC==0x1234`. Stops before or after the matching instruction. |
All run inside the pyhidra process via Ghidra's `EmulatorHelper` — no GDB/LLDB, no network ports, no debugger stubs. Works on ARM, x86, MIPS, and any Ghidra-supported architecture.
#### Worked example — breaking on a register condition
Suppose you're reversing a GBA ROM and want to find the first time `r0` becomes zero inside a loop at `0x08000100`:
```python
# Step until r0 == 0, stop before the matching instruction
result = emulate_slice_with_breakpoints(
session_id="gba_v1",
start_address="0x08000100",
max_instructions=5000,
stop_condition="R0==0",
stop_mode="before"
)
# result.exit_reason → "R0==0"
# result.instructions_executed → 312
# result.trace → [step 311: r0 goes 4→2, step 312: r0 goes 2→0]
# Check if a specific address was reached after a branch
result = emulate_slice_with_breakpoints(
session_id="gba_v1",
start_address="0x08000100",
max_instructions=5000,
stop_condition="PC==0x08001234"
)
# result.exit_reason → "PC==0x08001234"
# Use inequalities to catch bounds checks
result = emulate_slice_with_breakpoints(
session_id="gba_v1",
start_address="0x08000100",
max_instructions=5000,
stop_condition="R1>0xFF"
)
# result.exit_reason → "R1>0xFF"
# result.last_step["r1"] → 0x100
```
This is especially powerful for identifying copy-loop bounds (`R3 >= R4`), null-pointer paths (`R0==0`), or switch-table targets (`PC==0x`).
### Function fingerprinting / signature transfer
| Tool | Description |
|---|---|
| `calculate_function_fingerprint` | Generate a structural hash for a function (vars, params, body size, branches, called funcs, embedded strings, numeric constants). Survives compiler reordering. |
| `export_signature_map` | Build a complete `{hash → name}` map for every function in the current binary. Save this JSON to reuse across versions. |
What people ask about ghidra-retro-mcp
What is getanirao/ghidra-retro-mcp?
+
getanirao/ghidra-retro-mcp is mcp servers for the Claude AI ecosystem. A secure, headless Model Context Protocol (MCP) server for automated retro-reversing and bare-metal firmware triage. Utilizes PyGhidra for in-process P-code micro-emulation and multi-generation console ROM auto-triage (Nintendo, PlayStation, Sega) over secure stdio transport It has 0 GitHub stars and was last updated today.
How do I install ghidra-retro-mcp?
+
You can install ghidra-retro-mcp by cloning the repository (https://github.com/getanirao/ghidra-retro-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is getanirao/ghidra-retro-mcp safe to use?
+
getanirao/ghidra-retro-mcp has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains getanirao/ghidra-retro-mcp?
+
getanirao/ghidra-retro-mcp is maintained by getanirao. The last recorded GitHub activity is from today, with 0 open issues.
Are there alternatives to ghidra-retro-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy ghidra-retro-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/getanirao-ghidra-retro-mcp)<a href="https://claudewave.com/repo/getanirao-ghidra-retro-mcp"><img src="https://claudewave.com/api/badge/getanirao-ghidra-retro-mcp" alt="Featured on ClaudeWave: getanirao/ghidra-retro-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface