MTG Copilot Docs
Data model

Data model

Per-table field reference, with the source, owner and refresh cadence of every column.

Every table below lists each of its columns with a type, a description, and three pieces of provenance: where the value came from, what writes it, and how often that happens.

These pages are generated from a typed registry that lives beside the code, not written by hand. A migration that adds a column without registering it fails CI, so a field documented here exists, and a field that exists is documented here.

The tables

The reference covers the card database: the tables that hold the same values for everyone. They fall into six groups.

Cards

Card records and the printings they appear in, plus the registries of type words the parser recognises.

cards · card_popularity · card_printings · card_subtypes · mtg_card_types · mtg_supertypes · mtg_subtypes

Sets and products

Set metadata, the preconstructed decks shipped with a set and their contents, and sealed products.

sets · set_guides · precon_decks · precon_deck_cards · sealed_products

Prices

Current and historical prices. card_prices is per card; the rest are per printing, at daily and weekly resolution.

card_prices · printing_prices_current · printing_price_daily · printing_price_weekly

Taxonomy

The curated concept vocabulary, the rules that detect each concept, and the associations those rules produce. See taxonomy for how the three fit together.

game_concepts · tag_detection_rules · card_concept_associations

Rules

Comprehensive rules text, per-card rulings, and worked examples.

game_rules · card_rulings · rules_examples

Operations

One row per data job run, recording what it consumed, what it matched, and when.

data_job_runs

Your data

Decks, collections, conversations and profiles hold one person's rows rather than shared card data, so they live in your data. That section covers what each of those tables stores about you and who can read it.

Database functions

The database also carries functions the app calls directly. They are internal and undocumented. Publishing a list would imply an interface you can call from outside the app, and there is no such interface.

Source

Where a value originates, and therefore how much to trust it and who can change it.

SourceMeaning
scryfallImported from Scryfall bulk data.
mtgjsonImported from MTGJSON.
unmaintainedImported once and no longer refreshed. Read the timestamp beside the value.
wotcOfficial text from Wizards of the Coast, reproduced verbatim. Rules and rulings are never paraphrased, which is what makes them citable.
wikiParsed from the MTG Fandom wiki. Community-maintained, so treat it as context rather than authority.
calculatedDerived from other columns, by the database or a script.
aiProduced by a model, with the usual caveats.
userEntered by a person. Imports never overwrite it.

Updated

How often the owning job refreshes the value.

CadenceMeaning
on set releaseRefreshed when a new set is seeded.
daily / weeklyRefreshed on that schedule by a cron.
on demandRefreshed only when a pipeline is run manually.
on writeMaintained by the database on every write.
neverSet once when the row is created.

Written by

The single job permitted to write that column. If a value looks wrong, this names what to re-run. manual means the column is curated rather than imported: there is nothing to re-run, and an import will not restore it.

Coverage

Every reference table in the schema is documented here. That is enforced rather than asserted: each table is classified as published, private, or unused, and a migration that adds one without classifying it fails to compile.

User and deck tables live in your data, which lists every one of them and links to its reference as each lands.

For what a value means rather than what type it is, see card data.

On this page