MTG Cheaper Deck is a local Python tool that takes a public Moxfield deck URL and returns the best cheaper, functionally similar replacements for every card in the list. Instead of swapping cards purely by price tier or broad category, it scores each candidate by how much it actually shares with the original — overlapping keywords, matching oracle text patterns, similar mana cost, and EDHREC popularity — so every suggestion does something genuinely comparable. It is aimed at budget-conscious Commander and constructed players who want actionable swap recommendations without manually searching Scryfall for every slot in a deck.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/invvd/mtg-cheaper-deck/llms.txt
Use this file to discover all available pages before exploring further.
Web App
Local Flask interface with real Scryfall card images, per-category filtering, one-click replacements, and a live deck total — the most comfortable way to review an entire deck.
Interactive Terminal
Rich-powered terminal mode that walks through the deck card by card, letting you choose a replacement or skip to the next one.
CLI Report
Single-pass console table or
--json output, designed for scripting and piping into other tools.How It Works
A full walkthrough of the pipeline: Moxfield fetch → local DB match → scoring → output.
Key Features
- Moxfield deck fetching — reads the commander slot and full mainboard from a public deck via the
api2.moxfield.comendpoint, with errors isolated inmoxfield_client.pyso a breaking API change does not affect the rest of the pipeline. - Scryfall bulk sync (~38k cards) — downloads the Scryfall Oracle Cards bulk file once and stores it locally; never hits the per-card search API, so there is no rate-limit concern.
- Multi-factor scoring algorithm — scores each candidate with
3 × keyword similarity + 2.5 × oracle text similarity + 1 × CMC closeness + 1 × EDHREC popularity, all normalized to 0–1, for a theoretical maximum of 7.5. - Color identity bitmask filtering — encodes color identity as a single integer (W=1, U=2, B=4, R=8, G=16) and filters with a bitwise AND, which is both fast and portable across database engines.
- Format legality filtering — reads the deck’s format key from Moxfield and excludes cards that are not legal in that format.
- Three interfaces — web app (
webapp.py), interactive terminal (interactive.py), and a one-shot CLI report (main.py). - JSON output mode — pass
--jsontomain.pyto get machine-readable output for integration with external scripts. - Swappable database engine — the data layer uses SQLAlchemy Core; switching from SQLite to PostgreSQL requires only changing the
DATABASE_URLenvironment variable and installing the relevant driver.
Project Architecture
The tool is built as a linear pipeline with clearly separated concerns.moxfield_client.py fetches and parses the raw deck from Moxfield, producing a list of card entries with board position. matching.py looks up each card in the local database to resolve oracle IDs and enrich entries with local data. scoring.py loads the full candidate pool for the deck’s format and, for each original card, runs the similarity score against every cheaper candidate that shares a compatible color identity. The output layer — a Rich table, a Flask page, or raw JSON — is entirely separate from the scoring logic.
sync_scryfall.py runs as a completely independent process, intended for a daily cron job. It fetches the Scryfall bulk-data metadata endpoint to get the current download URL, streams the gzipped JSONL file, and upserts all cards into the local cards table in batches of 1,000. Because it runs outside the request path, it never blocks a user-facing operation.
License and Credits
MTG Cheaper Deck is released under the MIT License. It is a fan project with no affiliation with Wizards of the Coast, Moxfield, or Scryfall. Card data and images are sourced from the Scryfall API. Deck reading relies on an undocumented Moxfield endpoint. Magic: The Gathering is a registered trademark of Wizards of the Coast LLC.The Moxfield endpoint used to fetch deck data (
api2.moxfield.com) is not part of an official public API. It can change or disappear without any notice. If deck fetching breaks, check moxfield_client.py first — that module is intentionally isolated so failures are contained there.