Skip to content

Linell/mtg-analyzer

Repository files navigation

mtg-analyzer

Paste a Moxfield decklist, get card images and prices, an EDHREC "salt" score, a WotC bracket classification, a ramp/draw/removal/wipes composition report, and a short Claude-written review — all streamed into the browser as each piece of work finishes.

It's a demo app for Inngest: one function, several parallel fan-outs, a classification step, streamed over Inngest Realtime.

What to look at

Most of the interesting code is in src/inngest/functions.ts.

  • Scryfall enrichment runs as concurrent step.run calls in 8-card batches, so each batch retries and caches independently.
  • Salt score lookups fan out in parallel with the Scryfall work.
  • Four bracket signal checks (Game Changers, tutors, mass land denial, combos) run as four more parallel step.run legs, each publishing to the realtime channel as it lands. The classifier step consumes all four once they resolve.
  • A composition step fetches four Scryfall oracle tags (ramp / draw / removal / board-wipe) and counts each category against conventional Commander deckbuilding targets.
  • Each card shows up in the UI the moment its batch resolves; each bracket signal appears in the panel as its step returns. After everything resolves, a final ai-review step hands the enriched deck to Claude for a paragraph-long review.
  • Every external call is best-effort: Commander Spellbook or the Scryfall tagger failing downgrades the relevant panel to "unknown" without failing the run.
  • Event IDs are ${pageId}:${runId} (see src/routes/api/deck/analyze.ts), so client retries collapse to a single run.

Stack

Running locally

You'll need Node 20+, pnpm, an Anthropic API key, and the Inngest Dev Server.

cp .env.example .env          # fill in ANTHROPIC_API_KEY
pnpm install
npx inngest-cli@latest dev    # one terminal — http://localhost:8288
pnpm run dev                  # another — http://localhost:3000

Open http://localhost:3000, paste a decklist in Moxfield's "Export → Text" format (4 Lightning Bolt (LEA) 161, one per line), and watch the Inngest dashboard at http://localhost:8288 as cards stream in.

Project layout

src/
  inngest/
    client.ts         Inngest SDK client
    functions.ts      analyzeDeck function + realtime channel/topics
    schemas.ts        Zod event payload schemas
  routes/
    index.tsx         single-page UI
    api/
      inngest.ts      Inngest HTTP handler
      deck/analyze.ts POST endpoint that sends the analyze event
      realtime/token.ts  mints realtime subscription tokens
  moxfield/           decklist parser
  scryfall/           Scryfall types, stats helpers, oracle-tag lookups
  edhrec/             salt score fetcher
  brackets/           WotC bracket signal checks + classifier
  composition/        ramp/draw/removal/wipe counts vs. deckbuilding targets

Scripts

pnpm run dev        # vite dev server
pnpm run build      # production build
pnpm run test       # vitest
pnpm run typecheck  # tsc --noEmit
pnpm run check      # biome lint + format
pnpm run deploy     # build + wrangler deploy

Scope

This is a demo, not production code. Two shortcuts worth knowing about: the realtime token endpoint mints tokens for any pageId with no session check, and the publish loop is staggered so the streaming is actually visible in a demo. Both are called out in comments — see src/routes/api/realtime/token.ts and src/inngest/functions.ts.

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors