Skip to content

football-data-mcp

Verified

football-data-mcp · v0.1.2 · MIT

Data-provider MCP server for football: results, stats, odds, standings, form and head-to-head for 18 European leagues (1993-94 →) and 8 cup competitions, for any MCP client. Also a DeepSeek Harness (dsh) plugin.

Install

dsh plugin add football-data-mcp

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Readme

football-data-mcp

A data-provider MCP server for football: results, match stats, odds and derived analytics (standings, form, head-to-head) for 18 European leagues — seasons 1993-94 to today — served over stdio to any MCP client. Ships as a single npm package (npx entry + DeepSeek Harness plugin + embedded Python server); the intelligence lives in the calling agent.

Data sources

football-data.co.uk (base) ESPN scoreboard (enhancement)
Role Depth: 33 seasons of history + full odds Freshness: minute-level + cups
Coverage 18 leagues, 1993-94 → (E0 PL, SP1 La Liga, I1 Serie A, D1 Bundesliga, F1 Ligue 1, …) 8 cups (FA, LC, CDR, CI, DFB, CDF, UCL, UEL), ~2001 →
Per match score, HT score, referee, shots/corners/fouls/cards, ~20 bookmakers' 1X2 open+close, Pinnacle, O/U 2.5, Asian handicap score, kickoff, team stats, possession, assists
Freshness hours-to-a-day after full time minutes after full time, live state

The season provider merges both automatically: football-data rows win on conflicts (official stats + odds), ESPN fills freshness gaps (last night's matches, not-yet-published season files) and contributes possession/assists. Team names are canonicalized across sources (Man UnitedManchester United). Past seasons are cached forever; the current season revalidates with conditional GETs and fixture-aware staleness detection (kickoff + 2h with no result → refresh) — idle break weeks cost zero network calls.

Tools

Tool What it does
list_competitions() 18 league codes → names
list_teams(competition, season) team-name discovery (use before team filters)
get_matches(...) results/fixtures with filters (team, dates, played/upcoming), optional stats & compact odds views
get_standings(competition, season, as_of_date?) replayed league table; as_of_date gives leakage-safe historical views
get_team_form(team, ...) last N matches + W/D/L, goals, points-per-game summary
get_head_to_head(a, b, ..., seasons_back?, scope?) meetings with wins/draws/goals; seasons_back=9 covers 10 seasons in one call; scope: league / domestic_cups / europe / all / a concrete cup code (UCL, UEL, CDR, …), with by_scope + by_competition breakdowns; if scope is omitted the user is asked via MCP elicitation
list_cup_competitions() 8 cup codes → names
get_cup_matches(...) cup ties incl. penalty-shootout notes (advance 4-3 on penalties) and two-legged tie notes (1st Leg)

Semantics worth knowing: penalty shootouts count as final wins in head-to-head (pen_wins_a/b disclose them); goals count regulation/extra time only; league tables do not include administrative points deductions (source data has none).

Install

Distributed on npm only (the Python server is embedded and run via uv, which must be on PATH). No API keys.

Claude Desktop / Cursor / any stdio MCP client

{
  "mcpServers": {
    "football": {
      "command": "npx",
      "args": ["-y", "football-data-mcp"]
    }
  }
}

Codex

codex mcp add football -- npx -y football-data-mcp

DeepSeek Harness (dsh)

dsh plugin --profile web add football-data-mcp

Tools surface as mcp__football__get_matches, … in every dsh session.

Run a local checkout instead

git clone https://github.com/HOWILLMAKEIT/football-mcp && cd football-mcp
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}' \
  | node bin/cli.mjs     # smoke: should answer with server capabilities

Or point an MCP client at uv --directory <repo> run football-data-mcp.

Configuration

Env var Default Purpose
FOOTBALL_MCP_CACHE_DIR ~/.cache/football_mcp CSV/ESPN cache location

Example

User:  过去 10 个赛季国家德比,巴萨对皇马胜率?含杯赛
Agent: get_head_to_head("Barcelona", "Real Madrid", "SP1", "2025-26",
                        seasons_back=9, scope="all")
→      25 meetings: Barcelona 12 (48%), Real Madrid 9 (36%), 4 draws
       by_scope: league 20 (9-8-3) · domestic_cups 5 (3-1-1)

Development

uv sync --extra dev
uv run pytest      # 76 offline tests
uv run ruff check .
uv run football-data-mcp

Release: bump package.json and pyproject.toml versions in lockstep, then git tag v0.x.y && git push --tags (CI tests, then publishes to npm).

License

MIT