Overview
The APIfootball MCP server exposes our football data as tools that an AI agent can call directly, using the open Model Context Protocol (MCP) standard. It sits in front of the same data that powers our REST API, so your existing API key and plan work unchanged — the MCP server is a thin adapter, not a separate product.
If you're looking for the plain-language pitch and connection quick-start instead of the full reference below, see the MCP overview page.
count/truncated wrapper on list results) — it is not
the same shape as the raw apiv3.apifootball.com REST response documented on the
REST API docs page.
Authentication
Authentication uses your existing APIfootball API key as an OAuth-style bearer token — no separate MCP account or credentials.
Request URL
Header
| Header | Value |
|---|---|
| Authorization | Bearer YOUR_APIFOOTBALL_API_KEY — the same key you use for APIkey= on REST calls. |
Your plan's existing limits (requests, coverage, historical range) apply exactly as they do on the REST API. There is no separate MCP quota.
Connecting Your AI Client
Most MCP clients (Claude Desktop, Claude Code, Cursor) use the same JSON configuration shape:
{
"mcpServers": {
"apifootball": {
"url": "https://mcp.apifootball.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_APIFOOTBALL_API_KEY"
}
}
}
}
Once added, restart your AI client and the tools listed in the sidebar become available — you can just ask football questions in natural language and the client will call the right tool automatically.
search_football_leagues
Search competitions/leagues by country and/or name, to resolve a league_id before calling other tools. Always call this first if you don't already have a league id — never guess one.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| country | string | No* | Country name or partial match, e.g. "Italy" |
| league_name | string | No* | League name or partial match, e.g. "Serie A" |
| limit | integer | No | Max results, 1–100 |
* At least one of country or league_name is required.
Example call
{ "country": "Italy", "league_name": "Serie A" }
Example response
{
"count": 2,
"leagues": [
{ "league_id": "207", "name": "Serie A", "season": "2026/2027", "country": "Italy", "country_id": "5" },
{ "league_id": "8", "name": "Serie A Women", "season": "2026/2027", "country": "Italy", "country_id": "5" }
]
}
get_football_matches
Fixtures and results for a date range, optionally filtered by league or team. Maximum date range is 15 days.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| date_from | string | Yes | Start date, YYYY-MM-DD |
| date_to | string | Yes | End date, YYYY-MM-DD (max 15 days after date_from) |
| league_id | string | No | From search_football_leagues |
| team_id | string | No | Filter to one team |
| limit | integer | No | Max results, 1–100 |
Example call
{ "date_from": "2026-07-25", "date_to": "2026-07-25", "league_id": "302" }
Example response
{
"count": 1,
"truncated": false,
"matches": [
{
"match_id": "1234567",
"date": "2026-07-25",
"time": "20:00",
"kickoff_utc": "2026-07-25T17:00:00.000Z",
"status": "Not Started",
"league_id": "302",
"league": "La Liga",
"country": "Spain",
"home_team": "Real Madrid",
"home_team_id": "76",
"away_team": "Barcelona",
"away_team_id": "97",
"home_score": "",
"away_score": ""
}
]
}
kickoff_utc (computed by the MCP server) for any time-zone math — the raw
date/time fields come from apifootball in an account-dependent zone.
get_live_football_matches
Matches currently in progress, optionally filtered by league. Same response shape as get_football_matches.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| league_id | string | No | From search_football_leagues |
| limit | integer | No | Max results, 1–100 |
Example call
{}
Example response
{
"count": 1,
"truncated": false,
"matches": [
{
"match_id": "1234567",
"date": "2026-07-25",
"time": "20:00",
"kickoff_utc": "2026-07-25T17:00:00.000Z",
"status": "2nd Half",
"league_id": "302",
"league": "La Liga",
"country": "Spain",
"home_team": "Real Madrid",
"home_team_id": "76",
"away_team": "Barcelona",
"away_team_id": "97",
"home_score": "2",
"away_score": "1"
}
]
}
get_football_standings
Current league table for a competition — overall, home and away records.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| league_id | string | Yes | From search_football_leagues |
Example call
{ "league_id": "302" }
Example response
{
"league_id": "302",
"count": 1,
"table": [
{
"position": "1",
"team_id": "76",
"team": "Real Madrid",
"played": "10",
"wins": "8",
"draws": "1",
"losses": "1",
"goals_for": "24",
"goals_against": "8",
"points": "25"
}
]
}
get_match_details
Score, status and venue for a single match, plus optional goals/cards/lineups/statistics via include — all from one underlying call, so asking for more include values costs no extra latency.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| match_id | string | Yes | From get_football_matches / get_live_football_matches |
| date | string | Recommended | YYYY-MM-DD, narrows the lookup so match_id resolves reliably |
| include | array | No | Any of: goals, cards, lineups, statistics |
Example call
{ "match_id": "1234567", "date": "2026-07-25", "include": ["goals", "cards"] }
Example response
{
"match_id": "1234567",
"date": "2026-07-25",
"time": "20:00",
"kickoff_utc": "2026-07-25T17:00:00.000Z",
"status": "Finished",
"league_id": "302",
"league": "La Liga",
"country": "Spain",
"home_team": "Real Madrid",
"home_team_id": "76",
"away_team": "Barcelona",
"away_team_id": "97",
"home_score": "2",
"away_score": "1",
"stadium": "Santiago Bernabeu",
"referee": "A. Referee",
"round": "Round 10",
"halftime_score": "1-0",
"goals": [
{ "time": "23", "home_scorer": "K. Mbappe", "score": "1-0" }
],
"cards": [
{ "time": "55", "home_fault": "E. Camavinga", "card": "yellow card" }
]
}
get_head_to_head
Historical only: already-completed direct meetings between two teams, plus each
team's recent finished results. A match scheduled for today or the future will not appear here even
if it's the exact matchup being asked about — use get_football_matches or
get_live_football_matches to find upcoming or in-progress fixtures instead.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| team1_id / team2_id | string | Yes, or names below | Team ids, from other tools |
| team1_name / team2_name | string | Yes, or ids above | Team names (English) |
Example call
{ "team1_name": "Real Madrid", "team2_name": "Barcelona" }
Example response
{
"head_to_head": [
{ "match_id": "1200001", "date": "2026-03-15", "home_team": "Real Madrid", "away_team": "Barcelona", "home_score": "3", "away_score": "1", "...": "..." }
],
"team1_recent_form": [ "...compact matches..." ],
"team2_recent_form": [ "...compact matches..." ]
}
get_football_predictions
Mathematically-derived win/draw/loss probabilities for matches in a date range — not bookmaker odds. Use get_football_odds for real odds; use predictions as the fallback when odds aren't available on your plan, or when a match simply has no odds market.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| date_from | string | Yes | Start date, YYYY-MM-DD |
| date_to | string | Yes | End date (max 15 days after date_from) |
| league_id | string | No | Narrow to one league |
| match_id | string | No | Narrow to one match |
| limit | integer | No | Max results, 1–100 |
Example call
{ "date_from": "2026-07-25", "date_to": "2026-07-25", "match_id": "1234567" }
Example response
{
"count": 1,
"truncated": false,
"predictions": [
{
"match_id": "1234567",
"date": "2026-07-25",
"league": "La Liga",
"country": "Spain",
"home_team": "Real Madrid",
"away_team": "Barcelona",
"favorite": "home",
"home_win_pct": 55,
"draw_pct": 25,
"away_win_pct": 20,
"both_teams_score_pct": 62,
"over_2_5_goals_pct": 58,
"under_2_5_goals_pct": 42
}
]
}
get_football_odds
Real bookmaker pre-match odds — 1X2, double chance, both-teams-to-score, over/under. Maximum date range is 5 days (stricter than other tools). The response does not include team names, only match_id — resolve it first via get_football_matches or get_head_to_head.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| date_from | string | Yes | Start date, YYYY-MM-DD |
| date_to | string | Yes | End date (max 5 days after date_from) |
| match_id | string | Strongly recommended | From get_football_matches / get_head_to_head |
| limit | integer | No | Max results, 1–100 |
Example call
{ "date_from": "2026-07-25", "date_to": "2026-07-26", "match_id": "1234567" }
Example response
{
"count": 1,
"truncated": false,
"odds": [
{
"match_id": "1234567",
"bookmaker": "Bet365",
"updated": "2026-07-25 18:00:00",
"1x2": { "home": "1.85", "draw": "3.60", "away": "4.20" },
"double_chance": { "home_or_draw": "1.25", "home_or_away": "1.15", "draw_or_away": "1.95" },
"both_teams_to_score": { "yes": "1.70", "no": "2.05" },
"over_under_2_5": { "over": "1.90", "under": "1.90" }
}
]
}
get_football_predictions for win/draw/loss probabilities instead.
get_football_topscorers
A league's top scorers table, ranked by goals, with assists and penalty goals.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| league_id | string | Yes | From search_football_leagues |
| limit | integer | No | Max results, 1–100 |
Example call
{ "league_id": "302", "limit": 3 }
Example response
{
"count": 3,
"truncated": true,
"note": "70 scorers matched; only the first 3 are shown.",
"topscorers": [
{ "rank": "1", "player": "Kylian Mbappe", "player_id": 2354545782, "team": "Real Madrid", "team_id": "76", "goals": "25", "assists": "5", "penalty_goals": "8" },
{ "rank": "2", "player": "Vedat Muriqi", "player_id": 1468412695, "team": "Mallorca", "team_id": "7285", "goals": "23", "assists": "", "penalty_goals": "5" },
{ "rank": "3", "player": "Ante Budimir", "player_id": 1306374671, "team": "Osasuna", "team_id": "7269", "goals": "17", "assists": "", "penalty_goals": "6" }
]
}
get_live_football_odds_comments
In-play betting odds (market, value, handicap, suspended status) and live text commentary for matches currently live. Narrow with match_id — without it, this returns every live match worldwide that has live odds/commentary.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| match_id | string | Strongly recommended | From get_live_football_matches |
| league_id | string | No | From search_football_leagues |
| country_id | string | No | Filter by country |
| limit | integer | No | Max results, 1–100 |
Example call
{ "match_id": "4593" }
Example response
{
"count": 1,
"truncated": false,
"matches": [
{
"match_id": "4593",
"date": "2026-07-25",
"time": "10:30",
"status": "48",
"league": "C-League",
"country": "Cambodia",
"home_team": "Police Commissary",
"home_score": "0",
"away_team": "Phnom Penh Crown",
"away_score": "2",
"live_odds": [
{ "odd_name": "How many goals will Away Team score?", "suspended": "No", "type": "No goal", "value": "1.333", "handicap": "", "upd": "2026-07-25 11:12:12" }
],
"live_comments": [
{ "time": "44:58", "text": "Kunshan free kick", "state": "" }
]
}
]
}
Errors
Tool errors come back as a normal MCP tool result with isError: true, so your AI client can read the message and decide what to do next (retry, fall back to another tool, or tell the user) instead of the connection breaking.
Example: invalid or out-of-plan request
{
"content": [
{ "type": "text", "text": "apifootball API error (action=get_topscorers): Authentification failed!" }
],
"isError": true
}
Common messages you may see, straight from the underlying APIfootball API:
| Message | Meaning |
|---|---|
Authentification failed! | The API key is invalid or missing. |
No odd found (please check your plan)! | Odds aren't included in your current plan, or no odds exist for that query — try get_football_predictions instead. |