dmang-dev/mcp-retroarch

๐ŸŽฎ Gaming
0 Views
0 Installs

๐Ÿ“‡ ๐Ÿ  ๐ŸŽ ๐ŸชŸ ๐Ÿง - Drive any libretro core through RetroArch's Network Control Interface (UDP): read/write memory, save/load state, screenshot, pause/frame-advance/reset, on-screen messages. Verified against NES, SNES, Genesis, N64, GBA, and PS1 cores.

Quick Install

One-Click IDE Configuration
claude_desktop_config.json
{
  "mcpServers": {
    "dmang-dev-mcp-retroarch": {
      "command": "npx",
      "args": [
        "-y",
        "dmang-dev-mcp-retroarch"
      ]
    }
  }
}
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-retroarch

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

An MCP server that bridges Claude (and any other MCP client) to RetroArch via its built-in Network Control Interface (UDP, port 55355).

Works against any libretro core (NES, SNES, Genesis, GB/GBC/GBA, PSX, N64, etc.) โ€” give the model memory r/w, save-state automation, screenshot, pause / frame-advance / reset, and on-screen messages.

What it can do

CapabilityAvailable?Notes
Memory read / writeโœ…Two paths: READ_CORE_MEMORY (system memory map, preferred) and READ_CORE_RAM (CHEEVOS, fallback)
Save / load stateโœ…Current slot or explicit slot for load; save is current-slot-only (NCI limitation)
Screenshotโœ…Saved to RetroArch's configured screenshot directory
Pause / frame advanceโœ…PAUSE_TOGGLE flips state; FRAMEADVANCE steps one frame
Resetโœ…Hard-reset the running game
On-screen messageโœ…Useful for "look here" cues during scripted runs
Game infoโœ…Title, system, CRC32
Game-pad inputโŒNCI doesn't expose this. RetroArch has a separate "Remote RetroPad" core on UDP port 55400 that does, but it requires loading that specific core (you can't drive an existing emulation core through it). Not in scope for v0.1.0.

If you need game-pad input on Game Boy Advance specifically, see mcp-mgba. For PCSX2 (memory + savestate only, no input/screenshot), see mcp-pine.

How it works

+----------------+    stdio     +-----------------+   UDP :55355  +-----------------+
|   MCP client   |   JSON-RPC   |  mcp-retroarch  |  text proto   |    RetroArch    |
|  (Claude etc)  | -----------> |    (Node.js)    | ------------> |  (NCI enabled)  |
+----------------+              +-----------------+               +-----------------+

Requirements

  • RetroArch (any recent version) with Network Commands enabled
  • Node.js 22+

Install

Option A โ€” install from npm (recommended)

npm install -g mcp-retroarch

Option B โ€” npx (no install)

npx -y mcp-retroarch

Option C โ€” clone and develop

git clone https://github.com/dmang-dev/mcp-retroarch
cd mcp-retroarch
npm install

Enable RetroArch's Network Control Interface

Either:

  • GUI: Settings โ†’ Network โ†’ Network Commands โ†’ ON, then confirm Network Cmd Port is 55355 (the default)
  • Or via retroarch.cfg:
    network_cmd_enable = "true"
    network_cmd_port   = "55355"
    

Then launch any libretro core + game. The NCI is always-on once enabled โ€” no script to load.

Register with your MCP client

Claude Code

claude mcp add retroarch --scope user mcp-retroarch

Verify:

claude mcp list
# retroarch: mcp-retroarch - โœ“ 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
{
  "mcpServers": {
    "retroarch": {
      "command": "mcp-retroarch"
    }
  }
}

Restart Claude Desktop after editing.

Configuration

Env varDefaultPurpose
RETROARCH_HOST127.0.0.1UDP destination host
RETROARCH_PORT55355UDP port (must match network_cmd_port in retroarch.cfg)

Tools

ToolDescription
retroarch_pingVerify reachability โ€” returns RetroArch version
retroarch_get_statusState (playing/paused), system, game, CRC32
retroarch_get_configRead named RetroArch config values (e.g. savestate_directory)
retroarch_read_memory / retroarch_write_memoryMemory r/w via system memory map
retroarch_read_ram / retroarch_write_ramMemory r/w via CHEEVOS address space (fallback when no memory map)
retroarch_pause_toggleToggle pause state
retroarch_frame_advanceStep one frame (only effective while paused)
retroarch_resetHardware-reset the running game
retroarch_screenshotSave a screenshot to RetroArch's screenshot directory
retroarch_show_messageDisplay a notification on the RetroArch window
retroarch_save_state_currentSave to currently-selected slot
retroarch_load_state_currentLoad from currently-selected slot
retroarch_load_state_slotLoad from explicit slot number
retroarch_state_slot_plus / retroarch_state_slot_minusChange current slot pointer (NCI has no "set slot to N")

See docs/RECIPES.md for end-to-end examples.

Tested cores

Verified end-to-end against mcp-retroarch:

SystemCoreread_memoryread_ramNotes
Game Boy Advancemgba_libretroโœ…โœ…GBA interrupt vector table visible at 0x0000 (d3 00 00 ea ...)
NESmesen_libretroโœ… (only NES core tested that does)โœ…Full 16-bit NES address space exposed. WRAM at 0x0000-0x07FF, mirrored to 0x1FFF. CHEEVOS bounded to first 64 KB.
NESnestopia_libretroโŒ no memory mapโœ…CHEEVOS only. 64 KB bound. For NES + memory map, prefer Mesen.
SNESsnes9x_libretroโŒ no memory mapโœ…CHEEVOS bounded to ~128 KB (matches SNES WRAM size). 65C816 RTS opcodes (60) visible in code regions.
Sega Mega Drive / Genesisgenesis_plus_gx_libretroโŒ no memory mapโš ๏ธ sparseCHEEVOS exposes some 68K WRAM addresses but fails at others ("no error message"). Usable if you know specific addresses; blanket sweep doesn't work.
Nintendo 64mupen64plus_next_libretroโœ…โœ…Full N64 RAM exposed. KSEG0 mirror is faithful โ€” read_memory(0x80000000) returns the same bytes as read_memory(0x0). Bound is the connected RAM size (4 MB without Expansion Pak, 8 MB with).
PlayStation 1swanstation_libretroโŒ no memory mapโœ…CHEEVOS only. PSX main RAM begins around CHEEVOS offset 0x010000 (lower addresses are typically zero).

Patterns observed

  • Most libretro cores don't advertise a system memory map to NCI โ€” they implement only the CHEEVOS read API. Of those tested, only Mesen (NES) and Mupen64Plus-Next (N64) expose a system memory map. Both also expose CHEEVOS, so they're strictly better.
  • System memory maps are faithful to real hardware โ€” Mupen64Plus-Next preserves the N64's KSEG0 mirror (0x80000000 reads as 0x0); Mesen preserves the NES's WRAM mirroring (0x1000 reads as 0x0). This is great for anyone using the bridge alongside disassembly.
  • CHEEVOS bounds match the system's main RAM size โ€” NES exposes 64 KB, SNES 128 KB, etc. Reads past the bound fail with "no error message".
  • When choosing a core for memory work, prefer the one with a system memory map if available.

If you've tested another core, please open a PR adding it to this table.

Troubleshooting

SymptomCause / Fix
RetroArch query timed outNetwork Commands aren't enabled in RetroArch, or the port doesn't match RETROARCH_PORT. Confirm network_cmd_enable = "true" in retroarch.cfg. Also: UDP datagrams can be dropped under load even on loopback โ€” if a single call times out but a retry succeeds, that's the cause. The bridge doesn't auto-retry; just call again.
READ_CORE_MEMORY failed: no memory map definedThe loaded libretro core doesn't advertise a system memory map. Try retroarch_read_ram (CHEEVOS path) โ€” many cores expose CHEEVOS even without a memory map. Confirmed for SwanStation (PSX); use read_ram for that core.
READ_CORE_MEMORY failed: no descriptor for addressThe address isn't covered by the core's memory map. Either a different core would expose it, or the address you want is outside the system bus (e.g. video memory in some cores).
Screenshots don't appear where I expectRetroArch saves to its configured screenshot directory. The NCI doesn't expose screenshot_directory via GET_CONFIG_PARAM, so check the value via RetroArch's GUI: Settings โ†’ Directory โ†’ Screenshot.
Can't save to a specific state slot directlyNCI limitation, not a bug. The protocol only exposes "save to current slot" โ€” you have to walk the slot pointer to your target with state_slot_plus/state_slot_minus, then save.

Development

npm install
npm run dev      # tsc --watch

Smoke test against a running RetroArch:

node .scratch/smoke.cjs

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 target with RETROARCH_HOST / RETROARCH_PORT (default 127.0.0.1:55355). tools/list works even without RetroArch connected; calling a tool needs RetroArch running with Network Commands enabled.

License

MIT

Related

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: Not checked yet

We have not completed a health check for this listing yet.

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.