Skip to main content
Glama

mtg-export

A CLI that turns a Magic: The Gathering deck into a printable PDF proxy sheet — a 3×3 grid of card images with the border trimmed (2.5% of the width off the sides, 2% off top/bottom) printed at ~95% of real card size (≈2.375″×3.40″) on US-Letter pages, with faint cut guides. Point it at an Archidekt deck, a text card list, or your clipboard.

Card images come from Scryfall, respecting their usage policy (descriptive User-Agent, request throttling, and on-disk image caching so files are never re-downloaded).

With --modernize, old-frame cards are redrawn in modern M15 frames by mtg-crucible, so a 1996 card prints as legibly as a current one.

Example proxy sheet

A page from a generated proxy sheet — 3×3 cards at true size with cut guides. Printings here span 1993 black and white borders, 1997 and 2003 frames, and M15.

The same page with --modernize

The same nine cards with --modernize. The seven old-frame cards are redrawn — note that they also pick up current oracle wording, so "Interrupt" becomes "Instant" and Swords to Plowshares exiles rather than removes from the game. History of Benalia and Atraxa are already M15, so they are left exactly as printed.

Install

npm install          # pdf-lib + @modelcontextprotocol/sdk + mtg-crucible

Requires Node 18+ (developed on Node 24). No Python. mtg-crucible pulls in a native canvas (@napi-rs/canvas) with prebuilt binaries; it is only loaded when you pass --modernize, so the default path stays pure JS.

Optionally link it as a global command:

npm link             # then run `mtg-export ...` anywhere

Related MCP server: Mystic Forge

Usage

# Archidekt deck by id or URL (public/unlisted work with no login)
node index.js 2087352
node index.js https://archidekt.com/decks/2087352/the-public-library

# From a text export file
node index.js --file mydeck.txt

# From the clipboard (macOS pbpaste) — e.g. after "Copy" on Archidekt/Moxfield
node index.js --clipboard

# Redraw old-frame cards in a modern frame (old cards are hard to read)
node index.js 2087352 --modernize

Options

Flag

Description

-o, --output <file>

Output PDF path (default: derived from the deck/file name)

--size <size>

Scryfall image size: small | normal | large | png (default normal)

--modernize

Redraw pre-M15 cards in a modern frame from their art crop (see below)

--modernize-all

Modernize every card, no exceptions

--include-basics

Include basic lands (they are excluded by default)

--single

One copy of each card, ignoring deck quantities

--cache-dir <dir>

Where to cache images/metadata (default ~/.cache/mtg-export)

-c, --clipboard

Read the card list from the clipboard

-h, --help

Show help

Text list format

One card per line, in the common Archidekt/Moxfield/MTGA export shape. The set code and collector number are honored when present, so you get the exact printing:

1x Sol Ring (mh1) 213
1 Delver of Secrets (isd) 51        # double-faced: both faces are printed
2 Lightning Bolt (2x2) 117 *F*      # *F* (foil) is accepted and ignored for art
3 Forest                            # basic land — excluded unless --include-basics
Counterspell                        # bare name resolves to a default printing

# ... / // comment lines and section labels (Deck, Sideboard, Commander, …) are ignored. If a collector number doesn't match the named card, it falls back to a name lookup rather than printing the wrong card.

Modern frames (--modernize)

Old-border cards are hard to read at proxy size — thin type, low-contrast text boxes, pre-modern mana symbols. --modernize throws those printed card images away and rebuilds the card:

  1. Scryfall's art_crop (the bare illustration, no frame) is downloaded.

  2. The card's oracle data — name, mana cost, type line, rules text, flavor text, P/T, loyalty, rarity, artist, set, collector number — is mapped onto a mtg-crucible CardData, with designer set to mtg-export.

  3. Crucible draws a current-frame card around the art.

You also get current oracle text, because Scryfall's rules text is the up-to-date wording rather than what was printed on the card. "Interrupt" becomes "Instant", "Summon Dragon" becomes "Creature — Dragon", Swords to Plowshares exiles instead of removing from the game, and mana abilities stop mentioning the mana pool. For a proxy you are going to play with, that is often worth as much as the frame.

Your printing is still respected. The art crop, artist, set code and collector number all come from the exact printing your deck specifies, so the illustration you picked is the illustration you get. What changes is the frame around it and the wording inside it.

What is left alone

Modernizing is for cards that are hard to read, not a restyle of the whole collection, so these keep their printed image:

Kept as printed

Why

Already an M15 frame (frame: "2015")

Nothing to gain — and the real printing is more faithful

Full-art printings

The art treatment is the point of the printing

Basic lands

If you chose specific lands, you chose them for a reason

Planeswalkers

The art crop is a 626×457 landscape; a planeswalker's art box is far taller, so the crop comes out badly zoomed

Split cards

Scryfall has one art crop covering both halves, so both halves would share a mangled crop

Every run reports what it did and why:

  modernized 27 of 117 cards
    kept printed — already an M15 frame: 90

Pass --modernize-all to override all of it and push every card through crucible — useful when you want one visually uniform sheet.

The two images at the top of this README are the same nine-card deck run with and without the flag: archidekt.com/decks/24672003.

Details

Templates are picked up from the Scryfall data, so sagas, classes, levelers, adventures, transform and MDFC cards all keep their proper layout (double-faced cards still print as two slots). Snow, devoid, nyx and colorless full-bleed frames carry over too.

--size selects render quality instead of a Scryfall image size — small→low, normal→medium (default), large/png→high. A modernized sheet is trimmed only on the sides (so cards print at a full 3.5″ tall), because crucible's footer runs to the bottom edge of the card and the usual top/bottom trim would slice through it.

Rendering is much slower than downloading, so renders are cached under <cache-dir>/modern/, keyed by Scryfall id, quality, format and crucible version. A re-run of the same deck is near-instant.

Caveats:

  • Renders are crucible's interpretation of the card, not a facsimile of the printed one — set symbols, holo stamps and art-frame quirks won't match.

  • A deliberately retro-frame reprint looks like any other old card to Scryfall, so it gets modernized. There is no field that distinguishes "this card is old" from "this printing is retro on purpose".

  • The art crop is 626×457, which matches a standard card's art box almost exactly — but at --size large/png it is upscaled ~3×, so art is softer than the frame around it.

  • If a card fails to render, the printed Scryfall image is used for it instead and a note is logged; the sheet is never left with a gap.

File size (for GitHub)

normal and large are JPEG, which keeps a full ~100-card EDH deck small enough to commit to a repo:

--size

Format

≈ per card

≈ 100-card PDF

normal (default)

JPEG 488×680

~90 KB

~9 MB

large

JPEG 672×936

~180 KB

~18 MB

png

PNG 745×1040

~1 MB

~100 MB (too big — local printing only)

Use normal for anything you'll upload; use large for the nicest home prints.

--modernize renders are somewhat bigger — at the default (normal → medium quality, 745×1040 JPEG) a modernized card is ~130 KB, against ~90 KB for a printed one. How much that costs depends on how much of the deck is old. large and png render at 2010×2814 and are local-printing only.

Private Archidekt decks

Public and unlisted decks need no login. For a private deck, provide your Archidekt credentials via environment variables or a .env file (copy .env.example):

ARCHIDEKT_USERNAME=your-username
ARCHIDEKT_PASSWORD=your-password

The tool tries anonymously first and only logs in (JWT) if the deck isn't publicly accessible.

MCP server

The same functionality is exposed as an MCP tool so an agent (Claude Desktop, Claude Code, etc.) can generate proxy sheets.

Run it over stdio:

node mcp.js        # or: npm run mcp   (also installed as the `mtg-export-mcp` bin)

Register it with an MCP client, e.g. Claude Desktop claude_desktop_config.json:

{
  "mcpServers": {
    "mtg-export": {
      "command": "node",
      "args": ["/absolute/path/to/mtg-export/mcp.js"],
      "env": {
        "ARCHIDEKT_USERNAME": "your-username",
        "ARCHIDEKT_PASSWORD": "your-password"
      }
    }
  }
}

(env is only needed for private decks.)

It provides one tool, create_proxy_pdf:

Argument

Type

Notes

deck

string

Archidekt deck id or URL. Provide this or cards.

cards

string

Text card list (one per line). Provide this or deck.

output

string

Absolute path for the PDF (recommended).

size

enum

small | normal | large | png (default normal). With modernize, selects render quality.

modernize

boolean

Redraw pre-M15 cards in modern frames (default false).

modernize_all

boolean

Modernize every card, no exceptions (default false).

include_basics

boolean

Include basic lands (default false).

single

boolean

One copy of each card (default false).

It writes the PDF to disk and returns the path plus a summary (cards resolved, basics excluded, pages, size, any unresolved names).

Test with the MCP Inspector

Copy .env.example to .env and fill in your credentials (only needed for private decks):

cp .env.example .env

Run the inspector against the server:

npm run inspect
# equivalently:
npx @modelcontextprotocol/inspector node mcp.js

This opens a local web UI where you can list the tool and call create_proxy_pdf interactively.

How it works

  1. Input → a list of {name, quantity, printing} entries (Archidekt deck, text file, or clipboard).

  2. Resolve → Scryfall. Archidekt entries carry the exact printing's Scryfall id, so images are batch-resolved directly; text entries resolve by set+collector / name+set / name.

  3. Cache → every downloaded image is stored under the cache dir and reused.

  4. Modernize (optional) → with --modernize, cards that would benefit have their art crop plus oracle data run through mtg-crucible to produce a fresh modern-frame card image, itself cached.

  5. Renderpdf-lib lays out a 3×3 grid at ~95% of card size, trimming the border (2.5% of the width off the sides, 2% off top/bottom), with cut guides; double-faced cards contribute a front and a back slot.

Notes

  • Basic lands are excluded by default

  • Deck quantities are printed by default; use --single for one of each.

  • Foil is cosmetic for proxies — the printing is respected but the same art is used.

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    D
    maintenance
    Provides AI assistants with access to Magic: The Gathering card data via Scryfall API, enabling card search, image downloads, and database management.
    25
    2
    Apache 2.0
  • A
    license
    -
    quality
    B
    maintenance
    Unified MCP server for Magic: The Gathering, combining Scryfall card search and pricing, EDHRec commander recommendations, Archidekt deck reading, and decklist validation into a single service.
    MIT
  • F
    license
    -
    quality
    B
    maintenance
    Provides access to Magic: The Gathering card data via Scryfall API, including search, rulings, sets, and local deck management with multi-owner support.
  • F
    license
    -
    quality
    A
    maintenance
    Provides Magic: The Gathering card, deck, provider, and statistical evidence tools for LLMs to make informed deckbuilding decisions.

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/domainellipticlanguage/mtg-export'

If you have feedback or need assistance with the MCP directory API, please join our Discord server