sportapi-mcp
Officialsportapi-mcp
An MCP server that lets AI assistants (Claude Desktop, Claude Code, Cursor, VS Code, Windsurf and other MCP clients) look up Live and Prematch matches, scores, live statistics and betting odds from SportAPI. It runs on demo data out of the box, without an API key.
claude mcp add sportapi -- uvx sportapi-mcpThen ask: "Which football matches are live right now, and who is favoured?"
This MCP server is free and MIT-licensed. The SportAPI data service behind it is a commercial product: live data needs a personal API key (how to get one). Without a key, every tool answers with the example responses from the SportAPI documentation, and every result says so.
Features
11 read-only tools covering the Sport Line API: sports, the navigation menu, countries, tournaments, Live and Prematch match lists, the match calendar, full match details with every market, team search, top matches, top championships and the key's account status.
Token-efficient output: compact JSON with empty fields dropped and odds rendered as one line per market (
"W1 1.525 | X 5.08 | W2 6.15"). A detailed match can carry 200+ markets, soget_matchreturns 15 by default and accepts amarketsfilter (["1X2", "Total"]).Polite by design: every request goes through a snapshot cache that enforces the documented minimum update intervals and never sends overlapping requests for the same data. No tool polls or fans out over matches, however often the assistant calls it.
Demo mode with no setup, clearly labelled (
"source": "demo") so that an assistant never presents a snapshot as live data.Actionable errors: an expired key, a sport outside the subscription, a finished match or a
game_idfrom the wrong line type come back as short explanations the assistant can act on.Two prompts: a live betting overview for a sport and a market comparison (implied probabilities, bookmaker margin, fair odds) for one match.
Built on the official SportAPI Python client and the official MCP Python SDK. stdio by default, Streamable HTTP optional.
Related MCP server: Odds-API MCP Server
What you can ask
Example conversations in demo mode (answers abridged). The assistant picks the tools itself.
"What's happening in live football right now?"
→ list_live_matches(sport_id=1)
Demo data from the SportAPI documentation, not live. 39 football matches are in play. Garuda Darwin 0:1 Darwin Olympic (76', NPL Northern Territory): Darwin Olympic are near-certain winners at 1.064. Ikonnect FA U19 0:1 Obosa U19 (33'): Obosa favoured at 1.40, the draw at 4.65. Caucaia U20 — Floresta EC U20 is goalless at 2', with Floresta slight favourites at 2.112.
"Arsenal against Coventry: how are the goal lines priced?"
→ get_match(game_id=746146992, line_type="live", markets=["Total"])
Arsenal lead 3:0 at 56' (xG 1.45 vs 0.03, shots on target 4:0). Total goals: Over 3.5 at 1.23, Over 4.5 at 2.09 / Under 4.5 at 1.81, Over 5.5 at 4.41. The market expects a fourth goal but leans against a fifth.
"When does Manchester City play next, and what are the odds?"
→ search_matches(text="Manchester"), then get_match(game_id=730321837, line_type="prematch", markets=["1X2", "Total"])
Manchester City — Bournemouth, Premier League, 23 Aug 2026 13:00 UTC. 1X2: City 1.525, draw 5.08, Bournemouth 6.15. Over 2.5 goals 1.39, under 2.5 2.72.
"What are the biggest games this weekend?" → top_matches(line_type="prematch", include_odds=True)
"Is my SportAPI key OK, and how many requests did I make this week?" → account_status() (live mode)
With a key, the same questions work for every sport in your subscription, with current data.
Install
The server is a Python package (Python 3.10+). The easiest way to run it is with
uv: uvx downloads and runs it in an
isolated environment, with no install step.
uvx sportapi-mcp # starts the stdio server; MCP clients launch it for youOr install it with pip and use the sportapi-mcp command instead of uvx sportapi-mcp:
pip install sportapi-mcpThe env blocks below are optional: leave them out to start in demo mode.
Claude Desktop
One-click install: download sportapi-mcp.mcpb from the latest release and open it — Claude Desktop installs the extension and asks for the optional key and base URL (leave them empty for demo data). The bundle sources are in mcpb/.
Or edit claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"sportapi": {
"command": "uvx",
"args": ["sportapi-mcp"],
"env": {
"SPORTAPI_KEY": "YOUR_API_KEY",
"SPORTAPI_BASE_URL": "https://YOUR_API_DOMAIN"
}
}
}
}Restart Claude Desktop; the SportAPI tools appear in the tools menu.
Claude Code
# demo mode
claude mcp add sportapi -- uvx sportapi-mcp
# live data, available in all your projects
claude mcp add sportapi --scope user \
-e SPORTAPI_KEY=YOUR_API_KEY -e SPORTAPI_BASE_URL=https://YOUR_API_DOMAIN \
-- uvx sportapi-mcpCursor
Add to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):
{
"mcpServers": {
"sportapi": {
"command": "uvx",
"args": ["sportapi-mcp"],
"env": {
"SPORTAPI_KEY": "YOUR_API_KEY",
"SPORTAPI_BASE_URL": "https://YOUR_API_DOMAIN"
}
}
}
}VS Code
Add to .vscode/mcp.json. VS Code asks for the key once and stores it securely:
{
"inputs": [
{
"type": "promptString",
"id": "sportapi-key",
"description": "SportAPI key",
"password": true
}
],
"servers": {
"sportapi": {
"type": "stdio",
"command": "uvx",
"args": ["sportapi-mcp"],
"env": {
"SPORTAPI_KEY": "${input:sportapi-key}",
"SPORTAPI_BASE_URL": "https://YOUR_API_DOMAIN"
}
}
}
}Windsurf and other clients
Any MCP client that can start a stdio server works: the command is uvx, the argument is
sportapi-mcp, and the environment variables are listed below. For Windsurf,
put the mcpServers block shown for Cursor into ~/.codeium/windsurf/mcp_config.json.
Streamable HTTP and Docker
sportapi-mcp --transport streamable-http --port 8000 # http://127.0.0.1:8000/mcp
docker build -t sportapi-mcp .
docker run -i --rm -e SPORTAPI_KEY -e SPORTAPI_BASE_URL sportapi-mcp # stdio
docker run --rm -p 8000:8000 sportapi-mcp --transport streamable-http --host 0.0.0.0The HTTP transport has no authentication of its own: keep it on localhost or behind your own gateway, because anyone who can reach it uses your key.
Configuration
Variable | Required | Description |
| for live data | Your API key. The server sends it only in the |
| for live data | Your personal API base URL, issued together with the key ( |
| no | Response language code, default |
Set both SPORTAPI_KEY and SPORTAPI_BASE_URL for live data, or neither for demo mode.
sportapi-mcp --demo forces demo mode even when a key is configured.
A key is bound to the server IP addresses or sites approved for it
(authentication and access).
An MCP server usually runs on your own computer, so make sure that address is allowed for the key;
account_status shows the IP address SportAPI sees.
Tools
Tool | What it answers | SportAPI method |
| Which sports have Live / Prematch matches now, with counts | |
| Sport → country → tournament tree with IDs and counts | |
| Countries with matches in one sport | |
| Tournaments of one sport and country | |
| Live matches of a sport or tournament: score, period, minute, main odds. Without a sport: live sports plus top live matches | |
| Upcoming matches: the "Top 50", a tournament, the full line, or the calendar (next 2/4/6/12 hours, today … 5 days ahead) | |
| One match: score, live statistics, every market and its odds, sub-events (halves, corners, cards…) | |
| Find matches by team or participant name, Live and Prematch | |
| Up to 10 most popular matches (all sports, or one sport for Prematch) | |
| Up to 12 popular championships with match counts | |
| Demo or live; with a key: expiry, sports, languages, access mode, requests over 7 days |
Prompts: live_betting_overview(sport) and compare_match_markets(match, markets).
How the output maps to the API data (decimal odds, blocked selections, market IDs, sub-events,
live statistics) is described in the odds,
match and
live statistics data models.
get_match(include_pointers=true) adds each selection's oc_pointer, the code used by bet
placement systems such as the SportAPI Coupon API.
Demo mode coverage
Demo mode serves the full English example responses from the SportAPI documentation (snapshots from August–October 2026):
list_sports,get_menu,top_matches: Live and Prematch;list_countries,list_live_matches,list_prematch_matches: football (sport_id1);list_tournaments: football,country_id1;get_match:746146992(Live, Arsenal — Coventry City) and730321837(Prematch, Manchester City — Bournemouth);search_matches: "Perth" (Live) and "Manchester" (Prematch).
Anything else (other sports and matches, the calendar, esports, top_championships) returns a
message that lists what demo mode covers and how to get a key.
Update intervals
Every response is a snapshot. The server reuses a snapshot until the documented minimum interval
for that method has passed, for example 7 s for the Live match list, 5 s for a Live match and
30 s for a Prematch match. Results served from the cache carry cached_seconds. Concurrent
calls for the same data wait for the request already in flight. See the
data update guidelines.
Documentation
Core concepts: Live vs Prematch, IDs
Building your own integration instead? Use the SportAPI Python client this server is built on.
Get an API key
Live data needs a personal API key and base URL from SportAPI. Plans start from $30/month, with a free 2-day trial.
Telegram: @sportapinet_bot
Website: sportapi.net
Keep the key in your MCP client's configuration or a secret store, never in a shared chat or a Git repository.
Contributing
Issues and pull requests are welcome; see CONTRIBUTING.md. Run
ruff check . && mypy && pytest before submitting.
License
MIT © 2026 SportAPI
Available Tools
11 toolsaccount_statusARead-onlyIdempotent
Show whether the server uses live data or demo data and, with an API key, the key's status: expiry, sports, languages, access restrictions and requests over 7 days.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, so the safety profile is covered. The description adds genuinely new behavioral context beyond that: the response varies depending on whether an API key is present, and the request-usage window is fixed at 7 days. It stops short of stating error behavior for invalid/expired keys.
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 that front-loads the primary distinction (live vs demo data) and then appends the keyed-detail fields. It is efficient with no filler, though the trailing list of six returned fields makes the sentence dense and slightly harder to parse.
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 zero parameters, a 100% covered schema, and no output schema (so return-shape explanation is not required), the description supplies what an agent needs: what the tool reports and the conditional keyed behavior. Minor gap in not clarifying what is returned when no API key is supplied.
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 takes zero parameters and schema coverage is 100%, so the baseline is 4. The mention of 'with an API key' describes an ambient credential rather than a schema parameter, and no parameter-level semantics are needed. There is minor ambiguity because the description implies an input (the key) that does not appear in 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 uses a specific verb ('Show') and names the exact resource: server data mode (live vs demo) plus API-key status fields. This is immediately distinguishable from all siblings, which deal with sports, matches, and tournaments rather than account/server state. It lacks only an explicit framing sentence stating the tool's overall role.
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 implied rather than stated: an agent can infer this is the tool to check authentication/account state, and the phrase 'with an API key' hints at a keyed vs unkeyed branch. However, there is no explicit when-to-use guidance, no prerequisites (e.g., how the key is supplied), and no statement of when this tool should be preferred over any sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_matchARead-onlyIdempotent
Full details of one match: score, live statistics, all betting markets and odds, and its sub-events (halves, corners, cards...).
A match can have hundreds of markets: filter with markets (e.g. ["1X2", "Total"]).
Odds are decimal; 'blocked' means the selection is suspended. Sub-events have their
own game_id: call get_match again with it and the same line_type.
| Name | Required | Description | Default |
|---|---|---|---|
| game_id | Yes | game_id from a match list, search or sub_events. | |
| markets | No | Only show these markets: case-insensitive name fragments (e.g. 'Total', '1X2', 'Handicap') or numeric market ids (group_id). Omit for the default markets. | |
| line_type | Yes | The line type the game_id came from ('live' or 'prematch'). | |
| max_markets | No | Maximum markets to return (API order). | |
| include_stats | No | Include live statistics (attacks, shots, xG...). | |
| include_pointers | No | Append each selection's oc_pointer code (needed only for bet placement systems). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, openWorld). The description adds real behavioral context beyond them: odds are decimal, 'blocked' means a suspended selection, a match can have hundreds of markets, and sub-events must be fetched via a recursive call with the same line_type.
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?
Front-loaded with the return-contents sentence, then two tight sentences on filtering and sub-event recursion. Dense but no filler; slightly list-like in the first line.
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 no output schema, the description carries the burden of describing returns and does so well (score, stats, markets, odds, sub-events). It doesn't address scale/pagination behavior for the default market set, but the schema's max_markets and default annotations fill most of that 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?
Schema description coverage is 100%, so baseline is 3. The description goes further by illustrating the `markets` filter with concrete values (["1X2", "Total"]) and by explaining that line_type is what ties a sub-event's game_id back to a valid get_match call, linking two parameters semantically.
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?
States a specific verb+resource ('Full details of one match') and enumerates the payload: score, live statistics, markets, odds, sub-events. That clearly distinguishes it from the list_*/search_matches siblings, which return sets of matches rather than one match's detail.
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?
Gives useful operational guidance — filter with `markets`, and re-call get_match with a sub-event's own game_id plus the same line_type to drill down. However it never states when to prefer this over alternatives (search_matches, list_live_matches) or any precondition, so the usage guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_countriesARead-onlyIdempotent
List the countries (regions) that have matches in one sport, with match counts.
| Name | Required | Description | Default |
|---|---|---|---|
| sport_id | Yes | sport_id from list_sports or get_menu (1 = Football). | |
| line_type | No | 'live' = matches in progress, 'prematch' = matches not started yet. | live |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds a genuine behavioral detail beyond the annotations: only countries/regions that actually have matches are returned, and counts accompany them, which tells the agent the result set is pre-filtered rather than a full country list.
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 with the resource front-loaded and no filler. Every clause (scope = one sport, filter = has matches, payload = match counts) carries 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?
For a read-only, two-parameter listing tool with no output schema, the description plus the fully documented schema cover what is needed to call it. It does not clarify how line_type affects the counts or the ordering of results, which is a minor 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?
Schema description coverage is 100%, so sport_id and line_type (including the live/prematch enum) are fully documented in the schema. The description only restates the 'one sport' scoping and adds no format or lookup detail, so the baseline 3 applies.
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 clear verb and resource ('List the countries (regions)') plus the scoping filter ('that have matches in one sport') and the return content ('with match counts'). It is readily distinguishable from siblings like list_tournaments or list_live_matches by resource, though no sibling is named explicitly.
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 implied by 'in one sport, with match counts' — an agent can infer this is the country-breakdown step after picking a sport. However, there is no explicit when-to-use, no when-not-to-use, and no mention of alternatives such as list_tournaments for a different grouping.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_live_matchesARead-onlyIdempotent
Live (in-play) matches with score, period, minute and main odds, grouped by tournament.
Use get_match with a game_id from here (line_type 'live') for all markets and live stats.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum matches to return. | |
| esports | No | Esports instead of traditional sports (SportAPI cybersport mode). | |
| markets | No | Only show these markets: case-insensitive name fragments (e.g. 'Total', '1X2', 'Handicap') or numeric market ids (group_id). Omit for the default markets. | |
| sport_id | No | sport_id (1 = Football). Omit for an overview: live sports with counts plus the top live matches. | |
| include_odds | No | Include the main odds. False makes the response much smaller. | |
| tournament_id | No | Only this tournament (from get_menu); 0 = all. | |
| max_markets_per_match | No | Maximum markets shown per match (API order). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds that results are grouped by tournament and that ids feed get_match with line_type 'live', but says nothing about result size, pagination, or freshness/latency of live data.
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?
Two sentences, front-loaded with the resource and its payload, followed by the precise next-step tool. No filler and nothing redundant.
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 no output schema, the description correctly names what is returned (score, period, minute, main odds, tournament grouping), which is exactly what an agent needs to decide to call it. It leaves minor gaps around response size and the overview-vs-filtered mode that the schema covers, so not quite complete.
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% and every parameter (limit, esports, markets, sport_id, include_odds, tournament_id, max_markets_per_match) is documented in the schema itself. The description only alludes to default markets and does not add syntax or interaction details beyond the schema, so the baseline 3 applies.
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?
States a specific verb and resource ('list_live_matches' → live in-play matches) and enumerates the returned fields (score, period, minute, main odds) plus grouping by tournament. The 'Live (in-play)' qualifier implicitly distinguishes it from the sibling list_prematch_matches, though no sibling is named.
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 routes the agent onward: use get_match with a game_id from here (line_type 'live') for all markets and live stats. This gives clear context for the tool's role as an overview entry point. It does not state when not to use it versus list_prematch_matches or top_matches, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_prematch_matchesARead-onlyIdempotent
Upcoming (Prematch) matches with start time and main odds, grouped by tournament.
For a whole sport (tournament_id 0) SportAPI returns its 'Top' selection of 50 matches (top leagues first, then by start time). Use within_hours or day for a schedule. Use get_match with a game_id from here (line_type 'prematch') for all markets.
| Name | Required | Description | Default |
|---|---|---|---|
| day | No | Only matches on one day: 0 = today, 1 = tomorrow ... 5. Days follow Kyiv time (Europe/Kyiv). | |
| limit | No | Maximum matches to return. | |
| esports | No | Esports instead of traditional sports (SportAPI cybersport mode). | |
| markets | No | Only show these markets: case-insensitive name fragments (e.g. 'Total', '1X2', 'Handicap') or numeric market ids (group_id). Omit for the default markets. | |
| sport_id | Yes | sport_id from list_sports or get_menu (1 = Football). | |
| full_line | No | With tournament_id 0: the sport's whole line instead of the 'Top' selection of 50 matches. | |
| include_odds | No | Include the main odds. False makes the response much smaller. | |
| within_hours | No | Only matches starting within the next 2, 4, 6 or 12 hours. | |
| tournament_id | No | Only this tournament (from get_menu); 0 = whole sport. | |
| max_markets_per_match | No | Maximum markets shown per match (API order). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld/idempotent, so the safety profile is covered. The description adds real behavioral context the annotations don't: the default 'Top' selection of 50 matches, the top-leagues-then-start-time ordering, and the full_line/tournament_id interaction. Return-format and paging details are absent, keeping it from a 5.
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?
Three tight sentences, front-loaded with the resource and its shape, then default-behavior caveats, then the get_match handoff. Every sentence carries non-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?
For a 10-parameter read tool with no output schema, the description covers the essential behavior (default selection size, ordering, day/within_hours scheduling, drill-down path). It is adequately complete, with only minor gaps around return shape that do not block correct 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, but the description adds genuine semantics on top: what tournament_id 0 means (whole-sport 'Top' selection of 50) and how full_line changes it. It doesn't explain the markets/limit/esports parameters, but it enriches the two most consequential ones.
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?
States a specific verb+resource with scope: upcoming prematch matches, start time, main odds, grouped by tournament. The '(Prematch)' qualifier implicitly separates it from list_live_matches, but it never names siblings or contrasts itself with top_matches/search_matches, so a 4 rather than 5.
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?
Gives concrete routing: use within_hours or day for a schedule, and use get_match with a game_id from the results (line_type 'prematch') for all markets. That is clear when-to-use guidance and a named handoff tool, though it doesn't state when NOT to use this tool versus top_matches.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sportsARead-onlyIdempotent
List the sports that have Live or Prematch matches right now, with match counts.
Start here to get a sport_id. Sports without matches are not listed.
| Name | Required | Description | Default |
|---|---|---|---|
| esports | No | Esports instead of traditional sports (SportAPI cybersport mode). | |
| line_type | No | 'live' = matches in progress, 'prematch' = matches not started yet. | live |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/openWorldHint, so the safety profile is covered. The description adds real behavior ('Sports without matches are not listed', match counts in the result), but it is muddled as to whether both Live and Prematch are returned or only the line_type selected, which the enum/default implies is a single value.
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?
Two sentences, zero filler, with the scoping constraint and the 'start here' guidance both front-loaded. Every clause carries 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?
There is no output schema, so the description sensibly names what comes back (sport_id, match counts). It is nearly sufficient for a two-parameter read-only discovery tool, with only the live-vs-prematch coverage ambiguity left unresolved.
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 both the esports and line_type parameters are already fully documented with enums and defaults; baseline 3 applies. The description only echoes the live/prematch notion and never mentions esports mode, adding no meaning beyond 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?
States a specific verb and resource ('List the sports') scoped to 'Live or Prematch matches right now, with match counts', which is far more precise than the bare tool name. The sentence 'Start here to get a sport_id' positions it in the workflow relative to siblings like list_tournaments and get_match.
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 frames the tool as the entry point ('Start here to get a sport_id'), which tells the agent when to reach for it before deeper match tools. It does not name a competing sibling or state a when-not condition, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tournamentsBRead-onlyIdempotent
List the tournaments of one sport and country that have matches, with match counts.
| Name | Required | Description | Default |
|---|---|---|---|
| esports | No | Esports instead of traditional sports (SportAPI cybersport mode). | |
| sport_id | Yes | sport_id from list_sports or get_menu (1 = Football). | |
| line_type | No | 'live' = matches in progress, 'prematch' = matches not started yet. | live |
| country_id | Yes | country id from list_countries. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description does add one meaningful behavioral detail beyond them: results are restricted to tournaments that actually have matches and each carries match counts. It says nothing about ordering, pagination, or whether an empty list is possible.
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 front-loaded sentence that names the resource, the filters, and the returned data with zero 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?
With no output schema, the description does the necessary work of indicating the return content (match counts) and the filtering behavior. Gaps remain around result ordering/paging and the tournament-vs-championship distinction, but for a simple read-only list tool it is largely sufficient.
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 all four parameters (esports, sport_id, line_type, country_id) are already documented with defaults, enums, and ID provenance in the schema. The description only alludes to sport/country scoping and adds no syntax or format meaning beyond 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?
States a specific verb and resource ('List the tournaments') plus scoping conditions (one sport and country, only those with matches) and the payload ('with match counts'). However, it never distinguishes itself from the closest sibling, top_championships, so an agent must infer the difference between tournaments and championships.
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 no when-to-use guidance, no prerequisites (that sport_id/country_id must first be resolved via list_sports/list_countries), and no indication of when top_championships or the match-listing tools are preferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_matchesARead-onlyIdempotent
Find matches by team or participant name. Returns game_id, teams, tournament, start time and (Live) score; use get_match for odds.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Full or partial team / participant name, e.g. 'Manchester'. | |
| limit | No | Maximum results per line. | |
| line_type | No | Where to search; 'both' searches Live and Prematch. | both |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint, openWorldHint and idempotentHint already declared, the description adds genuine context by enumerating the returned fields (game_id, teams, tournament, start time, Live score) and signalling what is absent (odds, deferred to get_match). It does not cover result ordering, truncation, or the effect of the default limit.
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?
Two short sentences, zero filler. The search scope is front-loaded and the return-field summary plus the get_match hand-off come second, which is the right order.
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 no output schema, describing the returned fields is essential and it does so. The search surface is left partly implicit but is recoverable from line_type in the schema; only pagination/limit behaviour and result ordering remain unaddressed for a 3-param tool.
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 text, limit, and line_type are already documented with examples, bounds, and an enum. The description only restates that matching is by team/participant name, adding no syntax or matching-rule detail beyond the schema, so baseline 3 applies.
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?
States a specific verb (find), resource (matches) and the search key (team or participant name), then names the sibling it is not (get_match) and why. An agent can distinguish it from list_live_matches, top_matches, and get_match without opening any schema.
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 a clear use context (lookup by team/participant name) and explicitly routes odds lookups to get_match, which is the key alternative. It stops short of stating when not to use it (e.g., browsing by tournament or country, which other siblings cover), so no full when/when-not pairing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
top_championshipsARead-onlyIdempotent
Up to 12 popular championships (tournaments) with their match counts, without esports. Use list_live_matches / list_prematch_matches with the tournament_id.
| Name | Required | Description | Default |
|---|---|---|---|
| line_type | No | 'live' = matches in progress, 'prematch' = matches not started yet. | prematch |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, idempotentHint, openWorldHint), so the bar is low. The description still adds real behavioral content the annotations lack: a hard cap of 12 results and the deliberate exclusion of esports, both of which affect interpretation of the output.
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?
Two short sentences, the result shape and scope constraints front-loaded, and the follow-up instruction second. No filler or restated boilerplate.
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?
There is no output schema, and the description compensates by naming the returned fields (championships plus match counts), the result cap, and the esports exclusion, plus how to use the returned id. Only the ranking criterion for 'popular' is left unstated.
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 single line_type parameter has 100% schema coverage with an enum and a description of both values, so the schema carries the meaning. The description only gestures at the live/prematch split indirectly by naming the two match-listing siblings; it adds no syntax or default guidance beyond 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?
States the resource (popular championships/tournaments) and the payload (match counts, capped at 12, esports excluded). It implicitly separates itself from list_tournaments via 'popular'/'without esports', though that contrast is never made explicit.
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?
Gives concrete downstream routing: take the tournament_id from here and feed it to list_live_matches or list_prematch_matches. It stops short of stating when to prefer this over list_tournaments or top_matches, so it is clear context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
top_matchesARead-onlyIdempotent
SportAPI's selection of up to 10 most popular matches right now (all sports, or one sport for Prematch). A quick answer to 'what are the big games?'.
| Name | Required | Description | Default |
|---|---|---|---|
| sport_id | No | Prematch only: top matches of this sport instead of all. | |
| line_type | No | 'live' = matches in progress, 'prematch' = matches not started yet. | live |
| include_odds | No | Include a short list of main odds per match. | |
| max_markets_per_match | No | Maximum markets shown per match (API order). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld and idempotent, so safety is covered. The description contributes the hard cap of 10 results and the Prematch-only caveat for sport scoping, which is genuine added context, but says nothing about ordering/freshness or how 'popular' is determined beyond the '(API order)' hint in the 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?
Two short sentences, zero waste, with the 10-match popularity scope front-loaded before the use-case gloss. Nothing redundant or padded.
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 an all-optional, four-parameter read tool with full schema coverage, annotations and no output schema, the description covers the essentials plus the result cap. It slightly under-serves by not clarifying ranking/freshness semantics or the live-vs-prematch differentiation that line_type exposes.
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 sport_id, line_type, include_odds and max_markets_per_match. The description only restates the sport_id Prematch-only restriction, adding no new parameter meaning beyond the structured fields; baseline 3 applies.
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 a concrete resource and quantifies scope: 'up to 10 most popular matches right now.' It is clearly a curated popularity-ranked list, distinct from list_live_matches/list_prematch_matches, but it never names those siblings to sharpen the distinction.
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 framing 'a quick answer to "what are the big games?"' implies the discovery/browse use case, which is helpful implied guidance. However it gives no explicit when-to-use-vs-alternatives routing, e.g. why to pick this over list_live_matches or search_matches.
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.
11 tool updates
v0.1.0- First observed
account_status - First observed
get_match - First observed
get_menu - First observed
list_countries - First observed
list_live_matches - First observed
list_prematch_matches - First observed
list_sports - First observed
list_tournaments - First observed
search_matches - First observed
top_championships - First observed
top_matches
TDQS
Scored across 11 tools
Most tools target distinct resources: navigation (sports/countries/tournaments), match listing (live/prematch), and details. Minor overlap exists between list_sports and get_menu without sport_id (both enumerate sports with match counts), and top_matches vs top_championships could be briefly confused, but descriptions clarify the distinction.
Strong verb_noun pattern (list_sports, get_match, search_matches, list_live_matches). Deviations are the 'top_' prefix tools (top_matches, top_championships) and the noun-style account_status, but these are minor and readable.
11 tools is well-scoped for a sports data API covering navigation, live/prematch listing, match detail, search, and account status. Each tool earns its place with no redundancy.
Covers the full navigation-to-detail lifecycle (sports -> countries -> tournaments -> matches -> match details) plus search and account status. Minor gaps like team/player info or head-to-head history aren't covered, but core live/prematch workflows are complete.
Maintenance
Related MCP Connectors
Live and prematch esports odds (ODDIN.GG feed) with no-vig fair prices. Free demo access, no key.
Sports odds, player props and source coverage for AI assistants. Connect with your own API key.
BetsAPI MCP — wraps BetsAPI (betsapi.com) sports events + odds.
Live and prematch FanDuel odds, price drops and feed health. No key, no signup.
Related MCP Servers
- AlicenseAqualityCmaintenanceGives your MCP host (Claude Desktop, Cursor, Continue, Zed) access to live scores, match details, standings, top scorers, knockout brackets and player stats across football, basketball, cricket and tennis. Backed by the free public SportScore API — no key, no signup, CORS-open.892 npm12MIT

Odds-API MCP Serverofficial
AlicenseAqualityAmaintenanceEnables AI assistants to access sports betting odds data from 265+ bookmakers across 34 sports, including events, odds, historical data, arbitrage, and value bets.22128 npm1MIT- AlicenseNot gradedqualityBmaintenanceEnables fetching sportsbook odds, live scores, and event information across 70+ books and 30+ leagues, with tools to list sports, get scores, and discover events.191 npm1MIT
- FlicenseBqualityDmaintenanceEnables access to live FotMob football data for fixture lookup, team and player research, match details, lineups, league discovery, and search-based entity lookup.278-