pixel-flippers
Enables Claude and other MCP clients to play Pokémon games on emulated Game Boy/GBA or real Switch hardware by exposing tools for button input, reading RAM-decoded game state, screenshots, save states, and persistent markdown notes.
README
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,~/Desktopand~/Downloads— macOS blocks Claude Desktop's child processes from reading those folders unless you grant it access.
Config reference (env vars)
| Variable | Default | Meaning |
|---|---|---|
PIXEL_FLIPPERS_BACKEND |
pyboy |
pyboy (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_VAULT |
unset | Folder for markdown notes (make it a folder inside an Obsidian vault) |
PIXEL_FLIPPERS_SAVES |
<rom dir>/saves |
Save-state directory |
PIXEL_FLIPPERS_GAME |
pokemon_red |
RAM decoder; none disables it (screenshots only — hard mode!) |
PIXEL_FLIPPERS_WINDOW |
SDL2 |
null for headless |
PIXEL_FLIPPERS_SCALE |
3 |
Window scale factor |
PIXEL_FLIPPERS_SPEED |
1 |
Emulation speed (0 = unbounded) |
PIXEL_FLIPPERS_MOCK |
off | Fake emulator, no ROM/PyBoy needed — for tests and plumbing checks |
PIXEL_FLIPPERS_TRANSPORT |
stdio |
http serves MCP at http://127.0.0.1:<port>/mcp for the pf CLI / Claude Code |
PIXEL_FLIPPERS_PORT |
8765 |
Port for the http transport |
PIXEL_FLIPPERS_PLAYER |
unset | Player 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
| Tool | What it is |
|---|---|
press_buttons |
Hands — sequence of a/b/start/select/up/down/left/right (+ l/r on GBA) |
read_game_state |
Cheap text report decoded from WRAM (location, party, HP, money, badges, bag, battle) |
get_screenshot |
Eyes — 2× upscaled PNG, use sparingly |
wait |
Let N frames pass (dialogs, animations) |
save_state / load_state / list_states |
Named full-game snapshots |
write_note / append_note / read_note / list_notes / search_notes |
The diary — markdown in the vault |
read_last_session |
Wake-up ritual: Status + goals + recent journal + current state, for reorienting after compaction |
set_goal / complete_goal / current_goals |
Persistent objective checklist (a Goals.md note) |
read_memory |
Raw hex peek at any address, for the curious |
freeze / resume / move_stick |
Real-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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。