oci ghcr.io/danielenricocahall/lorcana-mcp:2.4.0stdioMITupdated 9d ago
An MCP server for searching and aggregating Disney Lorcana cards.
O que dá para fazer com Lorcana MCP?
Lorcana MCP Server
An MCP server for searching and aggregating Disney Lorcana cards.
Startup behavior
On startup, the server fetches a JSON list of cards from https://danielenricocahall.github.io/lorcana-mcp/allCards.json. The snapshot is refreshed daily by data_pipeline/fetch_cards.py, which pulls from the Lorcast API, normalizes each card into our internal schema, and publishes the list to the gh-pages branch. The middle layer insulates running containers from Lorcast's availability and rate limits — the runtime never calls Lorcast directly.
Cards are kept in-memory as a Python list for fast filtering. With ~2,270 unique cards (each carrying a printings array for its alternate sets/rarities) this is lightweight and requires no external database. A local JSON file cache (LORCANA_CACHE_PATH, default cards.json) lets the server skip the network fetch on subsequent startups.
Startup data loading is controlled by:
LORCANA_REFRESH_ON_STARTUP:true: always fetch from API and repopulate storagefalse: use existing cache if available
LORCANA_SKIP_IF_DB_EXISTS:true(default): skip API fetch if the cache file already contains cardsfalse: fetch and repopulate
Quick start (no clone required)
The server is published to GHCR and the MCP Registry. Pull and run it directly:
docker pull ghcr.io/danielenricocahall/lorcana-mcp:latest
docker run --rm -i ghcr.io/danielenricocahall/lorcana-mcp:latest
To persist the card cache across container restarts, mount a volume:
docker run --rm -i \
-e LORCANA_CACHE_PATH=/data/cards.json \
-e LORCANA_SKIP_IF_DB_EXISTS=true \
-v lorcana_mcp_data:/data \
ghcr.io/danielenricocahall/lorcana-mcp:latest
Run locally (stdio MCP)
uv run python main.py
Docker
Build image
docker build -t lorcana-mcp:latest .
Run as stdio MCP server
docker run --rm -i lorcana-mcp:latest
Docker Compose
Start with compose
docker compose build
docker compose run --rm -T lorcana-mcp
Notes:
- No port is exposed; MCP communication is over stdio.
- Use a volume to persist the JSON cache across restarts.
Config
LORCANA_API(default:https://danielenricocahall.github.io/lorcana-mcp/allCards.json)LORCANA_CACHE_PATH(default:cards.json) — local file for caching fetched cardsLORCANA_HTTP_TIMEOUT_SECONDS(default:60)LORCANA_REFRESH_ON_STARTUP(falsedefault)LORCANA_SKIP_IF_DB_EXISTS(truedefault)
MCP client setup examples
Local process (Claude Desktop-style)
{
"mcpServers": {
"lorcana": {
"command": "uv",
"args": ["run", "python", "/absolute/path/to/lorcana-mcp/main.py"]
}
}
}
Published image — GHCR (Claude Desktop-style, no clone required)
{
"mcpServers": {
"lorcana": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/danielenricocahall/lorcana-mcp:latest"
]
}
}
}
Docker process (Claude Desktop-style, locally built)
{
"mcpServers": {
"lorcana": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"lorcana-mcp:latest"
]
}
}
}
Docker Compose process (Claude Desktop-style)
{
"mcpServers": {
"lorcana": {
"command": "docker",
"args": ["compose", "run", "--rm", "-T", "lorcana-mcp"]
}
}
}
Via the Claude CLI — published image (global, no clone required)
claude mcp add --scope user \
-- lorcana docker run --rm -i \
ghcr.io/danielenricocahall/lorcana-mcp:latest
Via the Claude CLI — locally built
claude mcp add --scope user \
-- lorcana docker run --rm -i lorcana-mcp:latest
Example questions
Once connected to an MCP client, you can ask natural language questions like:
Card lookup
- "Show me all cards named Moana"
- "What does the card Maui - Hero to All do?"
- "Find all legendary amber cards"
Deck building
- "What are the cheapest ruby characters with at least 3 strength?"
- "Show me inkable sapphire cards that cost 4 or less"
- "Find steel characters with 5 or more willpower"
- "What 3-lore characters exist in emerald?"
Keyword & ability search
- "How many Singer cards cost exactly 5?"
- "How many Evasive characters are there in the first set?"
- "How many ruby cards have Reckless?"
- "Find all cards with Ward in their text"
- "Show me Shift cards in amethyst"
Stats & aggregations
- "How many cards are in each set?"
- "What's the color distribution across all cards?"
- "What are the most common traits?"
- "Show me the ink curve — how many cards exist at each cost?"
- "How many legendary cards are inkable?"
Cross-filter queries
- "How many amber characters have 3 or more lore?"
- "Find cheap (cost 2-3) characters with high strength (4+) in steel"
- "How many cards in set 1 have Evasive and cost less than 4?"
Note: For plain keyword queries (Evasive, Bodyguard, Shift, etc.) use the
keywordparameter — it filters against the structured ability list and is more reliable than substring search. For value-specific queries likeSinger 5orResist +2, usebody_text(keyword values live in the card's full text, not the ability list).
MCP tools
search_cards— filter and retrieve card objects (supportsresponse_format="toon"for ~10% fewer tokens)count_cards— count cards matching a filter without returning full objectsaggregate_cards— card counts grouped bycost(ink curve),rarity,color,set_code, ortyperesolve_card— fuzzy-match an informal/partial/misspelled card name to the closest cards (returns full card data)top_traits— most common traits across all cardsexport_deck— render a deck as a Dreamborn/Pixelborn-compatible text deck listimport_deck— parse a Dreamborn/Pixelborn-style deck list, returning resolved cards plus any unresolved lines with fuzzy candidatesvalidate_deck— check a deck against the format rules (≥60 cards, max 4 copies, ≤2 inks); returns{legal, total_cards, inks, violations}deck_stats— compute ink curve, color split, inkable count, type breakdown, keyword counts (Evasive, Ward, Shift, ...), subtype counts, and per-card keyword tags for a deckserver_status— startup metadata (card count, config)
MCP prompts
build_deck(colors, playstyle="balanced")— guides the model through assembling a legal Lorcana deck (60-card minimum, ≤2 inks, max 4 copies of any card) for the requested color(s) and playstyle (aggressive/control/lore-race/balanced). Uses the search/aggregate tools above plus the rules embedded in the server instructions.
TOON response format
search_cards accepts a response_format argument:
"json"(default) — list of card objects, unchanged from prior versions."toon"— a TOON string with one column header line and one row per card, encoded by thetoonsRust-backed library (the official community reference implementation).
Example (search_cards(name="elsa", limit=2, response_format="toon")):
cards[2]:
- id: crd_01c4835a62df4960bb973aeff81f2bb2
name: Elsa
version: Ice Maker
full_name: Elsa - Ice Maker
cost: 7
...
printings[3]{set_code,set_name,number,rarity}:
"7",Archazia's Island,69,Super Rare
C2,Lorcana Challenge Year 3,2,Promo
C2,Lorcana Challenge Year 3,6,Promo
- id: crd_04bca46a8e2d4e9ba0fbdbfc6c99e51e
name: Elsa
...
The outer cards[2]: falls back to YAML-style per-card blocks (rather than a single tabular table) because card shapes vary — Actions and Items don't carry strength/willpower/lore, for example. The inner printings[N]{...}: block is fully tabular since every printing has the same four fields.
Benchmark
Measured with benchmarks/bench_toon.py against the live ~2,270-card dataset (post-consolidation), tokenizing with tiktoken cl100k_base (used as a proxy for Claude's tokenizer):
| query | rows | JSON tokens | TOON tokens | Δ |
|---|---|---|---|---|
color="amber", limit=200 |
200 | 43,672 | 39,282 | −10.1% |
color="ruby", limit=50 |
50 | 10,446 | 9,464 | −9.4% |
card_type="action", limit=50 (sparse cols) |
50 | 10,150 | 9,265 | −8.7% |
body_text="when", limit=50 (long full_text) |
50 | 11,574 | 10,380 | −10.3% |
name="elsa", limit=20 |
14 | 3,456 | 2,925 | −15.4% |
| total | 79,298 | 71,316 | −10.1% |
Note: TOON's relative savings are smaller here than they were before the printings consolidation (pre-PR-#29 the same queries showed ~50% reductions). That gap is structural to the nested printings array — TOON's columnar encoding wins on the top-level fields but falls back to JSON-style encoding inside the per-printing entries, so the array dilutes the relative gain. Absolute token counts are still down meaningfully versus the equivalent count of pre-consolidation rows since each unique card is now represented once with a small printings list rather than as 1-3 separate full rows.
Reproduce with PYTHONPATH=. uv run python benchmarks/bench_toon.py (requires a populated cards.json cache).
Disclaimer
This is a personal, unofficial fan and engineering project. It is not affiliated with, endorsed by, sponsored by, or reviewed by Disney, Ravensburger, or the Disney Lorcana TCG team. I worked only with publicly available/community data sources. All Disney Lorcana TCG names, card text, trademarks, and related intellectual property belong to Disney and Ravensburger. This project is non-commercial and reflects my personal views only, not those of my employer.
Instalação
Adicione Lorcana MCP ao seu cliente. Escolha o que você usa.
claude mcp add ghcr-io-danielenricocahall-lorcana-mcp-2 -- docker run -i --rm ghcr.io/danielenricocahall/lorcana-mcp:2.4.0codex mcp add ghcr-io-danielenricocahall-lorcana-mcp-2 -- docker run -i --rm ghcr.io/danielenricocahall/lorcana-mcp:2.4.0amp mcp add ghcr-io-danielenricocahall-lorcana-mcp-2 -- docker run -i --rm ghcr.io/danielenricocahall/lorcana-mcp:2.4.0{
"mcpServers": {
"ghcr-io-danielenricocahall-lorcana-mcp-2": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/danielenricocahall/lorcana-mcp:2.4.0"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"ghcr-io-danielenricocahall-lorcana-mcp-2": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/danielenricocahall/lorcana-mcp:2.4.0"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
code --add-mcp '{"name":"ghcr-io-danielenricocahall-lorcana-mcp-2","command":"docker","args":["run","-i","--rm","ghcr.io/danielenricocahall/lorcana-mcp:2.4.0"]}'Or add the block manually to `.vscode/mcp.json` under `servers`.
{
"mcpServers": {
"ghcr-io-danielenricocahall-lorcana-mcp-2": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/danielenricocahall/lorcana-mcp:2.4.0"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"ghcr-io-danielenricocahall-lorcana-mcp-2": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/danielenricocahall/lorcana-mcp:2.4.0"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"ghcr-io-danielenricocahall-lorcana-mcp-2": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/danielenricocahall/lorcana-mcp:2.4.0"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"ghcr-io-danielenricocahall-lorcana-mcp-2": {
"type": "local",
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/danielenricocahall/lorcana-mcp:2.4.0"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"ghcr-io-danielenricocahall-lorcana-mcp-2": {
"command": {
"path": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/danielenricocahall/lorcana-mcp:2.4.0"
]
}
}
}
}Add to your Zed `settings.json`.
docker run -i --rm ghcr.io/danielenricocahall/lorcana-mcp:2.4.0Run `goose configure`, choose **Add Extension → Command-line Extension**, and paste this command.
Pontuação
39 / 100
Incompleta
- Documentação25/25
- Manutenção25/25
- Confiança13/20
- Capacidade0/15
- Instalação12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 1 days ago
- Has a release history
- Repository is not archived
- Licensed MIT
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 0 tool(s) documented
- Provides prompt templates
- Provides resources
- 12 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint — no local install
Histórico de versões
| Versões | Publicada |
|---|---|
| 2.4.0Mais recente | 30 de ago. de 2026 |
| 2.3.0 | 3 de ago. de 2026 |
| 2.2.0 | 13 de jun. de 2026 |
| 2.1.0 | 27 de abr. de 2026 |
| 2.0.0 | 26 de abr. de 2026 |
| 1.5.0 | 26 de abr. de 2026 |
| 1.4.0 | 8 de abr. de 2026 |
| 1.3.0 | 29 de mar. de 2026 |
| 1.2.0 | 26 de mar. de 2026 |
| 1.1.1 | 23 de mar. de 2026 |
| 1.1.0 | 22 de mar. de 2026 |
| 1.0.1 | 10 de mar. de 2026 |
| 1.0.0 | 3 de mar. de 2026 |