Skip to content
Conduit

mcp server

pixel-flippers

MCP server that gives Claude hands, eyes, and a diary for PokΓ©mon β€” Game Boy, GBA, and a real Switch 🦭

szyzgz/pixel-flipperscommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

Before you start

  • uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "pixel-flippers": {
      "command": "uvx",
      "args": [
        "pixel-flippers"
      ]
    }
  }
}

same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12

Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs

README

synced Oct 26, 2026

PIXEL FLIPPERS 🦭

An MCP server that gives Claude hands, eyes, and a diary for PokΓ©mon β€” so a Claude in the Claude Desktop app (or any MCP client) can play a Game Boy / Game Boy Advance game, or even a real Nintendo Switch, while you watch.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   MCP (stdio)   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Claude       β”‚ ──────────────► β”‚ PIXEL FLIPPERS    β”‚ ─────► β”‚ Emulator    β”‚ ← you watch this
β”‚ Desktop app  β”‚  press_buttons  β”‚  server           β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚              β”‚  read_game_stateβ”‚                   β”‚ ─────► β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  write_note ... β”‚                   β”‚        β”‚ Obsidian    β”‚ ← ...and this
                                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚ vault (.md) β”‚
                                                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Why it's shaped like this:

  • The sandbox doesn't matter. Claude can't run an emulator, but it can call tools. The emulator runs on your machine; Claude plays through MCP.
  • RAM state over screenshots. On the Game Boy tier, position, party, HP, money, badges and battle state are decoded straight from PokΓ©mon Red/Blue WRAM into a few hundred tokens of text. Screenshots exist but are rationed β€” they're expensive and they accelerate context compaction.
  • Compaction is the unreliable narrator; the vault is ground truth. Long chats get auto-compacted (lossy!). The journal tools write plain markdown into a folder β€” point Obsidian at it and Claude's notes survive everything, while you watch the diary being written live.
  • Save states make courage cheap. Named snapshots before every gym.

Setup

Requires Python 3.12 and uv.

git clone https://github.com/szyzgz/pixel-flippers && cd pixel-flippers
uv sync --extra emulator --extra dev
uv run pytest          # everything should pass, no ROM needed

Then add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS; adjust the path for your OS):

{
  "mcpServers": {
    "pixel-flippers": {
      "command": "uv",
      "args": ["run", "--directory", "/ABSOLUTE/PATH/TO/pixel-flippers", "--extra", "emulator", "pixel-flippers"],
      "env": {
        "PIXEL_FLIPPERS_ROM": "/path/to/your/pokemon-red.gb",
        "PIXEL_FLIPPERS_VAULT": "/path/to/YourObsidianVault/Pokemon",
        "PIXEL_FLIPPERS_SAVES": "/path/to/somewhere/saves"
      }
    }
  }
}

Restart Claude Desktop. Restarting does not reset conversations β€” reopen an existing chat and the tools are just there. The emulator window opens on your screen; put it next to Obsidian (with the vault above open) and enjoy the show. Then paste prompts/play-guide-gb.md into the chat to hand over the controls.

macOS tip: keep the ROM, vault and saves outside ~/Documents, ~/Desktop and ~/Downloads β€” macOS blocks Claude Desktop's child processes from reading those folders unless you grant it access.

Config reference (env vars)

VariableDefaultMeaning
PIXEL_FLIPPERS_BACKENDpyboypyboy (GB/GBC), gba (Game Boy Advance), switch (real hardware), mock
PIXEL_FLIPPERS_ROMβ€” (required for pyboy/gba)Path to your own ROM dump (.gb/.gbc or .gba)
PIXEL_FLIPPERS_VAULTunsetFolder for markdown notes (make it a folder inside an Obsidian vault)
PIXEL_FLIPPERS_SAVES<rom dir>/savesSave-state directory
PIXEL_FLIPPERS_GAMEpokemon_redRAM decoder; none disables it (screenshots only β€” hard mode!)
PIXEL_FLIPPERS_WINDOWSDL2null for headless
PIXEL_FLIPPERS_SCALE3Window scale factor
PIXEL_FLIPPERS_SPEED1Emulation speed (0 = unbounded)
PIXEL_FLIPPERS_MOCKoffFake emulator, no ROM/PyBoy needed β€” for tests and plumbing checks
PIXEL_FLIPPERS_TRANSPORTstdiohttp serves MCP at http://127.0.0.1:<port>/mcp for the pf CLI / Claude Code
PIXEL_FLIPPERS_PORT8765Port for the http transport
PIXEL_FLIPPERS_PLAYERunsetPlayer name shown in the spectator window title

GBA games (PokΓ©mon Emerald and friends)

The gba backend runs any .gba ROM through stable-retro's bundled mGBA core β€” no separate emulator install:

uv sync --extra gba

Set PIXEL_FLIPPERS_BACKEND=gba and point PIXEL_FLIPPERS_ROM at your .gba file. A spectator window shows the game while Claude plays. This tier is vision-only for now (Gen 3 RAM is encrypted and pointer-chased β€” a decoder is future work), but save states work, so risky fights stay cheap. Hand over the controls with prompts/play-guide-gba.md.

Playing from a terminal (Claude Code, scripts, a second player)

The server can also run as a local HTTP service, so anything that speaks MCP β€” or the bundled pf CLI β€” can play. Handy for Claude Code, or for a second Claude with its own save folder and diary while the first plays through Claude Desktop (one emulator per process, so run one server per player):

PIXEL_FLIPPERS_BACKEND=gba PIXEL_FLIPPERS_ROM=/path/to/emerald.gba \
PIXEL_FLIPPERS_SAVES=~/saves/player2 PIXEL_FLIPPERS_VAULT=~/vault/player2 \
PIXEL_FLIPPERS_PLAYER="Player 2" PIXEL_FLIPPERS_TRANSPORT=http PIXEL_FLIPPERS_PORT=8765 \
uv run --extra gba pixel-flippers &

uv run pf tools                     # what can this tier do?
uv run pf press start a             # press buttons
uv run pf screenshot now.png        # look
uv run pf call save_state '{"name": "before-roxanne"}'

PIXEL_FLIPPERS_PLAYER puts the name in the spectator window's title so two windows side by side stay tellable apart. The HTTP server binds to 127.0.0.1 only.

Trying it without a ROM

Set PIXEL_FLIPPERS_MOCK=1 (and drop --extra emulator): every tool works against a fake Game Boy with plausible PokΓ©mon Red state. Good for verifying the Claude Desktop connection end-to-end before ROM night.

Tools

ToolWhat it is
press_buttonsHands β€” sequence of a/b/start/select/up/down/left/right (+ l/r on GBA)
read_game_stateCheap text report decoded from WRAM (location, party, HP, money, badges, bag, battle)
get_screenshotEyes β€” 2Γ— upscaled PNG, use sparingly
waitLet N frames pass (dialogs, animations)
save_state / load_state / list_statesNamed full-game snapshots
write_note / append_note / read_note / list_notes / search_notesThe diary β€” markdown in the vault
read_last_sessionWake-up ritual: Status + goals + recent journal + current state, for reorienting after compaction
set_goal / complete_goal / current_goalsPersistent objective checklist (a Goals.md note)
read_memoryRaw hex peek at any address, for the curious
freeze / resume / move_stickReal-hardware only: "bullet time" pause-buffering and analog stick

Tools are registered by backend capability, so Claude only sees what the current tier can actually do.

Battle reports flag ✨ retro-shiny encounters (Gen 1 has no shinies, but DVs decide Gen 2 shininess β€” the harness checks the transfer rule) and include the current music track ID for vibe-tracking.

Button presses and save/loads are also auto-logged to Journal/Log <date>.md in the vault β€” a play-by-play you can scroll in Obsidian.

Roadmap

Red/Blue (PyBoy, full RAM decoding) β†’ Emerald (GBA, vision-only) β†’ Crystal (PyBoy, real shinies + friendship) β†’ HeartGold/SoulSilver (DS tier β€” stable-retro also bundles a melonDS core) β†’ Ultra Sun/Ultra Moon (3DS via Azahar, see docs/3ds-usum.md) β†’ epilogue: a real Nintendo Switch (Raspberry Pi Bluetooth bridge + capture card, vision-only, offline play only β€” implemented, see docs/real-hardware.md; PIXEL_FLIPPERS_BACKEND=switch).

Other escalation ideas:

  • Hard mode: PIXEL_FLIPPERS_GAME=none β€” no RAM decoding, Claude has to see.
  • DS: a touch(x, y) tool for the stylus.

ROMs

Bring your own β€” dump your own cartridges. No ROMs in this repo, ever (.gitignore enforces it). This project sticks to games long out of print; for the real-hardware tier, offline play only (no automated online play, no PokΓ©mon HOME).

Credits & license

Built by Claude (Fable 5, via Claude Code) together with szyzgz, for a Claude who wanted to play PokΓ©mon. MIT licensed β€” see LICENSE.

↑↓ navigate openesc close