Skip to main content
Glama
l3p3r-muo

Vizier Yu-Gi-Oh! MCP

by l3p3r-muo
README.md
# Vizier Yu-Gi-Oh! MCP

A Model Context Protocol server for Yu-Gi-Oh! card data: cards, prices, printings, banlists (historical + cross-format), official rulings, comprehensive rules, card relations, and deck tools. Everything runs locally from a single SQLite database with embedded vector search — no network calls at query time.

## Features

- **Cards**: lookup by exact id or fuzzy-matched name, keyword search with type/ATK filters, semantic (vector) search by effect description, archetype listing.
- **Prices & printings**: current market prices (cardmarket / tcgplayer / ebay / amazon), full printing history with rarities and prices.
- **Banlists**: snapshots for `tcg`, `ocg`, `ocg-ae`, `ocg-cn`, `master-duel`, `rush`, `genesys`, `ocg-genesys`, `goat`, `edison`; per-card status across all formats, historical diffs between snapshots.
- **Rules & rulings**: semantic search over the official Comprehensive Rulebook (380 sections) and over 2,650 official OCG rulings; per-card ruling lookup with live-fetch fallback.
- **Relations**: search/summon/destroy/target relations mined from card text, Fusion/Synchro/Xyz/Link/Ritual material requirements, reverse lookups, archetype support detection.
- **Decks**: validate a decklist against a format's banlist, analyze main/extra composition and archetype mix.

## Requirements

- Python 3.11+
- ~1 GB disk for the embedding model download; the built database is ~75 MB
- ~2 GB RAM during the build (embedding model); much less at query time

The database path and data directory can be overridden with `VIZIER_DB_PATH` and `VIZIER_DATA_DIR` environment variables (the default is `<package root>/data/`).

## Setup

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
```

## Building the database

The build ingests cached API data (`data/cache/`) and the reference projects (`ref/`, `policy/`) into `data/vizier.db`. No network is required unless you pass `--fetch`.

```bash
# full build including embeddings (slow: ~15-20 min CPU for 17.6k vectors)
python scripts/build_db.py

# faster variants
python scripts/build_db.py --no-embed      # skip vector embeddings (no semantic search)
python scripts/build_db.py --skip-cards    # skip card ingestion, re-embed only
python scripts/build_db.py --fetch         # download fresh API payloads first
```

`--fetch` downloads the card dump from YGOPRODeck. Note: the live API currently returns HTTP 403, so the cached dump in `data/cache/` is authoritative. If the API is unreachable the build uses the cache.

## Running the server

```bash
python -m vizier_mcp
```

The server speaks MCP over stdio. There is also a console script:

```bash
vizier-mcp
```

## Client configuration

Point any MCP client at the installed command. The server name is `vizier-yugioh`.

### Claude Desktop / Claude Code

```json
{
  "mcpServers": {
    "vizier-yugioh": {
      "command": "/path/to/.venv/bin/python",
      "args": ["-m", "vizier_mcp"]
    }
  }
}
```

### Generic clients

```json
{
  "mcpServers": {
    "vizier-yugioh": {
      "command": "/path/to/.venv/bin/vizier-mcp",
      "args": []
    }
  }
}
```

Use absolute paths to the venv. The DB path is resolved relative to the package location (or `VIZIER_DB_PATH`), not the CWD.

## Tools

| Tool | Description |
|---|---|
| `get_card` | One card by name (fuzzy) or id: type line, stats, effect, ban status per format, prices |
| `search_cards` | Keyword search over names/types/archetypes/effect text with `filter_type` and `min_atk` filters |
| `semantic_card_search` | Vector search by natural-language description of a card's function |
| `get_archetype` | All cards of an archetype / series |
| `get_card_prices` | Market prices (cardmarket/tcgplayer/ebay/amazon) + cheapest printing |
| `get_printings` | Full printing history: sets, rarities, editions, prices |
| `get_banlist` | Full banlist snapshot for a format and date |
| `check_card_banlist` | One card's ban status across all formats + history |
| `banlist_history` | Dates of available banlist snapshots for a format |
| `compare_banlists` | Diff two snapshots: cards moved between Forbidden/Limited/Semi-Limited |
| `list_banlist_formats` | Which formats have banlist data |
| `search_rules` | Semantic search of the official Comprehensive Rulebook |
| `get_rulings` | Official OCG rulings (Q&A) for one card, live-fetch fallback |
| `search_rulings` | Semantic search over the rulings corpus |
| `get_related_cards` | Cards related by effect: searches, summons, destroys, targets, materials |
| `find_search_targets` | What a card can search/add from deck or grave |
| `find_summon_targets` | What a card can summon / Special Summon |
| `find_cards_that_search` | Reverse: which cards search this card |
| `find_cards_that_summon` | Reverse: which cards summon this card |
| `get_card_materials` | Fusion/Synchro/Xyz/Link/Ritual material requirements |
| `find_cards_using_material` | Reverse: monsters that use this card as material |
| `find_archetype_support` | Support cards whose text names an archetype |
| `combo_guide` | The built-in combo creation playbook: exact breadth-first process for building combos |
| `card_combo_profile` | Exhaustive combo profile of one card: summoning, per-effect kind/OPT/actions, locks, relations, materials, material-for |
| `extra_deck_options` | Every Fusion/Synchro/Xyz/Link/Ritual summon reachable from the current board (best-effort material checks) |
| `board_options` | EVERY legal next play from the current board: all extra-deck summons, hand plays, search/add effects with ranked targets, pendulum range, active/pending locks. Archetype-agnostic |
| `line_search` | Bounded breadth-first search over board states: complete multi-step lines from the current board to a goal (`field_levels`, `field_count`, `no_locks`, `reach_field`, `reach_hand`) |
| `validate_deck` | Validate a decklist against a format's banlist |
| `analyze_deck` | Deck breakdown: main/extra counts, archetype mix, per-card details |
| `mcp_guide` | Overview of every tool and resource |
| `database_status` | What data is loaded: counts, build time, formats |

`filter_type` examples: `monster`, `spell`, `trap`, `effect`, `fusion`, `link`, `pendulum`, `tuner`, `normal monster`, `normal spell`, `quick-play`, `counter trap`, `equip`, `field`, `ritual`. Multi-word filters match the exact subtype.

## Combo creation

The server ships a built-in combo-creation playbook that turns line-building into a deterministic breadth-first process: enumerate every possible action, expand, deepen, prune, record, repeat.

1. **`combo_guide()`** — load the playbook (also available as the `combo` prompt). It defines a combo-state JSON schema, the 6-step protocol, per-card enumeration checklists, tool routing, hard/soft OPT discipline, lock detection, and termination criteria.
2. **`card_combo_profile()`** — for any card you consider: summoning options (normal/tribute/pendulum/self-special), every effect with activation kind + once-per-turn status + action verbs, lock/restriction sentences, its full relation graph (searches/summons/destroys/targets/materials), materials it requires, and monsters it can be material for (named + archetype-wide).
3. **`board_options()`** — one call that returns EVERY legal next play from the current board, archetype-agnostic: all extra-deck summons (the full ~2,300-monster pool, not just the deck's archetype), every hand monster's plays (normal summon / self-special / pendulum scale), every search/add effect with its targets (archetype targets list top-ranked members), the pendulum summon range, and active/pending locks. This is the anti-tunnel-vision tool: the model must not restrict itself to in-archetype candidates.
4. **`line_search()`** — server-side bounded breadth-first search from the current board to a goal (`field_levels`, `field_count`, `no_locks`, `reach_field`, `reach_hand`). Returns complete multi-step lines, so the model plans several steps deep instead of one move at a time.
5. **`extra_deck_options()`** — paste your current field (plus hand/graveyard/extra deck and format) and get every Fusion/Synchro/Xyz/Link/Ritual monster whose material requirement is satisfiable, with the exact material reasoning for each candidate.

Example — two Level 4 `D/D` monsters on field:

```text
extra_deck_options(field=["D/D Savant Copernicus", "D/D Ark"], summon_types="xyz")
→ options include D/D/D Wise King Solomon ("2 Level 4 D/D monsters")
```

Best-effort material checks are validated against the full relation graph; always confirm borderline candidates with `get_card_materials` before finalizing a line.

## Resources

| URI | Description |
|---|---|
| `card://{name_or_id}` | Compact card summary as text |
| `banlist://{format}` | Latest banlist snapshot for a format as text |
| `rules://{query}` | Top rulebook sections for a question (semantic) |

URL-encode resource parameters containing spaces (`rules://damage%20step`).

## Database layout

`data/vizier.db` — SQLite with `sqlite-vec` extension. Key tables:

- `cards` — one row per card with computed type flags (`is_monster`, `is_quickplay_spell`, ...)
- `card_sets`, `card_prices` — printings and market prices
- `card_ban_status`, `banlist_history` — current status per format + historical snapshots
- `relations` — card-to-card effect relations with types
- `rulebook_chunks`, `rulings` — rules and rulings text
- `card_vec`, `rule_vec`, `ruling_vec` — embedding tables for semantic search
- `meta` — build timestamp and counts

## Data sources

- **Cards / prices / banlists**: YGOPRODeck bulk API (cached in `data/cache/`)
- **Rules**: official Comprehensive Rulebook (`ref/yugioh_comprehensive_rulebook/`)
- **Rulings**: official OCG rulings Q&A list + YGOPEDIA fallback
- **Policy**: tournament policy documents (`policy/`)

## Tests

```bash
python -m pytest tests/ -q
```

Runs 32 smoke tests against an in-process server client, covering every tool and resource.