diff --git a/.changeset/document-scryfall-query-limit.md b/.changeset/document-scryfall-query-limit.md new file mode 100644 index 0000000..82615e6 --- /dev/null +++ b/.changeset/document-scryfall-query-limit.md @@ -0,0 +1,7 @@ +--- +"@mtg-deckbuilder/shared": patch +"@mtg-deckbuilder/mcp-server": patch +"@mtg-deckbuilder/electron-app": patch +--- + +Document Scryfall's 500-character query limit in the `scryfall-search` skill (cause and mitigation), with a pointer from `mtg-deckbuilder-lookup` near `get_collection_filter`, the most common source of long `OR`-chains that hit it. diff --git a/skills/mtg-deckbuilder-lookup/SKILL.md b/skills/mtg-deckbuilder-lookup/SKILL.md index d9efd45..c44281d 100644 --- a/skills/mtg-deckbuilder-lookup/SKILL.md +++ b/skills/mtg-deckbuilder-lookup/SKILL.md @@ -2,7 +2,7 @@ name: mtg-deckbuilder-lookup description: Search for Magic the Gathering cards through the mtg-deckbuilder MCP server's Scryfall integration. Use when a user wants to find cards by name, by attributes (color, type, mana cost, format legality), or by mechanical role ("find me artifact removal in red"). For query syntax, see the scryfall-search skill; for function:tag vocabulary, see the scryfall-tags skill. metadata: - version: "2026-05-31" + version: "2026-07-14" --- # MTG Deckbuilder — Card Lookup @@ -74,6 +74,8 @@ Returns a Scryfall filter string composed from the user's tracked collection (pe Note: this filter reflects the user's *tracked* collection (set-level granularity with rarity levels), not their literal owned cards. It's a useful approximation, not a guarantee. +**Query length ceiling:** combining `get_collection_filter`'s output with additional filters can push a query past Scryfall's hard 500-character limit — common once a tracked collection spans many sets. See the **scryfall-search** skill's "Query length limit" section for the cause and mitigation (splitting into multiple searches, avoiding per-set/per-card `OR`-chains). + ### Collection levels — what each level means | Level | Includes | diff --git a/skills/scryfall-search/SKILL.md b/skills/scryfall-search/SKILL.md index ca89d9d..4a86c24 100644 --- a/skills/scryfall-search/SKILL.md +++ b/skills/scryfall-search/SKILL.md @@ -2,7 +2,7 @@ name: scryfall-search description: How to construct Scryfall search queries for Magic the Gathering. Use when you need to find cards by attributes (color, type, mana cost, power/toughness, format legality, oracle text, etc.) or when composing a multi-operator query — on scryfall.com, through the Scryfall API, or via an MTG-aware MCP tool. For looking up specific function/oracle tag names, see the scryfall-tags skill instead. metadata: - version: "2026-05-24" + version: "2026-07-14" --- # Scryfall Search Syntax @@ -211,6 +211,17 @@ art:dragon -t:dragon game:arena -game:paper is:digital ``` +## Query length limit + +Scryfall enforces a **hard 500-character ceiling** on a single query string. Queries over the limit are rejected, not truncated. + +**Why it bites deck-building queries specifically:** the usual way to blow past it is a large `OR`-chain — most often one `set:` clause per owned set, e.g. the output of `get_collection_filter` (`(s:dmu r<=r OR s:lci r<=r OR s:mh3 r<=m OR ...)`). A tracked collection spanning 20+ sets can exceed 500 characters before any other filter is even added. + +**Mitigation:** +- Prefer compact operators over enumerating values — `r<=u` instead of `(r:c OR r:u)`. +- If a filter is inherently large (a collection-scoped `OR`-chain, a long list of names), split it into multiple searches, each covering a subset of the clauses, and merge results client-side rather than building one all-encompassing query. +- Avoid encoding a per-item filter that scales with collection/list size (one clause per set, per card). The query grows unbounded as the user's data grows. Prefer a coarser filter (rarity or format-level) plus client-side post-filtering. + ## Gotchas 1. **Multi-word phrases must be quoted in `o:`.** `o:draw a card` matches cards whose oracle text contains "draw" AND "a" AND "card" anywhere, in any order. `o:"draw a card"` matches the exact contiguous phrase.