Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/invvd/mtg-cheaper-deck/llms.txt

Use this file to discover all available pages before exploring further.

The web app is the most visual way to work with MTG Cheaper Deck. It loads your entire Moxfield deck at once and presents every card with its Scryfall image, up to five cheaper alternatives lined up side-by-side, and a live running total in a fixed bottom bar. Choose it when you want a point-and-click workflow — no typing required after the initial URL — or when you want to see what a replacement card actually looks like before committing to it.

Starting the web app

Run the following command from the project root. Flask starts on http://127.0.0.1:5000 and your default browser opens automatically after one second.
python webapp.py
Navigate to http://127.0.0.1:5000 if the browser does not open on its own.

Workflow

1

Enter your Moxfield deck URL

On the landing page, paste a public Moxfield deck URL (e.g. https://moxfield.com/decks/YOUR-DECK-ID) into the input field and click Cargar mazo. The server fetches the deck from Moxfield, matches each card against the local database, and computes suggestions for every card that has a known price.
2

Browse your deck grouped by card type

The /deck page shows every card in the deck with its Scryfall card image, price, and up to five suggestion buttons to the right. A sidebar on the left lets you filter by card type (Creature, Instant, Sorcery, etc.) so you can focus on one section at a time. The commander is displayed separately at the top with a gold border — no replacements are suggested for it.
3

Click a suggestion to replace a card

Each suggestion is rendered as a clickable card image button showing the candidate’s name, price, percentage savings, and similarity score. Clicking one fires an AJAX request to POST /replace — the page does not reload. The selected button gains a green border, the plain-text list in the top-right panel updates instantly, and the bottom bar recalculates the totals.
4

Revert to the original card

The original card is also rendered as a button (with a dashed blue border). Clicking Original at any time sends choice=original to /replace and restores that slot to its starting card. The plain-text list and totals update immediately.
5

Copy the plain-text deck list

The textarea in the top-right panel (and the Copiar button in the bottom bar) always reflects the current state of the deck — originals where no replacement was chosen, and the chosen replacement where one was accepted. Click Copiar lista or Copiar to write the list to the clipboard, ready to paste into MTGO, Moxfield, or any other tool.

Sort options

The Ordenar por dropdown in the sidebar controls the order in which cards appear on the /deck page. The order is fixed at page load based on each card’s best suggestion (the top-ranked one), so it does not change as you accept replacements.
KeyLabelDescription
pricePrecio original (mayor a menor)Most expensive original cards first — the default.
savingsMayor ahorro ($)Cards where the best suggestion saves the most absolute dollars first.
savings_pctMayor ahorro (%)Cards where the best suggestion saves the highest percentage first.
similarityMayor similitud (puntaje)Cards whose best suggestion has the highest similarity score first.

Live price total

The fixed bottom bar shows three figures that update automatically every time a replacement is accepted or reverted — no page reload needed:
  • Original — the sum of all original card prices (quantity × unit price for each card with a known price).
  • Ahorrado — the difference between the original total and the current total.
  • Total — the current deck price with all chosen replacements applied.

Plain-text export

The copyable deck list uses the standard Commander format produced by plain_text.build_plain_text(). The layout is:
Commander
1 Atraxa, Praetors' Voice

Deck
1 Cultivate
1 Swords to Plowshares
...
The Commander section header comes first, followed by one quantity name line per commander. A blank line separates it from the Deck section header, which is followed by all remaining cards in the same quantity name format. Cards without a known price or a matched local entry are included in their original positions and are never replaced.

State management

All deck state is held in memory on the local Flask server in a single STATE dictionary. Refreshing the page or navigating away does not reset your choices — state persists as long as the Python process is running. However, clicking Resetear in the bottom bar clears all chosen replacements and returns every card to its original. Stopping and restarting webapp.py also clears all state. The app is designed for single-user local use only and should not be exposed to the internet or shared across multiple browser sessions.

Routes

MethodRouteDescription
GET/Landing page with the deck URL input field. If a deck is already loaded, redirects to /deck.
POST/loadAccepts the link form field, fetches and processes the deck, then redirects to /deck. Returns to / with an error query parameter on failure.
GET/deckMain deck view. Accepts an optional ?sort= query parameter (price, savings, savings_pct, or similarity). Redirects to / if no deck is loaded.
POST/replaceJSON API endpoint. Accepts idx (card index) and choice ("original" or a zero-based integer index into the suggestions list). Returns updated plain_text, row_savings, totals, idx, and chosen.
POST/resetClears all chosen values for every card entry and redirects back to /deck, preserving the current sort order via the sort form field.

Build docs developers (and LLMs) love