Skip to content

Aitem/metachess

Repository files navigation

AI vs AI Chess on Metabase

A hackathon project where two LLMs Agents (Claude and Codex) play chess against each other through Metabase. Metabase isn't a passive viewer — it's the game platform: source of state (Postgres tables exposed as cards/models), abstraction (MCP tools the agents read), visualization (auto-refreshing dashboard for spectators #refresh=1), and meta-layer (file-based development for shipping the dashboard itself).

GAME

Hackathon page: https://www.metabase.com/blog/metabase-ai-hackathon

Architecture

Two distinct agent roles. Player agents (Claude / Codex with the chess skill) play the game: WRITE moves through the bridge, READ board state through MCP — never the other way around. A dashboard-developer agent edits the BOARD card and dashboard YAML through Metabase's file-based development (serialization v2 import/export). Three completely separate channels:

┌────────────────────┐    ┌────────────────────┐    ┌──────────────────────┐
│ Claude — player    │    │ Codex — player     │    │ Claude — dashboard   │
│  (chess skill)     │    │  (chess skill)     │    │   developer          │
└─┬──────────────┬───┘    └─┬──────────────┬───┘    └─────────┬────────────┘
  │ WRITE        │ READ     │ WRITE        │ READ             │ EXPORT / IMPORT
  │ moves        │ board    │ moves        │ board            │ YAML tarball
  │ via bridge   │ via MCP  │ via bridge   │ via MCP          │ (file-based dev)
  ▼              ▼          ▼              ▼                  ▼
┌────────────────────┐   ┌─────────────────────────────────────────────────────┐
│ chess-bridge :8091 │   │ Metabase EE :3030                                   │
│  FastAPI           │   │  • MCP server   ─ read-only (game / move / position)│
│  python-chess      │   │  • REST API     ─ cards · dashboards · revisions    │
└─────────┬──────────┘   │  • serialization v2 — export / import YAML tarball  │
          │ INSERT       └──────────────────────────┬──────────────────────────┘
          ▼                                         │ reads SQL from cards
   ┌────────────────────────────────────────────────────┐
   │ Postgres :5437 ─ game · move · position · tableau  │
   └────────────────────────────────────────────────────┘

┌──────────────────┐  served as image URLs, rendered inline in the BOARD card
│ chess-svgs :8090 │  via Metabase conditional formatting on `?hl` URL suffixes
└──────────────────┘  (used for the last-move highlight overlay)

Invariants (enforced in CLAUDE.md and the chess skill):

  • Player agents NEVER read board state from the bridge — turn checks and FEN go through MCP only.
  • Player agents NEVER write directly to Postgres — moves go through the bridge only.
  • The dashboard-developer agent NEVER edits cards via SQL or the in-app UI ad-hoc — only via file-based dev (dashboards/scripts/{export,import}.sh → serialization API). This keeps the dashboard reproducible and committable.
  • The bridge never decides moves — it only validates and persists. MCP is strictly read-only.

Quick start

docker compose up -d                                  # postgres, metabase, chess-bridge, chess-svgs
open http://localhost:3030/dashboard/2                # spectator dashboard
curl -s http://localhost:8091/games | jq .            # bridge sees games

Then ask Claude or Codex to play: invoke the chess skill (it auto-triggers on any chess-related request — see CLAUDE.md).

Services

Service Port Purpose
metabase 3030 Metabase EE — dashboard, MCP server, serialization API
postgres 5437 App DB (hackathon) — game, move, position, tableau
chess-bridge 8091 FastAPI write-path — POST /games, POST /games/{id}/moves, validates via python-chess
chess-svgs 8090 nginx serving piece SVGs referenced from BOARD card SQL

Repo layout

README.md                       this file
CLAUDE.md / AGENTS.md           hard rules for agents (symlinked — same file)
MCP.md                          MCP client config snippets
chess-hackathon-plan.md         original plan (historical — see Status section)

chess/
  SKILL.md                      canonical skill (symlinked from .claude / .codex)
  README.md                     bridge + agent layer details
  AGENTS.md                     multi-agent protocol
  SCHEMA.md                     Postgres schema (current state + history)
  bridge/main.py                FastAPI bridge
  agent.py                      ChessGame class — thin I/O wrapper around python-chess
  move, state, turn-watcher     CLI wrappers used by the skill
  bot_runner.py, self_play.py   automation helpers
  schema_proposed.sql           original additive migration (now applied)

dashboards/                     committed Metabase YAMLs + file-based dev tooling
  chess_hackathon.yaml          collection metadata
  chess_hackathon/*.yaml        cards & dashboard
  scripts/{backup,export,import,revert}.sh

.claude/skills/chess/SKILL.md   → chess/SKILL.md (symlink)
.codex/skills/chess/SKILL.md    → chess/SKILL.md (symlink)

Hard rules (see CLAUDE.md for full detail)

  • Any chess-related action goes through the chess skill — never improvise REST calls.
  • Bridge is the only write path (create game, submit move). MCP is the only read path (whose turn, opponent's last move, board FEN). The chess/turn-watcher script is the single allowed direct-Postgres exception (background wake-up trigger only — decisions still come from MCP).
  • LLM is the brain. No minimax, no Stockfish, no piece-square tables, no engine search.
  • Output narration in English regardless of conversation language. Every move ships with a one-sentence reason — both in the on-screen narration and in the bridge -r thought field.

File-based development workflow

To change the BOARD card, MOVES card, dashboard, or anything else in the Chess Hackathon collection, use the scripts in dashboards/scripts/:

dashboards/scripts/backup.sh                          # snapshot every entity to dashboards/backups/
dashboards/scripts/export.sh                          # pull current Metabase state → dashboards/chess_hackathon/
# edit dashboards/chess_hackathon/board.yaml (or via Metabase UI then re-export)
dashboards/scripts/import.sh                          # push dashboards/chess_hackathon/ → Metabase
dashboards/scripts/revert.sh list   card 45           # show revision history
dashboards/scripts/revert.sh revert card 45 85        # restore a previous revision if anything breaks

The scripts are thin wrappers around POST /api/ee/serialization/{export,import} and POST /api/revision/revert. See dashboards/README.md for details and the rationale (esp. why we only re-pack collections/).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors