lorcana-mcp
MCP server that connects Claude to Disney Lorcana card data — it enriches your TCGPlayer collection CSV and provides card lookup, searching, deck building/analysis, format legality, and live pricing tools.
Enrich a collection (
enrich_csv): turn a raw TCGPlayer export into a full card database (ink, cost, stats, keywords, abilities) plus a dreamborn.ink-ready import file; optionally refresh prices live.Look up cards (
lookup_card,resolve_card): fetch full stats, abilities, and legality by exact name, or fuzzy-match informal/misspelled/subtitle-less names.List printings (
list_printings): compare every printing of a card side by side — set, number, rarity, per-format legality, cheapest market price.Search the card pool (
search_cards): filter all released cards by color, type, rarity, set, cost range, keyword, ability text, or subtype.Find song synergies (
find_song_synergies): discover every character that can sing a song, split into Singer discounts and plain cost-qualifiers, optionally flagging owned copies.Filter your collection by format (
filter_collection): show only owned cards legal in core, infinity, core_zh, core_ja, or poorcana.Audit a CSV (
audit_csv): diff an enriched collection against live API data and report stale/wrong fields.Analyze a deck list (
analyze_deck): report ink curve, inkable split, color/type split, estimated lore-per-turn, and Core Constructed legality.Price a deck gap (
what_am_i_missing): cross-reference a deck list against your collection and estimate the live cost to complete it.Build decks (
build_deck): auto-assemble a legal, curve-balanced ~60-card deck from your collection, an ideal build, or a full market build — supporting core/infinity/regional/poorcana/coconut formats, rotation-safety, and tribal themes.Get metagame info (
get_meta): a bundled (non-live) Core Constructed tier list plus tournament standings and decklists.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lorcana-mcp Enrich my collection at ~/Downloads/export.csv"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
lorcana-mcp
MCP server that connects Claude to Disney Lorcana card data. Export your collection from TCGPlayer, hand it to Claude, and get it fully enriched with ink cost, stats, keywords, abilities, and format legality — plus a ready-to-import file for dreamborn.ink.
The simple version
What it does: plug this into Claude and it becomes a Disney Lorcana expert that knows your actual collection — no more tab-switching between TCGPlayer, dreamborn.ink, and a wiki.
Once it's connected, you can just talk to Claude like:
🗂️ "Enrich my collection at ~/Downloads/export.csv" — turns a bare TCGPlayer export into a full card database (cost, stats, keywords, abilities) plus a file ready to import into dreamborn.ink
🔎 "What's that card, big pete?" — finds cards even if you don't remember the exact name or spelling
🎴 "Show me cheap Evasive characters in Amber" — searches the entire card pool by color, cost, keyword, rarity, whatever
🎵 "Who can sing Be Our Guest for free?" — finds the best Singer combos for a song
📋 "Is this deck legal? 4x Goofy - Musketeer, 4x..." — checks curve, colors, and tournament legality of any deck list
💰 "What am I missing to finish this deck, and what would it cost?" — compares a deck list to your collection and prices the gap with live market data
🏗️ "Build me a Core Constructed Amber/Sapphire deck" — automatically assembles a legal, curve-balanced decklist from your collection, an ideal build priced to complete, or a full market build
✅ "Is my collection data still accurate?" — audits your CSV against live card data and flags anything stale
Everything reads from public card APIs plus your own exported CSV — no account, no login, nothing to configure.
Get it running in under a minute
Claude Desktop — one click: download lorcana-mcp.mcpb and double-click it (or Settings → Extensions → Install extension…). No terminal, no Python install, nothing to configure.
Everything else — one command:
1. Connect it (uvx fetches it on demand — install uv first, or pip install lorcana-mcp and drop the uvx):
claude mcp add lorcana -- uvx lorcana-mcp serveUsing Claude Desktop config, Cursor, VS Code, Windsurf, Cline, or Zed instead? Every client is covered in docs/INSTALL.md.
2. Talk to it: Export your collection from TCGPlayer (My Account → My Collection → Export), then just say:
"Enrich my collection at /path/to/your/export.csv"
That's it — Claude does the rest. Everything below is reference detail for when you want more control.
Related MCP server: Pokemon TCG Card Search MCP
Tools
Thirteen tools are available in Claude once the server is running:
Tool | What it does |
| Enriches a raw TCGPlayer export with Ink, Cost, Type, Subtypes, STR/WIL/Lore, Inkable, Keywords, and Abilities. Writes an enriched CSV and a dreamborn.ink-ready import file next to the input. |
| Looks up any card by name. Returns full stats, ability text, format legality, and card image URL. |
| Fuzzy-resolves an informal, misspelled, or subtitle-less card name (e.g. "goofy musketeer", "elsa"). Returns a single confident match, a ranked top-3 to disambiguate, or nothing found. |
| Lists every printing of a card — or every card sharing a character name — side by side: set, number(s), cost, stats, rarity, per-format legality, and cheapest market price. Optional |
| Searches the full card pool by color, type, rarity, set, cost range, keyword, ability text, or subtype — with pagination. |
| Finds every character that can sing a given song (or a raw cost threshold), split into Singer-keyword discount picks and plain cost-qualifiers. Optionally flags which ones you own. |
| Filters your collection to cards legal in a given format: |
| Compares an enriched collection against live API data and reports any stale or wrong fields. |
| Analyzes a raw deck list ( |
| Compares a deck list against your collection: what you already own, what's missing or short, and a live TCGPlayer cost estimate (via tcgcsv.com) to complete it. |
| Automatically assembles a legal, curve-balanced ~60-card decklist for an ink pair/format, in one of 3 modes: |
| Builds the best 40-card Sealed / prerelease deck from an opened card pool (6 packs, ~72 cards). Takes one card per line — names (informal/misspelled is fine) or the collector numbers printed on the cards ( |
| Returns a hand-maintained Core Constructed metagame snapshot: every two-ink pair's tier, rough meta share, and playstyle, plus recent tournament results — optionally filtered to one pair ( |
Listed on
Directory | Link |
MCP Registry (official) | |
mcp.so | |
PyPI |
Install
You don't have to install anything if you use uvx (below) or the Claude Desktop bundle. To install the package explicitly:
pip install lorcana-mcp
# or: uv tool install lorcana-mcpFrom source:
git clone https://github.com/IcaroBichir/lorcana-mcp
cd lorcana-mcp
pip install .Claude Desktop bundle: lorcana-mcp.mcpb on the releases page — a one-click install that bundles its own runtime. Built from packaging/mcpb/.
Add to your client
lorcana-mcp is a local stdio server — it runs on your machine, no hosting or API key. docs/INSTALL.md is the full guide, with copy-paste config for every client. The short version:
Client | Supported | How |
Claude Desktop | ✅ | |
Claude Code | ✅ |
|
Cursor · VS Code · Windsurf · Cline · Zed | ✅ | stdio config — see docs/INSTALL.md |
Any other stdio MCP client | ✅ | Command: |
Claude.ai (web) · ChatGPT | ❌ | Those need a hosted remote server; this one is local-only — see docs/INSTALL.md |
Claude Code (CLI)
claude mcp add lorcana -- uvx lorcana-mcp serveClaude Desktop (manual config)
Easiest is the one-click bundle. To wire it up by hand instead, edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\, or Settings → Developer → Edit Config):
{
"mcpServers": {
"lorcana": {
"command": "uvx",
"args": ["lorcana-mcp", "serve"]
}
}
}Use "command": "lorcana-mcp", "args": ["serve"] if you installed with pip rather than uv. Fully quit and reopen Claude Desktop after saving.
Usage
Once the server is connected, just talk to Claude naturally. No slash commands needed.
Enrich a collection
Export your collection from TCGPlayer → My Collection → Export CSV, then:
"Enrich my collection at /Users/me/Downloads/Lorcana_063026.csv"
Claude will fetch card data from the APIs and write two files next to your input:
enriched_Lorcana_063026.csv— your collection with 10 new columnsdreamborn_Lorcana_063026.csv— ready to import at dreamborn.ink
On re-runs, pass the previous enriched file as a cache to skip already-seen cards:
"Enrich /Users/me/Downloads/Lorcana_new.csv using /Users/me/lorcana/enriched_Lorcana_old.csv as cache"
To refresh prices on demand without re-exporting from TCGPlayer:
"Re-enrich my collection at /Users/me/lorcana/enriched_Lorcana_063026.csv and refresh prices"
refresh_prices=True overwrites each row's TCG Market Price with a live tcgcsv.com lookup for that exact printing — useful when an enriched CSV's prices are stale.
Look up a card
"Look up Mirage - Super Recruiter"
"What are the stats on Alma Madrigal - Heart of the Family?"
"Is Will o' the Wisp legal in Core?"
Returns: ink color, cost, type, subtypes, STR/WIL/Lore, inkable status, keywords, full ability text, format legality, and a card image URL.
Resolve an informal or misspelled card name
"Find the card 'goofy musketeer'"
"What's that card 'big pete'?"
"Look up 'elsa' — not sure which version"
Tokenizes the query and scores it against every card's name and subtitle, tolerating missing dashes, missing subtitles, word order, and minor typos. Returns full detail for a single confident match, a ranked top-3 with confidence scores when several cards are plausible (e.g. a bare name matching every printing of that character), or nothing if the query doesn't resemble any card.
Search the full card pool
"Show me all Evasive characters in Amethyst that cost 3 or less"
"Find Toy characters"
"Search for Rare Steel cards from Wilds Unknown"
Filters: ink color(s), card type (Character / Action / Item / Location / Song), rarity, set name, cost range, keyword, ability text substring, and subtype — all combinable, plus pagination (offset + limit). Results are grouped by ink color and sorted by cost.
Find who can sing a song
"Which characters can sing Be Our Guest?"
"Show me Amber characters that can sing a cost-7 song"
"Who can sing Friends on the Other Side, and which ones do I own?" (pass your enriched collection CSV)
A character can sing a song if its printed cost meets the song's cost outright, or it has a matching Singer X keyword — Singer lets a cheap character punch above its actual cost for singing purposes only. Results split into Singer-keyword "discount" picks (highest Singer value, then cheapest actual cost) and plain cost-qualifiers (cheapest first). Pass collection_csv to flag ownership.
Filter your collection by format
"Which of my cards are legal in Core Constructed?"
"Show me my Infinity-legal cards grouped by ink color"
"What Poorcana-legal cards do I have in Amber?"
Valid formats: core, infinity, core_zh, core_ja, poorcana
Poorcana filtering uses the Rarity column in your enriched CSV (Common + Uncommon only) — no API call needed.
Core/Infinity/regional legality comes from duels.ink, which tracks the current rotation for each region.
Audit an existing enriched file
"Audit my collection at /Users/me/lorcana/enriched_collection.csv"
Useful after a new set releases or if a card's data looks wrong. Compares every non-promo card against live API data and reports field-by-field discrepancies.
Analyze a deck list
"Analyze this deck: 4x Goofy - Musketeer, 4x Elsa - Spirit of Winter, ..." (paste a full list, one card per line)
Accepts 4x Card Name or 4 Card Name; quantity defaults to 1 if omitted. Lines starting with # or // are treated as comments.
Returns: ink curve (1-2/3-4/5-6/7+ cost brackets), inkable vs. uninkable count, color split, card type split, an estimated lore-per-turn (sum of Character lore values), a Core Constructed legality check (60-card minimum, max 4 copies of any card, at most 2 ink colors), and any card names that couldn't be resolved.
Check what a deck list is missing
"What am I missing to build this deck?" (paste the deck list and point me at your collection CSV)
"How much would it cost to finish this Amber/Steel list?"
Same deck list format as analyze_deck. Cross-references against your enriched collection CSV, then splits results into cards you already have enough of and cards you're missing or short on. For cards you're short on (own at least one printing already), the cost comes straight from the CSV's own TCG Market Price column — no network call needed. Only cards you own zero copies of fall back to a live TCGPlayer lookup via tcgcsv.com (cheapest printing across all sets/rarities, since gameplay is identical), and even then only if at least one card actually needs it. Live price data is cached for 24h, so the first call that needs it takes a bit longer while it warms up.
Enriched columns
The enricher adds these 10 columns to the raw TCGPlayer export:
Column | Description |
Ink | Ink color(s) — dual-ink cards show both, e.g. |
Ink Cost | Numeric cost to play (1–12) |
Card Type | Character / Action / Action - Song / Item / Location |
Subtypes | e.g. |
Strength | ⚔ stat — blank for Actions, Items |
Willpower | 🛡 stat — blank for Actions, Items |
Lore Points | ◆ gained per quest — blank for Actions, Items |
Inkable | Yes / No |
Keywords | Comma-separated: |
Abilities | Full card text, pipe-separated lines |
Data sources
Source | Sets | Used for |
All sets (1–14+) | Primary source for Set 12+; fallback for 1–11 | |
Sets 1–11 | Preferred for Sets 1–11 (richer body text) | |
All sets | Format legality, card images | |
All sets | TCGPlayer market prices (daily mirror) |
Card data is fetched live and cached locally for 24 hours at ~/.cache/lorcana-mcp/. If LorcanaJSON is unreachable, the server falls back to a bundled card snapshot (lorcana_mcp/data/allcards_fallback.json.gz, refreshed each release) and warns once that data may be stale. Manage the cache with the CLI:
lorcana-mcp cache stats # show entry count, expiry status, and file size
lorcana-mcp cache clear # delete all cached responses (fresh fetch on next use)Supported sets
Set | Name |
1 | The First Chapter |
2 | Rise of the Floodborn |
3 | Into the Inklands |
4 | Ursula's Return |
5 | Shimmering Skies |
6 | Azurite Sea |
7 | Archazia's Island |
8 | Reign of Jafar |
9 | Fabled |
10 | Whispers in the Well |
11 | Winterspell |
12 | Wilds Unknown |
13 | Attack of the Vine! |
14 | Hyperia City |
New sets are picked up automatically via LorcanaJSON as long as the set name is added to the internal mapping. Open an issue if a new set isn't resolving.
TCGPlayer export format
Go to TCGPlayer → My Account → My Collection → Export. The raw file has columns like Product Name, Set Name, Number, Rarity, Condition, Printing, and Add to Quantity (this is the real owned-quantity column — Total Quantity is always blank in exports).
Promo cards: resolved automatically where possible. dreamborn.ink's bulk import represents a promo as
(Set Number, Card Number)whereSet Numberis the LJ set the promo drop is tied to andCard Numberis the full"N/Series"string (e.g."57/P3") — verified against a real dreamborn export, not just its card-browser display (an earlier attempt based on the display alone silently corrupted imports; see CHANGELOG.md's 0.2.2/0.2.3 entries). Any promo not yet in that map still needs manual entry via dreamborn.ink's card search after importing the rest.
CLI reference
lorcana-mcp --version
lorcana-mcp serve Start the MCP server (stdio)
lorcana-mcp cache stats Show cache info
lorcana-mcp cache clear Clear cached API responsesStaying up to date
The card data is always live (fetched from public APIs, cached 24h) — but the
bundled metagame snapshot (get_meta) and any tool/behaviour changes only move
when you update the package:
pip install -U lorcana-mcp # or: uv tool upgrade lorcana-mcpClaude Desktop .mcpb users: re-download lorcana-mcp.mcpb and reinstall — the bundle pins an exact version and does not auto-update. Restart your MCP client after updating so it reconnects to the new server.
Get told when there's a new release:
The server checks PyPI about once a day (fail-silent, cached, one request) and, if it's behind, prints a one-line notice to stderr on startup — visible in Claude Code's MCP logs / Claude Desktop's log files — and appends a note to
get_meta's output. Opt out withLORCANA_MCP_NO_UPDATE_CHECK=1in the server'senv.Or watch the repo: Watch → Custom → Releases, or subscribe to the Atom feed
https://github.com/IcaroBichir/lorcana-mcp/releases.atom.
Development
git clone https://github.com/IcaroBichir/lorcana-mcp
cd lorcana-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest355 tests, no network calls required. CI runs the full suite on Python 3.11, 3.12, and 3.13 on every pull request and on push to main (see .github/workflows/tests.yml).
License
MIT — see LICENSE.
🤖 CLAUDE READ THIS
If you're an AI agent (Claude or otherwise) with this MCP server connected, read this section before making tool calls. It's the fast path to using this correctly.
Which tool to call
The user wants... | Call... | Not... |
Their raw TCGPlayer export turned into a real database |
| — |
To bring stale prices up to date without re-exporting |
| manually curling TCGPlayer |
Stats on a card whose exact name they gave you |
| — |
A card by an informal, partial, or misspelled name (e.g. "goofy musketeer", "big pete", "elsa") |
|
|
Which printing of a card is legal in a format / cheapest to buy / whether it got an Enchanted |
|
|
To browse/filter the whole card pool (by color, type, rarity, set, cost, keyword, ability text, subtype) |
| — |
Singer combos / "who can sing this song for free" |
| — |
Format legality of their collection (Core, Infinity, Poorcana, etc.) |
| — |
To sanity-check an enriched CSV against live data |
| — |
A decklist rated for curve, color balance, and legality |
| — |
"What do I need to buy to finish this deck, and how much?" |
| — |
"Build me a [princess / detective / Stitch] deck" |
| filtering |
"Build me a deck for [ink pair]" |
| manually assembling a decklist from |
"Here's my prerelease / sealed pool" (a list or a photo of opened cards) |
|
|
Hard rules
Always pass absolute paths for
csv_path/input_path/collection_csv. Relative paths resolve against the server process's cwd, not the user's — this fails silently or points at the wrong file. If you don't have an absolute path, ask the user or find the file first.Default to
resolve_cardoverlookup_cardunless the user gave you a name you're confident is exact and correctly spelled. When in doubt,resolve_cardis strictly more forgiving and costs nothing extra.Never hand-roll price lookups.
find_song_synergies,what_am_i_missing, andbuild_deckalready call tcgcsv.com internally with 24h caching and cheapest-printing logic. Don'tcurlTCGPlayer or scrape prices yourself.Gameplay is identical across printings (base, Enchanted, Epic, promo — same name, cost, stats, abilities). Every price-aware tool already picks the cheapest printing automatically; don't second-guess a suspiciously low result, and don't treat rarity as a gameplay signal. Use
list_printingswhen the user needs the per-printing breakdown (which one is legal in a format, which is cheapest, whether it got an Enchanted).If a user says data looks wrong or stale, suggest
lorcana-mcp cache clearbefore assuming a tool is broken — card and price data is cached 24h.Ambiguous tool output is a feature, not an error.
resolve_cardandfind_song_synergiescan return a ranked "did you mean" list instead of a single answer — present it to the user rather than guessing which one they meant.build_deckis a curve/keyword-value heuristic, not a synergy engine. It doesn't detect multi-card combos (Merlin/Mim bounce, Steelsong, etc.) — don't present its output as a finished, tournament-tuned decklist. Treat it as a strong starting point to review and adjust, not a final answer.
Known gotchas (found the hard way — see CHANGELOG.md)
Product ID(CSV column 1) ≠TCGplayer Id(column 2). OnlyProduct IDmatches external pricing APIs (LorcanaJSON'sexternalLinks.tcgPlayerId, tcgcsv.com'sproductId). Column 2 is an unrelated secondary ID — if you're ever writing custom code against this data, matching on it silently returns zero results.Promo cards resolve via
PROMO_DREAMBORN_ROW/PROMO_DREAMBORN_ROW_BY_NUMBER(api.py) — verified against a real dreamborn.ink export, not its card-browser display (an earlier browser-based guess silently corrupted a real import; CHANGELOG.md 0.2.2). A promo's dreambornCard Numberis the full"N/Series"string, not split into a separate series field — don't re-split it if extending this map. Anything not yet in the map still needs manual entry via dreamborn.ink's search after importing.Duplicate-looking rows in search results are printings, not bugs —
search_cardsandfind_song_synergiesalready deduplicate alt-art/Enchanted reprints by name internally, so don't be surprised the count is lower than you'd expect from a raw card list.
If you're modifying this codebase
Run
pytestbefore and after any change — 355 tests, all network-free (external calls are mocked;tests/conftest.pyalso disables the PyPI update check).Code layout: pure/testable logic lives in
api.py(card data + fuzzy matching + pricing),deck.py(deck list parsing/analysis),deckbuilder.py(Constructed deck synthesis),sealed.py(Sealed pool resolution + 40-card builds),enricher.py(CSV pipeline),meta.py+tournaments.py(bundled metagame/tournament snapshot), andupdate_check.py(PyPI version check).server.pyonly wraps those as MCP tools and formats output — keep it that way rather than putting logic directly in tool functions.lorcana_mcp/data/allcards_fallback.json.gzis the offline card-data fallback (refresh withscripts/update_fallback_snapshot.py).A release bumps the version in four files (
pyproject.toml,server.json,packaging/mcpb/pyproject.toml— both itsversionand thelorcana-mcp==pin — andpackaging/mcpb/manifest.json), adds aCHANGELOG.mdentry, and updates this README +docs/INSTALL.mdif tool behavior changed. Checkgit logfor thechore: release X.Y.Zpattern.Publishing is a separate, explicit step (
python -m build,twine upload,mcp-publisher publish) — never assume a version bump inpyproject.tomlmeans it's live on PyPI or the registry. Check before telling a user a feature is "available."
Available Tools
13 toolsanalyze_deckA
Analyze a raw deck list (a list of card names, not a collection CSV) and return its ink curve, composition, and Core Constructed legality — the tool for "is this decklist actually good/legal", independent of what you own or can afford.
Accepts one card per line, e.g. "4x Goofy - Musketeer" or "4 Goofy - Musketeer" (both "4x" and "4 " are accepted; qty is optional and defaults to 1). Lines starting with "#" or "//" are treated as comments and skipped.
Reports: ink curve (1-2/3-4/5-6/7+ cost brackets), inkable vs. uninkable count, color split, card type split, an estimated lore-per-turn (sum of Character lore values), a Core Constructed legality check (60-card minimum, max 4 copies of any card, at most 2 ink colors), and any card names that couldn't be resolved.
Behavior: card names are matched the same simple way as lookup_card
(exact, then substring) — not fuzzy-resolved like resolve_card — so a
typo'd or oddly-abbreviated name lands in the unresolved list rather than
being guessed. Unresolved lines are excluded from every stat (curve,
color split, lore/turn, legality counts), so a deck list with several
unresolved names will under-report its true totals; always check that
list before trusting the numbers. The legality check is Core Constructed
only — it does not check rotation-group safety (whether the deck's cards
survive the next rotation) or Infinity/Poorcana rules; for rotation
safety, cross-reference the card list against search_cards filtered by
set, or build fresh via build_deck(rotation_safe=True).
Usage guidelines: use this on a decklist you already have — hand-written,
pasted from elsewhere, or build_deck's output — to sanity-check curve
and legality before playtesting or buying anything. It never touches your
collection, so it can't tell you what's missing or what it costs; for
that, feed the same deck list to what_am_i_missing instead.
Args: deck_list: Raw deck list text, one card per line.
Inputs: deck_list (required). Returns: result
audit_csvA
Audit an already-enriched Lorcana collection CSV against live API data and report exactly which fields drifted from the current source of truth — a correctness check on data already in the CSV, not a re-enrichment.
Checks Ink color, Ink Cost, Card Type, Subtypes, Inkable, and stats (Strength / Willpower / Lore Points) for every non-promo card, one live API call per unique card. Promo rows are always skipped entirely (counted separately as "promos skipped") since there's no reliable live source to diff a promo printing against. Ability/Keyword text is not checked — only the structured fields above.
Behavior: reports every field-level mismatch as "csv_value" → "api_value", grouped by card. One known, harmless false-positive class:
Subtypes differences that are purely separator/ordering (e.g.
"Storyborn/Ally/Toy" vs "Storyborn, Ally, Toy") — same data, different
formatting convention, most common in newer sets. Skim for those before
treating every reported line as a real error. A completely clean CSV
returns a one-line "no discrepancies found" summary instead of an empty
list.
Usage guidelines: run this after a new set releases, after any manual CSV
edits, or whenever enrichment output looks suspicious — not as a routine
step after every enrich_csv call, since it re-fetches from the live API
per unique card and adds real latency on a large collection. If it turns
up genuine (non-Subtypes-formatting) discrepancies, the fix is to re-run
enrich_csv, not to hand-edit the CSV — this tool only reports drift, it
does not write any changes back to the file.
Args: csv_path: Absolute path to an enriched Lorcana collection CSV.
Inputs: csv_path (required). Returns: result
build_deckA
Automatically assemble a legal, curve-balanced ~60-card decklist for an ink pair and format, in one of 3 modes:
"collection": build only from cards you own (capped at owned quantity per card). If fewer than 60 legal owned cards exist, reports the shortfall honestly instead of padding with irrelevant fillers.
"ideal": build the best deck regardless of ownership. If collection_csv is given, also shows what you already own, what's missing, and the price to complete it (via tcgcsv.com).
"market": build the best deck ignoring any collection, and prices every card in it (not just the gap) via tcgcsv.com.
This is a heuristic curve/keyword-value builder — it optimizes ink curve, stat efficiency, and keyword value, not multi-card combos or synergy packages. See the disclaimer at the bottom of every result.
format="coconut" builds for Format Coconut (Ravensburger's multiplayer singleton beta, open since 2026-07-28 — rules/card pool may still change; see the project CLAUDE.md's "Format Coconut" section). It needs coconut_card, allows up to 3 ink colors (one must match the Coconut's own ink), has no rotation and no tracked banned list (every released card is treated as legal), and every card in the build is capped at 1 copy except the Coconut's associated real character, which may run up to 4 — this replaces the usual max-4-of-anything rule entirely. Call with format="coconut" and no coconut_card to get the full list of the 18 beta Coconuts to choose from.
Args: ink_colors: Comma-separated ink color(s), e.g. "Amber,Sapphire". 1-2 colors for core/core_zh/core_ja/poorcana, 1-6 for infinity, 1-3 for coconut (must include the Coconut card's own ink — see coconut_card). May be omitted entirely when format="coconut" and coconut_card is also omitted — that combination just lists the 18 beta Coconut cards (filtered to the given ink(s), if any) and doesn't build anything yet. mode: "collection", "ideal", or "market". format: "core", "infinity", "core_zh", "core_ja", "poorcana", or "coconut". collection_csv: Absolute path to an enriched collection CSV. Required for mode="collection"; optional for "ideal"; ignored for "market". rotation_safe: If True and format="core", restrict to the rotation group that will still be legal after the next rotation event. No-op (with a note) for other formats. coconut_card: Required when format="coconut" — fuzzy name of one of the 18 beta Coconut cards (e.g. "Ariel", "Mickey Mouse", "snow white"). Ignored for every other format. include_preview: If True and format is "core" or "infinity", also admit cards from announced sets that aren't legal yet (e.g. Hyperia City before its release date) — whatever LorcanaJSON has revealed so far, which may be a partial set. Preview cards are marked in the decklist and usually have no TCGPlayer price yet. No-op (with a note) for other formats. theme: Optional deck theme — a classification ("princess", "detective", "seven dwarfs", "villain", ...) or a character name ("mickey mouse", "stitch"). Cards of that classification/ name, and cards whose text references it (payoffs like "your Princess characters get +1 ¤"), are strongly preferred. If ink_colors is omitted, the two-ink pair with the most theme cards in the legal pool is chosen automatically (not for coconut, which needs its Coconut's ink).
Inputs: mode, theme, format, ink_colors, +4 more. Returns: result
build_sealed_deckA
Build the best 40-card Sealed (prerelease) deck from a player's opened card pool — for prerelease events, where everyone opens 6 booster packs (~72 cards) on-site and has ~45 minutes to build.
Sealed rules applied: 40-card minimum; NO ink-color limit; NO copy limit (every copy you opened is playable, even 5+); the stamped prerelease promo is allowed; unused cards are the sideboard (swappable between games). No format-legality or rotation check — the set doesn't need to be released yet.
Strategy: ranks every two-ink pair by pool depth and builds around the
best one (or ink_colors), splashing a third/fourth ink only when the
core pair can't reach 40 on its own — common from 6 packs. Ink is
colorless in Lorcana, so a splash costs synergy, not consistency.
Input — pool is one card per line, quantity optional ("2x Card Name",
"2 Card Name", or just "Card Name"; repeats are summed). Each line can be:
a card name, informal or misspelled is fine ("mickey best in town");
the collector number printed at the card's bottom ("123", "123/204", "123/204 EN 14") — matched within
set_name.
If the user sends a PHOTO of their pool: read every visible card from the image and pass one line per card. Prefer the collector number when it's legible (most reliable); otherwise the name + subtitle. Count duplicates. Then tell the user which cards came back ambiguous/unrecognized so they can confirm, and re-call with corrected lines.
Output: ink-pair ranking, the 40-card list by cost, splash notes, stats (curve, inkable count, lore), the strongest sideboard cards, and any ambiguous/unrecognized lines (excluded from the build — never guessed). Heuristic curve/keyword-value scoring with Shift-chain awareness, not a full synergy engine: review the list before sleeving it.
Args: pool: The opened cards, one per line (names and/or collector numbers). ink_colors: Optional comma-separated core inks to force, e.g. "Amber,Steel" (any number allowed in Sealed). Empty = auto-pick the deepest pair. set_name: The prerelease set, used to scope name matching and to read collector numbers. Default "Hyperia City" (Set 14).
Inputs: pool (required), set_name, ink_colors. Returns: result
enrich_csvA
Enrich a raw TCGPlayer Lorcana CSV export with full card data — the
required first step before any other tool here can read your collection
(filter_collection, audit_csv, what_am_i_missing, build_deck, and
find_song_synergies's collection_csv all expect this tool's output,
not the raw TCGPlayer export).
Fetches card data from LorcanaJSON (sets 12+) and lorcana-api.com (sets
1–11) and adds Ink color, Ink Cost, Card Type, Subtypes, Strength,
Willpower, Lore Points, Inkable, Keywords, and Abilities to each row. Both
sources are disk-cached 24h, so a second run soon after the first is
fast regardless of cache_path.
Behavior: writes two new files next to the input — never modifies
input_path itself — and always reports fill-rate stats per column plus
any cards it couldn't match (usually a name typo in the export, or a
brand-new card the APIs haven't indexed yet). Promo cards (Set Name
"Disney Lorcana Promo Cards") are matched by name against their
non-promo equivalent for stats, and separately resolved to a
dreamborn.ink-importable (Set Number, Card Number) row when this
server's built-in promo table covers that card; promos it doesn't
recognize are listed for manual entry rather than guessed. cache_path
only skips re-fetching for card names already present in that prior
enriched CSV — it does not skip enrichment for new cards in the input.
Writes two output files next to the input: enriched_{filename} — enriched collection CSV dreamborn_{filename} — import-ready CSV for dreamborn.ink
Usage guidelines: run this on every fresh TCGPlayer export before doing
anything else with it. Pass cache_path pointing at your previous
enriched CSV on a re-export to speed things up — otherwise every row
re-fetches from the API even for cards you've already enriched before.
Use refresh_prices=True specifically to bring an existing enriched
CSV's prices current without a fresh TCGPlayer export (it only touches
the price column, not the card-data columns); leave it off for a
same-day fresh export, since the TCGPlayer download already has current
prices and refreshing adds an extra tcgcsv.com call per row.
Args: input_path: Absolute path to the raw TCGPlayer CSV export. cache_path: Optional path to a previous enriched CSV to speed up re-runs by skipping API calls for cards already seen. refresh_prices: If True, overwrite each row's TCG Market Price with a live tcgcsv.com lookup for that exact printing, instead of leaving whatever the raw TCGPlayer export had at download time. Use this to bring an old enriched CSV's prices current without re-exporting from TCGPlayer.
Inputs: input_path (required), cache_path, refresh_prices. Returns: result
filter_collectionA
Filter an enriched collection CSV down to the cards you own that are legal in a specific play format — answers "which of my cards can I actually play in format X", grouped by ink color with owned quantities.
Legality data comes from a live duels.ink fetch, which tracks Core EN, Infinity, Core ZH, and Core JA rotation. Poorcana (Common/Uncommon only, 50-card min) is the one exception: it's derived purely from the CSV's own Rarity column, no external lookup, so it still works offline and always reflects the CSV's rarity data exactly.
Behavior: promo rows (Set Name == "Disney Lorcana Promo Cards") are always
excluded from Core/Infinity/regional results, not flagged as illegal —
duels.ink's legality table is keyed by (set, number) and promos don't map
onto that cleanly (see "Promo cards" in the reference doc). Any other row
duels.ink doesn't recognize (usually a card from a set duels.ink hasn't
indexed yet) is silently skipped and counted in a "rows skipped" footer —
that's a data-lag note, not a legality verdict, so don't read a skipped
row as "illegal". Requires the enriched CSV's columns (Set Name, Number,
Ink, Ink Cost, Add to Quantity, etc.) — running this against the raw
TCGPlayer export (pre-enrich_csv) will silently undercount or return
nothing useful.
Usage guidelines: run this when you want to see your full legal card pool
for a format before hand-building a deck, or to sanity-check whether a
deck idea is even feasible with what you own. If you want a finished
decklist rather than just the eligible pool, use build_deck with
mode="collection" instead — it already applies this same legality
filter internally as part of assembling a curve-balanced list, so you
don't need to call both.
Args: csv_path: Absolute path to an enriched Lorcana collection CSV. format: "core", "infinity", "core_zh", "core_ja", or "poorcana".
Inputs: csv_path (required), format. Returns: result
find_song_synergiesA
Find every Character that can sing a given song — the tool for building or
checking a Singer/song combo (e.g. the Amber/Steel Steelsong package), not
for general card search (use search_cards for that).
A character can sing a song if its printed ink cost meets the song's cost outright, OR it has a "Singer X" keyword with X meeting the song's cost — Singer lets a cheap character punch above its actual cost for singing purposes only (see the Steelsong package: Amber Singers unlocking expensive Steel songs for free). Provide either song_name (resolved the same fuzzy way as resolve_card, so "beauty and beast" or a slight typo still works) or a raw cost threshold — exactly one is required; passing neither, or both, returns an error message instead of guessing.
Results are grouped: Singer-keyword characters first (the actual
"discount" picks — highest Singer value, then cheapest actual cost),
followed by characters that simply cost enough to sing it outright,
cheapest first. This only tells you who can sing — it doesn't check
whether that character is otherwise good (stats, other abilities) or
whether you own enough copies to make the combo consistent unless you
pass collection_csv, in which case each result is annotated with owned
quantity so you can see the combo's real consistency at a glance.
Args: song_name: Name of a Song card, e.g. "Be Our Guest". Fuzzy-matched. cost: Raw song cost threshold to use instead of song_name, e.g. 5. colors: Optional comma-separated ink color(s) to restrict characters to, e.g. "Amber,Steel". collection_csv: Optional path to an enriched collection CSV — when given, each character is flagged with how many copies you own. limit: Max characters to list (default 50, capped at 200).
Inputs: cost, limit, colors, song_name, +1 more. Returns: result
get_metaA
Return a hand-maintained Core Constructed metagame snapshot: a tier list
of every two-ink pair (archetype name, tier, rough meta share, playstyle)
plus a summary of recent notable tournament results — for answering
"what's strong right now" or "how does my ink pair compare". With event
set, returns that tournament's full standings and decklists instead.
Unlike every other tool here, this is NOT a live fetch. There is no free,
structured feed for competitive metagame share or tournament decklists —
inkDecks.com and lorcana.gg publish this as HTML, and tournament results
circulate as social-media images, not an API. This tool instead returns a
versioned snapshot bundled into the package at release time (see
lorcana_mcp/meta.py / tournaments.py and the CHANGELOG for when it was
last refreshed). The response states its own snapshot date and sources up
front, and flags which rows have actually been checked against a real
recent tournament result versus older, unverified metagame-tracker data
— don't treat an old row's tier/meta-share as more current than it is.
Tournament decklists are transcribed from card-grid images: counts/art
are reliable, but a few 1-of tech slots and some subtitles are best-effort
(per-list notes flag where).
Usage guidelines: reach for this when a player asks what's currently
good, whether a given ink pair is competitive, or wants context before
calling build_deck. For a specific event's lists, pass event (the
plain snapshot output lists which events are available). It complements
build_deck/analyze_deck, which build or evaluate one concrete deck.
Args:
ink_colors: Optional pair of ink colors to filter to one tier-list
row, comma- or slash-separated, e.g. "Emerald,Steel" or
"Amber/Sapphire" (order doesn't matter). Ignored if
event is set.
event: Optional tournament key or name fragment (e.g. "nac",
"kobe", "asia-championship-2026") to get that event's full
standings + decklists instead of the tier list.
Inputs: event, ink_colors. Returns: result
list_printingsA
List every printed version of a Lorcana card — or every card sharing a character name — side by side: each one's set, card number(s), cost, stats, rarity, per-format legality, and the cheapest market price to acquire it.
Reach for this whenever the answer depends on which printing:
"is any Milo Thatch legal in Core?", "which Elsa is cheapest?", "did this
card ever get an Enchanted?", "what's the current-set version vs. the
rotated-out one?". lookup_card silently collapses to just the newest
printing; this shows them all.
Matching, in order: exact full name ("Elsa - Spirit of Winter"); exact character name ("Elsa" → every distinct Elsa card); full-name substring; then a fuzzy resolve. A bare character name lists every subtitle; a full name lists that one card's base + Enchanted/Epic printings. Enchanted and Epic printings are gameplay-identical to the base — they only change the number, rarity, and price, which is exactly what this tool compares.
fmt (optional): one of core, infinity, core_ja, core_zh, poorcana,
coconut. When given, adds a legality column for just that format and lists
legal cards first. Legality/images come from duels.ink and prices from
tcgcsv.com (a daily TCGPlayer mirror); both are fetched live, cached 24h,
and shown as "?" / omitted (never errored) when unavailable.
Args: name: A card's full name, or a bare character name. fmt: Optional play format to flag legality for.
Inputs: name (required), fmt. Returns: result
lookup_cardA
Look up one specific, already-known Lorcana card by (near-)exact name and return its full stats, abilities, and format legality in one call.
Behavior: tries an exact name match against LorcanaJSON first, then falls
back to a plain substring match — this is simple matching, not fuzzy
scoring. If the same card name exists across multiple sets/printings and
set_name isn't given, it silently returns the most recent printing
rather than listing the alternatives (Enchanted/Epic/promo variants are
gameplay-identical to the base card either way, so this rarely matters
for stats — but a specific older printing's card ID/legality nuance won't
surface without set_name). Card data (LorcanaJSON + duels.ink) is
fetched live and cached on disk for 24h — see lorcana-mcp cache stats /
cache clear if you suspect stale data right after a new set drops.
Usage guidelines: reach for this first when you already have a specific
printed card name (even with the subtitle omitted, e.g. "Mirage") — it's
the cheapest, most precise lookup. If it returns "no card found" for a
name you're unsure is spelled/formatted correctly (informal phrasing,
missing dashes, a likely typo, or a bare first name meant to cover several
printings), retry with resolve_card instead, which fuzzy-matches and
will disambiguate multiple candidates rather than failing outright. For
browsing/filtering many cards by criteria instead of one known name, use
search_cards.
Args: name: Card name, e.g. "Mirage - Super Recruiter" or just "Mirage". set_name: Optional set name to narrow the search, e.g. "Wilds Unknown".
Inputs: name (required), set_name. Returns: result
resolve_cardA
Resolve an informal, misspelled, or subtitle-less card name to specific card(s).
Unlike lookup_card's simple substring match, this tokenizes the query and scores it against every card's name and subtitle, tolerating missing dashes ("goofy musketeer"), missing subtitles ("Elsa" — which returns all her versions), word order, and minor typos ("musketer"). Use this when lookup_card fails or when you're not sure of a card's exact printed name.
Returns one of three shapes:
A single confident match: full card detail (same as lookup_card).
Multiple plausible matches: a ranked top-3 list with confidence scores, for you to disambiguate (e.g. "Pete" with no further qualifier, or a bare character name matching several printings).
No match: nothing scored above the noise floor.
Args: name: Informal, partial, or misspelled card name. set_name: Optional set name to narrow the search, e.g. "Wilds Unknown".
Inputs: name (required), set_name. Returns: result
search_cardsA
Search the full Lorcana card pool (all sets, every printed card) by any combination of filters — not your collection. This is a discovery tool for "what cards fit X criteria", independent of what you own or have priced.
All filters are optional and ANDed together, except colors: a card matches if it has ANY of the given colors, so dual-ink cards surface for either half. Calling with no filters at all returns the entire card pool, paginated.
Behavior: always fetches from a live, in-process-cached copy of
LorcanaJSON (see the "Card data APIs" reference) — never reads a local CSV,
so results always include the newest released set. A card that has no
Strength/Willpower/Lore (Action, Item, Location) shows "—" for those
stats rather than being excluded. Results are grouped and displayed by ink
color, then returned as one or more Markdown tables; when more results
exist than limit, the response tells you the exact offset to pass next
— call again with that offset rather than guessing pages.
Usage guidelines: use this to browse/filter by criteria (e.g. "every
Evasive Sapphire character costing 3 or less") — if you already have a
specific (possibly misspelled or subtitle-less) card name in mind, use
resolve_card or lookup_card instead, they're cheaper and more precise
for a single known card. Results carry no ownership or price information;
to check what you already own, cross-reference the card names against an
enriched collection CSV yourself, or use what_am_i_missing /
find_song_synergies's collection_csv param for tools that do that
automatically. To narrow to a specific play format's legal pool, combine
with set_name, or post-filter the result against filter_collection's
format logic.
Args: colors: Comma-separated ink color(s), e.g. "Amber,Steel". Case-insensitive. card_type: "Character", "Action", "Item", "Location", or "Song" (Action cards with the Song subtype). rarity: "Common", "Uncommon", "Rare", "Super Rare", "Legendary", "Enchanted", "Epic", "Iconic", or "Special". set_name: Set name substring, e.g. "Wilds Unknown". cost_min: Minimum ink cost, inclusive. Pass -1 (default) for no minimum. cost_max: Maximum ink cost, inclusive. Pass -1 (default) for no maximum. keyword: Keyword ability name, e.g. "Evasive", "Rush", "Bodyguard", "Shift". ability_text: Substring to search for in full ability text (case-insensitive). subtype: Subtype/classification, e.g. "Toy", "Hero", "Villain", "Princess". offset: Pagination offset, 0-based. limit: Max results in this page (default 25, capped at 200).
Inputs: limit, colors, offset, rarity, +7 more. Returns: result
what_am_i_missingA
Compare a deck list against your collection: what you already own, what's
missing or short, and the estimated cost to complete it — the shopping-list
counterpart to analyze_deck, which checks curve/legality but never looks
at ownership.
Cross-references a raw deck list (same format as analyze_deck: 4x Card Name per line) against an enriched collection CSV. Card names are matched
the same simple exact-then-substring way as lookup_card (not fuzzy like
resolve_card); a name that doesn't resolve is dropped from the "Already
have"/"Missing" tallies and listed separately under an "unresolved" section
instead of being silently skipped — check that section if the totals look
short. For every card you're short on, price comes first from the CSV's
own TCG Market Price if you already own at least one printing (no network
needed); only cards you own zero copies of fall back to a live TCGPlayer
lookup via tcgcsv.com for the cheapest printing across all sets/rarities
(gameplay is identical regardless of rarity or art). That fallback fetch
only fires if at least one card actually needs it, and its price data is
cached 24h — the reported total is always a snapshot, not a quote.
Usage guidelines: use this once you have a specific decklist in hand
(hand-written, or build_deck's output) and want to know what to buy or
borrow before playtesting it. It doesn't check Core Constructed legality
or curve — run analyze_deck on the same list for that. If instead you
want a deck built around what you can realistically complete rather than
checking a fixed list, use build_deck(mode="ideal"), which folds this
same ownership/pricing logic into deck construction itself.
Args: deck_list: Raw deck list text, one card per line (e.g. "4x Goofy - Musketeer"). collection_csv: Absolute path to an enriched Lorcana collection CSV.
Inputs: deck_list (required), collection_csv (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 13 tools
The 13 tools have largely distinct purposes, and descriptions cross-reference each other extensively (e.g., lookup_card vs resolve_card vs search_cards). However, four tools (lookup_card, resolve_card, list_printings, search_cards) all return card data, creating some initial overlap that could lead to misselection without careful reading.
Names are consistently snake_case and mostly follow a verb_noun pattern (build_deck, analyze_deck, search_cards, enrich_csv). The one deviation is the interrogative what_am_i_missing, which breaks the pattern though the meaning remains clear.
13 tools is well within the sweet spot for a TCG assistant, covering card lookup, collection management, deck building, and meta without obvious redundancy. Each tool earns its place and no single tool feels trivial or bloated.
The surface covers the full lifecycle: card discovery (lookup/resolve/search/printings/synergies), collection import and validation (enrich_csv/audit_csv/filter_collection), deck construction (build_deck/build_sealed_deck), evaluation (analyze_deck/what_am_i_missing), and metagame context (get_meta). No obvious dead ends exist for the stated domain.
Maintenance
Related MCP Connectors
Search curated Lorcana resources, evidence, taxonomies, and public change history.
Connect Claude to your Platform7n workspaces: chat, links, work and decks. One-click OAuth.
Run UX research from Claude — create card sort studies, list studies, pull headline stats.
Look up Pokemon TCG Pocket cards, sets, packs, and evaluate decks with battle simulations.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables Magic: The Gathering players to manage decks and access card information through Claude, supporting gameplay actions like drawing cards and mulligans while providing Scryfall API integration for card lookups.15-
- AlicenseCqualityDmaintenanceA Model Context Protocol server that allows Claude to search and display Pokemon Trading Card Game cards with filtering by attributes like name, type, legality, and statistics.27 npm12ISC
- AlicenseNot gradedqualityNot gradedmaintenanceConnects Claude to Spotify for music discovery, playlist creation, and collection analysis through natural language. Enables searching songs, analyzing music diversity, creating playlists, and getting recommendations using Spotify's API.-
- AlicenseAqualityDmaintenanceMagic: The Gathering MCP server with card search, rules lookup, deck analysis, and Commander intelligence1465 npm5MIT