Skip to main content
Glama
pixelwix

sleeper-mcp

by pixelwix

sleeper-mcp

Connects Claude to a Sleeper fantasy football account two ways:

  1. MCP tools — ask Claude directly ("who should I start this week") and it pulls live Sleeper data via the tools below.

  2. Daily report dashboard — a site with matchup summary, a full recommended lineup (every starting slot, not just close calls), win probability, waiver targets, and trade suggestions, regenerated every morning (and again Sunday 11am). Also has a live matchup card (your lineup vs. theirs, live score, injury badges — refreshed straight from Sleeper, not the daily report) and a live standings card.

  3. Gameday alerts — a background watcher pushes a phone notification (via ntfy.sh) the moment one of your starters' injury status changes.

  4. Private owner settings — the existing owner profile is the only account that can sign in and open the health/configuration panel.

Sleeper's API is public and read-only, so this only ever reads league data; it can't submit waiver claims, propose trades, or set your lineup for you. Those actions still happen in the Sleeper app — this is for the research and reasoning that inform them.

Configured leagues

Two league slots (keys butt-punt/no-fun — rename in src/config.js if you like) set entirely via env vars: SLEEPER_USERNAME, SLEEPER_USER_ID, SLEEPER_LEAGUE_BUTT_PUNT, SLEEPER_LEAGUE_NO_FUN. See .env.example. This The dashboard is intentionally single-owner and reads only these configured leagues.

Related MCP server: flaim

Tools

  • list_leagues — both leagues with current standings

  • get_my_roster — your starters/bench/taxi/IR + record

  • get_all_rosters — every team's roster, for scouting trade targets

  • get_matchup — your starters vs. your opponent's for a given week (defaults to current)

  • get_waiver_wire — available free agents, ranked, filterable by position

  • get_trending_players — sitewide add/drop trends (not league-specific)

  • get_transactions — recent waiver/trade activity in a league

  • get_player_intelligence — cached, multi-source player news, stats, outlook, confidence, source conflicts, freshness, and direct source links

Setup — local (stdio, this Mac only)

npm install

Register as a user-scoped MCP server (adjust the path to wherever you cloned this):

claude mcp add --scope user sleeper -- node /path/to/sleeper/src/index.js

Just ask Claude things like "who should I start this week in the Butt Punt League" or "any good waiver pickups at RB" — no need to invoke tools by name.

The MCP server is model-neutral. Ready-to-edit client examples live in examples/mcp/ for Claude and Gemini. ChatGPT/OpenAI clients use the hosted Streamable HTTP endpoint; see examples/mcp/chatgpt.md. The hosted endpoint requires a Bearer token. If the ChatGPT custom-connector UI requires OAuth, place an OAuth-capable gateway in front of /mcp rather than removing auth.

Setup — hosted (HTTP, behind Traefik)

src/http.js runs the same tools over the MCP Streamable HTTP transport instead of stdio, so other devices (e.g. Claude Desktop on your phone) can reach it too. docker-compose.yml has a Traefik label setup assuming Docker-label discovery on a proxy network with a myresolver cert resolver — adjust to your own reverse-proxy setup, or drop the labels: block entirely and just publish a port if you don't use Traefik. Set SLEEPER_DOMAIN in .env to your own hostname.

Requires SLEEPER_MCP_TOKEN in .env (the server refuses to start without it) — every request to /mcp must send Authorization: Bearer <token>. .env is gitignored; generate a token with:

node -e "console.log(require('crypto').randomBytes(24).toString('base64url'))"

To deploy/update, sync everything except local state to wherever Docker runs and rebuild:

rsync -av --delete --exclude .git --exclude node_modules --exclude data \
  ./ your-docker-host:/path/to/sleeper/
ssh your-docker-host "cd /path/to/sleeper && docker compose up -d --build"

To add it as a remote MCP server elsewhere:

claude mcp add --transport http sleeper https://your-domain/mcp \
  --header "Authorization: Bearer <token>"

Daily report

automation/generate-report.mjs runs Claude Code headless (claude -p) once a day with a tightly scoped tool surface — only the read-only sleeper MCP tools plus WebSearch (for real injury/matchup context), no Bash/Write/ Edit — and --json-schema to force valid structured output matching automation/report-schema.json. This runs under the Claude Pro plan, not the pay-per-token API, so there's no separate billing (a report for both leagues costs roughly $1–1.50 in notional usage against Pro's limits, not an actual charge).

On the Docker host, automation/run-daily-onhost.sh prefers the subscription-backed Antigravity CLI when it is installed and authenticated. It runs from an isolated workspace, uses only the read-only Sleeper MCP server plus web research, and returns JSON constrained by automation/report-schema.json. If Antigravity fails or returns an incomplete report, the runner tries the Gemini Interactions API when GEMINI_API_KEY is set, then Claude. The existing report is preserved if every provider fails. AGY_MODEL and GEMINI_MODEL both default to gemini-3.6-flash.

Scheduled on the docker host via cron (automation/setup-host-cron.sh): daily at 8:00 AM local time, plus a second Sunday 11:00 AM run to catch late-week inactive/injury news before the early games lock. Pregame kickoff refreshes and the injury watcher run on the same host every 10 minutes. Logs land in automation/logs/ on the host.

The Mac-side run-daily.sh + deploy-report.sh rsync path is legacy — only useful if you intentionally generate reports locally and push them up. Normal operation writes straight into the container's bind-mounted data/ on the host, so a new report does not need a redeploy or rsync. To run it by hand on the host:

ssh docker-host "cd /mnt/docker/sleeper && ./automation/run-daily-onhost.sh"

To install or refresh host cron after pulling changes:

ssh docker-host "cd /mnt/docker/sleeper && ./automation/setup-host-cron.sh"

Cross-checked matchup data

Sleeper has no projections, no matchup difficulty, and no Vegas lines — the daily report, injury advisories, and player popups all lean on outside sources to fill that in, combining two kinds:

  • Real computed numbers, fetched and handed to the model as ground truth rather than left to search results:

    • src/defenseMatchups.js — defense-vs-position matchup difficulty (PPR points allowed per game, trailing 6 weeks) computed from nflverse's free, public, play-by-play-derived weekly player stats. Cached to data/defense-matchups.json for ~20h (the source only meaningfully updates weekly).

    • src/vegasLines.js — spread + over/under from ESPN's public odds API, converted to implied team point totals (scoring environment / game script), per game for the upcoming week.

  • Web research, explicitly cross-checked across outlets — the daily report prompt (automation/prompt.md), injury advisor (automation/injury-advisor-prompt.md), and player-info batches (automation/player-info-batch-prompt.md) all instruct Claude to check more than one source (ESPN, FantasyPros, Rotoworld/RotoWire, Yahoo, NFL.com, beat reporters) for projections/rankings/injury news, and to flag it when sources disagree rather than silently picking one. Player-info cards preserve 2-5 direct source URLs, an as_of timestamp, and an explicit confidence rating so you can inspect the evidence yourself.

Both data sources are free and unauthenticated — no API keys, no scraping of subscription content. Yahoo's fantasy data isn't pulled directly since their public API is OAuth-per-user and scoped to league data, not league-agnostic projections/consensus; it's covered the same way ESPN/ FantasyPros/Rotoworld are, via web research. The automation never bypasses paywalls or copies subscription-only content.

Live data (no LLM, no daily-report lag)

/api/matchup?league=<key> and /api/standings?league=<key> hit Sleeper directly on every request via getMatchupView()/getStandingsView() in src/sleeperApi.js — same functions the MCP tools use. The dashboard's Live Matchup and Standings cards poll these every 90s while the tab is visible. Unauthenticated, same trust level as /api/report and the dashboard itself — only /mcp (tool execution) requires the bearer token.

Installable PWA and push notifications

The dashboard is an installable Progressive Web App with a manifest, offline app shell, install icons, and a service worker. Use the Install control in supported desktop/Android browsers. On iPhone/iPad, open the site in Safari, choose Share → Add to Home Screen, then open the installed app.

Tap Enable alerts from the dashboard to create a Web Push subscription. Installed devices receive the same injury/status and urgent lineup-lock alerts as ntfy, plus a notification when a kickoff-aware pregame report finishes. iOS Web Push requires the Home Screen-installed app. Subscriptions are stored in data/push-subscriptions.json with restricted file permissions; VAPID keys stay in the host .env and are never sent to the browser except for the public application key.

The dashboard header uses a bell icon for device notification status and a gear icon for the authenticated system control panel. The control panel keeps the dashboard's existing visual language and provides three views:

  • Configuration — an allowlisted set of Sleeper, model, alert, and domain settings. Secret fields are write-only and never returned by the API.

  • System Health — live Sleeper latency, MCP uptime, report age, watcher and pregame-scheduler state, provider availability, and push-device count.

  • Notifications — enable or disable Web Push on the current device.

Only SETTINGS_ADMIN_USER_ID may access these APIs. Saves are validated, backed up under data/env-backups/, written to the host .env, and applied by a locked host job that recreates the service within one minute.

Gameday alerts

automation/watch-starters.mjs polls your current starters' injury_status in both leagues and diffs against data/starter-status.json. On a real change (to/from Questionable/Doubtful/Out/IR/PUP/Suspended), it pushes a notification via ntfy.sh to the topic in .env's NTFY_TOPIC — subscribe to that topic in the ntfy app (iOS/Android) or at https://ntfy.sh/<topic> to receive them. Treat the topic name like a shared secret — ntfy.sh topics are unauthenticated by default, so anyone who knows it can read or publish to it.

Two additional checks run alongside the basic status diff:

  • Waiver/bench advisory — for the more serious statuses (Doubtful/Out/ IR/Suspended, not the very common/often-inconsequential Questionable), automation/injuryAdvisor.mjs runs the same locked-down headless-Claude- Code pattern as the daily report (only get_waiver_wire/get_my_roster + WebSearch, no Bash/Write/Edit) to confirm the news, check the waiver wire for a same-position replacement, and check the bench for a better play — folded into the same notification.

  • Gametime lock checksrc/nflSchedule.js pulls real kickoff times from ESPN's public scoreboard API (Sleeper has no schedule endpoint of its own). If a starter is marked Out and their game kicks off within 4 hours, it sends an urgent separate "bench them now" alert with the same waiver/bench advisory attached. Deduplicated per player per game via data/gametime-alerts.json so it fires once, not every 10 minutes.

General lineup optimization (is a healthy bench player just a better play this week) is handled by the daily report plus kickoff-aware pregame refreshes, not this watcher. automation/pregame-refresh.mjs reads actual regular-season kickoff times and triggers a full report/player-card refresh when one of your active roster players is 55-95 minutes from kickoff. It does not assume a weekday, so Thursday night, Monday night, Saturday, international, holiday, and rescheduled games are covered. Completed kickoff windows are deduplicated and a host lock prevents overlapping report jobs.

Scheduled on the docker host via the same cron block as the daily report (automation/setup-host-cron.sh), every 10 minutes, year-round — Sleeper's API is free and this is a cheap read, so there's no real cost to running it in the off-season too. The first run after a reset just seeds a baseline without alerting (avoids a flood of "changes" for every player's pre-existing status). Run by hand on the host:

ssh docker-host "cd /mnt/docker/sleeper && ./automation/with-host-env.sh node --env-file=.env automation/watch-starters.mjs"

Player detail popup

Clicking any player name on the dashboard (lineup, waiver wire, trades, live matchup) opens a popup with a news/stats/outlook summary. This is a pure cache lookup at request time — GET /api/player-info?name=<name> in src/http.js reads data/player-info-cache.json and returns a 404 if the player isn't in it. No LLM call happens in the container, since the container has no Claude Code CLI or credentials.

The cache itself is built on the docker host alongside the daily report: automation/generate-player-info.mjs collects your complete rosters, both weekly opponents' starters and benches, plus the current report's waiver targets. It batches them (6 at a time) through Gemini/Antigravity with Claude as fallback and web research enabled, and writes the results keyed by a normalized player name. Entries older than 7 days that no longer correspond to a rostered/targeted player are dropped on each run. automation/run-daily-onhost.sh runs it right after the report generator; a failed batch is non-fatal and just leaves that player's prior cache entry in place.

Only covers players the daily pipeline actually cares about (your rosters, current opponents, and that day's waiver targets) — not the whole league, since generating profiles for every free agent isn't worth the cost.

Private owner access

  • src/db.js keeps the existing owner credential and signed sessions in data/app.db; public account creation is disabled.

  • /settings.html is owner sign-in/profile only.

  • The gear on the main dashboard opens configuration and system health only when the signed-in user matches SETTINGS_ADMIN_USER_ID.

  • Sleeper identity and league IDs come from .env; there is no per-user onboarding, league storage, or report generation path.

Known limitation

Sleeper's public player list is occasionally stale for deep veterans (a handful of long-retired players are still marked as active on a team). The waiver wire tool filters on Sleeper's own fantasy relevance ranking to push most of that noise out, but it isn't a second, independently-verified data source, so treat any surprising deep-bench name with suspicion.

Player data cache

data/players_cache.json caches Sleeper's full player list (~2000 players) for 24 hours, per Sleeper's API guidance not to poll that endpoint more often than that. Gitignored — regenerates automatically on first use each day.

A
license - permissive license
-
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

  • F
    license
    B
    quality
    C
    maintenance
    Enables comprehensive Sleeper Fantasy Football integration with Claude, providing real-time player projections, historical performance analytics, league management, and waiver wire analysis. Supports advanced NFL metrics, lineup optimization, and matchup analysis for fantasy football decision-making.
    12
    1
  • A
    license
    -
    quality
    C
    maintenance
    Connect ESPN & Yahoo fantasy leagues to AI assistants via MCP. Read-only tools for rosters, standings, matchups, free agents, and league info across football and baseball.
    10
    MIT
  • F
    license
    -
    quality
    D
    maintenance
    Enables Claude to interact with Yahoo Fantasy Baseball and Basketball leagues, allowing roster analysis, matchup tracking, free agent browsing, and player stats retrieval via natural language.
    1
  • A
    license
    -
    quality
    B
    maintenance
    Enables AI models to manage and query fantasy sports leagues through the Sleeper API, supporting tasks like player lookups, league activity, and draft management.
    27
    MIT

View all related MCP servers

Related MCP Connectors

  • Read-only fantasy analysis for ESPN, Yahoo, and Sleeper leagues via MCP

  • WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.

  • Uptime, SSL, DNS and domain monitoring you can talk to from Claude or any MCP client.

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/pixelwix/sleeper-mcp'

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