Model Context Protocol server for live & historical sports stats and odds via ESPN.
Runs on your machine from its package; the steps are below.
At most: only reads or looks up information.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted โ your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
uvx mcp-server-espn
MCP client config
{
"mcpServers": {
"espn": {
"command": "uvx",
"args": [
"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.
Important
Community Project Disclaimer
mcp-server-espn is 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.
Autonomous sports analysis requires high-velocity, structured, and resilient data feeds:
mcp-server-espn provides a unified, hardened Model Context Protocol interface directly to ESPN's public sports data endpoints.
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
mcp-server-espn implements canonical FastMCP 4 Server Composition via root.mount(..., namespace="..."):
espn-games (games_*), espn-teams (teams_*), and espn-news (news_*).ParentAuditMiddleware (timing logs, audit trails, and secret scrubbing) and ReadOnlyGateMiddleware (fail-closed read-only enforcement).GamesDomainGuardMiddleware (query limit validation <= 100) and TeamsDomainGuardMiddleware (team and athlete identifier validation).--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.tools/list by default for seamless client compatibility, while enabling regex search transforms via --enable-tool-search (ESPN_MCP_ENABLE_TOOL_SEARCH).games_get_scoreboard(sport="football", league="nfl") to identify close games in the 2nd half.games_get_game_situation(sport="football", league="nfl", event_id="401872947") and games_get_win_probabilities(sport="football", league="nfl", event_id="401872947") to inspect down/distance, red zone state, and live win expectancy curve.games_get_play_by_play(sport="football", league="nfl", event_id="401872947") for drive-by-drive sequencing and scoring event logs.teams_get_athlete_bio(sport="football", league="nfl", athlete_id="12483") to retrieve draft capital, college pedigree, and physical metrics.teams_get_athlete_gamelog and teams_get_athlete_splits to analyze performance trends against specific defensive schemes and venue conditions.games_get_leaders_by_athlete(sport="football", league="nfl", category="passing", sort="yards") to evaluate percentile rankings.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 |
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 | Live scores, state (pre/in/post), period/clock, TV broadcasts, starting probables. |
| 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 | Full regular season and postseason schedule with historical game results and scores. |
| Games | games_get_standings | sport, league, season | Division, conference, and overall league standings, win-loss records, games back, and win percentages. |
| 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 | League-wide calendar of scheduled events, optionally filtered by 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. |
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).
pip or uv# Using pip
pip install mcp-server-espn
# Using uv
uv add mcp-server-espn
docker run --rm -i ghcr.io/christianclaudio/mcp-server-espn:latest
| 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 with jittered exponential backoff |
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 regex search transform |
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
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
}
}
}
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
}
}
}
Add to .cursor/mcp.json:
{
"mcpServers": {
"espn": {
"command": "uvx",
"args": ["--from", "mcp-server-espn", "espn-mcp"]
}
}
}
Add to cline_mcp_settings.json or .vscode/settings.json:
{
"mcpServers": {
"espn": {
"command": "uvx",
"args": ["--from", "mcp-server-espn", "espn-mcp"]
}
}
}
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 ...
When developing, hardening, or extending MCP servers, consult the official framework and protocol references:
https://gofastmcp.com/llms.txt โ Server composition (mount), hierarchical middleware, transforms (ToolTransform, ToolSearch), lifespans, and in-memory test clients.https://modelcontextprotocol.io/llms.txt โ Official Spec (2026-07-28), wire-level JSON-RPC schemas, annotations, and transport framing.Connect your AI coding agent directly to live documentation servers:
https://gofastmcp.com/mcp (Tools: search_fast_mcp, query_docs_filesystem_fast_mcp, submit_feedback)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" }
}
}
# 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
Distributed under the Apache-2.0 License.