Pulls live scores, schedules, standings, and player/team data from ESPN, MLB StatsAPI, and TheSportsDB without requiring API keys. Seven tools handle the full workflow: fuzzy-match team or player names, fetch today's games, pull upcoming fixtures, check league tables, and retrieve full roster or bio details. Routes each sport to its best source internally (MLB goes to StatsAPI, everything else to ESPN), then normalizes the output so you get consistent game, team, and player objects regardless of upstream API. Returns empty arrays with reason strings when there's no data instead of throwing errors, which keeps agents from breaking on off-season queries. Built on the author's mcp-ts-core framework with support for both stdio and streamable HTTP transports.
THESPORTSDB_API_KEYdefault: 3TheSportsDB API key. Defaults to '3' (free public test key). Replace with a paid key for higher rate limits.
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.
Get live scores, schedules, standings, team and player data for NFL, NBA, MLB, NHL, soccer, and more via MCP. STDIO or Streamable HTTP.
Seven tools organized around what an agent needs — find a team or player, get today's scores, check the schedule, read the standings, or pull full team or player detail:
| Tool | Description |
|---|---|
sports_find_team | Resolve a team name or partial name to its canonical record and source IDs. Use before any team-scoped query. |
sports_find_player | Resolve a player name to their canonical record via TheSportsDB. Disambiguation step before player-scoped queries. |
sports_get_scores | Live and final scores for a league on a given date, optionally scoped to a specific team. |
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: active roster, last 5 results, next 3 fixtures, venue, and metadata. |
sports_get_player | Player detail: bio, current team, position, nationality, birth date, height/weight, and thumbnail. |
sports_find_teamResolve a fuzzy team name to its canonical record across ESPN, MLB StatsAPI, and TheSportsDB.
sports_get_scores, sports_get_schedule, sports_get_standings, or sports_get_team to get a valid team_namesports_find_playerResolve a player name to their canonical record.
sport filter to narrow ambiguous names (e.g. "Michael Jordan")player_id with sports_get_player for full bio detailsports_get_scoresLive and final scores for a league on a given date.
scheduled/in-progress/final), period/clock, and UTC start timedate for today's games; use team_name to filter to one team's gamegames: [], reason: '...' (not an error) when no games are scheduledsports_get_scheduleUpcoming and past fixtures for a team or league over a date range.
date_from/date_to filtering server-sideteam_name for the full league calendar; provide it for a single team's fixturessports_get_standingsCurrent standings or league table for a league and season.
season for the current season; pass a YYYY year for historical standingswins/otLosses/losses); soccer returns points for the league tablesports_get_teamComposite team detail combining multiple source calls.
sports_get_playerFull player profile from TheSportsDB.
tsdb:-prefixed IDs (from sports_find_player) or raw numeric TheSportsDB IDsBuilt on @cyanheads/mcp-ts-core:
none, jwt, oauthin-memory, filesystem, Supabase, Cloudflare KV/R2/D1Sports-specific:
3) — no API credentials requiredNormalizedGame, NormalizedTeam, NormalizedPlayer, NormalizedStanding — with source provenance on every recordgames: [] with a reason string, not an errorAgent-friendly output:
source: 'espn' | 'mlbstats' | 'thesportsdb' so agents can reason about data authorityreason field on empty score responses so agents can explain the result to userssports_find_team — espnId, mlbId, tsdbId — for seamless downstream routing without re-resolving namesAdd 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. Replace with a paid key for higher rate limits. | 3 |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
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 |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. | false |
See .env.example for the full list of optional overrides.
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 defaults to HTTP transport, 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 and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
com.mcparmory/google-sheets
domdomegg/google-sheets-mcp
henilcalagiya/google-sheets-mcp
cct15/war-dashboard-data
moooonad/mcp-google-sheets-full
io.github.br0ski777/csv-to-json