JS

joscaz/sleeper-mcp

Developer tools
4 stars 6 forks Quality 84 Trend 32MIT

MCP server for Sleeper fantasy football — leagues, rosters, matchups, players, stats and projections, plus optional account tools (lineups, IR, waivers, trades, league chat) over stdio or Streamable...

Overview

A Model Context Protocol server for Sleeper fantasy football, built so an AI assistant can actually answer fantasy questions instead of handing you a wall of player IDs. Ask Claude, Cursor, or any MCP client things like: - "Who should I start this week in my dynasty league?" - "Show me the standings and who's on the waiver wire at RB." - "Was the Bijan-for-Chase trade fair? Who won it?" - "Who did I draft in round 1 the last three years?" - "Am I going to win this week? What are my playoff odds, and how many wins do I need?" - "Would trading for Justin Jefferson actually raise my playoff odds? What about picking up a backup RB?" - "Are any of my lineups broken this week?" (one check across all your leagues: empty slots, byes, players ruled out) - "Move Jacobs to IR, start Corum, and put a claim in for Kaelon Black." (with a Sleeper session, see Account tools) No login, no API key for reads: Sleeper's public API covers everything above the "Account" line.

README

sleeper-mcp

A Model Context Protocol server for Sleeper fantasy football, built so an AI assistant can actually answer fantasy questions instead of handing you a wall of player IDs.

Ask Claude, Cursor, or any MCP client things like:

  • “Who should I start this week in my dynasty league?”
  • “Show me the standings and who’s on the waiver wire at RB.”
  • “Was the Bijan-for-Chase trade fair? Who won it?”
  • “Who did I draft in round 1 the last three years?”
  • “Am I going to win this week? What are my playoff odds, and how many wins do I need?”
  • “Would trading for Justin Jefferson actually raise my playoff odds? What about picking up a backup RB?”
  • “Are any of my lineups broken this week?” (one check across all your leagues: empty slots, byes, players ruled out)
  • “Move Jacobs to IR, start Corum, and put a claim in for Kaelon Black.” (with a Sleeper session, see Account tools)

No login, no API key for reads: Sleeper’s public API covers everything above the “Account” line. Add your Sleeper session and the same server can also set lineups, manage IR/taxi, submit waiver claims and propose trades.

Why another Sleeper MCP?

There are several community Sleeper MCP servers. This one focuses on the things that make the difference between “it works” and “it’s useful in a conversation”:

sleeper-mcp (this) typical alternatives
Player IDs resolved to names/positions/teams/injury flags in every response ✅ everywhere (rosters, matchups, transactions, drafts, brackets) usually raw IDs, or names only in one or two tools
Roster IDs resolved to team + manager names ✅ rarely
Computed standings (rank, record, PF/PA, streak, FAAB left, divisions) ✅ raw roster settings
Matchups paired with per-player points and margins ✅ raw matchup arrays
Trades summarized as “gave / got” per side, picks and FAAB included ✅ raw adds/drops maps
Free agents for a league (unrostered, ranked, trending-annotated) ✅ ❌
Projections & stats scored with the league’s exact scoring settings ✅ ❌ (or PPR only)
Start/sit: optimal lineup with slot eligibility (FLEX, SUPER_FLEX, IDP) ✅ ❌
Live win probability, Monte Carlo playoff odds and trade/waiver what-ifs over the real schedule, under league scoring ✅ rare
League history across seasons with champions ✅ ❌
Select a team by username, user_id, roster_id or team name ✅ user_id / roster_id only
“Current week/season” defaults from Sleeper’s NFL state ✅ manual
Transports stdio and Streamable HTTP (stateless, bearer auth, CORS, health check, Docker) stdio only
Player database (~5 MB) memory + disk cache, daily refresh, stale-cache fallback re-downloaded per process
Rate limiting / retries 600 req/min budget, backoff on 429/5xx, in-flight de-dup none
Tests 100+ unit + integration tests (in-memory and HTTP transports) plus a live smoke test varies
Tool annotations, structuredContent, prompts, resources ✅ partial

The 28 read tools need no login. They use Sleeper by default; optional injury context can add ESPN reports. The 11 account tools (2 private reads, 9 writes) are registered only when you configure a Sleeper session, and --read-only keeps the writes off even then.

Quick start

Requires Git, Node.js 20+ and npm. Install from source; this project is not currently distributed on npm. npm is used below to install dependencies and build the local server, not to download a published @joscaz/sleeper-mcp package.

git clone https://github.com/joscaz/sleeper-mcp.git
cd sleeper-mcp
npm ci
npm run build
node dist/index.js --help

Keep the checkout: MCP clients launch its built dist/index.js. Replace /absolute/path/to/sleeper-mcp in the examples with its actual location. Use the full path to node too if your desktop client cannot find it on PATH. On Windows, use a path such as C:/Users/you/sleeper-mcp/dist/index.js.

The examples use --read-only, so they cannot change your account even if session credentials are present. To enable account changes deliberately, see Account tools.

Claude Desktop

claude_desktop_config.json:

{
  "mcpServers": {
    "sleeper": {
      "command": "node",
      "args": ["/absolute/path/to/sleeper-mcp/dist/index.js", "--read-only"],
      "env": { "SLEEPER_USERNAME": "your_sleeper_username" }
    }
  }
}

Claude Code

claude mcp add sleeper -e SLEEPER_USERNAME=your_sleeper_username -- node /absolute/path/to/sleeper-mcp/dist/index.js --read-only

Cursor / Windsurf / other stdio clients

Same shape: command node, args ["/absolute/path/to/sleeper-mcp/dist/index.js", "--read-only"], env SLEEPER_USERNAME.

Updating your checkout

From a clean checkout on the branch you want to follow:

git pull --ff-only
npm ci
npm run build

Restart your MCP client afterwards. If you have local changes or a detached release tag, choose how to preserve or update those before pulling.

Make it yours

Sleeper’s API is public and read-only, so there is no login step: every league, roster and matchup is readable by anyone who knows a username or league ID. The only thing the server cannot know by itself is who you are. Set SLEEPER_USERNAME (or pass --user) and every tool that takes a user or team falls back to you, so “what are my leagues?”, “show my roster” and “who should I start?” work without naming yourself. Explicit selectors always win, so questions about other managers still work.

Remote / hosted (Streamable HTTP)

node dist/index.js --http --host 127.0.0.1 --port 3000 --read-only
# MCP endpoint:  http://localhost:3000/mcp   (POST, JSON-RPC)
# Health check:  http://localhost:3000/healthz

This example listens only on your own machine. For remote hosting, configure SLEEPER_MCP_AUTH_TOKEN through your host’s secret manager, use --host 0.0.0.0, and put HTTPS in front of the service. Configure the same bearer credential securely in your MCP client. Not every remote MCP client supports static bearer authentication; check your client’s requirements.

When a Sleeper session is configured with write tools enabled, the bearer token is mandatory unless the server is bound to loopback: anyone who can reach an unauthenticated /mcp could otherwise change your lineups, drop players and send trades. The server refuses to start in that configuration unless the explicit insecure override is set. Bearer authentication is also recommended for remote read-only account access, which can expose private pending transactions. See SECURITY.md.

Build Docker locally from the checkout; no published container image is required. With SLEEPER_MCP_AUTH_TOKEN already set securely in your environment:

docker build -t sleeper-mcp .
docker run --rm -p 127.0.0.1:3000:3000 -e SLEEPER_MCP_AUTH_TOKEN -v sleeper-cache:/data sleeper-mcp node dist/index.js --http --read-only

The port is exposed only to the host by default. Use your hosting platform’s private ingress or HTTPS configuration for remote access. Neither command publishes an image.

Tools

Every tool that takes a team accepts any of username (or display name), user_id, roster_id, team_name (partial, case-insensitive), team (any of those names in one field, when you are not sure which kind you have), or nothing at all when SLEEPER_USERNAME is set. week defaults to the current NFL week and season to the current league season.

Users & leagues

Tool What it returns
get_nfl_state Current season, season_type, week, league_season.
get_user Username ↔ user_id, display name, avatar.
get_user_leagues A user’s leagues for a season with league_id, scoring format, roster shape, status.
get_league Summarized settings: scoring (PPR/half/std, TE premium, pass TD, bonuses), roster slots, redraft/keeper/dynasty, waivers/FAAB, playoffs, trade deadline, divisions, commissioners. include_raw for the full objects.
get_league_standings Ranked standings with record, PF/PA, streak, waiver position, FAAB remaining, division. Doubles as the roster_id → manager map.
get_league_history Walks previous_league_id back through seasons: champion, runner-up, regular-season leader, points leader.

Rosters & matchups

Tool What it returns
get_roster One team: current weekly starters during an active season, labeled with slots (QB, RB, FLEX…), plus bench, IR, taxi, record, FAAB. Uses live weekly starters with a session; otherwise public matchup data, which can lag.
get_league_rosters Every roster in the league, including roster-default starters (include_bench=false for a lighter payload). Use get_matchups for weekly scoring lineups.
get_matchups Paired matchups for a week with scores, margin, leader, starters with per-player points (include_bench for bench points). Filter to one team.
get_playoff_bracket Winners/losers bracket with round labels (“Championship”, “Semifinal”, “Toilet bowl final”), teams and results.

Transactions & picks

Tool What it returns
get_transactions Trades, waivers, free-agent moves with players, teams, FAAB bids, traded picks and a per-side trade_summary. Current week or all_weeks. Failed claims hidden unless status="failed"/"all".
get_traded_picks All traded picks grouped by current owner with original/previous owners.

Drafts

Tool What it returns
get_drafts Drafts for a league or for a user + season.
get_draft Draft settings and the resolved draft order (slot → manager → roster).
get_draft_picks Every pick with player, position, overall/round pick, drafter, keeper flag, auction price. Filter by round or team.

Players

Tool What it returns
search_players Name search (handles “ja marr”, “lions”) with position/team filters, injury and depth-chart info.
get_player Full profile plus sourced injury context: report/retrieval timestamps, cache expiry, stale flags, and disagreements. Existing profile fields remain Sleeper-based.
get_injury_report Current injury context for a roster (league_id + team selector) or up to 100 player_ids. Shows each source, timestamps, links, and a needs_check flag; never assumes a missing report means healthy.
get_trending_players Most added/dropped players platform-wide over the last N hours.
get_free_agents Unrostered players in a league ranked by Sleeper’s player rank, annotated with 24h trending adds. In season, flags players who can’t be picked up right now (availability: locked once their game has kicked off, on_waivers after a recent drop); addable_only hides them.

Projections & stats

Tool What it returns
get_projections Weekly or season (week=0) projections. Filter by players/position/league/team. scoring="league" applies the league’s exact scoring_settings.
get_player_stats Actual weekly/season fantasy production with the same filters and scoring options.
get_lineup_projections Start/sit for one team: current vs optimal lineup (respecting FLEX/SUPER_FLEX/IDP eligibility), suggested swaps, bye/injury/empty-slot warnings. Once games kick off, players whose game has started stay locked and count the points they have scored (plus a projection for the rest of a live game), so totals are projected finals and swaps only involve players still to play.
check_lineups Checks every in-season league for zero-point slots and missing projections. A separate needs_check watchlist flags questionable starters, stale injury snapshots, and conflicting reports without injury-driven set_lineup moves. Clear zero-point fixes can still return ready-made arguments. Locked starters, best ball leagues, and empty rosters are skipped.

Odds & simulations

Tool What it returns
compare_lineups Current weekly lineup versus up to five named start/sit scenarios, using one collected input set. Shows projected-point deltas, approximate win-probability deltas in percentage points, slot/lock validation, and injury warnings. Read-only; invalid roster/slot/lock scenarios do not discard valid ones.
get_matchup_odds Win probability for a week’s matchups, live during games: points so far, projected final and win % per side, plus a starter-by-starter view (final / playing / yet to play / bye) for a selected team. Past weeks come back as results, future weeks as projections.
get_playoff_odds Simulates the rest of the regular season (10,000 runs by default) over the real schedule: playoff %, first-round-bye %, #1-seed %, projected record and average seed for every team. For a selected team, also this week’s swing (playoff % if they win vs lose) and playoff % by final win total.
get_move_impact What-if for a trade, waiver claim or add/drop: playoff %, bye %, #1-seed %, projected record and average weekly projection before and after the move for your team and the trade partner, plus who enters and leaves the best lineup and a warning when a roster would be over its limit.

Comparing lineups (read-only)

compare_lineups uses your current scoring-week lineup as the baseline. Each named scenario starts from that same baseline, not from the preceding scenario. Use either moves (start/bench swaps) or a complete starters list in league slot order.

For example, if Warren is currently starting and Likely is on your bench, call compare_lineups with these arguments after replacing the league and username placeholders:

{
  "league_id": "YOUR_LEAGUE_ID",
  "username": "your_sleeper_username",
  "scenarios": [
    {
      "name": "Start Likely",
      "moves": [{ "start": "Isaiah Likely", "bench": "Tyler Warren" }]
    },
    {
      "name": "Keep Warren",
      "moves": [{ "start": "Tyler Warren", "bench": "Tyler Warren" }]
    }
  ]
}
  • The response includes baseline, opponent, and scenarios. Valid scenarios include resolved starters, changes, projected_points_delta, win_pct, and win_probability_delta_pp. A delta of 2.5 means 2.5 percentage points, not a 2.5% relative improvement.
  • It reuses the existing league scoring and matchup-odds model, including points already scored and the projection for the rest of live games. A no-op produces zero deltas.
  • Roster membership, position/FLEX eligibility, IR/taxi status, duplicate starters, and kickoff locks are validated. Roster/slot/lock errors return valid: false for that scenario while valid scenarios still run. Malformed tool arguments or duplicate scenario names reject the request.
  • The first version supports the current regular-season NFL week in an active, synchronized, non-best-ball league. No past/future-week counterfactuals, trades, pickups, or opponent lineup optimization.
  • Every scenario uses one collected set of inputs. This is not an atomic upstream snapshot; source caches apply, and public roster/matchup data can lag a recent change. The tool uses public weekly matchups even when a session is configured and never calls account APIs.
  • If there is no single head-to-head opponent or the opponent’s lineup is unavailable, point comparisons still work but win probabilities are null with a reason. Commissioner custom_points overrides keep the modeled team total fixed.
  • Injury evidence and warnings accompany the results, but Questionable/ESPN reports do not rewrite the model. Probabilities assume independent position-based variation and are approximate—not Sleeper’s official odds or a guarantee of improved results.
  • This tool never changes your lineup. Any later set_lineup action requires a separate decision and fresh validation.

Account tools (optional, session)

Registered only when a Sleeper session is configured (SLEEPER_TOKEN, or SLEEPER_EMAIL + SLEEPER_PASSWORD). They talk to Sleeper’s private GraphQL API (https://sleeper.com/graphql), the same one the web app uses. Every tool that changes the account takes dry_run=true to validate and preview first, resolves player names for you, and re-reads the roster afterwards so you see the result. “My team” is the roster owned by the logged-in user; pass roster_id to act on another one (co-owners/commissioners).

The quick-start client configurations explicitly disable writes. To enable them, configure the session securely and remove --read-only; also ensure SLEEPER_MCP_READ_ONLY is not enabled. These tools can affect your real account: preview with dry_run=true, require confirmation in your MCP client, and verify changes in Sleeper.

Tool What it does
get_auth_status Who the session belongs to, how it was configured, token expiry, whether writes are enabled. Call it first to verify a token.
get_pending_transactions Open trade offers (sent/received, who still has to accept) and pending waiver claims for your team, with names resolved. all_teams / include_finished widen it.
set_lineup Start/bench swaps (moves: [{start, bench?}]) or a full starters list. In season, reads and updates the current weekly matchup—not roster defaults—and verifies it independently. Checks slot eligibility, IR/taxi, duplicates, kickoff locks and week rollover.
update_ir Move players onto/off IR. A starter is benched first so the lineup stays valid; slot counts are enforced.
update_taxi Move players onto/off the taxi squad, same guarantees. force for commissioner overrides. Note: most leagues block taxi additions once the regular season starts, and Sleeper enforces that server-side.
add_drop_player Free-agent add and/or drop, refusing players who are already rostered.
submit_waiver_claim Waiver claim with optional drop and FAAB bid (required in FAAB leagues, capped at your budget). Sleeper checks roster room at submission time, so a full roster needs a drop.
cancel_waiver_claim Cancel one of your pending claims.
propose_trade Offer players to another manager (partner = username, display name, team name or roster_id); counter_transaction_id rejects their offer and sends yours in one step.
respond_to_trade Accept or reject an offer you received, or cancel one you sent.
post_league_message Post in the league chat (e.g. pitch a trade).

Write tools carry readOnlyHint: false so clients can ask for confirmation. Start with --read-only to keep the two private reads and drop every write tool even though a session exists.

Weekly lineup safety: In-season set_lineup returns week and verified: true only after a separate authenticated read confirms the requested starters. Missing/malformed weekly data, a failed live roster read, or unavailable kickoff information stops the write rather than falling back to roster defaults. If a request was sent but cannot be verified, check Sleeper before retrying: a transport or read-back failure does not prove nothing changed. Dry runs never send mutations. Outside an active season, lineup changes still update roster defaults and do not claim weekly verification.

IR/taxi moves that bench an in-season starter use the same weekly update and verification first. These are separate requests, not an atomic transaction: if the subsequent IR/taxi move fails, the error reports that the lineup already changed. Preflight checks catch observed concurrent lineup changes but cannot eliminate every race with another client.

Heads-up: the private API is undocumented and unsupported by Sleeper; field names and behaviour can change without notice. Use a session you are comfortable exposing to the machine running the server, and confirm each change in the Sleeper app the first few times.

Getting a token: log in at sleeper.com, open DevTools → Network, click any graphql request and copy the value of the authorization request header (a long eyJ... JWT). Set it as SLEEPER_TOKEN. Tokens are long-lived but do expire; get_auth_status tells you when. Alternatively set SLEEPER_EMAIL + SLEEPER_PASSWORD and the server logs in on first use (accounts with 2FA/captcha challenges need the token route).

Injury context (optional ESPN)

Sleeper-only mode is the default. To add the keyless, read-only ESPN injury feed to the existing tools:

SLEEPER_MCP_INJURY_SOURCE=espn node dist/index.js --read-only --user your_sleeper_username

For desktop clients, add SLEEPER_MCP_INJURY_SOURCE with value espn to the server’s env configuration. No new account connection, package, or credential is needed. The ESPN endpoint is unofficial and may change or stop working; opt in only if its use is appropriate for your deployment and the provider’s terms.

  • get_injury_report accepts a roster or explicit player_ids; get_player includes the same context. Current-week lineup projections include a needs_check list alongside their existing results.
  • Each report has source, reported_at, retrieved_at, cache_expires_at, stale, and a source link. Sleeper does not expose a reliable per-injury update time, so its reported_at is null—not the player-map load time or news_updated.
  • stale means the cached source snapshot has expired, not that the underlying injury has ended. Read the report timestamp too: a recently fetched feed can contain an older report. Expired snapshots retained after a refresh failure keep their original timestamps and carry a warning.
  • ESPN defaults to a five-minute shared cache/retry window, configurable with SLEEPER_MCP_INJURY_TTL_SECONDS (60–3600). This is an operational caching policy, not a prediction-confidence threshold. Concurrent callers share a request; there is no background polling. The daily Sleeper player-map cache is unchanged.
  • Player matching requires corroborated ESPN identity or a unique exact name/team/position match. Ambiguous mappings are surfaced, not guessed. The feed is fetched once per cache window rather than downloading every NFL team’s roster.
  • Conflicting designations are shown together with source: "conflict" and no chosen designation. An ESPN Active report does not silently clear a Sleeper injury flag. Absence from the feed is not proof of health.
  • Questionable means check availability, not automatically bench. Stale/conflicting reports and newly reported ESPN injuries go on the watchlist rather than creating injury-driven lineup moves. Clear existing Sleeper problems still work; questionable replacement candidates still require your judgment.
  • This release adds evidence, not a new forecasting model: projection totals, optimized lineups and odds remain Sleeper-based. Review the injury context before acting on those recommendations.
  • ESPN outages, malformed responses and timeouts produce warnings while basic Sleeper reads continue. Setting the source back to sleeper disables ESPN requests.

Prompts

  • weekly_briefing(league_id, username, week?) — matchup preview, lineup check, waiver targets, league news.
  • waiver_wire_report(league_id, username) — prioritized claims with drop candidates and FAAB suggestions.
  • trade_analysis(league_id, team_a, team_b, proposal) — needs, lineup impact, depth, dynasty value, verdict.

Resources

  • sleeper://nfl/state
  • sleeper://league/{league_id}

Configuration

Variable Purpose Default
SLEEPER_USERNAME Your Sleeper username (or user_id). Tools that take a user/team default to it, so “my team” questions need no selector. unset
SLEEPER_TOKEN Sleeper session JWT (see Account tools). Enables the private reads and the lineup/IR/taxi/waiver/trade/chat tools. unset (reads only)
SLEEPER_EMAIL, SLEEPER_PASSWORD Alternative to SLEEPER_TOKEN: log in with your Sleeper credentials on first use. unset
SLEEPER_MCP_READ_ONLY 1/true keeps write tools off even when a session is configured (same as --read-only). unset
SLEEPER_MCP_AUTH_TOKEN If set, HTTP clients must send Authorization: Bearer . Required in HTTP mode when a Sleeper session has writes enabled and the server is not bound to loopback: it refuses to start otherwise. unset (no auth)
SLEEPER_MCP_INSECURE_NO_AUTH Set to 1 to run account write tools on a non-loopback address without a bearer token, for deployments that authenticate in front of the server. unset
SLEEPER_MCP_CACHE_DIR Where the player database is cached on disk. Set to an empty string to disable. ~/.cache/sleeper-mcp
SLEEPER_MCP_INJURY_SOURCE sleeper or espn for optional sourced injury context. No account credentials are sent to ESPN. sleeper
SLEEPER_MCP_INJURY_TTL_SECONDS ESPN snapshot cache/retry window; integer 60–3600. 300
PORT, HOST HTTP bind defaults (--port/--host override). 3000, 0.0.0.0

CLI flags: --http, --port , --host , --user , --read-only, --no-preload, --help, --version.

How it works

  • Player database. Sleeper publishes one ~5 MB JSON of every NFL player. It is downloaded once, indexed for name search, cached in memory and on disk for 24 hours, and preloaded in the background on startup. If a refresh fails, the stale copy is used rather than failing requests.
  • Caching & rate limits. Every endpoint is cached with a TTL matched to how fast it changes (20 s for live matchups, 5 min for league lists, 24 h for players). Concurrent identical requests are de-duplicated. Outbound calls are capped at 600/min (Sleeper asks for < 1000) and retried with backoff on 429/5xx.
  • Payload design. Responses use short keys where they repeat hundreds of times ({id, name, pos, team, inj, pts}) and drop empty fields, which keeps token usage down for large leagues.
  • Projections/stats. These use Sleeper’s /projections, /stats and /schedule endpoints, which power the Sleeper app but are not in the public docs. They have been stable for years; if they change, the rest of the server is unaffected.
  • Odds. A starter’s remaining points are modeled around their league-scored projection for the share of their game still to play: Sleeper’s NFL schedule says which games are final, live or upcoming, and the plays both teams have run so far (rushes, pass attempts and sacks in the live box scores) estimate how far along a live game is, since Sleeper only adds snap counts once a game ends. The spread depends on position, and win % is the normal approximation of the score difference. get_playoff_odds plays out every remaining week with each team’s best projected lineup (the week in progress starts from live points), adds a season-long projection error per team, counts median games when the league plays them, and seeds by record, then points for. Runs are seeded, so the same data always gives the same odds. get_move_impact runs that simulation twice with the same random draws, before and after the move (which counts from the next week that has not started), so the difference comes from the move rather than chance: a pickup that would not start changes nothing.

Development

npm ci
npm run dev            # stdio server via tsx
npm run dev:http       # HTTP on :3000
npm test               # vitest (unit + in-memory MCP + HTTP integration)
npm run typecheck
npm run smoke          # live checks against the real Sleeper API
SLEEPER_USERNAME=you npm run smoke   # also exercises your own leagues
npm run inspect        # MCP Inspector against the built server

Layout:

src/
  index.ts            CLI entry (stdio / --http)
  server.ts           createServer(): tools, prompts, resources
  http.ts             Streamable HTTP host (stateless, auth, CORS, /healthz)
  context.ts          Shared context + resolvers (user, season, week, league, team)
  format.ts           Scoring summaries, standings math, slot eligibility, lineup helpers
  sleeper/            API client, TTL cache, player store, types
  tools/              Tool registrations grouped by domain
tests/                Fixtures + fake fetch; no network needed
scripts/smoke.ts      Live end-to-end check

Using the client library from a checkout

After building, run this as an ES module from the checkout root (for example in a local .mjs script):

import { SleeperClient } from "./dist/sleeper/client.js";

const sleeper = new SleeperClient();
const state = await sleeper.getNflState();
const leagues = await sleeper.getUserLeagues("", "nfl", state.league_season);

Contributing

Issues and pull requests are welcome. CONTRIBUTING.md covers the dev setup, the project layout and how to add a tool; the short version is npm ci && npm test. Security reports go through SECURITY.md, and everyone is expected to follow the Code of Conduct.

Releasing

Distribution is source-first. npm publication is intentionally disabled with "private": true in package.json; this does not make the GitHub repository private.

After a maintainer explicitly pushes a version tag, the release workflow validates the source and creates a draft GitHub release for review. It does not publish to npm or upload a container image. See Releasing in CONTRIBUTING.md for the version/tag procedure.

Credits & license

Data comes from Sleeper’s public API (docs.sleeper.com). This project is not affiliated with Sleeper. Thanks to the earlier community servers, in particular FloSchl8/sleeper-mcp, for mapping out the space.

MIT © 2026 Jose Zertuche

View the full README on GitHub

Install

docker run --rm -p 127.0.0.1:3000:3000 -e SLEEPER_MCP_AUTH_TOKEN -v sleeper-cache:/data sleeper-mcp node dist/index.js --http --read-only
New to MCP? Start with the mcpskill.org guide →

Configuration

{ "mcpServers": { "sleeper": { "command": "node", "args": ["/absolute/path/to/sleeper-mcp/dist/index.js", "--read-only"], "env": { "SLEEPER_USERNAME": "your_sleeper_username" } } } }