sleeper-fantasy-mcp
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-fantasy-mcpwho should I draft with pick 8 in my main league"
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-fantasy-mcp
An MCP server that turns Sleeper league data into league-accurate fantasy football advice. Every projection is scored through your league's actual scoring settings, and value is expressed as VOR against replacement given your roster shape — so a superflex league and a 1QB league get genuinely different answers, not the same ranking with a different label.
Read-only. Uses public, unauthenticated APIs (Sleeper, ESPN) plus an optional free OpenWeather key.
It answers the questions you actually ask mid-draft or mid-week: who to take, whether a trade is good, who to pick up, who to start.
What makes it league-accurate
Most fantasy tools rank players in generic PPR. This one doesn't.
Sleeper exposes each league's scoring_settings using the same stat keys that
appear in projected stat lines. So every projection is re-scored as a dot product
against your league's actual rules, then converted to VOR (value over
replacement) using your league's actual roster shape.
Replacement level is computed from your league — team count, starting slots,
and how flex spots distribute across positions — so the scarcity premium at each
position is whatever your rules actually produce. Nothing about league size or
roster shape is assumed or hardcoded; every value is derived from what Sleeper
returns for the league IDs in your config.json. Two leagues with different
settings get different answers from the same player pool, and the same league
gets different answers if you change its settings.
Related MCP server: rag-nfl-analyst
Setup
Requires Python 3.10+.
git clone https://github.com/<your-username>/sleeper-fantasy-mcp.git
cd sleeper-fantasy-mcp
pip install -r requirements.txt
cp config.example.json config.jsonThen edit config.json with your Sleeper details:
{
"username": "your_sleeper_username",
"default_league_id": "000000000000000000",
"leagues": [
{ "name": "main", "league_id": "000000000000000000" },
{ "name": "second", "league_id": "111111111111111111" }
]
}Finding your league ID: open your league on sleeper.app in a browser. The URL
looks like https://sleeper.app/leagues/1234567890123456789/team — the long
number is the league ID. You can list as many leagues as you like; every tool
takes a league_id argument and falls back to default_league_id.
No Sleeper API key is needed — the endpoints used are public and unauthenticated.
Optional — weather. The game_weather tool needs a free
OpenWeather key. Either export it:
export OPENWEATHER_API_KEY=your_key_hereor cp secrets.example.json secrets.json and put it there. Both files are
gitignored. A newly created OpenWeather key can take up to a couple of hours to
activate; until it does the tool reports a clear 401 rather than failing oddly.
Run the server:
python server.pyThen point your MCP client at it. To check everything works against your own leagues:
python validate.pyTools
League
list_leagues— configured leagues + current NFL weekleague_info— roster shape, scoring, waivers, playoffsstandings— record, PF/PA, FAAB remainingmy_roster/roster— any team, scored for this league
Draft
who_should_i_draft— the main one. Blends VOR, your positional needs, and ADP value, and warns on tier cliffs. Call it every time you're on the clock.position_tiers— where the real value drop-offs fall at a positionkeeper_analysis— which players are worth the pick they costdraft_plan— who will realistically be there at each of YOUR picksdraft_board— best available by VOR, with ADP alongsidedraft_results— picks so far, with value-vs-ADP on each
In-season
waiver_targets— best free agents + suggested FAAB bidevaluate_trade— pass names, get a verdict and roster-fit analysisset_lineup— optimal legal starting lineup, with context flags and close callsmatchup_preview— both lineups, projected marginplayer— projection, VOR, rank, owner, tier, prior-season usage, schedule, and this week's Vegas game environmentvegas_lines— spreads, totals, implied team totals, game-script readsconsistency_report— floor/ceiling/boom/bust, sortable for your formatregression_candidates— who outran their opportunity (fade) or fell short of it (buy)handcuff_report— which of your RBs need their backup rosteredstreaming_options— best streaming plays at DEF, K, QB or TEroster_risk— QB/receiver stacks and single-team over-exposureir_stash_targets— injured players worth an IR slotwaiver_strategy— FAAB or priority guidance, whichever your league usessimulate_season— Monte Carlo floor/median/ceiling, one player or severaldurability_report— availability history vs positional base ratesgame_weather— kickoff forecast + fantasy impact (needs an OpenWeather key)news_signals/submit_news_signals— structured signals read out of news prosetrending_players— league-wide adds/drops across all of Sleepersettings_check— live scoring/roster settings for every league, plus any driftrefresh_data— clear cache (use mid-draft or after a waiver run)
How the advice is built
VOR — projected points minus the last startable player at that position. Flex slots are distributed across RB/WR/TE so a 2-flex league correctly pushes replacement level deeper than a 0-flex one.
Need weighting — a position you have nothing at gets a 1.15x bump; a position you're already deep at gets 0.88x. Enough to break ties, not enough to make you reach two rounds early.
ADP delta — flags players falling past ADP (bargain) or reaches.
FAAB bids — anchored on VOR as a percentage of remaining budget, then adjusted for season timing (an early hit plays fifteen more games than a late one, and unspent budget is wasted) and for leverage against rivals' remaining budgets. Returned as a range, not a false-precision single number.
Handcuffs — RB only, because RB value is volume-driven and volume transfers to the next man up. Priority keys off the starter's carry share: a workhorse leaves a big transferable role, a committee back leaves little.
Lineup context — the optimiser picks on projected points alone, deliberately: silently reordering a lineup because of a weather reading would make the output unverifiable. Instead the models attach as flags (injury, weather severity, implied team total, boom/bust profile, and news signals — the last marked unverified, since they were read from prose rather than measured), and are paired with close calls — the slots where a bench player is within 2.5 projected points. A flag on someone 20 points clear of his backup is noise; a flag on a half-point start/sit is the entire decision.
Streaming — the signal inverts by position. A defense wants its opponent implied low; an offensive player wants his own team implied high plus a soft positional matchup. QB and K are filtered to depth-chart starters, or the list fills with backups who have a great matchup and will not play.
xFP (expected fantasy points) — what a league-average player would have scored with the same opportunities. Weights are fitted per position against your league's scoring, constrained non-negative, using only true opportunity (targets, carries, and their red-zone subsets). Sleeper's
rec_0_4-style buckets are excluded on purpose: they count receptions by yards gained, so they are outcomes, not opportunities, and would leak the answer into the model. Opportunity is sticky year to year; efficiency and TD luck are not — so a large gap either way is a regression signal.Monte Carlo — samples games played from a player's availability history and weekly scores from a gamma calibrated to his volatility, then reports p10/median/p90. Gamma because scores are non-negative and right-skewed: there are huge weeks but no symmetric huge-negative counterpart.
Correlation — a QB and his own receiver rise and fall together. That's an asset in best ball and a liability in weekly head-to-head, where it widens your variance without raising your expected score. Always a tiebreaker, never a veto.
Waiver priority — unlike FAAB, priority is all-or-nothing; you can't bid half of it. So timing dominates, and the advice keys off your position in the order and how much season is left.
Tiers — positions are split where the value gap between consecutive players is unusually large for that position. No fixed thresholds: the gap that matters at QB is a different size from the one at TE.
Usage — prior-season snap/target/carry/red-zone share from Sleeper's stats feed, because a projection alone can't tell you whether the role is real.
Strength of schedule — actual PPR points allowed by each defense to each position, joined to the upcoming schedule. Weeks 15–17 are reported separately, since that's when the league is decided.
Implied team totals —
total/2 ± spread/2. The best single read on how big a scoring pie an offense is walking into.Consistency — floor (p10), ceiling (p90) and boom/bust rates from last season's weekly scores. Boom/bust lines are per-position percentiles of the startable pool, not fixed numbers, because 18 points means something different at TE than at RB. Sort by floor for weekly head-to-head, ceiling for best ball.
Availability — games played over the 17-game era, anchored on each player's debut so rookies aren't charged for seasons before they entered the league, and compared against measured positional base rates.
News signals — the one model-backed layer
Everything above is deterministic. news_signals is the exception, and it's fenced:
It emits categorical fields and quotes only — the schema has no numeric field, so a model can't produce something that looks like a projection.
Every signal is checked against the league's real player list; anything that doesn't resolve is discarded, not shown.
Output is labelled unverified and kept separate from measured metrics.
It needs no API key by default. This is an MCP server, so the caller is already
a language model — news_signals hands back the article text plus the schema, the
caller extracts, and submit_news_signals runs the same validation on the result.
Set mode="direct" (with anthropic installed and a key) to have the server call
Claude itself instead, for headless use. The validation boundary is identical either
way, which is the point: the safety comes from what happens after generation, not
from which model generated it.
Validation
python validate.py runs ~113 invariant checks across every model (a few are cross-league comparisons, so the exact count depends on how many leagues you configure) — percentile
ordering, VOR reconciling against replacement, implied totals summing to the game
total, non-negative xFP weights, snake pick arithmetic, and league scoring actually
propagating. These assert correctness, not just that nothing threw.
Settings watchdog
Every value in this tool is downstream of scoring settings and roster shape. Change either and replacement levels move, VOR moves, tiers move — and nothing errors, the advice just quietly stops matching the league.
So every command re-reads every league's settings and compares them against a
stored baseline (.league_state.json, gitignored). Any drift is attached to that
command's output as settings_alert, naming the exact fields that moved.
Three design notes:
The check bypasses the cache — a cached copy of the settings cannot tell you the settings changed.
League fetches run in parallel, so the cost is one round trip (~350ms) rather than one per league.
It is fail-safe: any error verifying settings is swallowed and the command still returns. A watchdog that can break the thing it watches is worse than none.
Caching
Responses cache to .cache/ — 24h for the player dump (~5MB), 6h for projections,
5min for rosters, 30s for live draft picks. Sleeper asks callers to stay under
1000 requests/minute; this stays far below that. Call refresh_data to force-clear.
Bye weeks
Sleeper publishes none — the bye_week field is absent from every player in their
dump. So byes come from ESPN's public scoreboard API instead, which exposes an
explicit teamsOnBye list per week. No auth, one request per week, cached for a
week. ff/schedule.py handles it.
Byes are read live per season, so there is nothing season-specific hardcoded here.
who_should_i_draft warns when a pick would give you 3+ players on the same bye,
and my_roster reports bye_conflicts for any week you'd have multiple players out.
Configuration
Leagues live in config.json. API keys live in secrets.json (gitignored) or
environment variables — env wins:
{ "openweather_api_key": "..." }OPENWEATHER_API_KEY is the env equivalent. Weather is the only feature needing
a key; everything else runs on public, unauthenticated endpoints.
Keepers
Behaviour follows the league's own settings. max_keepers: 0 means keepers are off
and keeper_analysis says so rather than inventing advice; above zero it prices
each candidate. league_info reports configured and in use separately,
because a league can carry a non-zero max_keepers it never actually uses, and
advising on a mechanic nobody plays with is worse than staying quiet.
A keeper is never free — keeping someone forfeits a draft pick, so the question is whether he beats whoever that pick would have returned. That difference is his surplus, and it's what the tool ranks on:
An elite player at an expensive cost can be a bad keeper. Keeping the consensus 1.02 at a first-round price buys nothing you couldn't have had by drafting him.
A useful starter at a cheap cost is often a great one — most of a free roster spot.
Sleeper stores that keepers exist (max_keepers, roster.keepers, is_keeper on
picks) but not what they cost, so the pricing rule is a parameter rather than a
guess: same_round (default), round_earlier, or two_rounds_earlier, against the
round the player was drafted the previous season. Pick value comes from ADP — what
the market actually returns at that slot — floored at zero, since a pick returning a
below-replacement player is worth nothing rather than a negative.
Known limitations
Projections are Sleeper's. They're reasonable but they're one source. The value model is the differentiator here, not the underlying projections.
Read-only. Sleeper's API cannot set lineups or submit waiver claims. This tells you what to do; you still tap the buttons in the app.
The projections/ADP host is undocumented. It's stable in practice but Sleeper makes no promises about it.
No true aDOT. Sleeper publishes completed air yards, not intended air yards on all targets (verified:
rec_air_yd + rec_yar == rec_ydexactly). Sodepth_per_catchandyac_per_catchare reported instead — real aDOT would need a paid source.Availability is not injury. Games played mixes injury with benchings and rest, and the two cannot be separated from this feed. The measured base rates show it plainly: QB has the highest missed-game rate (6.31/season vs RB's 4.92), which is backups being benched, not quarterbacks being hurt. Read the number as availability, and weigh it only for players with a real role.
Consistency is backward-looking. It describes last season's weekly shape, not next season's. A changed role, offense or depth chart invalidates it.
The simulation is a model, not a forecast. It inherits every bias in the underlying Sleeper projection and only adds the shape that projection omits. It does not know about holdouts, scheme changes or camp news.
No kicker matchup data. Points-allowed splits don't cover kickers, so kicker streaming keys purely off the team's scoring environment.
Weather reaches ~5 days out. It's a lineup tool, not a draft tool. Dome and retractable-roof games are filtered out rather than given a meaningless reading.
Weather severity thresholds are priors, not fitted. The wind/snow/rain cutoffs come from conventional wisdom about how conditions affect passing and kicking, not from a regression against outcomes — unlike xFP or the simulation, whose weights are derived from data. The banding is asserted (monotonic in wind, gusts weighted, full 0–3 range) but the thresholds themselves are judgement.
No PFF/Next Gen Stats — no O-line grades, yards per route run, or EPA. Those need paid or non-public sources.
Privacy
This project reads public Sleeper league data and holds no personal information about anyone. There is no account system, no analytics, no telemetry, and nothing is transmitted anywhere except to the APIs listed above.
Your league IDs live in
config.jsonand your API keys insecrets.json. Both are gitignored and never leave your machine.Cached API responses live in
.cache/— also gitignored. Delete the folder, or runrefresh_data, to clear it at any time.The repository itself contains no league data, no rosters, and no sample datasets scraped from a real league.
If you publish output from this tool, remember it may contain your leaguemates' display names as Sleeper returns them.
Contributing
See CONTRIBUTING.md, the Code of Conduct, and SECURITY.md for reporting vulnerabilities.
Disclaimer
Not affiliated with, endorsed by, or connected to Sleeper, the NFL, ESPN, or OpenWeather. It reads their public endpoints; you are responsible for complying with their respective terms of service. Projections come from Sleeper and are one source among many — the value model is the contribution here, not the underlying projections.
Licensed under the MIT License.
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
- Alicense-qualityBmaintenanceMCP server that turns real NFL & fantasy data into a decisive edge, offering 70+ tools for draft assistance, start/sit recommendations, trade analysis, playoff odds, and more, with live league integration.MIT
- Flicense-qualityCmaintenanceMCP server for NFL fantasy football retrieval, providing access to NFL stats and Sleeper league data through retrieval-oriented tools.
- Alicense-qualityCmaintenanceA read-only MCP server that supplies live context from Sleeper fantasy-football leagues, including rosters, trade analysis, draft picks, and league settings via Sleeper's public API.MIT
- Alicense-qualityBmaintenanceMCP server that provides fantasy football draft tools including ranked boards, best available, player comparisons, sleeper/bust flags, and ADP market gaps using a calibrated projection model.MIT
Related MCP Connectors
An MCP server that integrates with Discord to provide AI-powered features.
MCP server for Flux AI image generation
MCP server for generating rough-draft project plans from natural-language prompts.
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/ekam-mann/sleeper-fantasy-mcp-'
If you have feedback or need assistance with the MCP directory API, please join our Discord server