dmang-dev/mcp-mgba

๐ŸŽฎ Gaming๐ŸŸข Verified Active
0 Views
0 Installs

๐Ÿ“‡ ๐Ÿ  ๐ŸŽ ๐ŸชŸ ๐Ÿง - Drive the mGBA Game Boy Advance emulator from any MCP client: read/write GBA memory, inject button presses, take screenshots, save/load state, and step the emulator. Lua bridge inside mGBA + Node MCP server.

Quick Install

One-Click IDE Configuration
claude_desktop_config.json
{
  "mcpServers": {
    "dmang-dev-mcp-mgba": {
      "command": "npx",
      "args": [
        "-y",
        "dmang-dev-mcp-mgba"
      ]
    }
  }
}
Or

Using an AI coding agent (Claude Code, Cursor, etc.)? Copy a ready-made prompt that tells it to fetch the setup instructions and install this server for you.

Documentation Overview

mcp-mgba

npm version npm downloads CI License: MIT Snyk Socket Bundlephobia npmgraph

An MCP server that exposes the mGBA Game Boy Advance emulator to any MCP-compatible client (Claude Desktop, Claude Code, etc.).

Lets your model read and write GBA memory, inject button presses, take screenshots, and step the emulator โ€” all through a clean tool interface.

demo

Claude driving an in-development homebrew side-scroller through mgba_press_buttons โ€” Start to begin, A to confirm New Game, then Right to walk and A to jump. Each frame is captured via mgba_screenshot.

How it works

+------------------+    stdio     +------------------+   TCP :8765   +------------------+
|   MCP client     |   JSON-RPC   |     mcp-mgba     |  newline JSON |  mGBA emulator   |
| (Claude / etc.)  | ===========> |     (Node.js)    | ============> |    bridge.lua    |
+------------------+              +------------------+               +------------------+

Two pieces:

  • lua/bridge.lua โ€” runs inside mGBA's scripting engine, opens a loopback TCP server on port 8765
  • dist/index.js โ€” Node.js MCP server, talks to the Lua bridge over TCP, exposes tools over stdio

Requirements

  • mGBA 0.10 or newer (with Lua scripting)
  • Node.js 22+ (for the MCP server)

Install

Option A โ€” install from npm (recommended)

npm install -g mcp-mgba

Puts mcp-mgba on your PATH. Verify with mcp-mgba --help (it'll print a startup line and wait for stdio โ€” Ctrl+C to exit).

Option B โ€” npx (no install)

npx -y mcp-mgba

Run on demand. Good for trying it out without committing to a global install.

Option C โ€” clone and develop

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

Then reference the absolute path to dist/index.js when registering, or npm install -g . to symlink the bin globally.

Set up the mGBA bridge

  1. Launch mGBA and load any GBA ROM.
  2. Open Tools > Scriptingโ€ฆ
  3. Click File > Load script and select lua/bridge.lua from this repo.

You should see in the scripting console:

[mcp-mgba] bridge listening on 127.0.0.1:8765
[mcp-mgba] frame callback registered โ€” bridge is active

If you see a bind failed error, the previous instance's socket is still held โ€” quit and relaunch mGBA.

Register with your MCP client

Claude Code (CLI)

claude mcp add mgba --scope user mcp-mgba

(if you used Option B without global install, replace mcp-mgba with node /absolute/path/to/dist/index.js)

Verify:

claude mcp list
# mgba: mcp-mgba - โœ“ Connected

Claude Desktop

Edit claude_desktop_config.json:

PlatformPath
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json
Linux~/.config/Claude/claude_desktop_config.json

Add (assuming Option A โ€” globally installed):

{
  "mcpServers": {
    "mgba": {
      "command": "mcp-mgba"
    }
  }
}

Or with explicit Node + path (Option B):

{
  "mcpServers": {
    "mgba": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-mgba/dist/index.js"]
    }
  }
}

Restart Claude Desktop after editing.

Other MCP clients

The server speaks standard MCP over stdio. Run mcp-mgba (or node dist/index.js) and connect any MCP client to its stdio.

Configuration

Env varDefaultPurpose
MGBA_HOST127.0.0.1Bridge host to dial
MGBA_PORT8765Bridge port to dial

Tools

ToolDescription
mgba_pingVerify bridge connectivity (returns pong)
mgba_get_infoGame title, code, frame count
mgba_read8 / mgba_read16 / mgba_read32Read memory at an address
mgba_write8 / mgba_write16 / mgba_write32Write to RAM
mgba_read_rangeRead up to 4096 bytes as a byte array
mgba_write_rangeWrite up to 4096 bytes from a byte array
mgba_press_buttonsQueue a button press (FIFO; consecutive calls produce distinct events)
mgba_advance_framesStep the emulator N frames
mgba_pause / mgba_unpausePause / resume emulation
mgba_resetReset the loaded ROM
mgba_screenshotSave a PNG of the current display
mgba_save_state / mgba_load_stateSave/load emulator state to a slot or path

See docs/RECIPES.md for end-to-end examples (RAM hunting, snapshot-experiment-restore, side-scroller automation, etc.).

GBA button names

A, B, Select, Start, Right, Left, Up, Down, R, L

GBA address space (cheat sheet)

RangeRegion
0x02000000EWRAM (256 KiB, general)
0x03000000IWRAM (32 KiB, fast)
0x04000000I/O registers
0x05000000Palette RAM
0x06000000VRAM
0x07000000OAM
0x08000000ROM (read-only)

Troubleshooting

SymptomCause / Fix
Cannot reach mGBA bridge at 127.0.0.1:8765mGBA isn't running, or bridge.lua isn't loaded โ€” open Tools > Scripting and load it
bind failed โ€” port 8765 may already be in useA previous mGBA instance still holds the socket; quit and relaunch mGBA
Tool calls hangThe bridge script may have errored out silently after a hot-reload โ€” check the mGBA scripting console
Tools missing in Claude after installRestart your MCP client; Claude only enumerates servers on startup
Tool calls return data shaped like an old version after editing bridge.lua and choosing Load Script againmGBA doesn't fully tear down a previous script when you reload. The new script's bind() may succeed but the old frame callback keeps serving requests. Fix: quit mGBA entirely, relaunch, load the ROM, then load bridge.lua once. Check the console for the frame callback registered line โ€” there should be exactly one.
attempt to index a nil value (global 'emu') at script loadmGBA's emu global only exists once a ROM is loaded. Load any ROM first, then load bridge.lua. (Or load the script first; capability detection will defer until a ROM is loaded.)
emu:foo not available on this mGBA build for pause, unpause, frameAdvance, etc.This particular build of mGBA doesn't expose that method. The bridge feature-detects on the first frame; check mgba_get_info for the full capabilities map. For frameAdvance, the bridge falls back to runFrame then step automatically.
read8/16/32 returns "invoking failed" intermittentlyKnown mGBA Lua quirk โ€” the typed read methods are flaky via pcall from the frame callback. The bridge already routes read8/16/32 through the more reliable readRange internally; if you still see this on a write, the retry loop usually clears it within a few attempts.
Multiple press_buttons calls don't seem to register as distinct eventsOlder mgba_press_buttons (โ‰ค0.1.0) had this bug; v0.2.0+ uses a FIFO queue. Make sure you've upgraded with npm install -g mcp-mgba and restarted your MCP client.

Development

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

The Lua side (lua/bridge.lua and lua/json.lua) needs no build step. Edit and reload via mGBA's File > Load script.

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 bridge address with MGBA_HOST / MGBA_PORT (default 127.0.0.1:8765). tools/list works even without mGBA connected; calling a tool needs mGBA open with lua/bridge.lua loaded.

License

MIT

Related MCP Servers

3aKHP/prts-mcp

๐Ÿ ๐Ÿ“‡ โ˜๏ธ ๐Ÿ  - MCP Server for Arknights, querying the PRTS Wiki API and serving auto-synced operator archives and voice lines from game data. Designed for fan-creation (ๅŒไบบๅ‰ตไฝœ) AI agents. Python (stdio/Docker) and TypeScript (Streamable HTTP) implementations.

๐ŸŽฎ Gaming0 views
alex-gon/thegamecrafter-mcp-server

๐Ÿ“‡ โ˜๏ธ - Design, manage, and price tabletop games on The Game Crafter. Browse catalogs, create projects, upload artwork, get pricing.

๐ŸŽฎ Gaming0 views
antics-gg/antics-mcp

๐Ÿ“‡ โ˜๏ธ - Deploy a single-file HTML game to a shareable multiplayer URL with rooms, state sync, and leaderboards. No backend or player accounts.

๐ŸŽฎ Gaming0 views
beckettlab/beckett-godot-mcp

๐Ÿ  ๐ŸŽ ๐ŸชŸ ๐Ÿง - Beckett โ€” MCP for Godot: a zero-sidecar GDScript editor addon that serves MCP over Streamable HTTP from inside the Godot 4 editor (no Node/Python sidecar). Reflection over any class, validate-before-write GDScript, scene/script/resource authoring, and a runtime play-test loop (play, screenshot, input, assert). MIT.

๐ŸŽฎ Gaming0 views

Engagement

Views
0
Installs
0
Upvotes
0

Views and upvotes are unique per visitor network (hashed IP). Installs count copy actions.

Status

Health: Active

Recent health check succeeded.

Last checked: 7/28/2026, 10:17:00 PM

Unclaimed listing (imported or pending owner verification). Claim it โ†’
โ˜… Spotlight Slot

Feature Your MCP Server

Get maximum visibility for your server across our directory, search results, and detail pages.

Spotlight Your Server

Own this project?

This directory is pre-filled from public sources. Claim via GitHub README, site badge, or DNS TXT to get the verified badge and attach your website.

Claim this listing

Promote this listing

Optional paid placement. Free listings stay free forever.

Share & Embed

Add our SVG badge (dark/light directory styles) or embeddable widget to your site.