matchday-mcp
Allows access to Premier League football data including standings, fixtures, results, top scorers, and team comparisons.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@matchday-mcpHow's Barcelona doing in La Liga this season?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
⚽ matchday-mcp
A Model Context Protocol server that gives any MCP client (Claude Desktop, Claude Code, …) live football/soccer data — standings, fixtures, results, top scorers and team comparisons across Europe's top leagues.
Built with TypeScript + Zod, backed by the free football-data.org API.
Ask Claude "How is Real Madrid doing this season?" or "Compare Arsenal and Liverpool's recent form" and it answers with real data through these tools.
🔗 Live playground: matchday-mcp-web.vercel.app — an interactive dashboard built with SvelteKit + Svelte 5 that runs on this server's data layer.
Demo
> get_standings { "competition": "La Liga" }
**La Liga standings — 2025**
# Team P W D L GD Pts
1 FC Barcelona 38 31 1 6 59 94
2 Real Madrid CF 38 27 5 6 42 86
3 Villarreal CF 38 22 6 10 26 72
4 Club Atlético de Madrid 38 21 6 11 18 69
...Related MCP server: mcp-sofascore
Tools
Tool | What it does |
| League table for a competition (position, W/D/L, GD, points). |
| Matches for a competition, filterable by status and matchday. |
| Top scorers for a competition. |
| Look up a club by name (country, stadium, founded year, competitions). |
| A club's recent results or upcoming fixtures, with a W/D/L form string. |
| Compare two clubs by recent form (last 5) and W/D/L tally. |
Competitions (free tier): Premier League (PL), La Liga (PD), Bundesliga (BL1),
Serie A (SA), Ligue 1 (FL1), Eredivisie (DED), Primeira Liga (PPL), Championship (ELC),
Brazil Série A (BSA), Champions League (CL), World Cup (WC), European Championship (EC).
You can pass a competition by name ("Premier League") or code ("PL").
Quick start (Claude Desktop)
Get a free API token at football-data.org/client/register (takes ~1 minute).
Add the server to your
claude_desktop_config.json:{ "mcpServers": { "matchday": { "command": "npx", "args": ["-y", "matchday-mcp"], "env": { "FOOTBALL_DATA_TOKEN": "your_free_token_here" } } } }Restart Claude Desktop. Ask it about standings, fixtures, scorers or team form.
Works the same in any MCP client. In Claude Code:
claude mcp add matchday -e FOOTBALL_DATA_TOKEN=your_token -- npx -y matchday-mcp.
Development
git clone https://github.com/reiorozco/matchday-mcp.git
cd matchday-mcp
npm install
export FOOTBALL_DATA_TOKEN=your_free_token # required to hit the live API
npm run dev # run the server over stdio (tsx)
npm test # run the unit tests (no token needed — fetch is mocked)
npm run typecheck # tsc --noEmit
npm run build # bundle to dist/ with tsupVariable | Required | Description |
| yes | Free token from football-data.org. |
Design notes
Zod-validated tools. Every tool input is described and validated with Zod, so the model gets clear schemas and bad arguments fail fast with readable errors.
Caching + rate-limit resilience. The free tier allows 10 req/min and returns HTTP 429 when exceeded, so the client adds an in-memory TTL cache plus bounded retry/backoff.
Lazy team index. football-data.org has no team-name search, so the client builds a name → id index across the domestic leagues one league at a time with early exit — a well-known club costs 1–2 requests, not a full sweep. Name resolution is ranked (exact → starts-with → shortest name), so
"Barcelona"→ FC Barcelona, not RCD Espanyol.Off-season aware. In the off-season the API's "current season" already points at the next, not-yet-started season (empty tables), so the default season rolls over in August.
Pure, testable handlers. Tool logic lives in plain functions returning strings; the MCP wiring is a thin layer on top. The same data layer powers the web playground (source).
Data
Data from football-data.org. This project is not affiliated with football-data.org or any league.
License
MIT © Reinaldo Orozco
Available Tools
6 toolscompare_teamsCompare two teamsA
Compare two clubs by recent form (last 5 results) and W/D/L tally.
| Name | Required | Description | Default |
|---|---|---|---|
| teamA | Yes | First club name | |
| teamB | Yes | Second club name | |
| season | No | Season start year as 'YYYY', e.g. '2024' for 2024-25. Defaults to current. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the tool uses last 5 results and W/D/L tally for comparison, but does not mention edge cases (e.g., teams with fewer than 5 matches), data source, or side effects. Adequate but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence of 14 words, directly stating the tool's purpose and metrics. No filler or redundant information; extremely concise and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description gives a sense of the output (form metrics), but is vague about the exact structure. It does not mention error handling or conditions like team not found. Adequate for a simple tool but could be more comprehensive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter has a basic description. The tool description adds meaning by explaining that the comparison is based on recent form and W/D/L tally, which is not in the schema. This adds value beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool compares two clubs by recent form (last 5 results) and W/D/L tally. It specifies the verb (compare), resources (two teams), and the specific metrics, differentiating it from siblings like find_team or get_standings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for comparing recent form between two clubs but does not provide explicit guidance on when to use this tool versus alternatives like get_standings or get_team_matches. No exclusions or prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_teamFind a teamA
Look up a club by name across the major leagues. Returns country, stadium, founding year and competitions.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Club name, e.g. 'Real Madrid' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the tool looks up a club and returns specific fields. It implies a read-only operation with no destructive behavior. No annotations are provided, so the description carries the full burden, but it is sufficient for a simple query.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence that front-loads the purpose and includes key details without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple lookup tool with one parameter and no output schema, the description completely explains inputs and outputs. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a well-described parameter. The description adds 'look up by name' but does not provide additional meaning beyond what the schema already offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'look up' and resource 'club', specifies the criterion 'by name across the major leagues', and lists returned fields. It distinguishes itself from siblings like get_team_matches which focus on matches, and compare_teams which is for comparison.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use when needing basic team info like country and founding year. It does not explicitly state when not to use or provide alternatives, but the context of sibling tools provides some differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_matchesGet competition matchesA
Get matches for a competition. Filter by status (SCHEDULED/FINISHED/IN_PLAY) and/or matchday.
| Name | Required | Description | Default |
|---|---|---|---|
| season | No | Season start year as 'YYYY', e.g. '2024' for 2024-25. Defaults to current. | |
| status | No | Match status filter | |
| matchday | No | Matchday number | |
| competition | Yes | Competition name or code. Use a league name or code: PL, PD, BL1, SA, FL1, DED, PPL, ELC, BSA, CL, WC, EC (e.g. "Premier League" / "PL", "La Liga" / "PD"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It lacks details on rate limits, authentication, data freshness, or any behavioral traits beyond the basic fetch operation. For a read tool, more context on safety and default behavior is needed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states purpose and filters without any redundant words. Highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description should reveal more about response format, pagination, or limitations. It covers the core function but leaves gaps for an AI agent to infer behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and descriptions are adequate. The description partially repeats parameter info (e.g., status examples) but does not add significant new meaning beyond what the schema provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get matches') and resource ('for a competition'), and lists filter options (status, matchday). It effectively distinguishes from sibling tools like get_team_matches and get_standings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions filters but does not explicitly compare to alternatives like get_team_matches. However, the context is clear enough that for competition-wide matches, this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_standingsGet league standingsB
Get the current league table for a competition (position, W/D/L, GD, points).
| Name | Required | Description | Default |
|---|---|---|---|
| season | No | Season start year as 'YYYY', e.g. '2024' for 2024-25. Defaults to current. | |
| competition | Yes | Competition name or code. Use a league name or code: PL, PD, BL1, SA, FL1, DED, PPL, ELC, BSA, CL, WC, EC (e.g. "Premier League" / "PL", "La Liga" / "PD"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not disclose behavioral traits beyond the basic read operation. It lacks details on data freshness, error handling, or rate limits, which are critical given no annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no unnecessary words. It efficiently communicates the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the return fields (position, W/D/L, GD, points), which partially compensates for the lack of output schema. However, it omits error handling, case sensitivity, and default behavior for missing competitions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with parameter descriptions, so the description adds minimal additional value. It mentions output fields but not parameter semantics beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get') and the resource ('current league table for a competition'), and lists the data fields (position, W/D/L, GD, points). It distinguishes from sibling tools like get_top_scorers or get_matches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving standings but provides no explicit guidance on when to use versus alternatives (e.g., compare_teams, find_team). No prerequisites or exclusions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_team_matchesGet team matchesA
Get a club's matches (recent results or upcoming fixtures), with a W/D/L form string.
| Name | Required | Description | Default |
|---|---|---|---|
| team | Yes | Club name, e.g. 'Liverpool' | |
| limit | No | How many matches (default 5) | |
| season | No | Season start year as 'YYYY', e.g. '2024' for 2024-25. Defaults to current. | |
| status | No | Match status filter (default: most recent) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It only hints at output (form string) but does not disclose behaviors such as error handling, authentication needs, rate limits, or what happens if the team is not found. This is insufficient for a tool with 4 parameters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, well-structured sentence that front-loads the core purpose. Every word is necessary, and there is no redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 4 parameters and no output schema, the description covers the basic purpose but omits details like default behaviors (e.g., limit defaults to 5, season defaults to current) and output format beyond the form string. It is adequate but not comprehensive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds no additional meaning to the parameters (e.g., default values, format details) beyond what the schema already provides. The mention of 'form string' relates to output, not parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Get' and clearly identifies the resource 'club's matches'. It distinguishes from siblings like 'get_matches' by specifying 'club's' and mentions the form string output, which is unique to this tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when a club-specific match list is needed, but it does not explicitly state when to use this tool over siblings like 'get_matches' or provide exclusions. No alternatives are mentioned, leaving the agent to infer context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_top_scorersGet top scorersC
Get the top scorers for a competition.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many scorers (default 10) | |
| season | No | Season start year as 'YYYY', e.g. '2024' for 2024-25. Defaults to current. | |
| competition | Yes | Competition name or code. Use a league name or code: PL, PD, BL1, SA, FL1, DED, PPL, ELC, BSA, CL, WC, EC (e.g. "Premier League" / "PL", "La Liga" / "PD"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden but fails to disclose behavioral traits such as read-only nature, authentication needs, rate limits, pagination, or performance implications. It only states 'get'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence is front-loaded and concise with no wasted words. However, it is under-specified for the complexity of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given three parameters, no output schema, and no annotations, the description is incomplete. It does not explain the return format, default behavior, or edge cases like empty results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the input schema already documents all three parameters. The description adds no extra meaning beyond what the schema provides, meeting baseline but not exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a clear verb and resource, 'Get the top scorers for a competition,' which is distinct from siblings like get_standings or get_matches. However, it could be more specific about what 'top scorers' includes (e.g., player names, goal counts).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs. alternatives like get_standings or get_team_matches. The description does not mention prerequisites or exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
compare_teams - First observed
find_team - First observed
get_matches - First observed
get_standings - First observed
get_team_matches - First observed
get_top_scorers
TDQS
Scored across 6 tools
Tools are mostly distinct, but compare_teams and get_team_matches both provide form data, which could cause slight confusion. Overall, each tool serves a clear purpose.
All tool names follow a consistent verb_noun pattern (e.g., find_team, get_matches, get_standings), with no mixing of conventions.
Six tools is a well-scoped set for a football data server, covering essential operations without being overly numerous or sparse.
Core football data (teams, matches, standings, scorers, comparison) is covered. Minor gaps include individual match details and player statistics, but the set is reasonably complete for common use cases.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Football fixtures, standings, and odds intelligence for AI agents.
Tables, results, fixtures, goal timing, season projections: 93 football leagues incl. lower tiers
Historical football results, teams, competitions and draw/streak statistics via 10 read-only tools.
Live sports stats and pre-computed analysis for AI assistants across NBA, MLB, NFL, and NHL.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides tools to query football match data, odds, standings, and team statistics via natural language, integrating with the football-scraper-api.-
- FlicenseNot gradedqualityDmaintenanceProvides live football match data from Sofascore, including formations, injuries, betting odds, and league positions, enabling natural language queries about matches.1-
- FlicenseBqualityBmaintenanceEnables access to live FotMob football data for fixture lookup, team and player research, match details, lineups, league discovery, and search-based entity lookup.78-
- FlicenseNot gradedqualityDmaintenanceEnables natural language querying of football/soccer data via the API-Football service, providing access to leagues, teams, players, fixtures, standings, and statistics.3-