sleeper-mcp
Sends phone notifications via ntfy.sh when a player's injury status changes during games.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sleeper-mcplist my leagues and standings"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
sleeper-mcp
Connects Claude to a Sleeper fantasy football account two ways:
MCP tools — ask Claude directly ("who should I start this week") and it pulls live Sleeper data via the tools below.
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.
Gameday alerts — a background watcher pushes a phone notification (via ntfy.sh) the moment one of your starters' injury status changes.
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 standingsget_my_roster— your starters/bench/taxi/IR + recordget_all_rosters— every team's roster, for scouting trade targetsget_matchup— your starters vs. your opponent's for a given week (defaults to current)get_waiver_wire— available free agents, ranked, filterable by positionget_trending_players— sitewide add/drop trends (not league-specific)get_transactions— recent waiver/trade activity in a leagueget_player_intelligence— cached, multi-source player news, stats, outlook, confidence, source conflicts, freshness, and direct source links
Setup — local (stdio, this Mac only)
npm installRegister 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.jsJust 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 todata/defense-matchups.jsonfor ~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, anas_oftimestamp, 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.mjsruns the same locked-down headless-Claude- Code pattern as the daily report (onlyget_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 check —
src/nflSchedule.jspulls real kickoff times from ESPN's public scoreboard API (Sleeper has no schedule endpoint of its own). If a starter is markedOutand 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 viadata/gametime-alerts.jsonso 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.jskeeps the existing owner credential and signed sessions indata/app.db; public account creation is disabled./settings.htmlis 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.
This server cannot be installed
Maintenance
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
- FlicenseBqualityCmaintenanceEnables 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.121
- Alicense-qualityCmaintenanceConnect 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.10MIT
- Flicense-qualityDmaintenanceEnables 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
- Alicense-qualityBmaintenanceEnables AI models to manage and query fantasy sports leagues through the Sleeper API, supporting tasks like player lookups, league activity, and draft management.27MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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