Skip to main content
Glama
README.md
# PokeMCP - AI Plays Pokemon Fire Red

An MCP server that lets Claude play Pokemon Fire Red through the mGBA emulator. Built for YouTube content — Claude has its own personality, names its Pokemon, trash-talks its rival, and reacts to everything happening in the game.

## How It Works

```
Claude <-> FastMCP Server (Python) <-> TCP Socket <-> Lua Script (inside mGBA)
```

**Split gameplay model:**
- **Claude handles:** Battles, dialog, menus, naming (trainer/rival/Pokemon), team strategy
- **Human operator handles:** Overworld navigation (walking to destinations)
- **Navigation is purely visual** — Claude reads screenshots to understand the game world
- **RAM reading** is used only for party Pokemon stats, battle data, badges, and money

## Prerequisites

- **mGBA** v0.10+ — [mgba.io](https://mgba.io)
- **Python** 3.12+
- **uv** — `pip install uv`
- **Pokemon Fire Red ROM** — US v1.0 (game code: BPRE)

## Setup

### 1. Install dependencies

```bash
uv sync
```

### 2. Load the Lua script in mGBA

1. Open mGBA and load your Pokemon Fire Red ROM
2. Go to **Tools > Scripting**
3. **File > Load Script** → select `lua/mgba_server.lua`
4. Console should show: `MCP Server listening on 127.0.0.1:5555`

### 3. Configure Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "pokemon-firered": {
      "command": "C:\\Users\\YOUR_USER\\AppData\\Roaming\\Python\\Python312\\Scripts\\uv.exe",
      "args": ["--directory", "C:/path/to/mGba MCP", "run", "mgba-mcp"]
    }
  }
}
```

> **Note:** Use the full path to `uv.exe` — Claude Desktop may not have it in PATH. Find it with `python -c "import shutil; print(shutil.which('uv'))"`.

### 4. Play!

Start a conversation with Claude. It will invent a personality, pick a trainer name, and start playing.

## Available Tools

| Tool | Description |
|------|-------------|
| `press_button` | Press a GBA button and get a screenshot |
| `press_buttons` | Press a sequence of buttons with timing |
| `get_screenshot` | See the current game screen |
| `get_game_state` | Read badges, money, party Pokemon, battle state from RAM |
| `get_party` | Detailed party info (stats, moves, IVs) |
| `get_battle_state` | Battle details (your/enemy Pokemon, HP, moves, PP) |
| `save_state` | Save emulator state (slots 1-9) |
| `load_state` | Load emulator state |
| `wait_frames` | Wait through animations/transitions |
| `hold_button` | Hold a button for extended walking/scrolling |

## What Claude Reads from RAM

- **Party Pokemon** — Species, level, HP, moves with PP, stats, IVs, status conditions
- **Badges** — Which gym badges have been earned
- **Money** — Current funds (XOR-decrypted)
- **Battle state** — Enemy Pokemon species, level, HP, moves

Navigation and dialog are handled **visually** through screenshots only.

## Claude's Personality

Each session, Claude invents a unique persona:
- Picks its own trainer name and rival name
- Names every Pokemon with creative nicknames
- Has strong opinions about Pokemon, moves, and characters
- Gets emotionally invested — celebrates wins, mourns faints
- Narrates its thought process for the audience
- All commentary in Spanish for YouTube content

## Project Structure

```
├── pyproject.toml
├── src/mgba_mcp/
│   ├── server.py        # FastMCP tools + personality instructions
│   ├── connection.py    # TCP client for mGBA communication
│   ├── game_state.py    # Pokemon Fire Red RAM parser
│   └── constants.py     # Memory addresses and lookup tables
├── lua/
│   └── mgba_server.lua  # Lua TCP server loaded into mGBA
└── data/
    ├── pokemon_species.json
    ├── pokemon_moves.json
    └── map_names.json
```

## Tips for YouTube Recording

- **Save states are your friend** — save before gyms, important battles, or risky catches
- **Let Claude fail** — mistakes and reactions are entertaining content
- **Navigate for Claude** — walk to destinations, let Claude handle the rest
- **Nudge when stuck** — tell Claude "we're at the Pokemon Center" or "there's a trainer ahead"
- **The game is in English but Claude comments in Spanish** — great for bilingual content

## Important Notes

- ROM must be US v1.0 (BPRE) for memory addresses to work
- Load the Lua script in mGBA **before** starting Claude Desktop
- mGBA must stay open while playing
- The Lua script auto-detects the ROM and warns if it doesn't match

## License

MIT

TDQS

A4/5.0

Scored across 10 tools

Disambiguation5/5

Each tool has a clearly distinct purpose with no overlap: get_battle_state, get_game_state, and get_party provide different scopes of game information, while press_button, hold_button, press_buttons, wait_frames, get_screenshot, save_state, and load_state handle distinct input/output operations. The descriptions explicitly differentiate tools like hold_button vs. press_button, preventing confusion.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (e.g., get_battle_state, press_button, save_state), using snake_case throughout. The naming is predictable and readable, with no deviations in style or convention across the set.

Tool Count5/5

With 10 tools, the count is well-scoped for an emulator control server, covering core functions like state retrieval, input simulation, and save management. Each tool earns its place without redundancy, fitting a typical range for such a domain.

Completeness4/5

The tool set provides comprehensive coverage for emulator interaction, including reading game state, simulating inputs, and managing saves. A minor gap exists in lacking direct emulation control tools (e.g., reset, speed adjustment), but agents can work around this using existing tools for most workflows.

Maintenance

ActivityInactive
ResponsivenessUnresponsive