Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/document-scryfall-query-limit.md
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 3 additions & 1 deletion skills/mtg-deckbuilder-lookup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 |
Expand Down
13 changes: 12 additions & 1 deletion skills/scryfall-search/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
Loading