Skip to main content
Glama
sdotj
by sdotj

SleepBot

An MCP server that connects Claude to fantasy football leagues. Phase 1: read-only tools over Sleeper's public API (no auth required). Built to extend to write actions, ESPN, and multiple leagues without changing the tool interface.

Architecture

The core is platform-agnostic. Every tool talks to a LeagueAdapter interface, never to a platform SDK directly:

tools ──▶ LeagueAdapter (interface) ◀── SleeperAdapter ──▶ api.sleeper.app
  │                                       (EspnAdapter later)
  └──▶ config (leagues[] registry)

Adding a league or a platform is a config change, not a code change. The architecture is mapped with Cairn in cairn.blueprint; run cairn scan to reconcile the map against the code.

Related MCP server: Yahoo Fantasy Baseball MCP

Setup

npm install
cp config/leagues.example.json config/leagues.json   # then edit with your league
npm run build

Find your Sleeper league id in the app URL or via https://api.sleeper.app/v1/user/<username>/leagues/nfl/<season>.

config/leagues.json

{
  "leagues": [
    {
      "id": "my-main-league",        // your own label, passed to every tool
      "platform": "sleeper",         // "sleeper" | "espn"
      "sleeper": { "leagueId": "123456789012345678", "username": "yourusername" }
    }
  ]
}

Secrets are never stored inline — a value like "env:ESPN_S2" is resolved from the environment at runtime (see .env.example). Phase 1 needs no secrets.

Run

npm start          # serves over stdio (built)
npm run dev        # serves over stdio (tsx, no build)

Register with Claude Code

// .mcp.json / claude mcp add
{
  "mcpServers": {
    "sleepbot": { "command": "node", "args": ["dist/index.js"] }
  }
}

Tools (Phase 1 — all read-only)

Tool

Purpose

list_leagues

Configured leagues (from config, no API call)

get_league_info

Settings, scoring, season, roster positions

get_rosters

Every roster: starters, bench, IR (player names resolved), record

get_my_roster

Your own roster, identified from the configured username

get_matchups

Weekly matchups + scores (defaults to current week)

get_standings

Ranked by wins, then points-for

get_transactions

Trades, waivers, add/drops (defaults to current week)

search_players

Players by name, filter by position/team

get_trending_players

Sleeper's most-added / most-dropped

Every tool takes your leagueId label, so multi-league support is just "pass a different id." Set sleeper.username in config and rosters/standings/matchups are flagged with isYou, so SleepBot knows which team is yours without asking.

Tools (Phase 2 — write actions, confirm-by-default)

Tool

Purpose

propose_trade

Draft a trade (runs rules); returns a draft, never sends

propose_waiver_claim

Draft a waiver claim (add/drop + FAAB); draft only

propose_add_drop

Draft a free-agent add/drop; draft only

execute_action

Send a previously-proposed action, by actionId (explicit confirm)

list_pending_actions

Drafts awaiting confirmation

get_auth_status

Whether writes are authorized (ok / needs-reauth) + token expiry

Nothing changes your league silently: a propose_* tool returns a draft; execute_action is the explicit send. Guardrails live in config/rules.json (copy config/rules.example.json):

{
  "mode": "manual",                 // "manual" = approve each; "auto" = send anything unblocked
  "protect": [                      // hard blocks
    { "playerName": "Ja'Marr Chase", "actions": ["trade", "drop"] }
  ],
  "warn": [                         // non-blocking flags
    { "type": "trade_value_diff", "thresholdPct": 20 }
  ]
}

trade_value_diff uses KeepTradeCut (KTC) player values, bridged to Sleeper ids by name+position (~99% match). A snapshot ships in config/ktc-values.example.json; drop a fresher one at config/ktc-values.json to update, and set SLEEPBOT_KTC_MODE=oqb for 1-QB leagues (default superflex). Values from KeepTradeCut via cameron-eth/sleeper-sdk.

Enabling writes (unofficial Sleeper API)

Sleeper has no official write API. Writes go through its private GraphQL endpoint (https://sleeper.com/graphql), authenticated with a session JWT — there is no password automation. To enable them:

  1. Log in at sleeper.com in a desktop browser.

  2. DevTools → Network → filter graphql → click any request → copy the full authorization header value (a long eyJ... JWT).

  3. Put it in .env as SLEEPER_TOKEN=eyJ... (never commit it; .env is ignored).

The token is a JWT, so SleepBot reads its expiry and reports needs-reauth before attempting a doomed write. Check status any time with the get_auth_status tool. When the token expires or is rejected, writes pause, reads keep working, and you're notified to re-capture — no refresh endpoint exists, so recovery is a manual re-capture by design. Some networks/regions may need a VPN to reach the endpoint.

Protocol reverse-engineered by the community (cameron-eth/sleeper-sdk); it is unofficial and may change without notice.

Run the tests with npm test.

GUI (Phase 3)

A local React (Vite) app over a thin HTTP API that reuses the same core operations as the MCP server. Screens: My Team, Standings, Matchups, Draft, the Audit log, and a Chat panel (server-side Claude with the same tools).

npm run build && npm run api          # HTTP API on :8787 (reuses the core)
cd web && npm install && npm run dev  # GUI on :5173 (proxies /api -> :8787)

Then open http://localhost:5173. Secrets (SLEEPER_TOKEN, ANTHROPIC_API_KEY) live on the server only; the browser never sees them. The Chat panel needs ANTHROPIC_API_KEY — without it, chat returns a clear message and everything else keeps working.

Cloud deploy: one container serves the API + GUI, with Postgres for state (set DATABASE_URL) and the leagues config as an env secret (SLEEPBOT_CONFIG_JSON). See docs/deploy.md — there's a Dockerfile and a Fly.io walkthrough.

Roadmap

  • Phase 2 (built) — write actions (confirm-by-default) wired to Sleeper's private GraphQL API, rules engine, audit log, JWT session handling with fail-safe re-auth. Add SLEEPER_TOKEN to enable real sends.

  • Phase 3 (built) — local GUI (Vite/React) + HTTP API + in-app Claude chat, all over the shared core. Surfaces the audit log ("what SleepBot did while I was away").

  • Drafts (built) — read-only draft assistant for mock and real drafts: live board (status, on-the-clock, your next pick), and best-available recommendations by KTC value + roster need. Tools get_drafts / get_draft_board / get_draft_recommendations, a GUI Draft tab (auto-refresh while live), and chat with real draft context. Picks are made by you in Sleeper (their pick-submit is an undocumented real-time websocket).

  • Autonomous (built) — an opt-in per-league manager: a scheduled sweep reasons with Claude (+ web search for news) and proposes waiver/add-drop/trade moves through the same rules → pipeline → audit. Real-time Telegram alerts with Approve / Deny, and Override for rule-blocked moves. auto mode auto-executes clean actions; warned/blocked always wait. Opt in with an agent block in the league config + TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_ID.

  • Phase 4EspnAdapter against ESPN's cookie-based API, same interface

License & disclaimer

MIT — see LICENSE. You're free to use, modify, and distribute it.

Not affiliated with Sleeper, ESPN, or KeepTradeCut. SleepBot talks to Sleeper's unofficial, undocumented private API for writes; that can break at any time and may be against their terms — use it at your own risk, with your own account. The write protocol is derived from the community project cameron-eth/sleeper-sdk, and player values come from KeepTradeCut data. The software is provided "as is", without warranty (see the LICENSE).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

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.
    6
    12
    1
    -
  • F
    license
    Not graded
    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
    Not graded
    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.
    71
    MIT

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/sdotj/sleeper-bot'

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