Skip to main content
Glama
szyzgz
by szyzgz

PIXEL FLIPPERS 🦭

一个 MCP 服务器,给 Claude 手、眼睛和日记—— 这样 Claude Desktop 应用(或任何 MCP 客户端)里的 Claude 就能玩 Game Boy / Game Boy Advance 游戏,甚至是一台真正的 Nintendo Switch,而你在一旁观看。

┌──────────────┐   MCP (stdio)   ┌──────────────────┐        ┌─────────────┐
│ Claude       │ ──────────────► │ PIXEL FLIPPERS    │ ─────► │ Emulator    │ ← you watch this
│ Desktop app  │  press_buttons  │  server           │        └─────────────┘
│              │  read_game_state│                   │ ─────► ┌─────────────┐
└──────────────┘  write_note ... │                   │        │ Obsidian    │ ← ...and this
                                 └──────────────────┘         │ vault (.md) │
                                                              └─────────────┘

为什么做成这样:

  • 沙盒无关紧要。 Claude 无法运行模拟器,但它可以调用工具。模拟器在你的机器上运行;Claude 通过 MCP 游玩。

  • RAM 状态优先于截图。 在 Game Boy 层级,位置、队伍、HP、金钱、徽章和战斗状态直接从 Pokémon Red/Blue 的 WRAM 解码为几百个 token 的文本。截图存在但被限量供应——它们很昂贵,而且会加速上下文压缩。

  • 压缩是不可靠的叙述者;保险库才是事实来源。 长对话会被自动压缩(有损!)。日志工具把纯 markdown 写进一个文件夹——让 Obsidian 指向它,Claude 的笔记就能在一切情况下幸存,而你则能实时看着日记被写出来。

  • 存档状态让勇气变得廉价。 每个道馆前都做带命名的快照。

设置

需要 Python 3.12 和 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

然后添加到 ~/Library/Application Support/Claude/claude_desktop_config.json(macOS;请根据你的操作系统调整路径):

{
  "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"
      }
    }
  }
}

重启 Claude Desktop。重启不会重置对话——重新打开一个现有聊天,工具就在那里。模拟器窗口会在你的屏幕上打开;把它放在 Obsidian 旁边(打开上面的保险库),然后享受表演。然后把 prompts/play-guide-gb.md 粘贴到聊天中,交出控制权。

macOS 提示: 把 ROM、保险库和存档放在 ~/Documents、~/Desktop 和 ~/Downloads 之外——除非你授予权限,否则 macOS 会阻止 Claude Desktop 的子进程读取这些文件夹。

配置参考(环境变量)

变量

默认值

含义

PIXEL_FLIPPERS_BACKEND

pyboy

pyboy(GB/GBC)、gba(Game Boy Advance)、switch(真实硬件)、mock

PIXEL_FLIPPERS_ROM

—(pyboy/gba 必需)

你自己 ROM 转储的路径(.gb/.gbc 或 .gba)

PIXEL_FLIPPERS_VAULT

未设置

markdown 笔记的文件夹(把它做成 Obsidian 保险库里的一个文件夹)

PIXEL_FLIPPERS_SAVES

<rom dir>/saves

存档状态目录

PIXEL_FLIPPERS_GAME

pokemon_red

RAM 解码器;none 禁用它(仅截图——困难模式!)

PIXEL_FLIPPERS_WINDOW

SDL2

null 表示无头模式

PIXEL_FLIPPERS_SCALE

3

窗口缩放系数

PIXEL_FLIPPERS_SPEED

1

模拟速度(0 = 无限制)

PIXEL_FLIPPERS_MOCK

关闭

假模拟器,不需要 ROM/PyBoy——用于测试和管道检查

PIXEL_FLIPPERS_TRANSPORT

stdio

http 在 http://127.0.0.1:<port>/mcp 上为 pf CLI / Claude Code 提供 MCP 服务

PIXEL_FLIPPERS_PORT

8765

http 传输的端口

PIXEL_FLIPPERS_PLAYER

未设置

显示在观众窗口标题中的玩家名称

GBA 游戏(Pokémon Emerald 和朋友们)

gba 后端通过 stable-retro 捆绑的 mGBA 核心运行任何 .gba ROM——无需单独安装模拟器:

uv sync --extra gba

设置 PIXEL_FLIPPERS_BACKEND=gba 并把 PIXEL_FLIPPERS_ROM 指向你的 .gba 文件。观众窗口会在 Claude 游玩时显示游戏画面。这个层级目前仅支持视觉(Gen 3 的 RAM 是加密的且需要指针追踪——解码器是未来的工作),但存档状态可用,所以冒险的战斗依然廉价。用 prompts/play-guide-gba.md 交出控制权。

从终端游玩(Claude Code、脚本、第二个玩家)

服务器也可以作为本地 HTTP 服务运行,所以任何能说 MCP 的东西——或捆绑的 pf CLI——都可以游玩。对 Claude Code 很方便,或者当第一个 Claude 通过 Claude Desktop 游玩时,给第二个 Claude 自己的存档文件夹和日记(每个进程一个模拟器,所以每个玩家运行一个服务器):

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 把名字放进观众窗口的标题里,这样并排的两个窗口就能区分开。HTTP 服务器只绑定到 127.0.0.1。

在没有 ROM 的情况下试用

设置 PIXEL_FLIPPERS_MOCK=1(并去掉 --extra emulator):所有工具都能针对一个具有合理 Pokémon Red 状态的假 Game Boy 工作。适合在 ROM 之夜前端到端验证 Claude Desktop 连接。

Related MCP server: mcp-dolphin

工具

工具

是什么

press_buttons

双手——a/b/start/select/上/下/左/右 的按键序列(GBA 上还有 l/r)

read_game_state

从 WRAM 解码出的廉价文本报告(位置、队伍、HP、金钱、徽章、背包、战斗)

get_screenshot

眼睛——2 倍放大的 PNG,请谨慎使用

wait

让 N 帧过去(对话框、动画)

save_state / load_state / list_states

带命名的全游戏快照

write_note / append_note / read_note / list_notes / search_notes

日记——保险库中的 markdown

read_last_session

唤醒仪式:状态 + 目标 + 最近的日志 + 当前状态,用于压缩后重新定位

set_goal / complete_goal / current_goals

持久化的目标清单(一个 Goals.md 笔记)

read_memory

对任意地址的原始十六进制窥视,给好奇的人

freeze / resume / move_stick

仅限真实硬件:“子弹时间”暂停缓冲和模拟摇杆

工具按后端能力注册,所以 Claude 只看到当前层级实际能做的事情。

战斗报告会标记 ✨ retro-shiny 遭遇(Gen 1 没有闪光,但 DVs 决定 Gen 2 的闪光——验证框架会检查转移规则),并包含当前音乐曲目 ID 以追踪氛围。

按键和存档/读档也会自动记录到保险库中的 Journal/Log <date>.md——一份你可以在 Obsidian 里滚动的逐回合记录。

路线图

红/蓝(PyBoy,完整 RAM 解码)→ Emerald(GBA,仅视觉)→ Crystal(PyBoy,真正的闪光 + 亲密度)→ HeartGold/SoulSilver(DS 层级——stable-retro 还捆绑了 melonDS 核心)→ Ultra Sun/Ultra Moon(通过 Azahar 的 3DS,见 docs/3ds-usum.md)→ 尾声:一台真正的 Nintendo Switch(Raspberry Pi 蓝牙桥接 + 采集卡,仅视觉,仅离线游玩——已实现,见 docs/real-hardware.md;PIXEL_FLIPPERS_BACKEND=switch)。

其他扩展思路:

  • 困难模式: PIXEL_FLIPPERS_GAME=none——没有 RAM 解码,Claude 必须亲眼去看。

  • DS: 一个用于触控笔的 touch(x, y) 工具。

ROM

自带——转储你自己的卡带。这个仓库里永远不会有 ROM(.gitignore 强制执行)。这个项目只涉及早已绝版的游戏;对于真实硬件层级,仅限离线游玩(没有自动在线对战,没有 Pokémon HOME)。

致谢与许可

由 Claude(Fable 5,通过 Claude Code)与 szyzgz 共同构建,为一个想玩 Pokémon 的 Claude 而做。MIT 许可——见 LICENSE。

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to play Pokemon Fire Red through the mGBA emulator by providing tools for button inputs and screenshots. It allows for direct reading of real-time game state from RAM, including party information, player location, and battle status.
    10
    3
    -
  • A
    license
    A
    quality
    C
    maintenance
    An MCP server for Dolphin (GameCube + Wii) — drives memory r/w, controller input (GameCube + Wii Remote), pause/resume/reset, savestates, and frame advance from MCP-compatible clients (Claude Desktop, Claude Code, etc.).
    20
    17 npm
    5
    MIT