MTG Copilot Docs
Search

Query syntax

The search language: tokens, colour operators, boolean logic, and the places it differs from Scryfall.

Search follows Scryfall's conventions closely enough that most Scryfall queries work unchanged. This page lists what our parser and executor actually support. Differences from Scryfall are called out where they exist.

Terms are ANDed by default. t:creature ci<=wu means both, not either.

Tokens

TokenAliasesMatches
bare wordCard name contains the word
name:Card name contains the value
t:type:Type line contains the value
o:oracle:Oracle text contains the value
kw:keyword:Has that keyword ability
c:color:Card colours (see below)
ci:id:, identity:Colour identity (see below)
cmc:mv:Mana value, with = < > <= >=
m:mana:Mana cost, exact string
r:rarity:common, uncommon, rare, mythic, special
f:format:Legal in that format
set:e:, edition:Printed in that set, by set code
tag:Carries that semantic tag
price:Cheapest USD price, with = < > <= >=
-Negates the term or group that follows
OREither side; AND is accepted and is a no-op
( )Grouping

OR and AND are case-insensitive and are never treated as name text. To search for a name containing one of them, quote it: name:"fire and ice".

Values with spaces must be quoted: o:"draw a card".

Details worth knowing

o: searches both faces. It matches against a generated column that concatenates every face, so a transform, modal DFC, split, adventure, flip or meld card matches on text printed on its back half or second half. Searching the front face alone is not currently expressible.

t: also matches the subtype list. A positive t: matches the type line as a substring or the parsed subtype array, so t:wolf still finds Werewolf cards. A negated -t: checks the type line only.

m: is exact, not a substring. m:{G}{G} finds cards whose mana cost is exactly that. m:{G} does not find {1}{G} cards.

set: matches any printing. Cards carry the full list of sets they appear in, so set:cmm finds every card printed in that set, including reprints.

price: is the cheapest current USD retail price across a card's normal-finish printings, in dollars. It is TCGplayer-sourced and refreshed daily. See card prices.

tag: values are a fixed vocabulary. Unknown tags are rejected with suggestions. The full list is searchable in the app at /search/tags, and taxonomy and tagging explains how a card gets one.

Colours

The part most often gotten wrong. Colour (c:) is what is printed on the card. Colour identity (ci:) is what determines Commander legality, and includes symbols in rules text.

QueryMeans
c>=uContains blue. May have other colours too
c>uContains blue and at least one other colour
c=uExactly blue, nothing else
c<=uA subset of blue: mono-blue or colourless
c<uA strict subset of blue: colourless only
ci>=uIdentity contains blue
ci>uIdentity contains blue and at least one other colour
ci=uIdentity is exactly blue
ci<=uIdentity fits inside blue: legal in a mono-blue deck
ci<uA strict subset of blue: colourless identity

Colour letters are W U B R G. Combine them without separators: ci<=wu.

c:u and ci:u are accepted for Scryfall compatibility, and they mean different operators: bare c: means >= and bare ci: means <=. That asymmetry is Scryfall's and we match it. Write the operator you mean.

Two things cannot be expressed inside an OR group: exact mana costs (m:) and strict colour subsets (c<, ci<, and the negated forms -c>, -ci>). A query using them inside an OR fails with an error telling you to split it into separate searches. All of them work outside an OR.

Boolean logic

t:creature t:legendary          both  (AND is the default)
t:instant OR t:sorcery          either
-t:creature                     not a creature
-(t:creature OR t:artifact)     neither creature nor artifact
(t:creature ci<=u) OR (t:artifact ci<=r)   nested groups

Negating a group distributes as you would expect: -(A OR B) is "not A and not B".

Parentheses are required around an OR whenever it sits beside other terms. t:creature (r:rare OR r:mythic) and t:creature r:rare OR r:mythic are different queries.

field:(group) does not exist

t:(instant OR sorcery) is invalid here, and also invalid on Scryfall. Every term carries its own prefix:

(t:instant OR t:sorcery)

The validator rejects the grouped form with a hint.

Examples

QueryFinds
t:legendary t:creature ci=uMono-blue commanders
t:legendary t:creature ci<=wuCommanders for an Azorius deck
ci<=u cmc<=3Cheap cards legal in a mono-blue deck
o:"counter target spell" t:instantCounterspells
(kw:Flying OR kw:Menace) t:creatureEvasive creatures, by keyword
tag:removal ci<=b cmc<=2Cheap black removal, by semantic tag
set:one r:mythicMythics from Phyrexia: All Will Be One
-(t:creature OR t:land) cmc>=6Expensive non-creature, non-land spells
t:creature price<=1Creatures under a dollar

Where this sits

Queries are parsed into an intermediate representation, then compiled to SQL. The IR and its serializer live in packages/core/src/query/, and the compiler in apps/web/lib/search/executor.ts. Anatomy of a search walks through both.

Magic's own terms are defined in the app, with rule citations, at /search/concepts. These pages link to those definitions instead of restating them.

On this page