mcp-ff2026
# Sleeper Fantasy Football MCP 2026
An MCP server that helps an AI agent run a Sleeper fantasy football team from draft night through
the championship. Sleeper is the read-only source of league state; recommendations, draft queues,
decision history, and model data are stored locally in SQLite.
## What it does
- Discovers your league, roster, and draft from one Sleeper username or user ID.
- Syncs rosters, drafts, picks, matchups, transactions, players, and league history.
- Imports public ffverse player crosswalks and current rankings without an API key.
- Best-effort fills projection/ADP gaps from Sleeper's public projection feed.
- Optionally enriches remaining gaps with FantasyPros or normalized third-party snapshots.
- Recommends draft picks and estimates who may survive to your next pick.
- Maintains a conflict-safe local draft queue.
- Optimizes lineups and analyzes waivers, FAAB, trades, and season strategy.
- Learns descriptive manager tendencies from historical league behavior.
- Preserves source snapshots, recommendations, actions, and outcomes for later evaluation.
The models expose their inputs and uncertainty. Heuristic survival, FAAB, and championship
estimates are not presented as calibrated facts.
## Requirements
- Python 3.12+
- [uv](https://docs.astral.sh/uv/)
- A Sleeper username or user ID
FantasyPros is optional. The public ffverse feed is the preferred model-evidence source. Its
rankings are distributed through the nflverse ecosystem by DynastyProcess and originate from
FantasyPros consensus, so the server preserves that upstream lineage rather than double-counting
the two feeds as independent evidence.
## Setup
```bash
uv sync
cp .env.example .env
```
Edit `.env`:
```dotenv
FF2026_SLEEPER_USER_ID=your-sleeper-username
# Optional:
# FF2026_FANTASYPROS_API_KEY=your-api-key
```
Start the stdio MCP server:
```bash
uv run --env-file .env ff2026-mcp
```
State is stored in `.data/ff2026.sqlite3`. Credentials are read only from the environment and are
excluded from source control.
## MCP configuration
```json
{
"mcpServers": {
"ff2026": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/mcp-ff2026",
"run",
"--env-file",
".env",
"ff2026-mcp"
]
}
}
}
```
## First run
Ask the agent to perform these operations:
1. `initialize_season` discovers and stores the league, roster, and draft defaults.
2. `get_season_context` confirms the selection.
3. `sync_ffverse` imports the public player crosswalk and preseason rankings using week `0`.
4. `sync_sleeper_projections` attempts free preseason projection and ADP fallback data.
5. `get_provider_status` reports unresolved player identities.
6. `sync_league_history` imports previous seasons for manager analysis.
ffverse's draft dataset contains ranks, not season point projections. Import a licensed projection
feed with `import_provider_snapshot`, configure the optional FantasyPros API, or use the
best-effort Sleeper-hosted projection fallback. Third-party evidence fills a missing
player/metric/horizon only; matching native ffverse evidence remains authoritative. The weekly PPR
rank-to-points field is retained as an explicitly labeled fallback rather than promoted to a native
projection. Sleeper's projection URL is public but not part of its documented API, so refresh
failures warn and preserve the last good evidence instead of blocking ffverse refreshes.
If the account has multiple leagues, `initialize_season` returns the choices instead of guessing.
## During the draft
1. Run `refresh_decision_inputs` with week `0`.
2. Read `get_draft_state` and stop if it reports stale data.
3. Use `recommend_draft_pick` and review the alternatives and survival ranges.
4. Update the local queue with `set_draft_queue_entry`.
5. Record the chosen action, sync the draft, and repeat.
No tool makes picks or other changes in Sleeper.
## During the season
Refresh inputs each week, then use the lineup, waiver, trade, value-change, simulation, and season
strategy tools as needed. Record actions and outcomes so calibration reports can evaluate the
system prospectively.
Create a transactionally consistent backup with:
```bash
uv run --env-file .env ff2026-backup
```
## Development
```bash
uv run ruff format --check .
uv run ruff check .
uv run mypy
uv run pytest
```
Detailed design and contracts:
- [Architecture](docs/architecture.md)
- [Data model](docs/data-model.md)
- [MCP tool surface](docs/mcp-tools.md)
- [Implementation plan](docs/implementation-plan.md)
- [Architecture decision](docs/decisions/0001-python-sqlite-modular-monolith.md)
Additional data sources must be licensed for your use. Boris-style tiers are treated as a
FantasyPros-derived benchmark, not as independent evidence.
TDQS
Scored across 33 tools
Most tools target distinct resources and actions, but the multiple sync_* variants (sync_league, sync_draft, sync_league_history, sync_fantasypros, sync_sleeper_market) and refresh_decision_inputs create potential confusion about which synchronization to call for a given task. Descriptions mitigate this, but boundaries are not always obvious.
All tool names use a consistent snake_case verb_noun pattern (e.g., get_draft_state, sync_league, recommend_draft_pick), with no convention mixing. The pattern is predictable and helps agents infer functionality.
With 33 tools, the server exceeds the 25-tool threshold for a typical MCP server. While the fantasy football domain is broad, many sync and decision-recording tools could be consolidated, making the surface unnecessarily large.
The tool set covers the full fantasy football decision lifecycle, from data ingestion and state synchronization to analysis, recommendations, and outcome recording. Minor gaps exist such as no transaction execution or lineup setting, but these appear deliberately excluded from the server's decision-support scope.