open-leagues

Quickstart

Six steps from an empty box to an agent answering a question about your league. Neither side needs integration code.

Six steps

  1. 1

    Run a box

    Docker gives a durable box with the clock running. Locally, bun run dev binds 0.0.0.0:8080 and migrates its own PGLite on first access.

    shell
    git clone https://github.com/ryanwaits/open-leagues.git
    cd open-leagues
    docker compose up -d
    
    # or, locally
    bun install
    bun run dev
  2. 2

    Make your account

    A fresh box has no users or leagues. Open http://localhost:8080/login, choose Need an account?, and sign up. There is no admin tier.

    Nothing is seeded. For the maintainer's fixture league, start the box with OPENLEAGUES_DEV_SEED=1.

  3. 3

    Start or migrate a league

    Go to /new. Start from scratch, or import from Sleeper, ESPN, or a pasted recap. Whoever commits an import becomes its commissioner.

    An agent can do this too: previewImport, then importLeague with confirm: true. See Migrate a league.

  4. 4

    Mint an agent token

    On your league box, open /account (any member). Under Agent tokens, name one and create it. The raw ol_… value is shown once.

    The CLI mints the same credential with no browser: bun scripts/ledger.mjs mintToken --write --user …

    If you lose it, revoke and mint a new one.
  5. 5

    Point a client at it

    Every client below speaks the same endpoint. None is a plugin we wrote.

    leagues.waits.dev · no account, no token · public read verbs
    claude mcp add --transport http open-leagues https://leagues.waits.dev/api/mcp
    codex  mcp add open-leagues --url https://leagues.waits.dev/api/mcp
    
    # receipts, week boards, the season ledger, lines, cohorts, grading, staking
    # rate-limited per IP · nothing here needs a person
  6. 6

    Ask it something

    The agent introspects the catalog and picks its own verbs.

    shell
    codex exec "Use the open-leagues MCP tools to get my league context —
      team name, record, and this week's matchup opponent if one exists."

Verify the connection

Confirm the transport first. The row should read enabled with Bearer token.

codex mcp list
Name          Url                                 Bearer Token Env Var  Status   Auth
open-leagues  https://leagues.waits.dev/api/mcp   OPENLEAGUES_TOKEN     enabled  Bearer token
Your token must belong to someone with a seat in the league. Every call on an lg_ league runs assertLeagueViewer: commissioner or seat holder, or the call returns Unauthorized. A raw Sleeper league id is public data and needs no seat.