Sports MCP Server - ESPN MCP for Scores, Injuries & Odds
Pricing
from $7.30 / 1,000 tool call answereds
Sports MCP Server - ESPN MCP for Scores, Injuries & Odds
Sports MCP server for Claude, Cursor and AI agents: live ESPN scores, injury reports, betting odds with line movement, standings, team schedules and news for NFL, NBA, MLB, NHL, WNBA, college and top soccer leagues. Pay per successful tool call; failed calls and empty answers are free.
Pricing
from $7.30 / 1,000 tool call answereds
Rating
0.0
(0)
Developer
NeverEmpty
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
a day ago
Last modified
Categories
Share
Give Claude, Cursor or your own AI agent live sports data in one connection. This Sports MCP server answers questions like "Who is out for the Chiefs on Monday?", "How far has the Broncos-Chiefs total moved since it opened?" or "Show me the Premier League table" straight from ESPN's public data, with no ESPN API key and nothing to host.
Built for:
- Sports betting research - bookmaker spreads, totals and moneylines with the opening line and how far each line has moved, next to the injury report that moved it.
- Fantasy and sports analytics - injury status with the latest analyst note, standings, team schedules and results as clean JSON.
- AI agents and chat assistants - seven small tools with short, token-efficient answers and plain-English error messages your agent can act on.
Leagues: NFL, NBA, MLB, NHL, WNBA, NCAA Football, NCAA Men's Basketball, Premier League, LALIGA, Bundesliga, Serie A, Ligue 1, MLS and the UEFA Champions League.
What makes this ESPN MCP server different
- Injury reports are a tool of their own. Every NFL, NBA, MLB, NHL and WNBA injury on ESPN with status (Out, Questionable, Day-To-Day, Injured Reserve), the ESPN athlete id and the latest analyst note, most recent first.
- Line movement, not just the line. For each upcoming game the odds tool returns the current spread, total and moneylines and the opening numbers, plus
spreadMove,totalMoveandfavoriteFlipped. Upcoming games are read first and finished games are skipped (ask withincludeFinishedfor closing lines). In-game lines (for example "DraftKings - Live Odds") are markedisLive: trueand carry no opening-line movement, because comparing a live line with the pre-game opener means nothing. MLB odds that are missing from ESPN's scoreboard are read from ESPN's per-game odds feed, so baseball lines are not silently dropped. - You pay only when you get what you asked for. A failed call (ESPN refused or did not answer), an invalid argument, an empty answer ("no games today", "no odds posted yet", "no injuries for that team") and a scoreboard for a different day than the one you asked for are not charged.
list_leaguesis always free. - "Today" means today. Game dates are the US Eastern game day, so a Sunday night kick-off at 00:20 UTC is still dated Sunday. When you ask for today's scoreboard and there are no games, ESPN shows its next game day instead; the answer starts with "No NBA games today (2026-09-13, US Eastern); ESPN's next games are on ..." and is not charged.
- No silent empty results. ESPN answers some league and feed combinations with an empty 200 response (for example injuries for any soccer league). That looks like "nobody is injured" but means "no feed". This server refuses those combinations up front and says why, instead of returning an empty list as if it were a fact.
- Scores are
nullbefore kick-off, never0, so an unplayed game never reads as a 0-0 draw.
Connect
MCP endpoint (Streamable HTTP):
https://neverempty--sports-mcp-server.apify.actor/mcp
Authenticate with your Apify API token (Apify Console → Settings → API & Integrations), either as a header Authorization: Bearer <APIFY_TOKEN> or as ?token=<APIFY_TOKEN> on the URL. Both forms were checked against the live server on 2026-09-14; a request with no token is rejected by Apify.
Claude Code
$claude mcp add --transport http sports https://neverempty--sports-mcp-server.apify.actor/mcp --header "Authorization: Bearer <APIFY_TOKEN>"
Claude Desktop (claude_desktop_config.json, via the mcp-remote bridge). The token goes in env and the header is written Authorization:${AUTH_HEADER} with no space after the colon: this is the workaround the mcp-remote README gives for Claude Desktop on Windows (and Cursor), which do not escape spaces inside args.
{"mcpServers": {"sports": {"command": "npx","args": ["-y", "mcp-remote", "https://neverempty--sports-mcp-server.apify.actor/mcp", "--header", "Authorization:${AUTH_HEADER}"],"env": { "AUTH_HEADER": "Bearer <APIFY_TOKEN>" }}}}
Cursor (.cursor/mcp.json) and other clients that accept a URL with headers
{"mcpServers": {"sports": {"url": "https://neverempty--sports-mcp-server.apify.actor/mcp","headers": { "Authorization": "Bearer <APIFY_TOKEN>" }}}}
Any MCP client - if your client only takes a URL, use https://neverempty--sports-mcp-server.apify.actor/mcp?token=<APIFY_TOKEN>. Keep that URL private: it contains your token.
The server is stateless: every request is answered on its own, so it works with clients that do not keep a session.
Tools
Every tool returns two text parts: a one-line summary for the model to read, then compact JSON.
| Tool | Arguments | Leagues | Charged |
|---|---|---|---|
list_leagues | none | all 14 | never |
get_scoreboard | league, date (YYYY-MM-DD US Eastern; omit for today, or the current week for nfl / ncaaf), limit (1-200, default 100) | all 14 | when games are returned for the day you asked for |
get_injuries | league, team, status (e.g. Out), limit (1-500, default 50) | nfl, nba, mlb, nhl, wnba | when reports are returned |
get_odds | league, date, team, maxGames (1-20, default 8), includeFinished (default false) | nfl, nba, mlb, nhl | when at least one line is returned |
get_standings | league, team (optional) | nfl, nba, mlb, nhl, wnba, ncaaf, epl, laliga, bundesliga, mls | when teams are returned |
get_news | league, limit (1-50, default 10) | nfl, nba, mlb, nhl, wnba, ncaaf, epl, laliga | when articles are returned |
get_team_schedule | league, team, season (e.g. 2025), seasonType (preseason / regular / postseason), which (upcoming / completed / all), limit - each game has start time, home team, away team, season type, state, score and winner | nfl, nba, mlb, nhl, wnba, epl | when games are returned |
League keys: nfl, nba, mlb, nhl, wnba, ncaaf, ncaab, epl, laliga, bundesliga, seriea, ligue1, mls, ucl. How team is matched: an exact abbreviation, ESPN team id, full name, city or nickname wins (KC, Chiefs, Brooklyn Nets, Texas). Otherwise the words you give must appear as whole words in the team name (Kansas City). Parts of words never match, so Nets never matches Charlotte Hornets and NE never matches Tennessee. When several teams qualify, only the exact matches are kept, so Texas returns Texas Longhorns, not Texas Tech or Texas A&M (ask for those by name).
Example output (real calls to the live server, 2026-09-14)
get_injuries { "league": "nfl", "team": "KC", "limit": 5 }
NFL: 800 injury report(s) on ESPN, 25 for team "KC"; 5 most recent returned. Status: Active 20, Out 3, Injured Reserve 2.{"league":"nfl","teamsInFeed":32,"reportsTotal":800,"reportsMatched":25,"injuries":[{"athlete":"Chris Jones","athleteId":"3044859","team":"Kansas City Chiefs","teamAbbreviation":"KC","position":"DT","status":"Active","reportedAt":"2026-09-12T19:46:00.000Z","comment":"Jones (calf) does not have an injury designation ahead of Monday night's game against the Broncos."}, ...]}
get_odds { "league": "nfl", "team": "KC" }
NFL: 1 line(s) from 1 game(s). Upcoming games first. Moneylines are American odds; *Move columns are current minus opening line.{"odds":[{"game":"DEN @ KC","startTime":"2026-09-15T00:15:00.000Z","state":"pre","provider":"DraftKings","isLive":false,"details":"KC -2.5","spread":-2.5,"overUnder":43.5,"homeMoneyLine":-135,"awayMoneyLine":114,"openSpread":-2.5,"openOverUnder":42.5,"spreadMove":0,"totalMove":1,"favoriteFlipped":false}]}
get_scoreboard { "league": "nfl" }
NFL: 16 game(s) (post 10, in 4, pre 2). Scores are null before a game starts, never 0.{"gamesTotal":16,"games":[{"gameId":"401872928","state":"in","status":"In Progress","startTimeUtc":"2026-09-13T20:25Z","homeTeam":"Las Vegas Raiders","awayTeam":"Miami Dolphins","homeScore":27,"awayScore":13,"venue":"Allegiant Stadium","period":4}, ...]}
get_standings { "league": "epl" }
Premier League standings 2026-27 English Premier League: 20 team(s) in 1 group(s).{"standings":[{"teamId":"359","team":"Arsenal","abbreviation":"ARS","wins":4,"losses":0,"ties":0,"gamesPlayed":4,"points":12,"rank":1,"pointsFor":8,"pointsAgainst":1,"pointDifferential":7,"note":"Champions League"}, ...]}
get_team_schedule { "league": "mlb", "team": "NYY", "which": "completed", "limit": 3 }
New York Yankees 2026 Regular Season: 166 game(s) on ESPN, 3 completed returned, record 86-63.{"games":[{"shortName":"NYM @ NYY","state":"post","status":"Final","homeScore":6,"awayScore":4,"winner":"New York Yankees","venue":"Yankee Stadium"}, ...]}
An error tells the model what failed and that nothing was charged, for example:
ESPN does not recognise team "zzz" in NFL (HTTP 400: Bad request for team with value: zzz). Use the team abbreviation (for example KC) or the numeric teamId from get_standings. This call was not charged.
Measured on the Apify platform (2026-09-14)
- Every ESPN request made from the Apify network in the checks above answered HTTP 200 without a proxy.
- The full NFL injury feed is an 8.86 MB response; the tool answered in 641 ms once the server was running.
- The other tools answered in 194-305 ms. The first request after the server has been idle waits for it to start (about 5 seconds in our check).
Pricing
Pay per event: $0.01 per successful tool call on the Apify Free plan, lower on paid Apify plans (down to $0.007). Calls that return no data, scoreboards for a different day than the one asked for, calls ESPN refused or could not answer, invalid arguments and list_leagues are not charged. If your run has a maximum total charge, the server counts calls that are still in progress against it and refuses a call before contacting ESPN once the limit would be reached, so several simultaneous calls cannot go over the limit.
Starting the Actor normally (the Start button in Apify Console, the API, or a schedule) does not start a long-running server. The run asks ESPN for the NFL scoreboard once, writes a single health-check row (status, the MCP URL, the tool list and ESPN's answer) and finishes in a few seconds. That run is not charged. To use the tools, connect an MCP client to the URL above.
Limits and what is not included
- Not an official ESPN product. Data comes from ESPN's public site endpoints and can change or disappear without notice.
- Odds cover NFL, NBA, MLB and NHL only, from the bookmaker(s) ESPN lists for each game (often a single provider). Each game is one ESPN request, so
maxGamesis capped at 20; passteamfor a single game. No historical line archive. - Injuries cover NFL, NBA, MLB, NHL and WNBA. ESPN publishes no injury feed for soccer or college basketball, and its college football feed held only three reports dated 2020-2022 when we checked on 2026-09-14, so college football injuries are not offered.
- Soccer team schedules need ESPN's numeric team id (Arsenal is
359); take it fromget_standings. Abbreviations are rejected by ESPN. - News returns headlines, summaries, tags and links, not full article text. ESPN serves at most 50 articles.
- Not included: play-by-play, box scores, player season stats and game logs, rankings, search, and leagues not listed above.
- A league and tool combination that is not listed is refused rather than guessed.
Support
Found a wrong number or a league you need? Open an issue in the Issues tab of this Actor with the tool name, the arguments and what you expected.