io.github.christianclaudio/espn
Model Context Protocol server for live & historical sports stats and odds via ESPN.
Installation
Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).
mcp-server-espnclaude mcp add espn -e 'ESPN_BASE_URL=https://site.web.api.espn.com' -e 'ESPN_TIMEOUT_SECONDS=30.0' -e 'ESPN_MAX_RETRIES=3' -e 'ESPN_MCP_READONLY=0' -e 'ESPN_MCP_PROFILE=full' -e 'ESPN_MCP_ENABLE_TOOL_SEARCH=0' -e 'ESPN_MCP_TOOL_SEARCH_BACKEND=bm25' -- uvx mcp-server-espn==2.1.1
{
"mcpServers": {
"espn": {
"command": "uvx",
"args": [
"mcp-server-espn==2.1.1"
],
"env": {
"ESPN_BASE_URL": "https://site.web.api.espn.com",
"ESPN_TIMEOUT_SECONDS": "30.0",
"ESPN_MAX_RETRIES": "3",
"ESPN_MCP_READONLY": "0",
"ESPN_MCP_PROFILE": "full",
"ESPN_MCP_ENABLE_TOOL_SEARCH": "0",
"ESPN_MCP_TOOL_SEARCH_BACKEND": "bm25"
}
}
}
}
Variables d'environnement
ESPN_BASE_URLOptional REST base URL overrideESPN_TIMEOUT_SECONDSHTTP request timeout in secondsESPN_MAX_RETRIESMaximum retry attempts on HTTP 429 / 5xxESPN_MCP_READONLYRestrict server execution strictly to read-only inspection toolsESPN_MCP_PROFILEServer domain profile (full, games, teams, news, readonly)ESPN_MCP_ENABLE_TOOL_SEARCHReplace flat tool catalog with dynamic search transformESPN_MCP_TOOL_SEARCH_BACKENDTool Search backend: bm25 (default) or regex
Documentation
Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.
Sommaire
- 🏈 mcp-server-espn
- ⚠️ Disclaimers & Fair Use Notice
- 💡 Why This Exists
- 🏟️ System Architecture
- 🚀 FastMCP 4 Server Composition
- 📈 Sports Intelligence Workflows
- 🏟️ Supported Sports & Leagues Reference Matrix
- 📊 Tool Suite (33 Domain Tools)
- 🏃 Quickstart & Installation
- 🎛️ Engine Configuration
- 🎮 Client Integration Guides
- 📚 Canonical Documentation & Live Doc MCPs
- 🏆 Verification & Quality Gates
- 📜 License
🏈 mcp-server-espn
Enterprise-grade Model Context Protocol (MCP) server for live and historical sports analytics, consensus betting odds, and predictions via ESPN.
Equips AI agents with real-time sports intelligence, live win probabilities, in-depth boxscore statistics, roster hierarchies, and matchup analytics.
⚠️ Disclaimers & Fair Use Notice
[!IMPORTANT] Community Project Disclaimer
mcp-server-espnis an independent open-source community project. It is not affiliated with, sponsored by, endorsed by, or supported by ESPN Inc. or The Walt Disney Company. "ESPN" is a trademark of ESPN Inc. All data provided via ESPN's public REST endpoints is intended for educational, research, and personal non-commercial use.
💡 Why This Exists
Autonomous sports analysis requires high-velocity, structured, and resilient data feeds:
- Live Game State & Win Probability: Real-time game events (turnovers, scoring plays, pitching changes) shift momentum and expected outcomes dynamically.
- Key Player Injuries & Depth Chart Swaps: An in-game injury or substitution fundamentally alters team efficiency and tactical matchups.
- Consensus Odds & Predictive Models: Aggregating consensus sportsbook lines (DraftKings, Caesars, ESPN BET) alongside predictive metrics (FPI, BPI) powers deep statistical game evaluations.
mcp-server-espn provides a unified, hardened Model Context Protocol interface directly to ESPN's public sports data endpoints.
🏟️ System Architecture
graph TD
Client["AI Agent / MCP Client<br>(Antigravity, Claude, Codex, Cortex)"]
Gateway["Root FastMCP Gateway (espn-mcp)<br>(stdio / Streamable HTTP)"]
ParentMW["Parent Middleware Pipeline<br>(ParentAuditMiddleware & ReadOnlyGateMiddleware)"]
GamesSub["Sub-Server: espn-games<br>(games_* | GamesDomainGuard)"]
TeamsSub["Sub-Server: espn-teams<br>(teams_* | TeamsDomainGuard)"]
NewsSub["Sub-Server: espn-news<br>(news_* | Resources)"]
ClientHandler["Hardened ESPN AsyncClient<br>(Connection Pool & 429 Jitter Backoff)"]
ESPN["ESPN Public REST CDN<br>(https://site.web.api.espn.com)"]
Client <-->|"JSON-RPC (tools/list, tools/call)"| Gateway
Gateway --> ParentMW
ParentMW --> GamesSub
ParentMW --> TeamsSub
ParentMW --> NewsSub
GamesSub & TeamsSub & NewsSub <-->|"API Methods"| ClientHandler
ClientHandler <-->|"HTTPS REST Mirror"| ESPN
🚀 FastMCP 4 Server Composition
mcp-server-espn implements canonical FastMCP 4 Server Composition via root.mount(..., namespace="..."):
- Domain Sub-Servers: Partitioned into
espn-games(games_*),espn-teams(teams_*), andespn-news(news_*). - Hierarchical Middleware:
- Parent:
ParentAuditMiddleware(timing logs, audit trails, and secret scrubbing) andReadOnlyGateMiddleware(fail-closed read-only enforcement). - Child:
GamesDomainGuardMiddleware(query limit validation <= 100) andTeamsDomainGuardMiddleware(team and athlete identifier validation).
- Parent:
- Focused Profiles: Run lightweight surfaces via
--profile full|games|teams|news|readonly(ESPN_MCP_PROFILE):full(default): All 33 domain tools and resources mounted.games: Scores, summaries, schedules, standings, rankings, transactions, league leaders, draft, live play-by-play, situations, odds, probabilities, predictor, calendar, futures, power index (20 tools).teams: Rosters, depth charts, player stats, athlete profiles, bio, stats, gamelog, splits, search, list teams, team detail, team statistics (12 tools).news: League news and reference resources (1 tool).readonly: Read-only enforcement across all routes.
- Opt-In Tool Search: Preserves standard flat
tools/listby default for seamless client compatibility, while enabling search transforms via--enable-tool-search(ESPN_MCP_ENABLE_TOOL_SEARCH): BM25 ranking for natural-language queries by default (search_toolstakes aquery), or regex patterns with--tool-search-backend regex(ESPN_MCP_TOOL_SEARCH_BACKEND=regex;search_toolstakes apattern).
📈 Sports Intelligence Workflows
Workflow 1: Live In-Game Win Probability & Situation Tracking
- Poll Active Games: Agent calls
games_get_scoreboard(sport="football", league="nfl")to identify close games in the 2nd half. - Fetch In-Game Situation & Win Probability: Call
games_get_game_situation(sport="football", league="nfl", event_id="401872947")andgames_get_win_probabilities(sport="football", league="nfl", event_id="401872947")to inspect down/distance, red zone state, and live win expectancy curve. - Inspect Play-by-Play: Call
games_get_play_by_play(sport="football", league="nfl", event_id="401872947")for drive-by-drive sequencing and scoring event logs.
Workflow 2: Athlete Deep Dive & Fantasy Valuation
- Bio & Career Context: Call
teams_get_athlete_bio(sport="football", league="nfl", athlete_id="12483")to retrieve draft capital, college pedigree, and physical metrics. - Recent Gamelog & Splits: Pull
teams_get_athlete_gamelogandteams_get_athlete_splitsto analyze performance trends against specific defensive schemes and venue conditions. - League-Wide Leaderboard Standing: Call
games_get_leaders_by_athlete(sport="football", league="nfl", category="passing", sort="yards")to evaluate percentile rankings.
🏟️ Supported Sports & Leagues Reference Matrix
The server supports canonical sport/league slug pairs and auto-normalizes popular shortcuts:
| Sport Slug | League Slug | Recognized Shortcuts / Aliases | Common Display Name |
|---|---|---|---|
football | nfl | nfl | National Football League |
football | college-football | cfb, ncaa-football, fbs | NCAA College Football |
basketball | nba | nba | National Basketball Association |
basketball | mens-college-basketball | cbb, ncaa-basketball | NCAA Men's College Basketball |
basketball | womens-college-basketball | wbb, ncaa-womens-basketball | NCAA Women's Basketball |
basketball | wnba | wnba | Women's National Basketball Association |
baseball | mlb | mlb | Major League Baseball |
hockey | nhl | nhl | National Hockey League |
soccer | eng.1 | epl, premier-league | English Premier League |
soccer | usa.1 | mls | Major League Soccer |
soccer | uefa.champions | ucl, champions-league | UEFA Champions League |
soccer | esp.1 | la-liga | Spanish La Liga |
soccer | ita.1 | serie-a | Italian Serie A |
soccer | ger.1 | bundesliga | German Bundesliga |
soccer | fra.1 | ligue-1 | French Ligue 1 |
📊 Tool Suite (33 Domain Tools)
All tools implement explicit MCP 2.0 annotations (readOnlyHint=True, idempotentHint=True):
| Domain | Tool | Parameters | Description |
|---|---|---|---|
| Games | games_get_scoreboard | sport, league, date, week, season_type, group, limit | Final scores and results for any date (date=YYYYMMDD) or inclusive date range (date=YYYYMMDD-YYYYMMDD; ranges of up to 31 days are fetched one day at a time, because ESPN rejects the range form on team-sport scoreboards, so limit applies to each day (up to 31 × limit events) and one failed day fails the whole call; golf ranges are sent to ESPN as is), plus live scores, state (pre/in/post), period/clock, TV broadcasts, starting probables. Returns event IDs for other game tools. |
| Games | games_get_game_summary | sport, league, event_id | Consensus betting lines, matchup predictor win %, ATS, scoring plays, drives, leaders, momentum. |
| Games | games_get_team_schedule | sport, league, team_id, season, season_type | Season schedule with historical game results and scores: the regular season by default, postseason games with season_type=3. |
| Games | games_get_standings | sport, league, season | Division, conference, and overall league standings, win-loss records, games back, and win percentages. season is the year the season ends (2016 = the 2015-16 NBA season), or the year it starts for soccer (2026 = the 2026-27 Premier League season); the response echoes requested_season, season, and season_display. |
| Games | games_get_rankings | sport, league | Top 25 national polls and rankings (AP Top 25, Coaches Poll, College Football Playoff). |
| Games | games_get_transactions | sport, league, limit | League-wide transactions, roster trades, waivers, signings, and releases. |
| Games | games_get_leaders_by_athlete | sport, league, limit, category, sort | Statistical leaderboards across players in a league. |
| Games | games_get_leaders_by_team | sport, league, limit, category, sort | Team statistical rankings and leaderboards. |
| Games | games_get_league_groups | sport, league | League conference, division, and structural group hierarchies. |
| Games | games_get_league_events | sport, league, dates | The league's current scheduled events. ESPN's events route ignores dates, so date filtering is not supported: a dates value returns isError: true with no request, pointing to games_get_scoreboard with the same value as date. |
| Games | games_get_league_draft | sport, league, season | League draft rounds, team selections, and pick results. |
| Games | games_get_scoreboard_header | sport, league | Live ticker scoreboard header data across games for a sport and league. |
| Games | games_get_event_odds | sport, league, event_id, competition_id | Sportsbook consensus and provider odds (spreads, totals, moneylines). |
| Games | games_get_play_by_play | sport, league, event_id, limit, page | Play-by-play sequence, clock, scoring, and drive events. |
| Games | games_get_game_situation | sport, league, event_id | Real-time in-game situation (down, distance, yardline, possession, red zone). |
| Games | games_get_win_probabilities | sport, league, event_id | Live and historical win probability curves across game progression. |
| Games | games_get_game_predictor | sport, league, event_id | Pre-game and in-game matchup predictor and projection metrics. |
| Games | games_get_calendar | sport, league, dates | League schedule calendar and active event dates across a season. |
| Games | games_get_futures | sport, league, season | Season futures betting markets (championship odds, win totals). |
| Games | games_get_power_index | sport, league, season | Team power index (FPI / BPI) ratings and efficiency metrics. |
| Teams | teams_search | query, type, limit | Global search for athletes and teams by name/keyword (type="player" or "team"). |
| Teams | teams_list_teams | sport, league | Directory of all franchises/teams in a specified league with IDs, names, and logos. |
| Teams | teams_get_team | sport, league, team_id | Team detail overview, venue, record, standings summary, and upcoming scheduled event. |
| Teams | teams_get_team_statistics | sport, league, team_id | Comprehensive team and opponent statistical category splits (passing, rushing, etc.). |
| Teams | teams_get_team_roster | sport, league, team_id | Full active roster grouped by position, coach info, jersey numbers, and injury status. |
| Teams | teams_get_team_depth_chart | sport, league, team_id | Positional starter/backup hierarchy (QB1, QB2, etc.) to model injury substitution impacts. |
| Teams | teams_get_player_stats | sport, league, event_id | Boxscore statistics for individual athletes across game categories. |
| Teams | teams_get_athlete_overview | sport, league, athlete_id | Athlete biographical info, season/career stats, game logs, next game, and rotowire notes. |
| Teams | teams_get_athlete_bio | sport, league, athlete_id | Detailed athlete background, draft history, birth details, college pedigree. |
| Teams | teams_get_athlete_stats | sport, league, athlete_id, season | Full seasonal and career category statistics for an athlete. |
| Teams | teams_get_athlete_gamelog | sport, league, athlete_id, season | Game-by-game performance log for an athlete across a season. |
| Teams | teams_get_athlete_splits | sport, league, athlete_id, season | Situational statistical splits (home/away, turf/grass, monthly, vs opponents). |
| News | news_get_news | sport, league, limit | Recent news headlines, injury designations, and breaking roster analysis. |
🏃 Quickstart & Installation
1. Run Directly via uvx (Zero Install)
Console scripts in [project.scripts] both call espn_mcp.server:main: espn-mcp (used below) and mcp-server-espn. Install examples stay unpinned. To freeze a release, pin the version from Releases.
uvx --from mcp-server-espn espn-mcp
After an upgrade, reload the MCP host so the live process start time is after the new binary mtime (stale process ≠ new package).
2. Install via pip or uv
# Using pip
pip install mcp-server-espn
# Using uv
uv add mcp-server-espn
3. Run via Docker
docker run --rm -i ghcr.io/christianclaudio/mcp-server-espn:latest
🎛️ Engine Configuration
| Variable | CLI Flag | Default | Description |
|---|---|---|---|
ESPN_BASE_URL | — | https://site.web.api.espn.com | Target ESPN REST CDN base URL (bypasses Akamai TLS filter) |
ESPN_TIMEOUT_SECONDS | — | 30.0 | HTTP request timeout in seconds |
ESPN_MCP_AUTH_TOKEN | — | unset | Shared bearer token required on HTTP transports (stdio ignores it) |
ESPN_MCP_ALLOW_UNAUTHENTICATED_BIND | — | unset | 1 accepts a tokenless HTTP bind to a non-localhost host |
ESPN_MAX_RETRIES | — | 3 | Maximum retry attempts on 429 / 5xx with jittered exponential backoff, waiting longer when Retry-After asks (capped at ESPN_TIMEOUT_SECONDS) |
ESPN_MCP_READONLY | — | 0 | Restrict server strictly to read-only inspection tools |
ESPN_MCP_PROFILE | --profile | full | Domain sub-server profile: full, games, teams, news, readonly |
ESPN_MCP_ENABLE_TOOL_SEARCH | --enable-tool-search | 0 | Replace flat tool catalog with dynamic search transform (search_tools + call_tool) |
ESPN_MCP_TOOL_SEARCH_BACKEND | --tool-search-backend | bm25 | Tool Search backend: bm25 (BM25SearchTransform, natural-language ranking; search_tools takes query) or regex (RegexSearchTransform, regex patterns; search_tools takes pattern) |
🎮 Client Integration Guides
🧡 Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"espn": {
"command": "uvx",
"args": ["--from", "mcp-server-espn", "espn-mcp"],
"env": {
"ESPN_TIMEOUT_SECONDS": "20.0"
}
}
}
}
For Claude Code CLI:
claude mcp add espn -- uvx --from mcp-server-espn espn-mcp
♊ Google Antigravity & Gemini CLI
Add to .agents/mcp_config.json or ~/.gemini/config/mcp_config.json:
{
"mcpServers": {
"espn": {
"command": "uvx",
"args": ["--from", "mcp-server-espn", "espn-mcp"],
"env": {
"ESPN_TIMEOUT_SECONDS": "20.0"
},
"lazy": true
}
}
}
❄️ Snowflake Cortex
Add to ~/.snowflake/cortex/mcp.json:
{
"mcpServers": {
"espn": {
"command": "uvx",
"args": ["--from", "mcp-server-espn", "espn-mcp"],
"env": {
"ESPN_TIMEOUT_SECONDS": "20.0"
},
"lazy": true
}
}
}
⚡ Cursor IDE
Add to .cursor/mcp.json:
{
"mcpServers": {
"espn": {
"command": "uvx",
"args": ["--from", "mcp-server-espn", "espn-mcp"]
}
}
}
💻 VS Code (Cline / Roo Code / Copilot Agent Mode)
Add to cline_mcp_settings.json or .vscode/settings.json:
{
"mcpServers": {
"espn": {
"command": "uvx",
"args": ["--from", "mcp-server-espn", "espn-mcp"]
}
}
}
🌐 Local HTTP / Network Transport Mode
Launch the FastMCP server over modern Streamable HTTP:
uvx --from mcp-server-espn espn-mcp --transport streamable-http --host 127.0.0.1 --port 8000
Connect Streamable HTTP clients to http://127.0.0.1:8000/mcp (FastMCP's default Streamable HTTP path).
In the default (stateful) HTTP mode, a session idle for 30 minutes expires: its next request gets HTTP 404 and the client must start a new session. Change this with FastMCP's session_idle_timeout (on http_app()) or FASTMCP_HTTP_SESSION_IDLE_TIMEOUT (seconds, or none to never expire); see the FastMCP 4.1.0 release and #5229.
HTTP authentication. Set ESPN_MCP_AUTH_TOKEN to require Authorization: Bearer <token> on every HTTP request; a missing or wrong token gets 401. The token is stripped, and a blank value counts as unset. It is attached when the server is built, so espn-mcp, fastmcp run and an ASGI host mounting mcp.http_app() all enforce it. stdio never uses it.
With no token, espn-mcp refuses an HTTP bind to any host other than 127.0.0.1, ::1 or localhost and exits with code 2. Set the token, bind to localhost, or set ESPN_MCP_ALLOW_UNAUTHENTICATED_BIND=1 to accept an unauthenticated public bind. Other entry points get the token but not the localhost check: fastmcp run and http_app() do not go through espn-mcp's main(), so a bind to 0.0.0.0 with no token there is not refused and serves without authentication. The host or its process manager owns the bind address, so set ESPN_MCP_AUTH_TOKEN there.
To serve the image over HTTP, pass the token from your shell or an env file (never a fixed value) and name the public host clients use:
PUBLIC_HOST=mcp.example.com # the host name clients use
export ESPN_MCP_AUTH_TOKEN="$(openssl rand -hex 32)" # or keep it in an env file
docker run --rm -p 8000:8000 -e ESPN_MCP_AUTH_TOKEN \
ghcr.io/christianclaudio/mcp-server-espn:latest \
--transport streamable-http --host 0.0.0.0 --allowed-host "$PUBLIC_HOST"
# with an env file instead: docker run --rm -p 8000:8000 --env-file espn.env ...
📚 Canonical Documentation & Live Doc MCPs
When developing, hardening, or extending MCP servers, consult the official framework and protocol references:
- FastMCP 4 Framework Reference:
https://gofastmcp.com/llms.txt— Server composition (mount), hierarchical middleware, transforms (ToolTransform,ToolSearch), lifespans, and in-memory test clients. - Model Context Protocol Specification:
https://modelcontextprotocol.io/llms.txt— Official Spec (2026-07-28), wire-level JSON-RPC schemas, annotations, and transport framing.
Live Documentation MCP Endpoints (SSE / Streamable HTTP)
Connect your AI coding agent directly to live documentation servers:
- FastMCP Documentation Server:
https://gofastmcp.com/mcp(Tools:search_fast_mcp,query_docs_filesystem_fast_mcp,submit_feedback) - Anthropic MCP Documentation Server:
https://modelcontextprotocol.io/mcp(Tools:search_model_context_protocol,query_docs_filesystem_model_context_protocol,submit_feedback)
{
"mcpServers": {
"fastmcp-docs": { "type": "sse", "url": "https://gofastmcp.com/mcp" },
"mcp-official-docs": { "type": "sse", "url": "https://modelcontextprotocol.io/mcp" }
}
}
🏆 Verification & Quality Gates
# Run unit test suite (100% statement coverage enforced)
pytest
# Static type safety & formatting
mypy --strict src/
ruff check --fix .
ruff format .
# Tool contract, drift & protocol conformance audits
python scripts/check_tool_contract.py
python scripts/check_openapi_drift.py
./scripts/check_conformance.sh
📜 License
Distributed under the Apache-2.0 License.
Questions fréquentes
Qu'est-ce que io.github.christianclaudio/espn ?
Model Context Protocol server for live & historical sports stats and odds via ESPN.
Comment installer io.github.christianclaudio/espn ?
Il s'exécute sur votre machine. Dans Claude Code : claude mcp add espn -e 'ESPN_BASE_URL=https://site.web.api.espn.com' -e 'ESPN_TIMEOUT_SECONDS=30.0' -e 'ESPN_MAX_RETRIES=3' -e 'ESPN_MCP_READONLY=0' -e 'ESPN_MCP_PROFILE=full' -e 'ESPN_MCP_ENABLE_TOOL_SEARCH=0' -e 'ESPN_MCP_TOOL_SEARCH_BACKEND=bm25' -- uvx mcp-server-espn==2.1.1. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.
Faut-il une clé API pour io.github.christianclaudio/espn ?
Son entrée au registre n'indique aucune clé ni secret obligatoire. Certaines fonctions peuvent tout de même demander un compte auprès du service auquel il se connecte.
io.github.christianclaudio/espn est-il open source ?
Oui. Son code est sur GitHub sous licence Apache-2.0.
Qui maintient io.github.christianclaudio/espn ?
Il est publié par christianclaudio. AI.tn le référence sans le maintenir ni le recommander.
Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.