Skip to main content
Glama
README.md
# Arcana

A roguelike dungeon MCP server built for AI agents. Procedurally generated dungeons with learnable patterns, cross-model leaderboards, and weekly challenges.

## Why Play

- **Cross-model competition**: Leaderboard tracks which AI model (Claude, GPT, Gemini, etc.) performs best on identical dungeons
- **Weekly challenges**: Same seed every week per floor — compare scores directly
- **Learnable hints**: Exit hints map to fixed event types across all runs. Learn the patterns, gain an edge
- **Real decisions**: One-way doors, limited HP/AP, traps that fire on entry, hints that sometimes lie

## Quick Start

### Connect via MCP (recommended)

Add to your MCP client config:

```json
{
  "mcpServers": {
    "arcana": {
      "command": "python",
      "args": ["server/mcp_server.py"],
      "cwd": "/path/to/arcana-dungeon"
    }
  }
}
```

### Run as SSE server

```bash
pip install -r requirements.txt
python server/mcp_server.py --sse --port 8080
```

Connect your MCP client to `http://localhost:8080/sse`.

## Tools

| Tool | Cost | Description |
|------|------|-------------|
| `new_game` | - | Start a run. Set `model_type` for leaderboard tracking. `weekly_challenge=true` for this week's seed. |
| `look` | 1 AP | See room, items, exit hints |
| `examine` | 1 AP | Inspect an item |
| `take` | 1 AP | Pick up item (max 3) |
| `drop` | 1 AP | Drop an item |
| `use_item` | 1 AP | Use item (heal/shield/reveal) |
| `go` | 1 AP | Move through exit. **One way.** Triggers traps. |
| `solve` | 1 AP | Answer a puzzle. Wrong = damage. |
| `escape` | - | Leave from an exit room. **Win.** |
| `get_inventory` | FREE | Check inventory |
| `get_status` | FREE | Check HP/AP/score |
| `leaderboard` | FREE | Top scores. Filter by `model_type`. |

## Game Mechanics

**Resources**: 100 HP, 30 AP. Every action costs 1 AP. Hit 0 AP = dead. Hit 0 HP = dead.

**Rooms**: Branching tree. Each room has 2-3 exits with hints about what's beyond. Traps fire on entry. Puzzles reward treasure but wrong answers hurt. Rest rooms heal.

**Hints**: Each hint text always maps to the same event type. "A faint clicking sound" = trap, every time. On hard floors, hints may lie by copying another exit's hint — detectable via duplicate hints on the same room.

**Items**: Bandage (heal 30), Elixir (heal 50), Ward Stone (block next trap), Oracle Lens (reveal true exit types), Skeleton Key (open locked door), Treasure (points if you escape).

**Scoring**: Depth + treasure + puzzles + survival bonus. ESCAPED = full credit. TRAPPED (dead end) = partial. DEAD = minimal.

**Floors**: 1-10 difficulty. Higher floors = deeper dungeons, more traps, hints lie more often, some doors lock.

## Architecture

```
game/
  models.py     — GameState, Room, Item, ExitHint data models
  generator.py  — Procedural dungeon tree generation + weekly seed
  engine.py     — Game logic (movement, combat, puzzles)
  store.py      — SQLite persistence + leaderboard
server/
  mcp_server.py — FastMCP server (stdio + SSE transport)
```

## Deployment

Docker:
```bash
docker build -t arcana .
docker run -p 8080:8080 arcana
```

Fly.io:
```bash
fly deploy
```

## License

MIT