# 🏈 NFL MCP — Your AI Fantasy Football War Room > **Win your draft. Dominate your season. With data, not gut feeling.** [![CI](https://github.com/gtonic/nfl_mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/gtonic/nfl_mcp/actions/workflows/ci.yml) [![Data-source watchdog](https://github.com/gtonic/nfl_mcp/actions/workflows/contracts.yml/badge.svg)](https://github.com/gtonic/nfl_mcp/actions/workflows/contracts.yml) [![Docker image](https://img.shields.io/badge/image-ghcr.io%2Fgtonic%2Fnfl__mcp-2496ED?logo=docker&logoColor=white)](https://github.com/gtonic/nfl_mcp/pkgs/container/nfl_mcp) [![Python 3.11 | 3.12 | 3.13](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-3776AB?logo=python&logoColor=white)](https://github.com/gtonic/nfl_mcp) [![63 in-season MCP tools](https://img.shields.io/badge/MCP%20tools-63%20in--season%20%7C%2080%20total-8A2BE2)](#-whats-inside) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) NFL MCP turns real NFL & fantasy data into a decisive edge — a suite of tools that plug straight into your AI assistant (Claude Desktop, Claude Code, Cursor, …). Ask a plain question, get a data-backed answer: *who to draft, who to start, whether that trade is a fleece, and what your playoff odds really are* — for **your** league, **your** roster, **your** pick, in real time. This isn't another rankings site you tab away from mid-draft. It lives **inside your assistant** and answers the question you actually asked. ## 💬 See it in action > **You:** *"I'm on the clock at 1.09 in my 12-team half-PPR draft — who do I take?"* > > **🏈 NFL MCP:** *Jahmyr Gibbs (RB) — top value here (VBD 8787), and there's a **value cliff at RB after him (−1995)**. Elite WRs are deeper, so lock the RB now and grab WR at the turn.* > **You:** *"Start Puka Nacua or DeVonta Smith this week?"* > > **🏈 NFL MCP:** *Nacua — 18.7 projected vs Smith's 11.2, a 7.5-point edge (floor 4.9 / ceiling 32.5). Clear choice.* > **You:** *"Is trading my Bijan for their CeeDee + a WR2 fair?"* > > **🏈 NFL MCP:** *Slightly favors you (fairness 82/100) — two startable pieces beat one stud for your thin WR room. ⚠️ You'd drop to 3 RB, so mind the depth.* Real tool outputs — value cliffs, projections with floor/ceiling, market-value trade fairness — rendered by your assistant. ## 🔥 Why you'll win **🎯 Draft day** - **VBD draft board** ranked by *value over replacement* — the ordering that wins drafts, not raw ADP. - **Live "war room"** — during your real Sleeper draft it reads the board live and calls the best pick *for your roster*, with **value-cliff** warnings and **positional-run** alerts. - **Rehearse first** — run 100 mock drafts from your slot before you're on the clock. **📊 Every week** - **Start/sit with automatic projections** — no manual point entry. **Sleeper-first:** `0.25 × our model + 0.75 × Sleeper's projection`, where our model is `opportunity (regressed early-season) × matchup × Vegas game-script × usage × injury & practice` and falls back alone (labelled `model_only`) when Sleeper has no number; both priced in **your league's own Sleeper scoring settings** (not just PPR / half-PPR presets), with floor/ceiling and a transparent breakdown. **Decided on projected points**, with a verdict scaled to the model's own error, so a half-point difference is reported as a coin flip rather than an edge. - **A real matchup edge** — which defense a player actually feasts on, from real weekly results (not a stale rankings page). - **Streaming planner** — the best DST / K / QB / TE to stream over the next 1-3 weeks (soft defense, weak opposing offense, strong own offense). - **Weather / wind** — fade passing and kickers in the ugly-weather games (wind ≥ 15 mph), dome games flagged neutral. - **Game-day aware** — players whose game has kicked off are locked, byes are caught from the schedule, practice reports (DNP / LP / FP) and official inactives feed straight into the call. - **Who's throwing, and what the coach said** — a receiver whose starting QB is out is cut by the backup's quality (backtested), a QB missing his top targets is flagged, and the news text ("benched after his fumble", "gonna rotate", "week-to-week", "the lead back") is read into `news_flags` with the quote that triggered it. **🔄 Trades & waivers** - **Trade analyzer on real market values** — knows your league's exact format and flags a lopsided deal *with evidence*. - **FAAB bids or waiver priority** — exactly how much to spend on that waiver breakout (market value + league demand + your budget); in non-FAAB leagues, whether the add is worth burning your waiver priority. - **Rest-of-season aware** — waiver and trade gains are measured over the rest of the season and your fantasy-playoff weeks, not just this week. - **Role security** — waiver targets in a growing role rank ahead of equal upgrades whose volume is borrowed from an injured teammate, and bench players in a shrinking role (lost target share, a committee, week-to-week) surface first as drops, with the reasons shown. **🏆 Season strategy** - **Monte-Carlo playoff odds** — *"72% to make it — 84% if you win this week."* Real probabilities, not vibes (median-game leagues included). - **Strength of schedule** — rest-of-season and **fantasy-playoff-week** difficulty per position, for stash and trade-deadline calls. - **Bye-week plan** — which upcoming week leaves a slot empty, what to add and who is free; opponent-weakness scouting. ## ✅ Why you can trust it - **Real data, zero gut-feeling heuristics** — market-consensus values ([FantasyCalc](https://fantasycalc.com)), real weekly stats ([nflverse](https://github.com/nflverse)), your live league ([Sleeper](https://sleeper.com)), news & injuries (ESPN), practice reports (NFL.com), weather ([Open-Meteo](https://open-meteo.com)), Vegas lines ([The Odds API](https://the-odds-api.com), optional `ODDS_API_KEY`). **No paid API keys required to start.** - **Honest about uncertainty** — when it lacks live data it *says so* (and falls back transparently) instead of faking a confident call. If Sleeper is down and only an old roster snapshot is left, availability questions (waivers, FAAB, free-agent handcuffs) are refused rather than answered on stale rosters. - **It grades its own accuracy.** A built-in backtest measures whether its projections actually beat a baseline on real past seasons, and a daily watchdog alerts if a data source changes. *Most fantasy tools never check whether they're right. This one does.* ## ⚡ 60-second start ```bash docker run --rm -p 127.0.0.1:9000:9000 -v nfl-mcp-data:/data ghcr.io/gtonic/nfl_mcp:latest ``` Publishing on `127.0.0.1` keeps the server off your network; the `nfl-mcp-data` volume keeps the warmed cache across restarts. Connect it to your assistant, then just ask: > *"My Sleeper username is `gary` — find my league, build my draft board, and simulate a draft from my slot."* **Claude Code (CLI):** ```bash claude mcp add --transport http nfl-mcp http://localhost:9000/mcp/ ``` **Sharing it beyond your machine?** Set a token and send it as a bearer header (the server then rejects `/mcp` calls without it): ```bash export NFL_MCP_AUTH_TOKEN=$(openssl rand -hex 32) docker run --rm -p 9000:9000 -v nfl-mcp-data:/data \ -e NFL_MCP_AUTH_TOKEN -e NFL_MCP_ALLOWED_HOSTS=nfl.example.lan \ ghcr.io/gtonic/nfl_mcp:latest claude mcp add --transport http nfl-mcp http://localhost:9000/mcp/ \ --header "Authorization: Bearer $NFL_MCP_AUTH_TOKEN" ``` Requests whose `Host` isn't localhost/127.0.0.1/[::1] (plus `NFL_MCP_ALLOWED_HOSTS`) are refused, which blocks DNS-rebinding attacks from a browser. **Claude Desktop / Cursor** — bridge via [`mcp-remote`](https://www.npmjs.com/package/mcp-remote): ```json { "mcpServers": { "nfl-mcp": { "command": "npx", "args": ["-y", "mcp-remote", "http://localhost:9000/mcp/"] } } } ``` Full setup, configuration and deployment → **[docs/TECHNICAL.md](docs/TECHNICAL.md)**. Draft-day walkthrough → **[docs/DRAFT_DAY.md](docs/DRAFT_DAY.md)**. Co-managers work too: pass your own Sleeper `user_id` and the roster is found via `co_owners`. ## 🧰 What's inside 63 MCP tools in the default in-season profile (80 in total), grouped by what they do. Every tool ships its own parameter schema over MCP, so your assistant can introspect them directly; **[AGENT.md](AGENT.md)** documents all of them plus integration guidance. **Tool profiles** — fewer, non-overlapping tools route better. Set `NFL_MCP_TOOL_PROFILE`: | Profile | Tools | Hides | |---|---|---| | `season` (default) | 63 | draft (8), coaching (4), cache-refresh admin (3), `get_league_leaders`, `get_cbs_expert_picks` | | `offseason` | 46 | in-season-only tools (lineups, waivers, Vegas, weather, byes, playoff odds, …), admin, `get_cbs_expert_picks` | | `full` | 80 | nothing | The active profile and its tool count are logged at startup and reported by `GET /health` (`tools`). **📊 Weekly lineup & projections** `get_weekly_briefing` (**start here** — roster, opponent, weather, usage and the lineup changes worth making, in one call; mid-week it scores played games for real and only optimizes what you can still change) · `get_league_changes` (**daily check** — what moved for your roster since you last looked) · `analyze_lineup` (grade the lineup you have set, optimal vs current, swaps, locked players; `risk_mode` says whether your situation calls for ceiling or floor) · `get_start_sit_recommendation` (one player or a list; team, position, opponent, snaps, injury and practice looked up for you) · `compare_players_for_slot` · `get_lineup_contingencies` (a questionable starter whose inactives come after the replacements lock — Monday night vs Sunday options: keep, swap before the lock, or wait for his list, with the decision deadline in Vienna time) · `get_win_probability_lineup` (lineup that maximises P(beating *this* opponent)) — lineup tools take `risk_mode` (auto | neutral | seek_variance | protect_floor): auto reads this week's P(win) and your playoff odds, so a 0-4 long shot chases ceiling and a heavy favourite protects its floor, and says when that differs from the points-optimal lineup ("starting X over Y raises P(win) 41%→44% although mean −0.6") · `project_players` (this week's points, one or many, with Sleeper's projection as a labelled second opinion) · `get_ros_projections` (rest-of-season + fantasy-playoff points in your scoring, every later week blended with Sleeper's projection for it, with each player's `value_trajectory`: sell-high / buy-low and why) · `get_opportunity_projections` · `get_usage_trends` · `get_weekly_retro` (after the games: actual vs projection, points left on the bench) · `get_projection_accuracy` (how accurate the logged projections were, week by week: MAE/bias per position, source and signal) · `get_weekly_signal_review` (is each signal's weight still right — practice buckets, role trend, QB coupling, news flags — with bootstrap intervals, minimum-sample rules and a keep / watch / review line per signal, plus the week's biggest misses) **🗓️ Matchup, schedule & environment** `get_bye_week_plan` (which upcoming weeks byes leave your lineup short, what to add, free agents who fill it) · `get_defense_rankings` (all defenses, or one via `opponent_team`) · `analyze_roster_matchups` (your roster's matchups this week) · `get_strength_of_schedule` (any week range, or `playoff_weeks=True` from your league's playoff window) · `get_streaming_options` · `get_weather_forecast` · `get_vegas_lines` (games, per-team environment via `teams`, or your whole roster via `league_id`+`roster_id`) · `get_stack_opportunities` **🔄 Trades, waivers & FAAB** `get_waiver_targets` (**who to pick up** in your league; unsigned free agents are named, not ranked) · `get_player_ownership` (**who owns X / is X a free agent** — teamless players included, ambiguous and unmatched names reported) · `recommend_faab_bid` · `get_waiver_log` (processed/failed claims, summary, re-entries; `sections`, `player` filter) · `audit_ir_slots` · `plan_roster_moves` (**check a multi-step add/drop/claim/IR/lineup plan** against roster size, IR rules, waiver timing, game locks, byes and backups; `suggest=True` proposes moves, `verify=True` checks what actually happened) · `get_handcuff_map` · `find_trade_targets` (trades both lineups gain from — one-for-one and packages up to `max_package_size` a side, ranked with a sell-high / buy-low timing bonus; reads the trade deadline) · `analyze_trade` (ROS lineup change per side, market fairness, per-player value trajectory and timing notes; `suggest_counters=True` for counter offers) · `get_trade_market` (**the league's trade market** — every team's needs, surpluses and situation, your natural partners with pre-scored packages and an `acceptance_likelihood`, counter offers for an incoming offer) · `get_player_values` (market consensus; one or many players) **🏆 Season strategy & opponents** `get_playoff_odds` (Monte-Carlo) · `analyze_opponent` **🏈 Your Sleeper league** `get_league` · `get_rosters` · `get_league_users` · `get_matchups` · `get_playoff_bracket` · `get_transactions` (the current week includes the previous leg, where Sleeper files the Wednesday waiver run) · `get_trending_players` · `get_fantasy_context` (aggregate) · `get_nfl_state` · `get_user` · `get_user_leagues` **🩺 Injuries & availability** `get_injury_report` (who is hurt: teams / players, `min_confidence`, `severity`, `since`, practice reports; healthy rows only with `include_healthy`; ESPN source) · `get_injury_trends` (**what changed** since you last looked) · `get_gameday_inactives` · `get_player_news` (**what is the latest on X** — one merged timeline per player from ESPN's fantasy feed, NBC Sports / Rotoworld and CBS, with the role / availability flags the projections read, each with source and link; `league_id` alone lists your league's rostered players with news) **📰 NFL data & news** `get_nfl_news` · `get_teams` · `get_depth_chart` · `get_team_player_stats` · `get_nfl_standings` · `get_team_schedule` · `get_cbs_player_news` · `get_cbs_projections` (CBS **season-long** totals, not weekly) **👥 Players / athletes** `lookup_athlete` · `search_athletes` · `get_athletes_by_team` **🎯 Draft** (`offseason` / `full`) `get_draft_board` (VBD-tiered board) · `recommend_draft_pick` (best pick live) · `simulate_draft` (offline mock) · `get_league_drafts` · `get_draft` · `get_draft_picks` · `get_draft_traded_picks` · `get_traded_picks` **🧠 Coaching intelligence** (`offseason` / `full`) `get_coaching_staff` · `get_all_coaching_staffs` · `get_coaching_tree` · `get_scheme_classification` **🛠️ Admin & niche** (`full`; `get_league_leaders` also `offseason`) `fetch_athletes` · `fetch_all_players` · `fetch_teams` (cache refreshes the prefetch loop already runs) · `get_league_leaders` · `get_cbs_expert_picks` (CBS experts' ATS betting picks) **🌐 Web, data & health** `crawl_url` (SSRF-guarded text extraction) · `refresh_data` (refresh injuries / practice / athletes / schedule / snaps / usage / accuracy grading **now** — when the prefetch went stale, e.g. after the host slept; per-scope counts, durations and resulting freshness; `background=True` + `job_id` to poll) · `GET /health` (REST) ## 🔌 Data sources & terms Every source is free and on by default. This server is meant for **personal, low-volume use**: you run it for your own leagues and it reads public pages and endpoints the way a browser would. | Source | What it reads | Access | Switch it off | |---|---|---|---| | **Sleeper** | your leagues, rosters, transactions, players, Sleeper projections | public API | — (core) | | **ESPN** | injuries, depth charts, teams, schedules, standings, news, fantasy player news (RotoWire notes) | public site / core / fantasy JSON endpoints | news: `NFL_MCP_NEWS_SOURCES=-espn_fantasy` | | **NBC Sports / Rotoworld** | player news | HTML scrape (RSS as fallback), 10 s between pages | `NFL_MCP_NEWS_SOURCES=-nbc` | | **CBS Sports** | player news (first page), projections, expert picks | HTML scrape | news: `NFL_MCP_NEWS_SOURCES=-cbs`; tools: `NFL_MCP_TOOL_PROFILE` (`get_cbs_expert_picks` is `full` only) | | **NFL.com** | the official weekly practice / injury report | HTML scrape, cached per week | — (the practice reads; fetched by the prefetch loop and on demand) | | **nflverse** | weekly stats, snap counts (GitHub releases) | public files | — | | **FantasyCalc** | market player values | public API | — | | **The Odds API** | Vegas lines / implied totals | your API key | leave `ODDS_API_KEY` unset | | **Open-Meteo** | game-day weather | public API | — | - **Terms.** Some of these sites' terms of use restrict automated access or reuse of their content. Read them and decide for yourself; switch off whatever you do not want to use. Nothing here republishes their content — the news text stays in your local database and is quoted only in short snippets in tool answers. - **Politeness.** Every outbound request goes through a per-host rate limiter (`config.py`; NBC at 6/min with no burst to keep its robots.txt `Crawl-delay: 10`); the HTML news scrapers read only pages their robots.txt allows (NBC's `/api/` and GraphQL are not used). A news source that keeps failing backs off (30 min doubling to 12 h) instead of retrying, and `/health` shows its state. - **Switches.** One env line each: `NFL_MCP_NEWS_SOURCES=-nbc` (all news sources but NBC; `-nbc,-cbs` for two, `espn_fantasy` to keep one, `none` for no news polling), `NFL_MCP_PREFETCH=0` (no background fetching at all), `NFL_MCP_PREFETCH_NEWS=0` (no background news polling), `NFL_MCP__RATE_LIMIT` (requests/minute per host, e.g. `NFL_MCP_NBC_RATE_LIMIT=3`). See [`.env.example`](.env.example). ## 📚 More - **[docs/TECHNICAL.md](docs/TECHNICAL.md)** — setup, configuration, architecture, data sources, eval suite, CI/CD, security. - **[AGENT.md](AGENT.md)** — full per-tool reference for AI agents. - **[docs/DRAFT_DAY.md](docs/DRAFT_DAY.md)** — before/during draft-day playbook. - **[SECURITY.md](SECURITY.md)** — security policy, SSRF protections, reporting. - **[CHANGELOG.md](CHANGELOG.md)** — release history. ## License MIT — see [LICENSE](LICENSE).