Get live scores, schedules, standings, team and player data for NFL, NBA, MLB, NHL, and soccer.
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
npx -y @cyanheads/sports-mcp-server
MCP client config
{
"mcpServers": {
"sports": {
"command": "npx",
"args": [
"-y",
"@cyanheads/sports-mcp-server"
]
}
}
}Run
npx -y @cyanheads/sports-mcp-server
MCP client config
{
"mcpServers": {
"sports": {
"command": "npx",
"args": [
"-y",
"@cyanheads/sports-mcp-server"
]
}
}
}Get live scores, schedules, standings, team and player data for NFL, NBA, MLB, NHL, soccer, and more via MCP. STDIO or Streamable HTTP.
Live and historical sports data from ESPN, MLB StatsAPI, and TheSportsDB. Check scores, schedules, and standings, and look up teams and players across the NFL, NBA, MLB, NHL, major soccer leagues, and college football and basketball.
| Tool | Description |
|---|---|
sports_find_team | Resolve a team name or partial name to canonical records and source IDs across providers. |
sports_find_player | Resolve a player name to canonical TheSportsDB records with ID, team, position, and bio fields. |
sports_get_scores | Live and final scores for a league on a given date, optionally filtered by team. |
sports_get_game | Game metadata, period scores, team totals, provider top performers, and paged scoring plays. |
sports_get_schedule | Upcoming and past fixtures for a team or league over a date range. |
sports_get_standings | Current standings or league table for a league and season. |
sports_get_team | Team detail combining metadata, roster, recent results, and upcoming fixtures. |
sports_get_player | Player details from TheSportsDB — biography, team, position, and physical stats. |
sports_find_team toolquery (max 200 characters) with an optional league filterespnId/mlbId/tsdbId cross-references merged across providers; totalFound counts returned recordsunavailableSources; no results returns no_match, or sources_unavailable if a source failed. The free TheSportsDB key can return incomplete resultssports_find_player toolquery (max 200 characters); optional sport is advisory and does not filterno_match when none is found3 limits searches to one recordsports_get_scores toolleague required; date (YYYY-MM-DD) defaults to today in US Eastern time; optional team_name filters gamesreason, emptyReason (no_games or no_team_matches), and noticelimit defaults to 100 (max 200) and offset to 0; responses include availableGames, totalReturned, effectiveLimit, offset, truncated, and nextOffsetsports_get_schedule toolleague required; optional team_name, date_from/date_to, limit (default 100, max 200), and offset (default 0). A single date bound requests that day; reversed dates failteam_name must identify one team: ambiguous_team lists candidates, team_not_found means no matchrequestedDateFrom/requestedDateTo, servedDateFrom/servedDateTo, availableGames, effectiveLimit, offset, and truncated; follow nextOffset, then nextDateFrom as date_fromsports_get_game toolleague and source-prefixed numeric game_id from scores, schedules, or team detail; mlb: IDs require league: "mlb"periodScores, teamStats, leaders, and scoringPlays; missing values are null. Scheduled games return metadata only; game_not_found for a missing or wrong-league game. Athlete IDs belong to ESPN or MLB, not TheSportsDBlimit defaults to 20 (max 50) and offset to 0; responses include totalCount, returnedCount, servedFrom/servedTo, effectiveLimit, and nextOffsetsports_get_standings toolleague required; optional season (4-digit year), current season if omittedseason_not_found when the season has no datalimit defaults to 100 (max 200) and offset to 0; responses include availableStandings, totalReturned, effectiveLimit, offset, truncated, and nextOffset. If the MLB team lookup fails, unavailableSources lists standings_team_metadatasports_get_team toolleague and team_name required; exact names or abbreviations win, otherwise a partial name must identify one team (ambiguous_team lists candidates, team_not_found means no match)sports_get_player toolplayer_id accepts a tsdb:-prefixed ID (from sports_find_player) or a raw numeric TheSportsDB IDplayer_not_found when the ID doesn't resolveespnId is filled when TheSportsDB supplies one, otherwise nullBuilt on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Sports-specific:
3)NormalizedGame, NormalizedTeam, NormalizedPlayer, NormalizedStandingsports_find_teamgames: [] with a reason (scoreboards) instead of an errorAgent-friendly output:
source: 'espn' | 'mlbstats' | 'thesportsdb'no_match, sources_unavailable, team_not_found, ambiguous_team, player_not_found, season_not_found, game_not_found, incompatible_game_source), each with a recovery hintAdd the following to your MCP client configuration file.
{
"mcpServers": {
"sports": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/sports-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"sports": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/sports-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"sports": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/sports-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
3).git clone https://github.com/cyanheads/sports-mcp-server.git
cd sports-mcp-server
bun install
cp .env.example .env
# edit .env to override defaults (all optional)
| Variable | Description | Default |
|---|---|---|
THESPORTSDB_API_KEY | TheSportsDB API key. The free key limits searches to one record. | 3 |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_SESSION_MODE | HTTP session mode: stateful, stateless, or auto. | stateless |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
LOG_TOOL_FAILURE_PAYLOADS | Log failed tool arguments and results, redacted by key name and capped by LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES (default 16384). Free-form values are not redacted. | false |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. | false |
OTEL_EXPORTER_OTLP_ENDPOINT | Base OTLP/HTTP URL for traces and metrics. | Unset |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | OTLP log endpoint. | Unset |
See .env.example for the full list of optional overrides.
Serving commands execute Node, including when launched with bun run. Bun handles dependency resolution and build tooling; ESPN requests run under Node.
Build and run:
# One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
docker build -t sports-mcp-server .
docker run --rm -p 3010:3010 sports-mcp-server
The Dockerfile builds with Bun, runs the production server under Node, defaults to HTTP transport and stateless session mode, and logs to /var/log/sports-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools and inits services. |
src/config | Server-specific environment variable parsing (THESPORTSDB_API_KEY). |
src/services/types.ts | Normalized cross-source types and league routing table. |
src/services/espn | ESPN site API service — scores, schedules, standings, teams. |
src/services/mlb | MLB StatsAPI service — scores, schedules, standings, rosters. |
src/services/thesportsdb | TheSportsDB service — player and team search/metadata. |
src/mcp-server/tools | Tool definitions (*.tool.ts). |
tests/ | Unit and integration tests mirroring src/. |
docs/ | Design doc and directory tree. |
See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagesrc/mcp-server/tools/definitions/index.tsIssues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.