A modified fork of RMG (Rosalie's Mupen GUI) with a built-in Qt6 WebSocket bridge and a companion Python MCP server for real-time Nintendo 64 reverse engineering.
This fork is designed for decompilation and recompilation workflows. It exposes emulator state to MCP-capable clients such as Claude Desktop and VS Code, allowing an LLM to inspect and control a live N64 session with symbol-aware debugging tools.
This project extends upstream RMG with:
- a local JSON/WebSocket bridge embedded in the emulator
- direct RDRAM and VR4300 register inspection
- symbol loading from
.mapfiles - breakpoints and watchpoints
- execution control primitives
- structured debug event capture
- JSONL trace export and comparison
- an MCP server that exposes all of the above as tools
flowchart LR
A["LLM Client<br/>Claude Desktop / VS Code"] --> B["Python MCP Server<br/>FastMCP over stdio"]
B --> C["Qt6 WebSocket Bridge<br/>embedded in RMG"]
C --> D["RMG + mupen64plus-core debugger"]
D --> E["Running Nintendo 64 ROM"]
F[".map symbol files"] --> B
F --> C
The embedded bridge currently supports:
- RDRAM read and write
- MIPS register read and write
- CPU state snapshots
- virtual-to-physical address translation
- disassembly by address or symbol
- pause, resume, single-step, step over, and step out
- soft reset, hard reset, and full ROM restart
- breakpoints and watchpoints
- symbol loading, lookup, and resolution
- structured debug event polling
- filtered event streaming
The Python MCP server in server.py currently exposes tools including:
read_rdram,write_rdramread_symbol,write_symbolread_mips_register,write_mips_registerdebugger_state,cpu_snapshottranslate_addressresolve_symbol_name,resolve_symbol,lookup_symboldisassemble_rdram,disassemble_symbolpause_emulation,resume_emulationreset_emulation,restart_romstep_instruction,step_over,step_outrun_until_address,run_until_symboladd_breakpoint,add_watchpointadd_symbol_breakpoint,add_symbol_watchpointremove_breakpoint,remove_symbol_breakpoint,remove_symbol_watchpointlist_breakpoints,clear_breakpointsload_symbols,clear_symbols,symbol_statusget_debug_eventscapture_instruction_tracecompare_trace_filesbridge_status
- symbol-addressed reads, writes, disassembly, breakpoints, and watchpoints
- watchpoint hit snapshots with registers and memory bytes
- filtered debug event streaming over WebSocket
- JSONL trace capture for offline analysis
- trace comparison for original-vs-recompiled behavior checks
RMG/
├── README.md
├── server.py
├── Source/
│ ├── RMG/
│ │ └── MCP/
│ │ ├── McpBridgeServer.cpp
│ │ └── McpBridgeServer.hpp
│ └── RMG-Core/
│ ├── Debugger.cpp
│ ├── Debugger.hpp
│ └── m64p/
│ ├── DebuggerApi.cpp
│ └── DebuggerApi.hpp
└── Bin/
└── Release/
The canonical implementation lives entirely inside this repository. Earlier standalone prototypes were removed to avoid drift.
- Windows 10/11
- Python 3.12+
- an MCP-capable client such as Claude Desktop or VS Code
- MSYS2
ucrt64 - CMake 3.15+
- Qt6 with
WebSockets - the normal dependencies required by upstream RMG
Install the usual RMG prerequisites in MSYS2 ucrt64, then configure with the MCP bridge enabled:
cmake -S . -B build-mcp-ucrt -G "MSYS Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DMCP_BRIDGE=ON ^
-DPORTABLE_INSTALL=ON ^
-DNETPLAY=OFF ^
-DVRU=OFF ^
-DUSE_ANGRYLION=OFF ^
-DUPDATER=OFF
cmake --build build-mcp-ucrt --config Release -j 8
cmake --install build-mcp-ucrtTo bundle runtime dependencies:
cmake --build build-mcp-ucrt --target bundle_dependenciesWhen finished, the portable build is typically available under Bin/Release.
Install Python dependencies:
pip install mcp websocketsThen start the MCP server:
python server.pyEnvironment variables:
RMG_MCP_HOSTdefault:127.0.0.1RMG_MCP_PORTdefault:8765RMG_MCP_TIMEOUT_SECONDSdefault:2.0
- Build RMG with
MCP_BRIDGE=ON. - Launch
RMG.exe. - Load a ROM.
- Start server.py.
- Connect your MCP client over
stdio. - Load a symbol map with
load_symbols. - Start debugging by symbol, address, trace, or watchpoint.
load_symbols("D:/symbols/game.map")
read_symbol("D_8010ADA0", 4)
run_until_symbol("thread3_main", offset_bytes=0xF4)
add_symbol_watchpoint("D_8010ADA0", access="write", size_bytes=4)
resume_emulation()
get_debug_events(limit=16, event_types="debugger.watchpoint_hit")
capture_instruction_trace(
duration_ms=2000,
output_path="trace_original.jsonl"
)
compare_trace_files(
trace_a_path="trace_original.jsonl",
trace_b_path="trace_recompiled.jsonl"
)
Example claude_desktop_config.json entry:
{
"mcpServers": {
"rmg-n64-debugger": {
"command": "python",
"args": ["D:/Proyectos/n64-mcp/RMG/server.py"],
"env": {
"RMG_MCP_HOST": "127.0.0.1",
"RMG_MCP_PORT": "8765",
"RMG_MCP_TIMEOUT_SECONDS": "5.0"
}
}
}
}Example .vscode/mcp.json entry:
{
"servers": {
"rmgN64Debugger": {
"type": "stdio",
"command": "python",
"args": ["D:/Proyectos/n64-mcp/RMG/server.py"],
"env": {
"RMG_MCP_HOST": "127.0.0.1",
"RMG_MCP_PORT": "8765",
"RMG_MCP_TIMEOUT_SECONDS": "5.0"
}
}
}
}This repository is based on upstream RMG:
RMG is a free and open-source mupen64plus front-end written in C++.
- richer structured execution traces
- stronger original-vs-recompiled comparison workflows
- symbol-aware memory layout decoding for structs and arrays
- more function-level reverse engineering automation
This fork follows the licensing terms of upstream RMG. See the repository license and upstream project for details.
Do not redistribute commercial ROMs or copyrighted game assets.