mcp-dolphin
mcp-dolphin
An MCP server for Dolphin (GameCube + Wii) — drives memory r/w, controller input (GameCube + Wii Remote), pause/resume/reset, savestates, and frame advance from MCP-compatible clients (Claude Desktop, Claude Code, etc.).
What you can do with it
Read & write emulated PowerPC memory — 8/16/32/64-bit, MEM1 + MEM2
Send controller input — GameCube (digital + analog sticks + triggers), Wii Remote buttons
Reset the emulator (pause/resume not in v0.1.0 — see Known limitations)
Save / load state to numbered slots (0-255; 1-10 map to F1-F10 in Dolphin)
Frame advance — wait N frames synchronously for TAS-style precision
Not yet wired in v0.1.0 (deferred to a later release):
Wii Remote motion (pointer, accelerometer, swing, shake, tilt)
Nunchuk / Classic Controller / GBA-via-Wii input
Memory breakpoints, register access, screenshots
Architecture (and the hard prerequisite)
┌─────────────────────────────────────────────────┐
│ Dolphin (Felk's fork — required, not mainline) │
│ │
│ mcp_bridge.py loaded via Scripting panel │
│ └─ TCP server on 127.0.0.1:55355 │
└─────────────────────────────────────────────────┘
↕ TCP loopback (newline-delimited JSON)
┌─────────────────────────────────────────────────┐
│ mcp-dolphin (Node.js — this package) │
└─────────────────────────────────────────────────┘
↕ MCP stdio
MCP client (Claude etc.)Mainline Dolphin does not have Python scripting. mcp-dolphin talks to Felk's actively-maintained Dolphin fork which embeds Python with first-class access to memory, controllers, savestates, and the frame loop. Mainline Dolphin Python PRs (#7064) have been stuck since 2022; the Lua forks (dolphinWatch, SwareJonge/Dolphin-Lua-Core) are dead. Felk is the only living scripting path.
One-time setup
1. Install Felk's Dolphin fork
Grab a build from Felk/dolphin Releases — currently Python Scripting Preview 4 (December 2025). Unzip it somewhere you can find. It's a regular Dolphin build plus a Scripting panel under the View menu.
If you see Python errors when loading the bridge, enable the Scripting log type: View → Show Log Configuration → check Scripting (set verbosity to "Info" or "Error"), then View → Show Log so the log window is visible.
2. Print the bridge script and load it
npx -y mcp-dolphin --print-bridge > mcp_bridge.pyThen in Felk's Dolphin:
View → Scripting to open the scripting panel.
Click Add New Script and pick the
mcp_bridge.pyyou just wrote.Verify in Dolphin's Log window — you should see
[mcp-bridge] listening on 127.0.0.1:55355 (bridge v0.1.0).
The script keeps running as long as Dolphin is open. Remove it from the Scripting panel to stop the bridge.
3. Register mcp-dolphin in your MCP client
Claude Code:
claude mcp add dolphin --scope user mcp-dolphinClaude Desktop — edit claude_desktop_config.json:
{
"mcpServers": {
"dolphin": {
"command": "npx",
"args": ["-y", "mcp-dolphin"]
}
}
}Restart your MCP client after editing.
4. Verify
Load a GameCube or Wii game in Dolphin, then ask the agent to call dolphin_ping. You should see OK — bridge v0.1.0 (Felk Python fork).
Tools
Tool | Description |
| Liveness probe + bridge-version sniff |
| Report bridge version and Dolphin label |
| Read PowerPC memory (big-endian) |
| Bulk read up to 64 KiB as hex dump |
| Write PowerPC memory |
| Set GameCube controller state (port + button/axis dict) |
| Set Wii Remote button state |
| Emulation soft-reset (pause/resume deferred to v0.2 — see Known limitations) |
| Wait N frames (TAS sequencing) |
| Slot-based savestate (0-255) |
GameCube + Wii address space (cheat sheet)
Range | Region |
| MEM1 main RAM (24 MiB) — GC + Wii |
|
|
| MEM2 (64 MiB) — Wii only |
| Flipper / Hollywood I/O — reads usually safe, writes can wedge |
| Wii-only Hollywood registers |
PowerPC is big-endian on hardware. The bridge handles byte-swap on read/write — pass and receive the value the game logically sees, not the byte order.
Controller input
GameCube (dolphin_press_gc_buttons)
{
"port": 0,
"state": {
"A": true, "B": false, "Start": true,
"StickX": 200, "StickY": 128,
"TriggerLeft": 0, "TriggerRight": 255
}
}Digital buttons:
A, B, X, Y, Z, Start, L, R, Up, Down, Left, RightAnalog axes:
StickX, StickY, CStickX, CStickY(0-255, 128 = center)Triggers:
TriggerLeft, TriggerRight(0-255, 0 = released)Omitted keys default to released / center.
Wii Remote (dolphin_press_wiimote_buttons)
{ "port": 0, "state": { "A": true, "Plus": true, "Up": true } }Buttons:
A, B, One, Two, Plus, Minus, Home, Up, Down, Left, Rightv0.1.0 covers buttons only — motion, pointer, Nunchuk, Classic Controller deferred to a future release.
Configuration
Env var | Default | Purpose |
|
| Bridge host (the Dolphin process is local, so this rarely changes) |
|
| Bridge port (must match |
|
| Per-call timeout |
| unset | Set to |
If you change the port, edit both mcp_bridge.py (in your scripts dir) and set DOLPHIN_BRIDGE_PORT.
Troubleshooting
Symptom | Cause / Fix |
| Dolphin not running, script not loaded in Scripting panel, or wrong port. Check Dolphin's Log window for |
| Bridge script is older than mcp-dolphin. Re-export with |
Memory reads return 0xFFFFFFFF or error | Address is unmapped on the current title. MEM2 ( |
Controller input has no effect | Game expects input on a different port. Try |
Tool calls hang ~10 s then time out | Bridge script crashed inside Dolphin. Open Felk's Scripting panel, remove the script, re-add it. |
License
MIT — see LICENSE.
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/dmang-dev/mcp-dolphin'
If you have feedback or need assistance with the MCP directory API, please join our Discord server