scryfall-mcp
scryfall-mcp
An MCP server that wraps the Scryfall API and gives any agent full access to Magic: The Gathering card data — search, rulings, sets, symbols, catalogs, and local deck management with multi-owner support.
Works with Claude Desktop, Pi, Hermes, Cursor, Claude Code, or any MCP client.
What you get
28 tools. Full Scryfall API coverage — search, rulings, sets, symbols, catalogs, bulk data, migrations, plus local deck management with multi-owner support, export/import, and card caching.
Area | Tools |
Card lookup |
|
Card display | Shows all faces (transform/adventure/battle), tokens/related cards, game changer flags, EDHREC rank, purchase links, preview info |
Rulings |
|
Sets |
|
Symbols |
|
Catalogs |
|
API data |
|
Deck CRUD |
|
Deck cards |
|
Deck analysis |
|
Format rules |
|
Export/Import |
|
Decks live as JSON files at ~/.config/scryfall-mcp/decks/. Each deck has an owner field — multiple people can manage their own decks from the same server.
Card data is cached locally at ~/.config/scryfall-mcp/cache/cards/ so repeated lookups (same card, same session or across sessions) cost zero API calls. The cache has a 24-hour TTL.
Both paths live outside your repo clone — updating the code or switching branches won't touch your data.
Quick start
git clone <repo-url> scryfall-mcp
cd scryfall-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python server.pyThat's it. The server starts on stdio, which is what most MCP clients expect.
Connecting
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"scryfall": {
"command": "python3",
"args": ["/absolute/path/to/scryfall-mcp/server.py"]
}
}
}Pi
Add to your Pi settings.json (global or project-local):
{
"mcpServers": {
"scryfall": {
"command": "python3",
"args": ["/absolute/path/to/scryfall-mcp/server.py"]
}
}
}Then /reload Pi.
Hermes
Same pattern — point your Hermes MCP config at the server script.
Any MCP client via Python
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
server_params = StdioServerParameters(
command="python3",
args=["/path/to/scryfall-mcp/server.py"],
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("search_cards", {
"query": "c:red t:instant cmc<=2",
})
print(result.content[0].text)Search syntax (the part you'll use most)
Scryfall's search is powerful. Here's the cheat sheet:
c:red Color
t:instant Type
o:"draw a card" Oracle text
m:{U}{U} Mana cost
pow>=4 Power
tou<=2 Toughness
s:mkm Set code
f:standard Format legality
id:ub Color identity
r:mythic Rarity
year:2024 Release year
is:transform Layout flag
-t:creature Negation
(t:instant OR t:sorcery) GroupingCombine freely. c:red t:instant cmc<=1 = cheap red instants.
Deck management
Decks are stored as JSON files in ~/.config/scryfall-mcp/decks/. One file per deck.
# Create a deck
python -c "
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def run():
async with stdio_client(StdioServerParameters(command='python3', args=['server.py'])) as (r, w):
async with ClientSession(r, w) as s:
await s.initialize()
r = await s.call_tool('create_deck', {
'name': 'My Deck',
'owner': 'zg',
'format': 'commander'
})
print(r.content[0].text)
asyncio.run(run())
"Or just use the tools directly from your agent — that's the whole point.
Export to MTG Arena / Archidekt
# Export a deck in MTGA format (importable into Arena, Archidekt, Moxfield)
python -c "
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def run():
async with stdio_client(StdioServerParameters(command='python3', args=['server.py'])) as (r, w):
async with ClientSession(r, w) as s:
await s.initialize()
r = await s.call_tool('export_deck', {
'deck_id': '<deck-uuid>',
'format': 'mtga'
})
print(r.content[0].text)
asyncio.run(run())
"Output:
// My Deck
// Format: commander
// Cards: 100 main + 1 side
// Mainboard
1 Krenko, Mob Boss (JMP) 338
20 Mountain (SLD) 432
4 Lightning Bolt (M10) 123
...
Sideboard
2 Pyroblast (EMA) 141Import from MTGA text
Paste a deck list into an existing deck:
python -c "... call import_deck_from_text with:
deck_id: '<deck-uuid>'
text: |
4 Lightning Bolt (M10) 123
20 Mountain
Sideboard
2 Disenchant
"Options
python server.py --transport sse --port 8000 # HTTP mode
python server.py --decks-dir ~/Dropbox/my-decks # Custom deck locationDefault transport is stdio. Default deck directory is ~/.config/scryfall-mcp/decks/.
Default card cache is ~/.config/scryfall-mcp/cache/.
License
MIT. Scryfall data belongs to Scryfall LLC. Magic: The Gathering belongs to Wizards of the Coast.