footballcharts-mcp
Server Details
Tables, results, fixtures, goal timing, season projections: 93 football leagues incl. lower tiers
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- ddevetak/footballcharts-mcp
- GitHub Stars
- 0
- Server Listing
- footballcharts-mcp
Available Tools
10 toolsabout_football_chartsAbout this sourceARead-onlyIdempotentInspect
What football-charts.com covers (93 leagues incl. lower divisions), what it does NOT hold (live scores, players, odds), how league keys and season strings work, how to phrase model probabilities honestly, and which tool answers what. Call when unsure whether this source fits a question, or once before the first call in a session. No parameters. Example: "Can you get me Estonian league data?" → about_football_charts, then list_leagues.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| what | Yes | |
| tools | Yes | |
| free_tier | Yes | |
| get_a_key | Yes | |
| do_not_use_for | Yes | |
| how_to_answer_well | Yes | |
| use_this_source_when | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that the tool is read-only, open-world, idempotent, and non-destructive. The description adds meaningful context beyond that: the source lacks live scores, players, and odds, and the tool itself serves as a routing/orientation layer rather than a data endpoint. No contradiction with 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 dense but efficient: coverage, exclusions, conventions, routing guidance, call timing, and a concrete example are packed into a compact paragraph. Every clause adds useful orientation information with no wasted words.
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 zero-parameter informational tool with an output schema, the description leaves no ambiguity about when or why to call it. It also addresses the likely decision an agent faces—whether this source fits a query—and provides a clear example.
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?
The tool has zero parameters and an empty input schema, so there is no parameter-semantic burden. The description explicitly notes 'No parameters,' matching the schema exactly.
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 that this tool is a source orientation guide: it covers what football-charts.com includes, what it excludes, key/season-string conventions, probability phrasing, and which sibling tool to use. This is a specific verb+resource description that differentiates it from the data-retrieval sibling tools.
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 gives explicit usage conditions: call when unsure whether the source fits a question, or once before the first call in a session. The Estonia example further demonstrates the intended call flow, ending with list_leagues.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_fixturesUpcoming fixturesARead-onlyIdempotentInspect
Upcoming matches of one league, earliest first: kick-off date and time, teams, a slug, and the model's calibrated probabilities (home/away, over/under ladders, both teams to score, half-time lines; draw = 1 − home − away) with team attack/defence ratings. Use for "who plays this weekend", kick-off times, or the chances in an upcoming match. The slug on each row is the input to get_match, which returns one fixture in full — call this first when you need one match in depth. Use get_results for matches already played. Probabilities are a baseline model from match history alone (no injuries, motivation or weather) and are not market prices or advice — say so. Example: "What are the chances of goals in Brentford v Sunderland?" → get_fixtures premier, read model_predictions.dc_v2.calibrated["over_2.5"].
| Name | Required | Description | Default |
|---|---|---|---|
| league | Yes | League key from list_leagues, e.g. 'premier' (England), 'spain1', 'brazil1', 'sweden1', 'wgermany1' (women). Not the display name. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| league | No | |
| matches | No | |
| attribution | No | Cite as "Data by football-charts.com" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond read-only/idempotent annotations, the description discloses ordering, exact output contents, the source of probabilities, and limitations (no injuries/motivation/weather, not market prices). It even instructs the agent to communicate the caveat to the user.
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 front-loaded with the core purpose and output, then efficiently covers usage, alternatives, limitations, and a concrete example. Every sentence adds value; there is no filler or repetition.
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?
With one well-documented parameter, an output schema present, and rich annotations, the description still adds necessary usage context, sibling-routing, and model caveats. Nothing essential for selecting or invoking the tool correctly is missing.
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?
The schema already documents the single league parameter thoroughly with examples and a note not to use display names, so schema coverage is complete. The description adds only a reinforcing example ('get_fixtures premier') rather than new parameter semantics.
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 states a specific verb and resource: 'Upcoming matches of one league, earliest first' with details of returned fields. It differentiates from siblings by explicitly contrasting with get_match (one match in full) and get_results (matches already played).
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?
It gives explicit use cases: 'who plays this weekend', kick-off times, and chances in an upcoming match. It also tells the agent when to use get_results instead and instructs calling get_fixtures first before get_match for in-depth match data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_goal_timingGoal timingARead-onlyIdempotentInspect
Goals per 15-minute bin (0-15 … 90+) for every team in a league season, each with peak_bins (the bin or bins with most goals — ties are listed; report a tie as a tie), late_share_pct and first_half_pct, plus league totals and the most active period. Use for "when does X score", late goals, fast starters, who concedes early, or which period a league's goals fall in. Pass team (name substring) for one team only. For one team's timing next to its match log get_team is more direct. Answer from peak_bins, never by eyeballing the bins. Example: "When does Flamengo score most?" → get_goal_timing brazil1, team="Flamengo".
| Name | Required | Description | Default |
|---|---|---|---|
| team | No | Team name substring, e.g. 'Flamengo' — returns that team's row only | |
| league | Yes | League key from list_leagues, e.g. 'premier' (England), 'spain1', 'brazil1', 'sweden1', 'wgermany1' (women). Not the display name. | |
| season | No | Season string exactly as list_leagues returns it: winter-calendar leagues look like '2026-2027', summer-calendar leagues (Brazil, Sweden, Norway, Japan…) like '2026'. Omit for the current season. The free tier serves the current and previous season only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | |
| note | No | |
| stats | No | |
| league | No | |
| season | No | |
| time_bins | No | |
| attribution | No | Cite as "Data by football-charts.com" |
| team_filter | No | |
| team_not_found | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only and idempotent safety, so no contradiction exists. The description adds real behavioral context beyond annotations: ties in peak_bins are listed and must be reported as ties, the tool returns league totals and the most active period, and the agent is explicitly warned not to eyeball bins. This materially changes how the agent should interpret and use the result.
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 front-loads the output shape and purpose, then gives use cases, parameter guidance, an alternative tool, and an example in a compact, ordered flow. Every sentence contributes: none repeats the name or annotations, and the example concretizes invocation.
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?
With an output schema present, the description does not need to enumerate return fields exhaustively, and it provides the essential invocation context: output semantics, tie handling, use cases, one-team vs. league-wide behavior, alternative routing, and a worked example. It is complete for an agent to select and invoke the tool correctly.
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 description coverage is 100%, so the baseline is 3. The description reinforces that team is a substring and can be used to return one team's row, and it gives a concrete example mapping league='brazil1' and team='Flamengo'. It adds modest practical color but does not uncover semantics absent from the schema.
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 states a specific verb and resource: it computes goals per 15-minute bin for every team in a league season, with named derived fields (peak_bins, late_share_pct, first_half_pct) plus league totals. It also names the exact sibling alternative (get_team) for the one-team-plus-match-log case, removing ambiguity. The title and name align with a clear goal-timing analysis 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?
Usage is explicitly scoped: it says to use this tool for 'when does X score', late goals, fast starters, early conceders, or league scoring periods. It also gives an exclusion by noting that get_team is more direct when one team's timing is needed next to its match log, and it instructs the agent to answer from peak_bins rather than raw bins.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_league_tableLeague tableARead-onlyIdempotentInspect
Standings for one league season: one row per team with position, played, W/D/L, goals, points, last-five form, plus expected points and a luck category (how far results run ahead of or behind the underlying numbers). Use for "who is top", "how many points", "what is the form", or any question about the table as ranked by points. view="luck" re-orders the same rows by over/under-performance (who is lucky, unlucky, flattered by the table); view="goals" by scoring. For one team in depth use get_team; for how the season is projected to END use get_season_projection. Omit season for the current one. Example: "Is Hull really a top-four side?" → get_league_table premier, view=luck, compare points with expected_points.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | Row order; default 'classic' (by points) | |
| league | Yes | League key from list_leagues, e.g. 'premier' (England), 'spain1', 'brazil1', 'sweden1', 'wgermany1' (women). Not the display name. | |
| season | No | Season string exactly as list_leagues returns it: winter-calendar leagues look like '2026-2027', summer-calendar leagues (Brazil, Sweden, Norway, Japan…) like '2026'. Omit for the current season. The free tier serves the current and previous season only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| view | No | |
| table | No | |
| league | No | |
| season | No | |
| attribution | No | Cite as "Data by football-charts.com" |
| season_state | No | 'in_season' or 'finished' |
| current_season | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool read-only, idempotent, and non-destructive, so the description doesn't need to repeat that. It adds genuinely useful behavioral detail beyond the annotations: rows are one per team, view='luck' re-orders the same rows by over/under-performance rather than filtering, and the free tier only serves current and previous seasons. No contradictions with 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 dense but each sentence carries weight: definition, use cases, view behavior, sibling routing, season hint, and example. It only loses a point for slight redundancy, such as restating 'Omit for the current season' which is already in the season parameter's schema description. Still, it is well-structured and front-loaded with 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?
An output schema exists, so the description doesn't need to explain return values. It covers the essential operational context: row semantics, column contents, view variants, season behavior, and the free-tier limitation. With the annotations covering safety, an agent has everything needed to select this tool and invoke it correctly without ambiguity.
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 already 3. The description adds meaning beyond the schema by explaining what each view does in behavioral terms ('view="luck" re-orders the same rows by over/under-performance... view="goals" by scoring') and by providing a concrete example query. This goes beyond the schema's terse 'Row order; default classic' label, though it doesn't independently document parameter syntax.
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 opens with a clear definition: 'Standings for one league season: one row per team with position, played, W/D/L, goals, points, last-five form, plus expected points and a luck category.' This specifies both the resource (league table) and the content of each row. It also proactively distinguishes itself from siblings by naming get_team for in-depth team data and get_season_projection for projected final 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?
Explicit usage guidance is provided: 'Use for "who is top", "how many points", "what is the form", or any question about the table as ranked by points.' It also names alternatives and when to choose them: 'For one team in depth use get_team; for how the season is projected to END use get_season_projection.' This is exactly the kind of when-to-use vs. when-not-to guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_matchMatch detailARead-onlyIdempotentInspect
One match in full: the complete model probability block (calibrated and raw, all markets), team ratings, first-goal-time histograms for both sides (fgt_h, fgt_a), recent form, and — once played — the score, half-time score and status. Use for one named fixture. slug has the form 'country/league-slug/YYYY-MM-DD-home-vs-away'; take it from a get_fixtures row rather than assembling it, because team spellings must match exactly. Use get_fixtures for a league's whole upcoming slate, get_results for scores of many matches. Probabilities are model output, not advice. Example: slug 'england/premier-league/2026-09-05-brentford-vs-sunderland'.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | Match slug from get_fixtures, e.g. 'england/premier-league/2026-09-05-brentford-vs-sunderland' |
Output Schema
| Name | Required | Description |
|---|---|---|
| match | Yes | |
| attribution | No | Cite as "Data by football-charts.com" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false. The description adds meaningful behavioral context on top: what data is included, the conditional nature of score/status fields (only once played), and that probabilities are model output and not advice. No contradictions with 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 front-loaded with the core purpose, then enumerates contents, gives routing guidance, adds a caveat, and provides a concrete example. Every sentence earns its place; there is no filler or redundant restatement of the tool name.
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 an output schema exists, the description does not need to spell out return values. It covers what the tool returns, how to construct the slug, when to use it versus siblings, and a critical caveat about model probabilities. This is complete for correct selection and invocation.
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 value beyond the schema by specifying the slug format explicitly, providing a complete example, and warning against constructing the slug manually because team spellings must match exactly. This is more than the schema alone 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 states a specific verb and resource: retrieving one full match record with probability data, team ratings, histograms, form, and score/status once played. It clearly distinguishes itself from siblings like get_fixtures and get_results by emphasizing that it covers one named fixture in full.
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?
Explicitly tells the agent when to use it ('Use for one named fixture'), when to use alternatives ('Use get_fixtures for a league's whole upcoming slate, get_results for scores of many matches'), and even instructs the agent to derive the slug from get_fixtures rather than assembling it manually due to exact spelling requirements.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_resultsMatch resultsARead-onlyIdempotentInspect
Finished matches of one league season, one row per match: date, teams, full-time and half-time score, first-goal minute, goalless flag. Rows are in chronological order, earliest first. last=N keeps only the N latest matches and still returns them earliest-first. team filters on a case-insensitive substring of either side's name. Use for scores, "how did X do lately", head-to-head within a season, half-time scores or first-goal minutes. Use get_fixtures for matches not yet played, get_match for one match's probability detail, get_team for one team's season in full. No odds. Example: "Last five Liverpool results" → get_results premier, team="Liverpool", last=5.
| Name | Required | Description | Default |
|---|---|---|---|
| last | No | Keep only the N latest matches of the season, e.g. 5 for recent form (default: all) | |
| team | No | Team name substring, e.g. 'Liverpool' | |
| league | Yes | League key from list_leagues, e.g. 'premier' (England), 'spain1', 'brazil1', 'sweden1', 'wgermany1' (women). Not the display name. | |
| season | No | Season string exactly as list_leagues returns it: winter-calendar leagues look like '2026-2027', summer-calendar leagues (Brazil, Sweden, Norway, Japan…) like '2026'. Omit for the current season. The free tier serves the current and previous season only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| count | No | |
| league | No | |
| season | No | |
| matches | No | |
| attribution | No | Cite as "Data by football-charts.com" |
| season_state | No | 'in_season' or 'finished' |
| current_season | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description clearly discloses behavioral details beyond the annotations: rows are chronological, last=N returns the N latest still ordered earliest-first, team filters case-insensitively on either side's name, and odds are not included. The readOnly/idempotent annotations already cover safety, and this description adds meaningful operation semantics without contradicting them.
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 dense but every sentence earns its place: purpose, output rows, ordering, filter semantics, usage scenarios, sibling alternatives, limitation, and a worked example. Information is front-loaded with the core purpose before details, and nothing feels redundant or filler.
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 that an output schema exists, annotations cover safety, and the schema documents all parameters, the description is complete for an agent to select and invoke the tool correctly. It covers selection criteria, parameter behavior, exclusions, and gives a realistic example, leaving no important operational gap.
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?
The schema already covers all parameters at 100%, so the baseline is 3. The description adds value beyond the schema by explaining that last preserves chronological order, team matches a case-insensitive substring of either side, and providing example league keys and season format nuances. This is more than repetition, though not all of it is required given the rich schema.
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 identifies a specific resource ('Finished matches of one league season') and output granularity (one row per match with listed fields). It also explicitly distinguishes itself from siblings by naming get_fixtures, get_match, and get_team, so an agent can tell exactly what this tool returns.
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 provides explicit when-to-use guidance: scores, recent form, head-to-head, half-time scores, and first-goal minutes. It also names alternatives with their conditions: get_fixtures for unplayed matches, get_match for probability detail, and get_team for full season team view, plus a concrete example mapping the query 'Last five Liverpool results' to parameters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_season_projectionSeason projectionARead-onlyIdempotentInspect
How one league's CURRENT season is projected to finish: 10,000 Monte Carlo simulations refreshed daily, per team the title, top-four and relegation (bottom3) probabilities, points now, mean final points, a 10th–90th percentile points range and a full finishing-position matrix, plus the change since the previous run. Use for forward-looking questions — who wins the league, who goes down, how safe a position is, likely final points. Use get_league_table for where things stand NOW and get_fixtures for individual match probabilities. Always the current season; there is no season parameter. Example: "Can Hull stay up?" → get_season_projection premier, read projection.teams.Hull.bottom3.
| Name | Required | Description | Default |
|---|---|---|---|
| league | Yes | League key from list_leagues, e.g. 'premier' (England), 'spain1', 'brazil1', 'sweden1', 'wgermany1' (women). Not the display name. |
Output Schema
| Name | Required | Description |
|---|---|---|
| projection | Yes | |
| attribution | No | Cite as "Data by football-charts.com" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, openWorld, idempotent, and non-destructive hints, so the bar is lower. The description adds useful behavioral context: 10,000 Monte Carlo simulations refreshed daily and the 'change since the previous run' output. It also discloses the current-season-only behavior, which is not obvious from the schema. No contradiction with 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 dense but well-structured: it front-loads the core purpose, then usage, then alternatives, then a concrete example. Every sentence contributes either capabilities, routing, or a limitation. It is slightly long, but the complexity of the tool justifies it.
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 tool with an output schema, the description goes beyond the minimum by summarizing the key output fields and giving a path-style example ('projection.teams.Hull.bottom3'). It also explains the current-season constraint and points to sibling tools for adjacent questions. The agent has everything needed to select and call this tool correctly.
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 baseline is 3, but the description adds a concrete example call ('get_season_projection premier') and explains the league parameter convention via examples. It also clarifies there is no season parameter, which prevents the agent from inventing one. This is a meaningful addition over the schema alone.
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 states a specific verb+resource: 'How one league's CURRENT season is projected to finish' and enumerates the exact outputs (title, top-four, relegation probabilities, points ranges, finishing-position matrix). It also distinguishes itself from siblings by explicitly naming get_league_table and get_fixtures and their different purposes. This makes the tool's role unmistakable.
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 gives explicit when-to-use guidance: 'forward-looking questions — who wins the league, who goes down, how safe a position is, likely final points.' It clearly says to use get_league_table for current standings and get_fixtures for individual match probabilities, and it states the limitation 'Always the current season; there is no season parameter.' This fully routes the agent to the correct tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_teamTeam pageARead-onlyIdempotentInspect
Everything held on one team in one league season: its table row (with luck and expected points), the full match log (date, opponent, venue H/A, score, half-time score, first-goal minute, outcome), goals per 15-minute bin, first-goal distribution, and the seasons available. team is a slug: lower-case, spaces as hyphens, e.g. 'arsenal', 'manchester-city'. Take the exact name from get_league_table first when unsure. Use for one team in depth ("tell me about Arsenal's season"). Use get_league_table for every team shallowly, get_results with a team filter for just the scores, get_goal_timing to compare timing across the whole league. Example: "How is Arsenal doing?" → get_team premier, team="arsenal".
| Name | Required | Description | Default |
|---|---|---|---|
| team | Yes | Team slug, e.g. 'arsenal', 'manchester-city' (from the table's team names, lower-case, spaces as hyphens) | |
| league | Yes | League key from list_leagues, e.g. 'premier' (England), 'spain1', 'brazil1', 'sweden1', 'wgermany1' (women). Not the display name. | |
| season | No | Season string exactly as list_leagues returns it: winter-calendar leagues look like '2026-2027', summer-calendar leagues (Brazil, Sweden, Norway, Japan…) like '2026'. Omit for the current season. The free tier serves the current and previous season only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| slug | No | |
| team | No | |
| league | No | |
| season | No | |
| matches | No | |
| ranking | No | The team's table row |
| seasons | No | |
| attribution | No | Cite as "Data by football-charts.com" |
| first_goal_bins | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds useful behavioral context by defining the team slug rules, instructing the agent to source exact names from get_league_table when unsure, and noting that 'seasons available' are part of the response.
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 dense but every sentence earns its place: output scope, slug guidance, usage routing, and an example. It is front-loaded with the most important information and contains no filler.
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 3-parameter read-only tool with a full output schema and rich annotations, the description covers what is returned, how to form parameters, when to use it versus alternatives, and gives a worked example. Nothing an agent needs to call it correctly is missing.
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 description coverage is 100%, so the schema already documents league, team, and season. The description reinforces team slug format and gives a full example call, but it does not add substantial semantic information beyond what the parameter descriptions already provide.
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 names the exact resource (one team in one league season) and enumerates the payload: table row, match log, goal bins, first-goal distribution, and seasons. It clearly separates this from sibling tools by framing it as the in-depth single-team endpoint.
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 gives explicit when-to-use guidance: 'Use for one team in depth' and contrasts with get_league_table for every team shallowly, get_results for just scores, and get_goal_timing for league-wide timing. It also provides a concrete natural-language-to-call example, making routing unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_track_recordModel track recordARead-onlyIdempotentInspect
The public settled ledger: every model lean published before kick-off and graded after the result — count, hit rate and profit/loss at flat 1-unit stakes, overall and by market (1x2, ft_ou_25, ft_ou_35, ht_ou_15, bts), a daily cumulative series, the 50 most recent graded leans, and calibration (Brier score, probability buckets vs actual hit rate). days sets the lookback window, default 90. Losing periods are included; nothing is filtered. Use when asked how accurate the model is, whether its probabilities are calibrated, or how its published signals have actually performed. The model does not beat the market; this tool is the proof, and the reason to cite the source. Example: "Is this model any good?" → get_track_record, quote summary.hit_rate, summary.pl and accuracy.brier.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Lookback window in days (default 90) |
Output Schema
| Name | Required | Description |
|---|---|---|
| attribution | No | Cite as "Data by football-charts.com" |
| track_record | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses meaningful behavior: losing periods are included, nothing is filtered, results are at flat 1-unit stakes, and the model is explicitly said not to beat the market. This prevents an agent from overstating accuracy and clarifies the integrity of the data. No contradiction with 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 front-loaded with the core metrics and scoping, then moves to usage guidance and a concrete example. It is long but dense; the only mild excess is the rhetorical 'this tool is the proof... reason to cite the source' sentence, which adds tone more than operational detail.
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 one-parameter, read-only tool with a full output schema and annotations, the description covers everything an agent needs: what the tool returns, which questions it answers, how the parameter behaves, and an example of quoting fields. There is no missing operational context that would cause a wrong invocation.
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 the only parameter (days) is described in the schema with type, range, and default. The description repeats that it sets the lookback window but adds no new semantic detail beyond what the schema already provides, so the 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 opens with a precise noun phrase ('public settled ledger') and states the resource: every model lean published before kick-off and graded after the result, along with the exact metrics returned (count, hit rate, P/L, calibration). This immediately distinguishes it from the football fixture/result sibling tools, which are about matches, not model performance.
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?
Explicit triggers are given: 'Use when asked how accurate the model is, whether its probabilities are calibrated, or how its published signals have actually performed,' plus a concrete example mapping a question to the tool and quoted output fields. It does not name alternatives or state when not to use it, but the guidance is clear enough to route an agent correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_leaguesList leaguesARead-onlyIdempotentInspect
Every league this source covers — 93 across 42 countries — with country, league key, display name and the seasons available, newest first. No parameters. Call first in any workflow: every other tool takes a league key and most take a season string, and both must match these values exactly. Season format differs by competition (winter leagues '2026-2027', summer leagues '2026'), so read the season here rather than constructing it. ("list" rather than "get": it enumerates everything, it does not fetch one thing.) Example: "Which Polish league do you have?" → list_leagues, filter by country.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| leagues | Yes | |
| attribution | No | Cite as "Data by football-charts.com" |
| season_window | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool read-only, idempotent, and non-destructive. The description adds useful behavioral context beyond that: no parameters, output ordered newest first, season availability included, and season format varying by competition ('2026-2027' vs '2026'). It does not discuss pagination or stability of the 93-league set, but those are minor given the available output schema.
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?
Every sentence earns its place: the first states the output inventory, followed by no-parameters, workflow precedence, season-format caveat, list-vs-get disambiguation, and an example. It is front-loaded with the core purpose and remains readable despite covering several important nuances.
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 parameterless, read-only list tool with a rich output schema and strong annotations, the description is complete: it names return fields, ordering, scope, and downstream matching requirements. An agent has everything needed to call this tool correctly and understand its role in a broader workflow.
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?
With zero parameters, the input schema carries no information beyond an empty object. The description explicitly states 'No parameters' and explains that league keys and season strings are output values that must match exactly when used in other tools, preventing the model from inventing or constructing 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 and resource, stating it lists every league the source covers, with country, league key, display name, and seasons available. It also explicitly distinguishes "list" from "get": 'it enumerates everything, it does not fetch one thing,' which separates it from sibling tools like get_match and get_team.
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?
It gives explicit workflow precedence: 'Call first in any workflow: every other tool takes a league key and most take a season string.' It also advises reading season strings from this tool rather than constructing them and provides a concrete example query, leaving no doubt about when to invoke it.
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. Dates show when Glama detected each change.
10 tool updates
- Changed
about_football_charts1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "do_not_use_for": { + "items": { + "type": "string" + }, + "type": "array" + }, + "free_tier": { + "type": "string" + }, + "get_a_key": { + "type": "string" + }, + "how_to_answer_well": { + "items": { + "type": "string" + }, + "type": "array" + }, + "tools": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "use_this_source_when": { + "items": { + "type": "string" + }, + "type": "array" + }, + "what": { + "type": "string" + } + }, + "required": [ + "what", + "use_this_source_when", + "do_not_use_for", + "how_to_answer_well", + "free_tier", + "get_a_key", + "tools" + ], + "type": "object" +}
- Changed
get_fixtures1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "attribution": { + "description": "Cite as \"Data by football-charts.com\"", + "type": [ + "string", + "null" + ] + }, + "count": {}, + "league": {}, + "matches": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "properties": { + "away_team": { + "type": "string" + }, + "country": { + "$ref": "#/properties/league" + }, + "home_team": { + "type": "string" + }, + "league": { + "$ref": "#/properties/league" + }, + "match_date": { + "$ref": "#/properties/league" + }, + "model_predictions": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "dc_v2": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "calibrated": { + "anyOf": [ + { + "additionalProperties": true, + "description": "Probabilities 0–1. The draw is NOT a field: draw = 1 − home − away.", + "properties": { + "away": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "btts_yes": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "expected_away_goals": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "expected_home_goals": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "expected_ht_goals": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "home": {}, + "ht_over_0.5": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "ht_over_1.5": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_0.5": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_1.5": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_2.5": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_3.5": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_4.5": { + "$ref": "#/properties/matches/anyOf/0/items/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Use these. Calibrated on settled matches." + }, + "computed_at": { + "$ref": "#/properties/league" + }, + "data_through": { + "$ref": "#/properties/league", + "description": "Last match date the model has seen" + }, + "model": { + "$ref": "#/properties/league" + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "real_league_name": { + "$ref": "#/properties/league" + }, + "slug": { + "description": "Input to get_match", + "type": "string" + }, + "status": { + "$ref": "#/properties/league" + }, + "time": { + "$ref": "#/properties/league" + } + }, + "required": [ + "slug", + "home_team", + "away_team" + ], + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" +}
- Changed
get_goal_timing2 fields changed- changed
Input schema / properties / team / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "attribution": { + "description": "Cite as \"Data by football-charts.com\"", + "type": [ + "string", + "null" + ] + }, + "data": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "properties": { + "bins": { + "anyOf": [ + { + "additionalProperties": { + "type": "number" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Goals per bin: '0-15','15-30','30-45','45+','46-60','60-75','75-90','90+'" + }, + "first_half_pct": { + "$ref": "#/properties/data/anyOf/0/items/properties/late_share_pct" + }, + "late_share_pct": { + "description": "% of goals from 75′ on" + }, + "peak_bins": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Bin(s) with most goals — ties are listed; report a tie as a tie" + }, + "peak_goals": { + "$ref": "#/properties/stats/anyOf/0/properties/total_goals" + }, + "team": { + "type": "string" + }, + "total": { + "$ref": "#/properties/stats/anyOf/0/properties/total_goals" + } + }, + "required": [ + "team" + ], + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "league": {}, + "note": { + "$ref": "#/properties/league" + }, + "season": { + "$ref": "#/properties/league" + }, + "stats": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "late_goals": { + "$ref": "#/properties/stats/anyOf/0/properties/total_goals" + }, + "match_count": { + "$ref": "#/properties/stats/anyOf/0/properties/total_goals" + }, + "most_active_period": { + "$ref": "#/properties/league" + }, + "total_goals": {} + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "team_filter": { + "$ref": "#/properties/league" + }, + "team_not_found": { + "$ref": "#/properties/league" + }, + "time_bins": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" +}
- Changed
get_league_table5 fields changed- added
Input schema / properties / view / anyOfAdded value: +[ + { + "enum": [ + "classic", + "luck", + "goals" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / view / descriptionPrevious value: -"Ranking view; default 'classic'"New value: +"Row order; default 'classic' (by points)" - removed
Input schema / properties / view / enumRemoved value: -[ - "classic", - "luck", - "goals" -] - removed
Input schema / properties / view / typeRemoved value: -"string" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "attribution": { + "description": "Cite as \"Data by football-charts.com\"", + "type": [ + "string", + "null" + ] + }, + "current_season": { + "$ref": "#/properties/league" + }, + "league": {}, + "season": { + "$ref": "#/properties/league" + }, + "season_state": { + "$ref": "#/properties/league", + "description": "'in_season' or 'finished'" + }, + "table": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "properties": { + "avg_goals_conceded": { + "$ref": "#/properties/table/anyOf/0/items/properties/avg_goals_scored" + }, + "avg_goals_scored": { + "$ref": "#/properties/table/anyOf/0/items/properties/expected_points" + }, + "clean_sheets": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "drawn": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "expected_points": { + "description": "Points the underlying numbers say the team should have" + }, + "expected_position": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "goal_difference": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "goals_against": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "goals_for": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "last_5_form": { + "$ref": "#/properties/league", + "description": "Latest results as letters, e.g. 'WWDLW'" + }, + "last_5_points": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "lost": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "luck_category": { + "$ref": "#/properties/league", + "description": "'lucky' | 'fair' | 'unlucky'" + }, + "luck_difference": { + "$ref": "#/properties/table/anyOf/0/items/properties/expected_points", + "description": "points − expected_points; positive = ahead of the numbers" + }, + "over_25_percentage": { + "$ref": "#/properties/table/anyOf/0/items/properties/avg_goals_scored" + }, + "played": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "points": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + }, + "position": {}, + "team": { + "type": "string" + }, + "won": { + "$ref": "#/properties/table/anyOf/0/items/properties/position" + } + }, + "required": [ + "team" + ], + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "view": { + "$ref": "#/properties/league" + } + }, + "type": "object" +}
- Changed
get_match1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "attribution": { + "description": "Cite as \"Data by football-charts.com\"", + "type": [ + "string", + "null" + ] + }, + "match": { + "additionalProperties": true, + "properties": { + "away_score": { + "$ref": "#/properties/match/properties/home_score" + }, + "away_team": { + "$ref": "#/properties/match/properties/slug" + }, + "country": { + "$ref": "#/properties/match/properties/slug" + }, + "fgt_a": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Away side first-goal-time histogram" + }, + "fgt_h": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Home side first-goal-time histogram" + }, + "home_score": {}, + "home_team": { + "$ref": "#/properties/match/properties/slug" + }, + "ht_result": { + "$ref": "#/properties/match/properties/slug" + }, + "label": { + "$ref": "#/properties/match/properties/slug" + }, + "league": { + "$ref": "#/properties/match/properties/slug" + }, + "match_date": { + "$ref": "#/properties/match/properties/slug" + }, + "match_status": { + "$ref": "#/properties/match/properties/slug", + "description": "'scheduled' before kick-off; 'ft' when finished" + }, + "model_predictions": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "dc_v2": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "calibrated": { + "anyOf": [ + { + "additionalProperties": true, + "description": "Probabilities 0–1. The draw is NOT a field: draw = 1 − home − away.", + "properties": { + "away": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "btts_yes": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "expected_away_goals": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "expected_home_goals": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "expected_ht_goals": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "home": {}, + "ht_over_0.5": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "ht_over_1.5": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_0.5": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_1.5": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_2.5": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_3.5": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + }, + "over_4.5": { + "$ref": "#/properties/match/properties/model_predictions/anyOf/0/properties/dc_v2/anyOf/0/properties/calibrated/anyOf/0/properties/home" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Use these. Calibrated on settled matches." + }, + "computed_at": { + "$ref": "#/properties/match/properties/slug" + }, + "data_through": { + "$ref": "#/properties/match/properties/slug", + "description": "Last match date the model has seen" + }, + "model": { + "$ref": "#/properties/match/properties/slug" + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "real_league_name": { + "$ref": "#/properties/match/properties/slug" + }, + "season": { + "$ref": "#/properties/match/properties/slug" + }, + "slug": {}, + "time": { + "$ref": "#/properties/match/properties/slug" + } + }, + "type": "object" + } + }, + "required": [ + "match" + ], + "type": "object" +}
- Changed
get_results7 fields changed- added
Input schema / properties / last / anyOfAdded value: +[ + { + "maximum": 500, + "minimum": 1, + "type": "integer" + }, + { + "type": "null" + } +] - changed
Input schema / properties / last / descriptionPrevious value: -"Return only the N most recent matches (default: all)"New value: +"Keep only the N latest matches of the season, e.g. 5 for recent form (default: all)" - removed
Input schema / properties / last / maximumRemoved value: -500 - removed
Input schema / properties / last / minimumRemoved value: -1 - removed
Input schema / properties / last / typeRemoved value: -"integer" - changed
Input schema / properties / team / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "attribution": { + "description": "Cite as \"Data by football-charts.com\"", + "type": [ + "string", + "null" + ] + }, + "count": {}, + "current_season": { + "$ref": "#/properties/league" + }, + "league": {}, + "matches": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "properties": { + "awayTeam": { + "type": "string" + }, + "date": { + "$ref": "#/properties/league" + }, + "first_goal_time": { + "$ref": "#/properties/count", + "description": "Minute of the first goal; null when goalless" + }, + "first_goal_time_extra": { + "$ref": "#/properties/count", + "description": "Stoppage-time minutes added to first_goal_time" + }, + "goalless": { + "type": [ + "boolean", + "null" + ] + }, + "homeTeam": { + "type": "string" + }, + "ht_result": { + "$ref": "#/properties/league", + "description": "Half-time 'home:away'" + }, + "score": { + "$ref": "#/properties/league", + "description": "Full-time 'home:away', e.g. '3:0'" + }, + "time": { + "$ref": "#/properties/league" + } + }, + "required": [ + "homeTeam", + "awayTeam" + ], + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "note": { + "$ref": "#/properties/league" + }, + "season": { + "$ref": "#/properties/league" + }, + "season_state": { + "$ref": "#/properties/league", + "description": "'in_season' or 'finished'" + } + }, + "type": "object" +}
- Changed
get_season_projection1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "attribution": { + "description": "Cite as \"Data by football-charts.com\"", + "type": [ + "string", + "null" + ] + }, + "projection": { + "additionalProperties": true, + "properties": { + "deltas_vs_prev": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": true, + "properties": { + "bottom3": { + "$ref": "#/properties/projection/properties/teams/additionalProperties/properties/title" + }, + "title": { + "$ref": "#/properties/projection/properties/teams/additionalProperties/properties/title" + }, + "top4": { + "$ref": "#/properties/projection/properties/teams/additionalProperties/properties/title" + } + }, + "type": "object" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Change since the previous run" + }, + "expected_remaining": { + "$ref": "#/properties/projection/properties/n_sims" + }, + "league": {}, + "n_sims": {}, + "partial_schedule": { + "type": [ + "boolean", + "null" + ] + }, + "run_date": { + "$ref": "#/properties/projection/properties/league" + }, + "scheduled_remaining": { + "$ref": "#/properties/projection/properties/n_sims" + }, + "season": { + "$ref": "#/properties/projection/properties/league" + }, + "teams": { + "additionalProperties": { + "additionalProperties": true, + "properties": { + "bottom1": { + "$ref": "#/properties/projection/properties/teams/additionalProperties/properties/title" + }, + "bottom2": { + "$ref": "#/properties/projection/properties/teams/additionalProperties/properties/title" + }, + "bottom3": { + "$ref": "#/properties/projection/properties/teams/additionalProperties/properties/title", + "description": "Relegation-zone probability (bottom three)" + }, + "gd_now": { + "$ref": "#/properties/projection/properties/n_sims" + }, + "mean_pts": { + "$ref": "#/properties/projection/properties/teams/additionalProperties/properties/title" + }, + "p10_pts": { + "$ref": "#/properties/projection/properties/n_sims" + }, + "p90_pts": { + "$ref": "#/properties/projection/properties/n_sims" + }, + "played": { + "$ref": "#/properties/projection/properties/n_sims" + }, + "position_matrix": { + "anyOf": [ + { + "items": { + "type": "number" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Probability of finishing 1st…last" + }, + "pts_now": { + "$ref": "#/properties/projection/properties/n_sims" + }, + "title": {}, + "top4": { + "$ref": "#/properties/projection/properties/teams/additionalProperties/properties/title" + } + }, + "type": "object" + }, + "description": "Keyed by team name", + "type": "object" + } + }, + "required": [ + "teams" + ], + "type": "object" + } + }, + "required": [ + "projection" + ], + "type": "object" +}
- Changed
get_team1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "attribution": { + "description": "Cite as \"Data by football-charts.com\"", + "type": [ + "string", + "null" + ] + }, + "first_goal_bins": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "properties": { + "count": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "time": { + "$ref": "#/properties/team" + } + }, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "league": { + "$ref": "#/properties/team" + }, + "matches": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "properties": { + "away": { + "$ref": "#/properties/team" + }, + "date": { + "$ref": "#/properties/team" + }, + "first_goal_time": { + "$ref": "#/properties/team" + }, + "home": { + "$ref": "#/properties/team" + }, + "ht": { + "$ref": "#/properties/team" + }, + "outcome": { + "$ref": "#/properties/team", + "description": "'W' | 'D' | 'L'" + }, + "score": { + "$ref": "#/properties/team" + }, + "time": { + "$ref": "#/properties/team" + }, + "venue": { + "$ref": "#/properties/team", + "description": "'H' or 'A'" + } + }, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "ranking": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "avg_goals_conceded": { + "$ref": "#/properties/ranking/anyOf/0/properties/avg_goals_scored" + }, + "avg_goals_scored": { + "$ref": "#/properties/ranking/anyOf/0/properties/expected_points" + }, + "clean_sheets": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "drawn": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "expected_points": { + "description": "Points the underlying numbers say the team should have" + }, + "expected_position": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "goal_difference": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "goals_against": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "goals_for": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "last_5_form": { + "$ref": "#/properties/team", + "description": "Latest results as letters, e.g. 'WWDLW'" + }, + "last_5_points": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "lost": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "luck_category": { + "$ref": "#/properties/team", + "description": "'lucky' | 'fair' | 'unlucky'" + }, + "luck_difference": { + "$ref": "#/properties/ranking/anyOf/0/properties/expected_points", + "description": "points − expected_points; positive = ahead of the numbers" + }, + "over_25_percentage": { + "$ref": "#/properties/ranking/anyOf/0/properties/avg_goals_scored" + }, + "played": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "points": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + }, + "position": {}, + "team": { + "type": "string" + }, + "won": { + "$ref": "#/properties/ranking/anyOf/0/properties/position" + } + }, + "required": [ + "team" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The team's table row" + }, + "season": { + "$ref": "#/properties/team" + }, + "seasons": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "slug": { + "$ref": "#/properties/team" + }, + "team": {} + }, + "type": "object" +}
- Changed
get_track_record5 fields changed- added
Input schema / properties / days / anyOfAdded value: +[ + { + "maximum": 365, + "minimum": 1, + "type": "integer" + }, + { + "type": "null" + } +] - removed
Input schema / properties / days / maximumRemoved value: -365 - removed
Input schema / properties / days / minimumRemoved value: -1 - removed
Input schema / properties / days / typeRemoved value: -"integer" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "attribution": { + "description": "Cite as \"Data by football-charts.com\"", + "type": [ + "string", + "null" + ] + }, + "track_record": { + "additionalProperties": true, + "properties": { + "accuracy": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "brier": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/pl", + "description": "Brier score over settled probabilities; lower is better, 0.25 = coin flip" + }, + "buckets": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "properties": { + "avg_prob": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/hit_rate" + }, + "hi": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/hit_rate" + }, + "hit_rate": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/hit_rate" + }, + "lo": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/hit_rate" + }, + "n": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/n" + } + }, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "n": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/n" + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "by_market": { + "anyOf": [ + { + "additionalProperties": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0" + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "pending": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/n", + "description": "Leans published but not yet settled" + }, + "recent": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "properties": { + "market": { + "$ref": "#/properties/track_record/properties/recent/anyOf/0/items/properties/slug" + }, + "model_prob": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/hit_rate" + }, + "outcome": { + "$ref": "#/properties/track_record/properties/recent/anyOf/0/items/properties/slug", + "description": "'won' | 'lost' | 'void'" + }, + "pl": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/hit_rate" + }, + "result_score": { + "$ref": "#/properties/track_record/properties/recent/anyOf/0/items/properties/slug" + }, + "side": { + "$ref": "#/properties/track_record/properties/recent/anyOf/0/items/properties/slug" + }, + "slug": {} + }, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "The 50 most recent graded leans" + }, + "signals_only": { + "type": [ + "boolean", + "null" + ] + }, + "summary": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hit_rate": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/pl" + }, + "lost": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/n" + }, + "n": {}, + "pl": { + "description": "Profit/loss in units at flat 1-unit stakes" + }, + "void": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/n" + }, + "won": { + "$ref": "#/properties/track_record/properties/summary/anyOf/0/properties/n" + } + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Whole window" + } + }, + "type": "object" + } + }, + "required": [ + "track_record" + ], + "type": "object" +}
- Changed
list_leagues1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "attribution": { + "description": "Cite as \"Data by football-charts.com\"", + "type": [ + "string", + "null" + ] + }, + "count": {}, + "leagues": { + "items": { + "additionalProperties": true, + "properties": { + "country": { + "type": "string" + }, + "league": { + "description": "The key to pass as `league`", + "type": "string" + }, + "name": { + "type": "string" + }, + "seasons": { + "description": "Newest first; exact strings for `season`", + "items": { + "type": "string" + }, + "type": "array" + }, + "url": {} + }, + "required": [ + "league", + "name", + "country", + "seasons" + ], + "type": "object" + }, + "type": "array" + }, + "season_window": { + "$ref": "#/properties/leagues/items/properties/url" + } + }, + "required": [ + "leagues" + ], + "type": "object" +}
10 tool updates
- First observed
about_football_charts - First observed
get_fixtures - First observed
get_goal_timing - First observed
get_league_table - First observed
get_match - First observed
get_results - First observed
get_season_projection - First observed
get_team - First observed
get_track_record - First observed
list_leagues
Frequently Asked Questions
Claiming proves that you control a remote MCP connector. It does not move, proxy, or interrupt the server.
Open the connector listing, choose Claim ownership, and sign in to Glama.
Complete one verification method:
GitHub identity — fastest for official registry listings. For a namespace such as
io.github.alice/server, link the matching GitHub user, then choose Claim with GitHub. An organization namespace such asio.github.acme/serveralso needs that organization to have installed the Glama AI GitHub App and approved its permissions, because GitHub discloses organization membership only to apps it has installed. Use HTTP or DNS when it has not.HTTP challenge — works when you can deploy a public file. Generate a token, publish the exact JSON Glama shows at
/.well-known/glama.jsonon the same origin as the connector, then choose Check HTTP challenge.DNS challenge — works when you control DNS but cannot change the server. Generate a token, create the exact TXT record Glama shows, wait for it to propagate, then choose Check DNS challenge.
After verification, Glama sends a confirmation email and gives you access to listing details, thumbnails, health checks, and analytics. Keep the HTTP file or DNS record in place: Glama periodically checks it and ownership remains verified while the token is discoverable.
The HTTP ownership file has this structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"claim": "glama_claim_..."
}Claim tokens are opaque, stable, and bound to the signed-in Glama account. They contain no email address or other personal information. If Glama can no longer discover a verified HTTP or DNS token, it starts a seven-day grace period before removing claim-based access. Restore the same token during that period to keep ownership verified. Never publish an email address, Glama session token, GitHub token, or connector credential as ownership proof.
If verification fails, confirm that you copied the current token exactly. The HTTP file must be public, return valid JSON with a successful HTTP response, and stay on the connector's origin. DNS changes may need more time to propagate. A claim cannot transfer to a different origin or hostname: if the connector target changes, Glama starts the grace period and the new target must be claimed separately after the previous claim is released.
For a connector linked to the official MCP Registry, registry updates continue to replace its name, description, and URL by default. After claiming, open Manage connector and enable Use Glama listing details as the source of truth if edits made on Glama should be preserved. Categories and thumbnails are always managed on Glama; registry linkage and technical connection settings continue to sync.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
To improve your MCP server's ranking:
Claim ownership of the server listing
Complete the server profile with an accurate description and thumbnail
Provide a test profile so Glama can connect to and evaluate the server
Keep tool definitions clear and complete to earn a high Tool Definition Quality Score (TDQS)
Route real usage through the Glama Gateway; more recorded successful server uses also improve the ranking
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!
Related MCP Connectors
Calibrated, sourced football predictions: odds, tournament sims, standings, brackets, model card.
Football-Data.org MCP — soccer competitions, matches, standings
Football fixtures, standings, and odds intelligence for AI agents.
Historical football results, teams, competitions and draw/streak statistics via 10 read-only tools.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides soccer match predictions and league statistics using xG data and Poisson distribution models. It enables users to forecast outcomes, analyze team performance, and view league tables across major European football leagues.3GPL 2.0
- AlicenseAqualityBmaintenanceLive football/soccer data from top European leagues, enabling queries for standings, fixtures, scorers, and team comparisons via natural language.614MIT
- AlicenseNot gradedqualityDmaintenanceProvides football analytics tools including player scouting, comparisons, market-value filters, expected-goals tables, match-by-match form, team attacking profiles, match search, shot maps, and more for 10 leagues.6GPL 3.0
- AlicenseNot gradedqualityCmaintenanceProvides comprehensive soccer/football data including standings, team search, league search, match predictions, and head-to-head records via the API-Football service.20MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.
TDQS
Each tool targets a clearly distinct resource or query type: fixtures, results, match details, standings, team profiles, goal timing, projections, track record, and league enumeration. Descriptions include explicit cross-references to related tools, eliminating boundary confusion.
The dominant pattern is get_ + noun, which is consistent and predictable. list_leagues and about_football_charts are deliberate exceptions that fit their meta/enumeration purposes, but they do break the otherwise uniform convention.
Ten tools is well-scoped for a football data and model-probability server. Each tool covers a meaningful slice of the domain without redundancy or bloat.
The tool surface covers the full read-only workflow: discovering leagues, viewing tables, fixtures, results, single matches, team deep-dives, goal timing, season projections, and model credibility. No obvious dead ends or missing operations for the stated purpose.