Featured

Deploy OpenClaw in 60 seconds β€” 20% off logoDeploy OpenClaw in 60 seconds β€” 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger β†’
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger β†’
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free β†’
6,000+ web scrapers for your AI agent, start free logo6,000+ web scrapers for your AI agent, start free

Apify gives your agent live web data: 6,000+ prebuilt scrapers and actors, MCP-ready. Sign up free with $5 in usage credits.

Try Apify free β†’
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data β€” no proxies, no parsers, no maintenance.

Start building free β†’
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it β€” secured from day one.

Get it set up for you β†’
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free β†’
Reach 48,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here β†’

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

dmang-dev/mcp-bizhawk MCP server](https://glama.ai/mcp/servers/dmang-dev/mcp-bizhawk/badges/score.svg)](https://glama.ai/mcp/servers/dmang-dev/mcp-bizhawk) πŸ“‡ 🏠 🍎 πŸͺŸ 🐧 - Drive the BizHawk multi-system emulator from any MCP client.

README.md

mcp-bizhawk

![npm version](https://www.npmjs.com/package/mcp-bizhawk) ![npm downloads](https://www.npmjs.com/package/mcp-bizhawk) ![CI](https://github.com/dmang-dev/mcp-bizhawk/actions/workflows/ci.yml) ![License: MIT](LICENSE) ![Snyk](https://snyk.io/test/npm/mcp-bizhawk) ![Socket](https://socket.dev/npm/package/mcp-bizhawk) ![Bundlephobia](https://bundlephobia.com/package/mcp-bizhawk) ![npmgraph](https://npmgraph.js.org/?q=mcp-bizhawk)

An MCP server that exposes BizHawk β€” the multi-system emulator the TAS community lives in β€” to any MCP-compatible client (Claude Desktop, Claude Code, etc.).

One bridge, many systems: NES, SNES, Game Boy / GBC / GBA, Sega Master System / Genesis / 32X / Saturn, N64, PlayStation 1, Atari 2600/5200/7800, Lynx, ColecoVision, Intellivision, and more β€” all through the same MCP tools, with per-system memory domains exposed cleanly.

<p align="center"> <img src="docs/sm-claude-play.gif" alt="Claude driving Super Metroid through mcp-bizhawk"> </p>

<p align="center"><em>Claude (the agent) drives Samus through the opening of Ceres Station β€” all input batched through <code>bizhawk_play_input_sequence</code>, all motion verified by reading WRAM addresses found via live RAM-hunt. Recording is 2Γ— speed; the actual playback runs at native 60fps emulation. See <a href="docs/RECIPES.md"><code>docs/RECIPES.md</code></a> and <a href="docs/SUPER-METROID-ADDRESSES.md"><code>docs/SUPER-METROID-ADDRESSES.md</code></a> for the workflow.</em></p>

How it works

+------------------+    stdio     +------------------+   TCP :8766   +------------------+
|   MCP client     |   JSON-RPC   |    mcp-bizhawk   |  newline JSON |     BizHawk      |
| (Claude / etc.)  | ===========> |     (Node.js)    | <============ |    bridge.lua    |
+------------------+              +------------------+               +------------------+

The transport is inverted compared to most other emulator-MCP bridges: BizHawk's Lua doesn't have native server sockets, only an outbound comm.socketServer* client. So mcp-bizhawk runs the TCP listener, and BizHawk's Lua bridge dials in once per frame to ferry commands and replies.

Two pieces:

  • lua/bridge.lua β€” runs inside BizHawk's Lua Console, polls our TCP server once per frame
  • dist/index.js β€” the Node.js MCP server, listens on 127.0.0.1:8766 by default, exposes tools over stdio

Trade-off: this design adds ~one frame of latency per call (β‰ˆ16ms at 60Hz). Fine for interactive memory hunting, save-state experimentation, and frame-by-frame inspection. Less ideal for high-rate-of-fire scripting.

Requirements

  • BizHawk 2.6.2 or newer (earlier builds use an older socket-server wire format)
  • Node.js 22+ (for the MCP server)

Tested on BizHawk 2.11.1 across SNES (Super Metroid). Should work on any system BizHawk supports.

Install

Option A β€” install from npm (recommended)

npm install -g mcp-bizhawk

Option B β€” npx (no install)

npx -y mcp-bizhawk

Option C β€” clone and develop

git clone https://github.com/dmang-dev/mcp-bizhawk
cd mcp-bizhawk
npm install        # also runs the build via the `prepare` hook

Set up the BizHawk bridge

There are two pieces to configure: telling BizHawk where to connect, and loading the bridge script.

1. Point BizHawk at the MCP server

Easiest: launch BizHawk with the socket flags directly.

EmuHawk.exe --socket_ip=127.0.0.1 --socket_port=8766 <path/to/rom>

(Adjust port if you're overriding BIZHAWK_PORT.)

Alternative: configure persistently via Settings β†’ Customize β†’ External Tools in BizHawk's UI.

2. Load the bridge script

In BizHawk: Tools β†’ Lua Console β†’ Open Script β†’ select lua/bridge.lua from this repo.

You should see in the Lua Console: `` [mcp-bizhawk] bridge starting [mcp-bizhawk] socket server target: 127.0.0.1:8766 [mcp-bizhawk] socket receive timeout set to 50ms [mcp-bizhawk] frame loop active β€” bridge is polling once per frame ``

And in the mcp-bizhawk process's stderr: `` [mcp-bizhawk] BizHawk client connected (waiting for bridge.lua to start polling) [mcp-bizhawk] bridge.lua is polling β€” bridge ready ``

Register with your MCP client

Claude Code (CLI)

claude mcp add bizhawk --scope user mcp-bizhawk

Verify: ```bash claude mcp list

bizhawk: mcp-bizhawk - βœ“ Connected


### Claude Desktop

Edit `claude_desktop_config.json`:

| Platform | Path |
|---|---|
| macOS    | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows  | `%APPDATA%\Claude\claude_desktop_config.json` |
| Linux    | `~/.config/Claude/claude_desktop_config.json` |

{ "mcpServers": { "bizhawk": { "command": "mcp-bizhawk" } } } ```

Restart Claude Desktop after editing.

Other MCP clients

The server speaks standard MCP over stdio. Run mcp-bizhawk and connect any MCP client to its stdio.

Configuration

| Env var | Default | Purpose | |----------------|---------------|--------------------------------------| | BIZHAWK_HOST | 127.0.0.1 | TCP host to listen on for BizHawk | | BIZHAWK_PORT | 8766 | TCP port to listen on for BizHawk |

Tools

| Tool | Description | |------|-------------| | bizhawk_ping | Verify bridge connectivity (returns pong) | | bizhawk_get_info | ROM name, ROM hash, framecount, memory domains, capabilities | | bizhawk_list_memory_domains | List available memory domains for the loaded core | | bizhawk_read8 / bizhawk_read16 / bizhawk_read32 | Read u8 / u16-LE / u32-LE from memory | | bizhawk_write8 / bizhawk_write16 / bizhawk_write32 | Write to memory | | bizhawk_read_range | Read up to 4096 bytes as a byte array | | bizhawk_write_range | Write up to 4096 bytes from a byte array | | bizhawk_press_buttons | Set joypad state for one player; keys are button names, values booleans | | bizhawk_frame_advance | Step the emulator by N frames | | bizhawk_pause / bizhawk_unpause | Pause / resume emulation | | bizhawk_reset | Reset the loaded core | | bizhawk_screenshot | Save a PNG of the current display to a path | | bizhawk_save_state / bizhawk_load_state | Save / load emulator state to a file path |

All memory r/w tools take an optional domain parameter β€” if omitted, the active "current" memory domain is used. Use bizhawk_list_memory_domains to discover the names available on the loaded core.

See docs/RECIPES.md for end-to-end examples (RAM hunting on SNES/NES/N64, frame-precise input, snapshot-experiment-restore, cross-system regression testing) and CHANGELOG.md for release history.

Memory domains by system (cheat sheet)

Names come straight from BizHawk's core implementation. Use bizhawk_list_memory_domains to see the exact set for the loaded ROM.

| System | Main RAM domain | Other common domains | |---------|-----------------|-----------------------------------| | NES | RAM | PPU, OAM, PRG ROM, CHR | | SNES | WRAM | VRAM, CARTROM, CARTRAM | | GB/GBC | WRAM | VRAM, HRAM, OAM, ROM | | GBA | EWRAM, IWRAM| VRAM, PALRAM, OAM, ROM | | Genesis | 68K RAM | VRAM, Z80 RAM, CARTRAM | | N64 | RDRAM | SP DMEM, SP IMEM, PI Reg | | PSX | MainRAM | VRAM, Scratchpad, BIOS |

Buttons by system

BizHawk's joypad.set takes a {ButtonName=true, ...} table where button names depend on the core. Common ones:

| System | Names | |---------|---------------------------------------------------------------------| | NES | A, B, Up, Down, Left, Right, Start, Select | | SNES | A, B, X, Y, L, R, Up, Down, Left, Right, Start, Select | | GB/GBC | A, B, Up, Down, Left, Right, Start, Select | | GBA | A, B, L, R, Up, Down, Left, Right, Start, Select | | N64 | A, B, Z, L, R, Start, Up, Down, Left, Right, C-Up, C-Down, C-Left, C-Right | | Genesis | A, B, C, X, Y, Z, Up, Down, Left, Right, Start, Mode |

If you're unsure, run a probe: bizhawk_press_buttons {"A": true} and watch the active core's input display in BizHawk.

Troubleshooting

| Symptom | Cause / Fix | |---|---| | MCP tool calls hang for 10 seconds, then time out with "is the bridge.lua script still polling?" | bridge.lua isn't loaded. In BizHawk: Tools β†’ Lua Console β†’ Open Script β†’ bridge.lua. Check the console for frame loop active. | | BizHawk connects to the server but tool calls still time out | You're on BizHawk older than 2.6.2 β€” the socket wire format changed then. Upgrade BizHawk. | | [mcp-bizhawk] FATAL: comm.socketServer not available in the Lua Console | BizHawk wasn't launched with --socket_ip / --socket_port flags, and no socket server is configured in Settings β†’ Customize β†’ External Tools. | | Tools missing in Claude after install | Restart your MCP client; Claude only enumerates servers on startup. | | Memory reads return zeros for the first few seconds after boot | The emulator hasn't initialized RAM yet. Either advance some frames (bizhawk_frame_advance) or check bizhawk_get_info to confirm framecount > 0 before relying on game state. | | unknown memory domain: <name> | The domain name didn't match anything for the loaded core. Call bizhawk_list_memory_domains to see the actual list β€” names are case-sensitive. | | client.screenshot not available or savestate. not available | Some BizHawk cores expose a slightly different surface. Check bizhawk_get_info β€” the capabilities map shows which optional functions are present on your current build/core combo. |

Development

npm install
npm run dev      # tsc --watch β€” autobuilds on src/ changes

End-to-end smoke test (launches BizHawk, loads ROM + bridge, runs ping/get_info/list_memory_domains/read_range):

node .scratch/test-all.cjs "I:\path\to\your\rom.smc"

Set DEBUG=1 to dump every RX/TX line.

Debugging with the MCP Inspector

Browse and call this server's tools interactively with the MCP Inspector:

npm run inspector

Build first if you've edited src/ since your last npm install (npm run build, or keep npm run dev running). Override the listener with BIZHAWK_HOST / BIZHAWK_PORT (default 127.0.0.1:8766). tools/list works even without BizHawk connected; calling a tool needs EmuHawk running with the socket flags and lua/bridge.lua loaded.

License

MIT

See related servers & alternatives β†’

Related MCP servers

Browse all β†’

Related guides

Hand-picked reading to help you choose and use Vector & Memory servers.