livetennisapi-mcp
Server Details
Live tennis scores, players, rankings, odds and win-probability. ATP, WTA, Challenger, ITF, juniors.
- Status
- Healthy
- Uptime
- 99.9% over 75 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- livetennisapi/livetennisapi-mcp
- GitHub Stars
- 148
- Server Listing
- livetennisapi-mcp
TDQS
Scored across 25 tools
Most tools are cleanly separated by resource and era, and the descriptions explicitly disambiguate the near-pairs (get_rankings vs get_player_rankings, get_archive_career vs player_stats, search_players vs search_archive_players). The main genuine collision is get_fixtures vs get_upcoming_matches, which both describe forward-looking schedules and will be easy to misselect. Live-viewing tools (get_match, get_match_score, get_live_matches, get_match_events, get_match_statistics) are distinguishable but numerous enough to need care.
The set is uniformly snake_case and almost entirely verb_noun (get_*, search_*, check_*), which makes the surface predictable. The notable deviation is player_stats, which is noun-first and semantically parallel to get_match_statistics / get_player, breaking the pattern for the same 'stats' concept. check_api_status is the only other mild outlier.
25 tools sits at the top of the 'heavy' band and is a lot for an agent to route between in one turn. The breadth is partly justified because the server covers four distinct sub-products (live, archive, charting, rankings), but the overlaps such as fixtures vs upcoming suggest some tools could be consolidated rather than each earning a distinct slot.
Coverage across live, scheduled, historical (1968-2022), charting, rankings, players, tournaments, h2h, odds, events and analysis is unusually thorough for a read-only API, with era and plan boundaries documented. Remaining gaps are modest: no tournament draw/bracket retrieval and no point-by-point listing beyond the derived event timeline.
Available Tools
25 toolscheck_api_statusAPI status and planARead-onlyIdempotentInspect
Check whether the Live Tennis API is reachable and which plan the configured key is on. Use it to find out why other tools are refusing data. Works with no key.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| tier | No | Detected plan: FREE, BASIC, PRO or ULTRA. Null when no key is configured. |
| has_key | No | Whether a key was configured for this tool set. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| reachable | No | True when the API answered its health check. |
| api_version | No | API version reported by the health check. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and open-world, so the description doesn't need to restate safety. It adds real value beyond that with 'Works with no key', telling the agent authentication is not a prerequisite, and by framing the result as a plan/health probe. It stops short of saying whether the check makes a network call that can be slow or rate-limited.
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 short sentences with no filler: what it checks, when to call it, and the no-key caveat. The primary purpose is front-loaded before the usage hint.
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 needn't enumerate return fields, and annotations cover the safety profile. For a no-argument diagnostic tool, naming the two checks and the no-auth behavior is everything an agent needs to call it 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?
Zero parameters, so there is nothing for the description to disambiguate. Baseline 4 applies; the free-text does not need to discuss inputs at all.
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 two concrete objects: reachability of the Live Tennis API and the plan tied to the configured key. That distinguishes it cleanly from every data-fetching sibling, none of which is a diagnostic 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?
'Use it to find out why other tools are refusing data' gives an explicit decision rule for reaching for this tool over the siblings. No exclusion cases are stated, but for a unique diagnostic endpoint there is no obvious alternative to route against.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_archive_careerArchive career aggregatesARead-onlyIdempotentInspect
One player's whole career over the results archive (1968 to 2022). W-L record in total and by surface/level/year, titles, and summed serve statistics. The corpus records serve stats from 1991 only, so matches_with_stats says how many matches the serve block covers. The name must resolve to one person. An ambiguous fragment returns the candidate list to choose from. Requires the BASIC plan or any History plan.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Player name fragment, min 3 chars. Must resolve to exactly one person. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| span | No | Career span inside the archive. |
| serve | No | Summed serve stats + derived ratios. matches_with_stats states the coverage. Ratios are null where the denominator is zero. |
| record | No | The W-L record. |
| by_year | No | Per-season W-L. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| player_name | No | The resolved player. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/idempotent/non-destructive, and the description adds genuinely new context: serve stats only exist from 1991 and matches_with_stats reports coverage, plus a plan/auth requirement (BASIC or any History plan) and the ambiguity return path. This is exactly the kind of disclosure that can't be inferred from structured fields.
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?
Five tight sentences, front-loaded with scope and contents, then caveats and prerequisites. Every sentence carries information, though the plan/entitlement sentence could be trimmed slightly.
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, return values needn't be spelled out; the description still conveys the shape of the result and the coverage caveat. Only the missing explicit route to a sibling for name resolution leaves a small 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 coverage is 100% and the schema already states "min 3 chars, must resolve to exactly one person," so the description's name constraint largely restates it. No additional syntax or format guidance is offered 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?
"One player's whole career over the results archive (1968 to 2022)" states a specific resource, scope and time coverage, then enumerates the aggregates returned (W-L total/by surface/level/year, titles, serve stats). That clearly separates it from sibling single-match tools like get_archive_match and search tools like search_archive_players.
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 states the key precondition (name must resolve to one person) and the fallback behavior (ambiguous fragment returns a candidate list to choose from), which tells the agent how to recover. It doesn't explicitly name search_archive_players as the disambiguation path or give exclusions versus get_player, so it falls 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.
get_archive_matchArchive result detailARead-onlyIdempotentInspect
One result from the results archive (1968 to 2022), with per-match serve statistics where the era recorded them. Stats are null for most rows before 1991, never synthesised. Requires the BASIC plan or any History plan.
| Name | Required | Description | Default |
|---|---|---|---|
| archive_match_id | Yes | Archive match id, as returned by search_archive_matches. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| stats | No | Per-match serve statistics (aces, double_faults, serve_points, first_in, first_won, second_won, serve_games, bp_saved, bp_faced). Null for most pre-1991 rows. |
| result | No | The archive result. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent safety, so the description spends its space on genuinely new behavior: null statistics before 1991, no synthesised values, and a BASIC/History plan requirement. That is exactly the kind of pre-call caveat annotations cannot express. It stops short of covering error behavior for missing ids or out-of-range years.
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 short sentences, front-loaded with what the resource is and immediately followed by the data-quality caveat and the access requirement. No filler and nothing repeated from structured fields.
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 needn't explain return shape; it usefully covers the era limitation and plan gating instead. Only the failure mode (invalid or out-of-range id) is left unaddressed.
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 single parameter is documented as coming from search_archive_matches, so the description adds nothing beyond the schema. 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+resource: a single result from the results archive, scoped 1968-2022, with serve statistics. The era range implicitly separates it from get_match / get_recent_results, but it never names the sibling that returns the same entity for the modern era.
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 through the id (an archive_match_id, matching search_archive_matches) and the plan prerequisite, but there is no explicit 'use this instead of X when...' or exclusion guidance against get_match or get_archive_career.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_charting_matchCharting: one match, every stat familyARead-onlyIdempotentInspect
Every charting stat family for ONE charted match, both players, with the per-set split (set 1, set 2, ..., Total) exactly as charted. Charting ids are their own id space (1960 to 2026). Most of these matches have no counterpart in the live tables. Requires the ULTRA plan.
| Name | Required | Description | Default |
|---|---|---|---|
| charting_match_id | Yes | Charting match id, in its own id space. Not a match_id. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| gender | No | |
| mcp_id | No | The charting dataset's own row identifier. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| players | No | Both players as charted. |
| families | No | Every stat family, per player, with the per-set split. |
| charting_match_id | No | The charted match. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, open-world behavior, so the bar is lower. The description still adds real value by disclosing the ULTRA plan gate, the id-space range, and the warning that these matches generally don't exist in the live tables, which is behavioral context an agent could not infer from 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?
Four short sentences, front-loaded with what is returned, then scope, id space, and plan requirement in descending order of importance. No filler or 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?
Details the return shape (per-set split through Total, both players), the id-space caveat, the plan prerequisite, and the non-overlap with live tables. Combined with existing annotations and an output schema, an agent has everything needed to call it 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% and the single parameter is already documented as being in its own id space. The description reinforces this with an explicit 1960-2026 range, which the schema does not state, adding modest extra semantic value.
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: every charting stat family for ONE charted match, both players, with per-set split. The 'ONE charted match, both players' scoping cleanly separates it from get_charting_player, which an agent can infer covers a single player.
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 strong selection context: charting ids live in their own id space (1960-2026), most charted matches have no live-table counterpart, and the ULTRA plan is required. It stops short of explicitly naming an alternative tool for live matches or the per-player variant, but the prerequisites and id-space warning make misuse unlikely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_charting_playerCharting: player career profileARead-onlyIdempotentInspect
Career profile from shot-level charting data, summed over the player's charted matches. Serve placement (deuce/ad x wide/body/T), return depth and outcomes, net play, and clutch break/game/set-point serving. Also winners and errors by wing, and rally-length tendencies. COVERAGE IS CURATED, not full-slate: 11,646 charted matches back to the 1960s, concentrated on the majors. An ambiguous name returns the candidates to choose from. Requires the ULTRA plan.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Player name fragment, min 3 chars. Must resolve to one charted person. | |
| gender | No | Disambiguates a name charted on both tours. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| player | No | The resolved charted player. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| coverage | No | A reminder that charting coverage is curated, not full-slate. |
| families | No | Per-family summed numeric columns: raw sums over the player's charted Total rows. |
| matches_charted | No | The sample every summed field covers. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnly/idempotent/openWorld already declare a safe, non-destructive read), the description discloses three things the annotations cannot: an ULTRA plan entitlement gate, a hard coverage window (~11,646 matches, majors-skewed), and the ambiguity fallback that returns candidate names rather than erroring. That is meaningful pre-call context for auth and reachability.
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?
Four sentences, all load-bearing: the first states what the profile contains, the second routes the reader to coverage limits, the third handles ambiguity, the fourth states the plan gate. Metric families are packed into a compact clause rather than prose padding, and the identity of the tool is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description is right not to explain return shapes, and it covers the remaining risk areas: entitlement, coverage skew, and name-resolution failure. The one gap is that a sibling named get_archive_career offers a broadly similar 'career profile', and the description never says which to pick when a player has both archive and charted data.
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 earns one extra by explaining the resolution contract for `name` — it must resolve to a single charted person, and an ambiguous fragment yields a candidate list to choose from. The `gender` disambiguator is left entirely to the schema, which is acceptable at full coverage.
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 specific resource (career profile) and its distinctive data source (shot-level charting), then enumerates the stat families returned: serve placement, return depth/outcomes, net play, clutch break/game/set-point serving, winners/errors by wing, rally-length tendencies. That is far more specific than the title alone. It does not, however, explicitly distinguish itself from the sibling get_archive_career, so an agent must infer the split from 'shot-level charting data'.
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?
'COVERAGE IS CURATED, not full-slate: 11,646 charted matches back to the 1960s, concentrated on the majors' is a strong when-to-use/when-not signal, and 'An ambiguous name returns the candidates to choose from' tells the agent how to recover from a failed resolution. What is missing is an explicit pointer to the alternative (get_archive_career, get_player) when the player is outside charted coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_fixturesFixture scheduleARead-onlyIdempotentInspect
Upcoming scheduled tennis fixtures, earliest first. This is the forward schedule, filterable by tour. Use this for "what is on this week". Works on the FREE plan (no card needed).
| Name | Required | Description | Default |
|---|---|---|---|
| tour | No | Tour filter. Each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used. | |
| limit | No | Maximum fixtures to return (1-200). |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| fixtures | No | Scheduled fixtures, earliest first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, open-world and non-destructive, so the safety profile is covered. The description earns credit by adding traits annotations cannot express: the guaranteed sort order (earliest first), the forward-looking window, and that it works on the free plan with no card required.
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 short sentences, front-loaded with the resource and its ordering, followed by the use case and the access constraint. 'This is the forward schedule' mildly repeats 'Upcoming scheduled', but nothing else is wasted.
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, return values need no explanation, and both parameters are fully documented. The description covers ordering, filtering intent and plan access. The only real gap is the unstated boundary against get_upcoming_matches.
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 tour parameter's enum plus its doubles/exhibition caveat is fully documented in the schema itself. The description only restates 'filterable by tour' and adds nothing on limit or ordering interaction, 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 resource and scope: upcoming scheduled tennis fixtures, returned earliest first, filterable by tour. That is much more than a restatement of the name. However, it never distinguishes itself from the sibling get_upcoming_matches, which an agent must otherwise infer from the 'fixtures' vs 'matches' wording.
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 a concrete selection scenario — 'what is on this week' — which tells the agent when this tool fits. It stops short of exclusions or naming the alternative to use for historical or live data, so the agent gets context but not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_h2hHead-to-headARead-onlyIdempotentInspect
The all-time record between two players, across BOTH halves of the product. That is the results archive (1968 to 2022) plus the completed matches from 2023 onward. Names are the keys. An ambiguous fragment returns the candidate list to choose from, and nothing is guessed. Totals count only meetings with a known winner. Walkovers and retirements are part of the record, and each meeting carries its outcome. Requires the BASIC plan or any History plan.
| Name | Required | Description | Default |
|---|---|---|---|
| player1 | Yes | First player name (fragment, min 3 chars), e.g. "federer". | |
| player2 | Yes | Second player name (fragment, min 3 chars), e.g. "nadal". |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| totals | No | The headline record. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| players | No | The resolved names. Null when no player matches the fragments. |
| meetings | No | Individual meetings, newest first, capped at 200. |
| by_surface | No | Decided wins per surface. The keys are surface names plus "unknown". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only annotations, the description discloses important behavior: it spans both data halves, does not guess on ambiguous names, counts only meetings with a known winner, includes walkovers and retirements, and carries each meeting's outcome. It also adds a plan requirement, which is useful operational context.
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 then adds relevant behavioral details. It is slightly longer than necessary, but nearly every sentence contributes useful calling context.
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 and full parameter descriptions, the description supplies the remaining important context: data coverage, ambiguity handling, counting rules, inclusion of walkovers/retirements, and plan requirements. Nothing essential for correct invocation 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 coverage is 100%, so parameter syntax is already well documented. The description adds meaningful semantics by explaining that names are keys and that ambiguous fragments return a candidate list rather than guessing.
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 resource: the all-time head-to-head record between two players. It also distinguishes the scope from archive-only tools by explicitly covering both the 1968-2022 archive and completed matches from 2023 onward.
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 clear usage context: names are the keys, ambiguous fragments return candidates, and a BASIC or History plan is required. It does not explicitly compare this tool to sibling alternatives, but the scope is specific enough that an agent can infer when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_live_matchesLive matchesARead-onlyIdempotentInspect
List tennis matches currently in progress, with live scores. Covers ATP, WTA, Challenger, ITF and juniors. Use this for "what tennis is on right now". Works on the FREE plan (no card needed).
| Name | Required | Description | Default |
|---|---|---|---|
| tour | No | Tour filter. Each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used. | |
| limit | No | Maximum matches to return (1-200). | |
| player | No | Player ids (from search_players), max 50. Keeps matches where ANY listed player is either participant. | |
| country | No | Either participant's country: the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| matches | No | The live matches, most relevant first. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive and open-world behavior, so the remaining burden is light. The description adds one genuinely new trait – availability on the FREE plan with no card – but says nothing about result caps, pagination, refresh cadence of 'live' scores, or behavior on empty results.
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?
Four short sentences, front-loaded with what the tool returns and followed by scope, usage cue and plan note. Slight redundancy in repeating the tour enum values, and the omission of the exhibition exclusion is a small missed detail rather than bloat.
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 and full parameter documentation, the description only needs to frame purpose, scope and access conditions – all of which it does. Minor gaps remain around ordering/refresh semantics of the live feed, but nothing that would cause a mis-call.
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 per-parameter meaning is already fully documented (including the non-ISO country code convention and the exhibition-exclusion rule). The description only restates the tour values, which duplicate the enum, and never mentions the player/country/limit filters. 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 tennis matches currently in progress, with live scores") and pins down scope with the tour list. It implicitly separates itself from get_upcoming_matches/get_recent_results via "currently in progress", but never names those siblings, so an agent must infer the boundary.
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 quoted intent "what tennis is on right now" gives a clear usage context an agent can match against a user request. No explicit exclusions or named alternatives are provided (e.g. 'use get_upcoming_matches for future fixtures'), which keeps it below a 5.
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
Full detail for one match by id: players, score, surface, round and status. Includes market prices on PRO and model analysis on ULTRA. Works on the FREE plan (no card needed).
| Name | Required | Description | Default |
|---|---|---|---|
| match_id | Yes | Match id, as returned by get_live_matches, get_upcoming_matches or get_recent_results. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| match | No | The match. |
| market | No | Match-winner market. Requires the PRO plan, absent otherwise. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| analysis | No | Model analysis. Requires the ULTRA plan, absent otherwise. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the description's real contribution is the entitlement behavior: the returned payload differs by subscription plan, with market prices only on PRO and model analysis only on ULTRA. That is non-obvious behavior an agent cannot get from structured fields, and it does not contradict the 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?
Two short sentences, front-loaded with what is returned before the plan-tier caveats. Efficient, though the plan sentence packs three distinct facts (FREE/PRO/ULTRA) into one dense clause.
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 return values need not be described, and the description still sketches the payload plus the plan-dependent variation, which is the main thing an agent could get wrong. The remaining gap is guidance on picking this over the narrower match-detail siblings.
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 the single match_id parameter is already documented in the schema, including where to obtain it. The description's 'by id' adds no syntax, format or constraint beyond that, 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 and resource ('Full detail for one match by id') and enumerates the payload fields (players, score, surface, round, status). 'Full detail' also implicitly distinguishes it from the narrower siblings get_match_score, get_match_statistics and get_match_events.
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 plan-tier notes ('Works on the FREE plan', market prices on PRO, model analysis on ULTRA) tell the agent about access gating, which is useful. However, nothing explicitly says when to call this instead of get_match_analysis, get_match_statistics or get_match_events, so sibling routing is left to inference from the word 'Full'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_match_analysisModel analysisARead-onlyIdempotentInspect
Model analysis for a match: predicted win probability, the model's thesis and the main factors behind it. Requires the ULTRA plan. Match rows carry has_analysis, so check it first. A match with no thesis or profile has nothing to return.
| Name | Required | Description | Default |
|---|---|---|---|
| match_id | Yes | Match id, as returned by get_live_matches, get_upcoming_matches or get_recent_results. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| thesis | No | Narrative view. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| profile | No | Quantitative view. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, it discloses a hard subscription gate (requires the ULTRA plan) and an empty-result condition tied to the has_analysis flag. These are exactly the operational facts an agent needs and that annotations cannot express.
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?
Four tight sentences, front-loaded with what the tool returns, then plan requirement, then the gating check. No redundant restatement of the name or title.
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 needn't describe return shapes, and it still sketches them. Auth gating and the has_analysis precondition close the remaining gaps for a single-parameter read 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% and the single match_id parameter already documents its provenance (get_live_matches, get_upcoming_matches, get_recent_results). The description adds no further parameter detail, 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+resource (model analysis for a match) and enumerates the payload: predicted win probability, the model's thesis, and the main factors. This clearly separates it from statistics/odds siblings, 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?
Gives a concrete pre-check ('Match rows carry has_analysis, so check it first') and an explicit when-not condition ('A match with no thesis or profile has nothing to return'). The prerequisite is stated up front, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_match_eventsMatch timelineARead-onlyIdempotentInspect
Timeline of events for a match: breaks, games won, sets won, momentum runs. Requires the PRO plan.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum events to return (1-200). | |
| match_id | Yes | Match id, as returned by get_live_matches, get_upcoming_matches or get_recent_results. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| events | No | Events, newest first, as the API returns them. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered structurally. The description's only added behavioral fact is the PRO plan entitlement, which is genuinely useful gating context, but it says nothing about pagination (limit truncation) or ordering of the timeline.
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, front-loaded with the resource and its contents, then the hard prerequisite. Nothing is wasted and no sentence merely restates 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?
An output schema exists, so return values need not be explained, and the PRO-gated access plus the event taxonomy covers what an agent needs to call it. The one gap is that a truncated timeline (limit default 30 of up to 200) is not flagged as a partial result.
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%: match_id provenance and the limit range/default are fully documented in the schema. The description adds no parameter meaning beyond that, 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?
Names a specific resource (match event timeline) and enumerates the event kinds returned (breaks, games won, sets won, momentum runs), which separates it from statistics/analysis siblings. It never names a sibling explicitly, so differentiation is by content rather than by routing.
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 only implied by the enumerated content — an agent can guess this is for sequence-level events rather than aggregates. No when-not-to-use and no pointer to get_match_statistics or get_match_analysis, which are the obvious near-neighbors.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_match_oddsMatch market pricesARead-onlyIdempotentInspect
Match-winner market prices for a match: implied probability per player, with bid, ask and mid. Requires the PRO plan. Match rows carry has_market, so check it first. A match with no market mapped has no prices to return.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum price points to return (1-200). | |
| match_id | Yes | Match id, as returned by get_live_matches, get_upcoming_matches or get_recent_results. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| market | No | The match-winner market. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent safety, so the description correctly spends its words on what annotations can't say: the PRO plan requirement and the empty-result behavior for unmapped markets. It does not mention rate limits or result ordering, which keeps it short of 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?
Four short sentences, front-loaded with what is returned, then the plan requirement, then the precondition. Each sentence carries a distinct, actionable fact.
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 tool with a full output schema and complete schema coverage, the remaining unknowns are access requirements and empty-result cases, and both are covered here.
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% – both match_id and limit are already documented, including where match_id comes from. The description adds no parameter-level detail 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: match-winner market prices for a given match, and names the exact payload (implied probability per player plus bid, ask, mid). No sibling tool covers markets, so an agent can route here without opening the 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?
Gives an explicit precondition ('Match rows carry has_market, so check it first') and a clear failure condition ('A match with no market mapped has no prices to return'), plus the PRO plan gate. It doesn't point at alternatives, but none of the siblings overlap with market pricing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_match_scoreMatch scoreARead-onlyIdempotentInspect
Current score for one match. This is the fastest read, with the lowest latency. Use it when you only need the score and already know the match id. Works on the FREE plan (no card needed).
| Name | Required | Description | Default |
|---|---|---|---|
| match_id | Yes | Match id, as returned by get_live_matches, get_upcoming_matches or get_recent_results. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| score | No | The current score. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and non-destructive behavior, so the description's added value is the latency claim ('fastest read, lowest latency') and the FREE-plan/no-card availability note. Those are genuine operational facts an agent cannot get from annotations, though the return shape is left entirely to the 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?
Three short sentences, front-loaded with what the tool returns, followed by the performance positioning and the access constraint. No sentence is redundant or buried.
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 return values need no explanation, and annotations cover the safety profile. The description supplies usage, latency, and plan access, leaving only minor unaddressed cases such as behavior for an invalid or finished match id.
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?
A single parameter with 100% schema coverage, including where match_id comes from (get_live_matches, get_upcoming_matches, get_recent_results). The description only echoes 'already know the match id' and adds no format or validation detail beyond the schema, matching the baseline for full-coverage schemas.
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 ('Current score for one match') and implicitly positions itself against the heavier match siblings via 'when you only need the score.' It does not name a specific alternative (e.g., get_match or get_match_statistics), so differentiation is implied rather than 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 a clear when-to-use rule and precondition: use when you only need the score and already know the match id. It lacks an explicit when-not-to-use or a named alternative for richer data needs, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_match_statisticsMatch statisticsARead-onlyIdempotentInspect
In-play (or final) statistics for one match, in TWO families kept separate on purpose. DERIVED is rebuilt from the point-by-point record (holds/breaks, break points, service/return points). MEASURED is counted per match. It includes what no point record can yield: aces, double faults, the serve split, winners/unforced errors. Measured coverage varies by tour. Absent fields are omitted, never zero-filled. Requires the ULTRA plan.
| Name | Required | Description | Default |
|---|---|---|---|
| match_id | Yes | Match id, as returned by get_live_matches, get_upcoming_matches or get_recent_results. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| statistics | No | The statistics. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only, idempotent, open-world profile, so the bar is lower. The description adds genuinely useful behavioral context beyond them: the ULTRA plan requirement, tour-dependent coverage of measured stats, and the non-zero-filling omission policy.
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-loads the core claim (in-play or final statistics for one match) and then explains the derived/measured split efficiently. Slightly dense, but every sentence carries information about scope, coverage, or requirements.
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 return-value details need not be restated, and annotations cover the safety profile. The description fills the remaining gaps an agent needs: the two-family structure, omitted-vs-zero semantics, variable coverage, and the plan prerequisite.
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?
There is only one parameter, and the schema documents match_id at 100% coverage, including where to obtain it from live, upcoming, or recent results tools. The description adds no parameter-specific semantics beyond that baseline.
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: statistics for one match, split into DERIVED and MEASURED families, with examples of the metrics in each. It is clear what the tool returns, but it does not explicitly differentiate itself from nearby siblings like get_match_analysis or get_match_score.
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?
Implies usage by saying it covers in-play or final statistics for a single match, which signals when it applies. However, it offers no explicit when-not guidance or alternatives, so the agent must infer whether get_match_analysis or get_match_score is more appropriate for a given need.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_playerPlayer profileARead-onlyIdempotentInspect
One player's profile: ranking, country, handedness, date of birth and cached stats. Works on the FREE plan (no card needed).
| Name | Required | Description | Default |
|---|---|---|---|
| player_id | Yes | Player id, as returned by search_players. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| player | No | The player. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
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 useful behavioral context beyond annotations by noting that stats are cached and that the tool works on the FREE plan without a card.
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 two tightly written sentences with no waste. The core profile content and the FREE-plan note are front-loaded and easy to scan.
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 return values need not be explained. The description is nearly complete for a low-complexity single-parameter lookup, though it could explicitly distinguish the tool from related player stats and ranking tools.
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 the schema itself states that player_id is the player ID returned by search_players. The description adds no further parameter semantics, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource as one player's profile and enumerates its fields: ranking, country, handedness, date of birth, and cached stats. It does not explicitly differentiate itself from siblings like player_stats, get_player_rankings, or get_charting_player, so it falls short of a 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?
The description implies usage by noting the player_id comes from search_players and that the tool works on the FREE plan. However, it does not explicitly state when to use this instead of siblings such as player_stats or get_player_rankings, leaving alternatives to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_player_rankingsPlayer rankings as of a dateARead-onlyIdempotentInspect
Point-in-time ranking records for SPECIFIC players. Per system, the newest record in force ON OR BEFORE as_of, never one dated after it. Every other ranking field in this API is the CURRENT value joined at read time. This one is the historical answer. Systems are never collapsed: ATP/WTA and the ITF circuits carry rank+points, UTR a rating. ITF and UTR history begins 2026-07-29. Requires the ULTRA plan.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | No | YYYY-MM-DD. The record in force on this date. Omit for the latest known. | |
| system | No | Restrict to one system. Omit for every system held for the player. | |
| player_ids | Yes | Roster player ids, as returned by search_players. Max 50. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| coverage | No | What resolved against what was asked (players_resolved, systems_resolved, oldest_available per system). Read before trusting an empty result. |
| rankings | No | One record per player × system held. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds substantial context beyond them: the ULTRA plan requirement, the 2026-07-29 history floors for ITF and UTR, the rule that systems are never collapsed, and the guarantee that no record dated after as_of is returned. These are exactly the operational constraints an agent needs.
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 core scope and contrast in the first two sentences, then supporting constraints. It is dense and every sentence carries information, though the terse, fragmented phrasing pushes slightly toward telegraphic rather than economical.
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 tool with an output schema present, the description supplies the plan gating, data availability windows, per-system field differences, and the exact as_of semantics. Little an agent needs in order 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 coverage is 100%, so the baseline would be 3, but the description adds genuine semantics the schema lacks: 'newest record in force ON OR BEFORE as_of, never one dated after it' sharpens the as_of boundary condition, and 'systems are never collapsed' clarifies the system parameter's behavioral effect. It also notes which fields each system carries (rank+points vs rating).
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 ('point-in-time ranking records for SPECIFIC players') and explicitly contrasts with the rest of the API whose ranking fields are 'CURRENT value joined at read time', which cleanly separates it from the get_rankings sibling. An agent can identify the historical variant without opening a 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?
The description gives a clear usage context ('This one is the historical answer', 'SPECIFIC players', 'Requires the ULTRA plan'), which tells the agent when the tool is appropriate. It does not name the alternative tool (get_rankings) explicitly or state exclusions such as bulk-listing, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_rankingsRankings listingARead-onlyIdempotentInspect
The FULL published ranking table in rank order for one system, from the newest week at or before as_of. Rows carry player_name as published and a null player_id for players outside our roster, so the table has no silent holes. ATP/WTA history runs deep. The ITF circuits begin 2026-07-29. For point-in-time records of SPECIFIC players use get_player_rankings. Requires the PRO plan.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | No | YYYY-MM-DD. Serves the newest published week at or before this date. Omit for latest. | |
| limit | No | Maximum ranking rows to return (1-200). | |
| system | Yes | Ranking system to list. utr has no listing, because it is a rating, not a ranking. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| rankings | No | The table in rank order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is a safe, read-only, idempotent operation. The description adds meaningful context beyond annotations: null player_id behavior for unrostered players, no silent holes, ATP/WTA historical depth, ITF start date, and PRO plan access.
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 then adds only operationally useful details about roster gaps, historical coverage, alternatives, and access. Every sentence contributes to correct tool selection or 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?
Given the rich annotations, complete input schema, and existing output schema, the description provides enough context for correct selection and invocation. It covers scope, historical availability, null handling, alternatives, and auth without redundantly explaining return values.
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 explains as_of, limit, and system. The description reinforces the as_of week-selection behavior and system scope but does not add parameter-level semantics beyond what the schema 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: it returns the full published ranking table in rank order for one system. It also distinguishes this listing tool from get_player_rankings, which is for point-in-time records of specific players.
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 explicitly names the alternative for player-specific ranking history and gives the condition for choosing it. It also states the PRO plan requirement, so the agent knows the access prerequisite before calling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recent_resultsRecent resultsARead-onlyIdempotentInspect
Recently completed tennis matches with final scores and winners. Filterable by tour, player, nationality and play date. Requires the BASIC plan or any History plan.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Latest play date: YYYY-MM-DD or ISO-8601. Must not precede from. | |
| from | No | Earliest play date: YYYY-MM-DD (a whole UTC day) or ISO-8601 datetime. | |
| tour | No | Tour filter. Each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used. | |
| limit | No | Maximum matches to return (1-200). | |
| player | No | Player ids (from search_players), max 50. Keeps matches where ANY listed player is either participant. | |
| country | No | Either participant's country: the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| matches | No | Completed matches, most recent first. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a safe, idempotent read (readOnlyHint, idempotentHint, destructiveHint=false), so the description does not need to carry the safety profile. It adds one genuinely useful behavioral fact — the BASIC/History plan requirement — but omits the recency window, default limit, and result ordering.
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: purpose first, filters second, access requirement last. No redundant wording or wasted clauses.
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 return values need not be explained, and annotations cover the safety profile. The remaining critical gap is that 'recently' is never operationally defined — an agent does not know the time window or whether results are capped by default — which matters for deciding between this and archive/live siblings.
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 fully documents each parameter (date formats, IOC codes, tour doubles behavior, player matching semantics). The description merely restates the filter categories ('tour, player, nationality and play date') without adding syntax, constraints, or interpretation 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+resource ('Recently completed tennis matches') with scope details ('final scores and winners') and filter dimensions. It implicitly separates itself from get_live_matches/get_fixtures/get_upcoming_matches via 'completed', but never names a sibling, so differentiation is inference-based rather than 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?
The context of 'recently completed' implies when to use it, and the plan requirement is a useful prerequisite. However, there is no explicit guidance on when to prefer it over search_archive_matches, get_match, or get_h2h, and no stating of the recency window or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tournamentTournament detailARead-onlyIdempotentInspect
One tournament by its stable id, the tournament_id carried on match objects. Name, tour, surface, indoor, plus host city/country and category where curated. Works on the FREE plan (no card needed).
| Name | Required | Description | Default |
|---|---|---|---|
| tournament_id | Yes | Stable tournament id, as returned by search_tournaments or carried on a match as tournament_id. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| tournament | No | The tournament. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. The description adds real context beyond them: the FREE-plan/no-card constraint and the 'where curated' qualifier warning that host city/country/category may be absent. It does not discuss error behavior for a bad id.
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 compact sentences, front-loaded with the resource and identifier, then the payload, then pricing. No filler; 'where curated' is the only slightly vague phrase.
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 return shape needn't be explained, yet the description still previews key fields. For a single-read lookup with full schema coverage and rich annotations, an agent has everything needed to invoke it correctly; only malformed-id behavior is unaddressed.
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 single parameter is fully documented in the schema, so the baseline is 3. The description reinforces provenance (stable id, carried on match objects) but adds no format or validation detail 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+resource (fetch one tournament by stable id) and enumerates the returned fields (name, tour, surface, indoor, host city/country, category), which tells an agent exactly what this is versus the search_tournaments sibling. It stops short of naming the sibling 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?
Gives a practical sourcing hint — the id is 'the tournament_id carried on match objects' — which implies the workflow of going through matches, and mentions the FREE plan so the agent knows no paid tier is required. No explicit when-not or named alternative, so usage is implied rather than prescribed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_upcoming_matchesUpcoming matchesARead-onlyIdempotentInspect
List tennis matches scheduled to start soon, with players, tournament and start time. Use this for "who plays next" or to find a match id before it starts. Works on the FREE plan (no card needed).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Latest play date: YYYY-MM-DD or ISO-8601. Must not precede from. | |
| from | No | Earliest play date: YYYY-MM-DD (a whole UTC day) or ISO-8601 datetime. | |
| tour | No | Tour filter. Each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used. | |
| limit | No | Maximum matches to return (1-200). | |
| player | No | Player ids (from search_players), max 50. Keeps matches where ANY listed player is either participant. | |
| country | No | Either participant's country: the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| matches | No | Matches due to start, soonest first. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so safety is covered elsewhere. The description adds two genuine nuggets: the tool works on the free plan, and returned ids feed downstream lookups. It says nothing about ordering, default time window, or whether an omitted range widens the result, which is the behavior an agent would most want.
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 core purpose and payload front-loaded, followed by the routing hint. Nothing is 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?
An output schema exists and every parameter is fully described in the schema, so the description does not need to explain returns. The only shortfall is the unstated default time horizon for 'soon', which matters for an all-optional-parameter tool but is minor.
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 each parameter already documents its format, enum, and edge cases (e.g. IOC-style country codes, tour doubles variants). The description repeats none of this and adds no parameter-level meaning, 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 and resource ('List tennis matches scheduled to start soon') plus the payload fields (players, tournament, start time). That implicitly separates it from get_live_matches and get_recent_results, but no sibling is named, so the differentiation is inferred rather than 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 a concrete use case ('who plays next') and a second, actionable one (find a match id before it starts, implying later use with get_match). No when-not-to-use guidance or explicit exclusion of live/finished matches beyond the word 'upcoming'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
player_statsPlayer record and splitsARead-onlyIdempotentInspect
One player's record over completed singles matches from 2023 onward, by default the last 365 days. It gives W/L overall, over the last 12 months and by surface, venue, level and season. It also gives tiebreaks, deciding sets, the record after winning or losing the first set, comebacks, withdrawals and the last N matches. Every count carries its sample size, and a percentage on an empty sample is null, never 0. On ULTRA it adds serve_return: measured serve and return statistics summed over the window. Singles only, so a doubles-team id is refused. For 1968 to 2022 use get_archive_career. Requires the PRO plan (serve_return requires ULTRA).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Window end: YYYY-MM-DD (the whole of that day) or a UTC ISO-8601 instant. Default now. | |
| from | No | Window start: YYYY-MM-DD (start of that day) or a UTC ISO-8601 instant. Default to minus 365 days. | |
| last | No | How many recent matches to list, newest first (1-50, default 20). | |
| level | No | The match tour. A match with no stated tour matches no level. | |
| surface | No | hard, clay or grass read the match surface; indoor keeps matches stated indoor, on any surface. | |
| player_id | Yes | Player id, as returned by search_players. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| sets | No | Set-based record: sample, tiebreaks, deciding_sets, after_winning_first_set, after_losing_first_set, comebacks, sets. |
| player | No | The player. |
| recent | No | The last N matches, newest first. |
| window | No | The window applied, UTC. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| overall | No | W/L over the window. |
| by_level | No | W/L keyed by match tour, or unknown. |
| by_venue | No | W/L keyed indoor, outdoor, unknown. |
| by_season | No | W/L keyed by UTC calendar year. |
| by_surface | No | W/L keyed hard, clay, grass, unknown. |
| withdrawals | No | Retired / walkover / default, each as given (this player) and received (the opponent). |
| serve_return | No | ULTRA only, null below: summed serve and return statistics, each ratio as numerator/denominator/pct with its match count. |
| last_12_months | No | W/L over the 12 months ending at the window end. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover safety (readOnly/idempotent), so the description carries the disclosure burden and does it: plan gating, tier-dependent extra field, the null-not-zero convention for empty samples, sample sizes on every count, and the singles-only refusal. That is real behavioral context beyond structured fields.
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-loads scope and default window, then enumerates the aggregate blocks, then the caveats and gating, then the sibling route-out. Every sentence carries information; nothing is repeated from the schema verbatim.
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?
Despite an output schema, it usefully previews the return shape (W/L splits, tiebreaks, deciding sets, serve_return) and the null semantics, and covers plan gating. Minor gap: filtering interactions between the top-level surface/level params and the by-surface/by-level breakdowns are not spelled out.
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; the description earns above that by explaining what the window means in terms of the aggregates (overall, last 12 months, by surface/venue/level/season) and that `last` controls the recent-match listing. It adds semantic framing the per-param text does not.
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 concrete verb and resource: one player's record over completed singles matches, with an explicit default window (last 365 days) and a floor (2023 onward). It is clearly distinguishable from get_player, get_recent_results and get_archive_career, the latter 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?
Gives explicit routing: use get_archive_career for 1968-2022, and PRO is required while serve_return requires ULTRA. It also states a hard exclusion (doubles-team ids are refused), so an agent knows when this tool is the wrong one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_archive_matchesResults archive (1968–2022)ARead-onlyIdempotentInspect
Search the results archive: completed-match RESULTS from 1968 through 2022. ATP and WTA, main draws, qualifying and the ITF/futures tiers. Each record has winner and loser, final score, and seeds and ranks AT THE TIME of the match. Use this for historical questions ("Borg's Wimbledon finals"). The archive ends 2022-12-31, where the current results (get_recent_results) begin. Requires the BASIC plan or any History plan.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Latest tournament START date, YYYY-MM-DD. | |
| from | No | Earliest tournament START date, YYYY-MM-DD. | |
| tour | No | atp or wta. | |
| level | No | Tier code: G=grand slam, M=masters, A=tour, F=finals, D=davis cup, C=challenger, O=olympics. Or a futures category code (e.g. 15). | |
| limit | No | Maximum results to return (1-200). | |
| round | No | Round code, e.g. F for finals. | |
| player_name | No | Case-insensitive fragment of EITHER player's name, min 3 chars, e.g. "borg". |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| results | No | Archive results, newest tournament first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive behavior, so the description only needs supplementary context — it adds the plan/entitlement requirement and the hard archive cutoff. It does not discuss rate limits or result ordering, keeping it just under 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?
Front-loaded with the core verb and scope, and the boundary with the sibling tool comes before the plan note. Dense but nearly every clause carries information; slightly longer than strictly needed.
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?
Output schema and annotations already cover return shape and safety, and the description fills in scope, tiers, and the archive cutoff. Only minor gaps remain (ordering, pagination behavior beyond the limit parameter).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter has an inline description, so the schema carries the semantics; the description adds only the 'seeds and ranks at the time' interpretation of returned fields rather than parameter guidance. 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?
Specific verb plus resource with explicit scope ('completed-match RESULTS from 1968 through 2022'), tours and tiers covered, and what each record contains. It is clearly distinguishable from get_recent_results by the stated 2022-12-31 archive boundary.
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 an explicit when-to-use trigger (historical questions like "Borg's Wimbledon finals") and names the alternative, get_recent_results, along with the date boundary that separates them. It also states the subscription prerequisite.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_archive_playersArchive player biosARead-onlyIdempotentInspect
The people of the results archive (1968 to 2022): hand, date of birth, country, height, and career-high rank with the week it was first reached. Their ids are corpus person ids (the winner/loser player_id on archive results), not roster ids. For current players use search_players. Requires the BASIC plan or any History plan.
| Name | Required | Description | Default |
|---|---|---|---|
| tour | No | atp or wta. | |
| limit | No | Maximum players to return (1-200). | |
| query | Yes | Full or partial player name, min 3 chars, e.g. "navratilova". |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| players | No | Matching archive people, ordered by name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description goes further with two things structured data does not carry: the plan requirement and the crucial id-space warning that ids are corpus person ids (winner/loser player_id on archive results), not roster ids. Return-shape detail is deferred to the output schema, which is appropriate.
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 ordered as scope → id semantics → alternative routing, which is the right priority. Minor deductions for the awkward opening 'The people of the results archive' and the ambiguous bare token 'hand' instead of 'handedness'.
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 to explain returns, all three params are schema-documented, and the description still covers the things schema and annotations cannot: plan entitlement and id provenance. Nothing needed to select or invoke 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?
Schema description coverage is 100%, with query (min 3 chars, example), tour enum, and limit bounds all documented in the schema. The description adds no syntax or semantics beyond that, so it lands at the baseline for fully-covered schemas.
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 (search the results archive for player bios) with an explicit scope of 1968–2022 and the fields returned (hand, DOB, country, height, career-high rank). It is unambiguously distinguishable from search_players, which it names.
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: 'For current players use search_players,' isolating this tool to historical/archive lookups. It also states the entitlement condition (BASIC plan or any History plan), which is a genuine gate on when the call will succeed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_playersSearch playersARead-onlyIdempotentInspect
Search tennis players by name. Returns id, country, ranking and tour. Use the returned id with get_player. Works on the FREE plan (no card needed).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum players to return (1-200). | |
| query | Yes | Full or partial player name, e.g. "alcaraz". |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| players | No | Matching players, best match first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and open-world, so the safety profile is covered. The description adds two genuinely new facts — the free-plan/no-card constraint and the id hand-off to get_player — but says nothing about result ordering or empty-result behavior beyond that.
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 short sentences, each carrying a distinct payload: what it searches, what it returns, and how to continue. The purpose is front-loaded and there is 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 an output schema and full annotation coverage, the description only needs to cover behavior and chaining, which it does. The one gap is that an agent cannot tell from this text when to prefer search_archive_players over this 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 description coverage is 100%, with both query (partial name matching, example) and limit (1-200) documented inline. The phrase "by name" reinforces query semantics but adds nothing 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 ("Search tennis players by name") plus the returned fields, so the agent knows exactly what it retrieves. It does not distinguish itself from the sibling search_archive_players, leaving ambiguity about which search to pick.
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 forward: "Use the returned id with get_player," which is a concrete next-step rule. It offers no when-not conditions and never mentions search_archive_players as the alternative for historical data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_tournamentsTournament catalogueARead-onlyIdempotentInspect
Search the tournament catalogue. Its ids are the tournament_id that match objects carry. Returns surface, indoor, host city/country and category where curated. Works on the FREE plan (no card needed).
| Name | Required | Description | Default |
|---|---|---|---|
| tour | No | Restrict to one tour. | |
| limit | No | Maximum tournaments to return (1-200). | |
| query | No | Full or partial tournament name, e.g. "wimbledon". Omit to list all. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message. |
| message | Yes | Human-readable summary of the result, safe to relay to the user verbatim. |
| tournaments | No | Matching tournaments, name order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds the useful access-tier fact (free plan, no card), but says nothing about result ordering, rate limits, or behavior when query matches nothing. It also lists return fields, which the output schema already carries.
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?
Four short sentences, front-loaded with the core verb+resource and the id linkage immediately after. The return-field sentence is partially redundant with the output schema, and "where curated" is vague, but nothing is 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?
With an output schema present, the return-value burden is lifted and the annotations cover safety. The description still conveys scope, empty-query behavior, the id handoff to match objects, and plan eligibility. Only result ordering and match semantics remain unstated, which are minor for a free-text search.
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%, including the tour enum and the limit bound of 1-200, so the description need not restate parameter mechanics. It adds no semantics beyond the schema — no guidance on matching behavior (case sensitivity, partial word matching) for query, which is the one thing the schema does not say.
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?
"Search the tournament catalogue" is a specific verb+resource, and the note that its ids are the tournament_id carried by match objects makes the catalogue's role in the data model concrete. It stops short of naming get_tournament as the follow-up sibling, so differentiation from that lookup tool is implied rather than stated.
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 concrete invocation guidance: "Omit to list all" for the query parameter and the note that the tool works on the FREE plan with no card. It lacks an explicit when-not clause or a pointer to get_tournament for single-record lookup, leaving the sibling boundary to inference.
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.
25 tool updates
- Changed
check_api_status4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / properties / has_key / descriptionPrevious value: -"Whether a key was supplied with this call."New value: +"Whether a key was configured for this tool set." - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_archive_career5 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"Player name fragment, min 3 chars — must resolve to exactly one person."New value: +"Player name fragment, min 3 chars. Must resolve to exactly one person." - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / record / properties / by_level / descriptionPrevious value: -"W-L per source tier code."New value: +"W-L per tier code." - changed
Output schema / properties / serve / descriptionPrevious value: -"Summed serve stats + derived ratios. matches_with_stats states the coverage; ratios are null where the denominator is zero."New value: +"Summed serve stats + derived ratios. matches_with_stats states the coverage. Ratios are null where the denominator is zero."
- Changed
get_archive_match9 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / result / properties / event_date / descriptionPrevious value: -"The tournament START date — per-match dates do not exist in this era’s records."New value: +"The tournament START date. Per-match dates do not exist in this era's records." - changed
Output schema / properties / result / properties / level / descriptionPrevious value: -"Source tier code: G, M, A, F, D, C, O, or a futures category code."New value: +"Tier code: G, M, A, F, D, C, O, or a futures category code." - changed
Output schema / properties / result / properties / outcome / descriptionPrevious value: -"completed, retired, walkover, default or abandoned — parsed, null when unparseable."New value: +"completed, retired, walkover, default or abandoned. Parsed, null when unparseable." - changed
Output schema / properties / result / properties / tour / descriptionPrevious value: -"atp or wta — the results archive covers those two tours."New value: +"atp or wta. The results archive covers those two tours." - changed
Output schema / properties / result / properties / winner / descriptionPrevious value: -"The winner — a stored field in the corpus, never an inference."New value: +"The winner, a stored field in the corpus, never an inference." - changed
Output schema / properties / result / properties / winner / properties / entry / descriptionPrevious value: -"Draw entry where recorded (WC, Q, LL, …) — null for direct acceptances."New value: +"Draw entry where recorded (WC, Q, LL, ...). Null for direct acceptances." - changed
Output schema / properties / result / properties / winner / properties / player_id / descriptionPrevious value: -"Corpus person id — pass to search_archive_players results to join bios. NOT a roster player id."New value: +"Corpus person id. Join it to search_archive_players results for bios. NOT a roster player id."
- Changed
get_charting_match4 fields changed- changed
Input schema / properties / charting_match_id / descriptionPrevious value: -"Charting match id — its own id space, not a match_id."New value: +"Charting match id, in its own id space. Not a match_id." - changed
Output schema / properties / mcp_id / descriptionPrevious value: -"The Match Charting Project's own row identifier."New value: +"The charting dataset's own row identifier." - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_charting_player4 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"Player name fragment, min 3 chars — must resolve to one charted person."New value: +"Player name fragment, min 3 chars. Must resolve to one charted person." - changed
Output schema / properties / families / descriptionPrevious value: -"Per-family summed numeric columns — raw sums over the player's charted Total rows."New value: +"Per-family summed numeric columns: raw sums over the player's charted Total rows." - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_fixtures6 fields changed- changed
Input schema / properties / tour / descriptionPrevious value: -"Tour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used."New value: +"Tour filter. Each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used." - changed
Output schema / properties / fixtures / items / properties / event_date / descriptionPrevious value: -"Scheduled start, ISO timestamp."New value: +"Scheduled date, YYYY-MM-DD." - added
Output schema / properties / fixtures / items / properties / start_timeAdded value: +{ + "description": "Scheduled start, UTC ISO-8601. Null until the order of play assigns a time.", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / fixtures / items / requiredPrevious value: -[ - "event_date", - "tournament", - "round", - "player1", - "player2" -]New value: +[ + "event_date", + "start_time", + "tournament", + "round", + "player1", + "player2" +] - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_h2h9 fields changed- changed
Output schema / properties / by_surface / descriptionPrevious value: -"Decided wins per surface; keys are surface names plus \"unknown\"."New value: +"Decided wins per surface. The keys are surface names plus \"unknown\"." - changed
Output schema / properties / meetings / items / properties / era / descriptionPrevious value: -"\"archive\" (results archive, 1968-2022) or \"current\" (our own completed matches, 2023 onward)."New value: +"\"archive\" (results archive, 1968-2022) or \"current\" (completed matches from 2023 onward)." - changed
Output schema / properties / meetings / items / properties / match_id / descriptionPrevious value: -"Our match id (current era rows) — pass to get_match."New value: +"Our match id (current era rows). Pass to get_match." - changed
Output schema / properties / meetings / items / properties / outcome / descriptionPrevious value: -"completed, retired, walkover, … — exclude non-completed yourself if needed."New value: +"completed, retired, walkover, ... Exclude non-completed yourself if needed." - changed
Output schema / properties / meetings / items / properties / score / descriptionPrevious value: -"Final score (archive rows only — read current rows from get_match)."New value: +"Final score (archive rows only. Read current rows from get_match)." - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / players / descriptionPrevious value: -"The resolved names; null when no player matches the fragments."New value: +"The resolved names. Null when no player matches the fragments." - changed
Output schema / properties / totals / properties / undecided / descriptionPrevious value: -"Meetings with no derivable winner — never counted in wins."New value: +"Meetings with no derivable winner. Never counted in wins."
- Changed
get_live_matches13 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Either participant's country — the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match."New value: +"Either participant's country: the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match." - changed
Input schema / properties / player / descriptionPrevious value: -"Player ids (from search_players), max 50 — keeps matches where ANY listed player is either participant."New value: +"Player ids (from search_players), max 50. Keeps matches where ANY listed player is either participant." - changed
Input schema / properties / tour / descriptionPrevious value: -"Tour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used."New value: +"Tour filter. Each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used." - changed
Output schema / properties / matches / items / properties / event_status_updated_at / descriptionPrevious value: -"The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced — never backfilled."New value: +"The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced. Never backfilled." - changed
Output schema / properties / matches / items / properties / round_code / descriptionPrevious value: -"Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed."New value: +"Round in the normalized vocabulary (F, SF, QF, R16 ... Q). Null when the label is unrecognised, never guessed." - added
Output schema / properties / matches / items / properties / scheduled_timeAdded value: +{ + "description": "Scheduled start, UTC ISO-8601. Null when no start time is set yet.", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / matches / items / properties / status / descriptionPrevious value: -"One of live, upcoming or completed."New value: +"One of live, upcoming, completed or cancelled." - changed
Output schema / properties / matches / items / properties / tour / descriptionPrevious value: -"atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events)."New value: +"atp, wta, challenger, itf or juniors. Null when no tour is recorded (exhibitions, team events)." - changed
Output schema / properties / matches / items / properties / tournament_id / descriptionPrevious value: -"Stable tournament id — pass to get_tournament. Null where uncatalogued."New value: +"Stable tournament id. Pass to get_tournament. Null where uncatalogued." - changed
Output schema / properties / matches / items / properties / win_probability_p1 / descriptionPrevious value: -"Model probability that player 1 wins, 0-1. Requires the ULTRA plan; null otherwise."New value: +"Model probability that player 1 wins, 0-1. Requires the ULTRA plan, null otherwise." - changed
Output schema / properties / matches / items / requiredPrevious value: -[ - "id", - "tour", - "tournament", - "tournament_id", - "round", - "round_code", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "event_status", - "event_status_updated_at", - "withdrew", - "has_analysis", - "has_market", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "scheduled_time", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "event_status_updated_at", + "withdrew", + "has_analysis", + "has_market", + "win_probability_p1" +] - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_match12 fields changed- changed
Output schema / properties / analysis / descriptionPrevious value: -"Model analysis. Requires the ULTRA plan; absent otherwise."New value: +"Model analysis. Requires the ULTRA plan, absent otherwise." - changed
Output schema / properties / market / descriptionPrevious value: -"Match-winner market. Requires the PRO plan; absent otherwise."New value: +"Match-winner market. Requires the PRO plan, absent otherwise." - changed
Output schema / properties / match / properties / event_status_updated_at / descriptionPrevious value: -"The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced — never backfilled."New value: +"The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced. Never backfilled." - changed
Output schema / properties / match / properties / round_code / descriptionPrevious value: -"Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed."New value: +"Round in the normalized vocabulary (F, SF, QF, R16 ... Q). Null when the label is unrecognised, never guessed." - added
Output schema / properties / match / properties / scheduled_timeAdded value: +{ + "description": "Scheduled start, UTC ISO-8601. Null when no start time is set yet.", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / match / properties / status / descriptionPrevious value: -"One of live, upcoming or completed."New value: +"One of live, upcoming, completed or cancelled." - changed
Output schema / properties / match / properties / tour / descriptionPrevious value: -"atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events)."New value: +"atp, wta, challenger, itf or juniors. Null when no tour is recorded (exhibitions, team events)." - changed
Output schema / properties / match / properties / tournament_id / descriptionPrevious value: -"Stable tournament id — pass to get_tournament. Null where uncatalogued."New value: +"Stable tournament id. Pass to get_tournament. Null where uncatalogued." - changed
Output schema / properties / match / properties / win_probability_p1 / descriptionPrevious value: -"Model probability that player 1 wins, 0-1. Requires the ULTRA plan; null otherwise."New value: +"Model probability that player 1 wins, 0-1. Requires the ULTRA plan, null otherwise." - changed
Output schema / properties / match / requiredPrevious value: -[ - "id", - "tour", - "tournament", - "tournament_id", - "round", - "round_code", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "event_status", - "event_status_updated_at", - "withdrew", - "has_analysis", - "has_market", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "scheduled_time", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "event_status_updated_at", + "withdrew", + "has_analysis", + "has_market", + "win_probability_p1" +] - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_match_analysis2 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_match_events3 fields changed- changed
Output schema / properties / events / descriptionPrevious value: -"Events in chronological order."New value: +"Events, newest first, as the API returns them." - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_match_odds2 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_match_score2 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_match_statistics6 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / statistics / properties / coverage / descriptionPrevious value: -"live | final | stale | none | diverged — summarises the response."New value: +"live | final | stale | none | diverged. Summarises the response." - changed
Output schema / properties / statistics / properties / freshness / descriptionPrevious value: -"Per-family coverage/as_of/age. The two ages use DIFFERENT clocks (derived: against the newest score row; measured: wall clock) and must not be compared. On diverged the measured values are withheld and measured_divergence says why."New value: +"Per-family coverage/as_of/age. The two ages use DIFFERENT clocks (derived: against the newest score row, measured: wall clock) and must not be compared. On diverged the measured values are withheld and measured_divergence says why." - changed
Output schema / properties / statistics / properties / players / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "p1": { - "anyOf": [ - { - "additionalProperties": false, - "properties": { - "derived": { - "additionalProperties": { - "type": [ - "number", - "null" - ] - }, - "description": "Rebuilt from the point-by-point record: service/return games and points, hold_pct, break_pct, break points faced/saved/converted. Null percentages mean a zero denominator, never 0.", - "type": "object" - }, - "measured": { - "anyOf": [ - { - "additionalProperties": { - "type": [ - "number", - "null" - ] - }, - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Counted upstream — aces, double_faults, the serve split, winners/unforced errors where covered. Absent fields are omitted, never zero-filled. Quantities named in both families are computed two different ways: a cross-check, not a duplication." - } - }, - "required": [ - "derived", - "measured" - ], - "type": "object" - }, - { - "type": "null" - } - ] - }, - "p2": { - "anyOf": [ - { - "$ref": "#/properties/statistics/properties/players/anyOf/0/properties/p1/anyOf/0" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "p1", - "p2" - ], - "type": "object" - }, - { - "type": "null" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "p1": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "derived": { + "additionalProperties": { + "type": [ + "number", + "null" + ] + }, + "description": "Rebuilt from the point-by-point record: service/return games and points, hold_pct, break_pct, break points faced/saved/converted. Null percentages mean a zero denominator, never 0.", + "type": "object" + }, + "measured": { + "anyOf": [ + { + "additionalProperties": { + "type": [ + "number", + "null" + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Counted per match: aces, double_faults, the serve split, winners/unforced errors where covered. Absent fields are omitted, never zero-filled. Quantities named in both families are computed two different ways: a cross-check, not a duplication." + } + }, + "required": [ + "derived", + "measured" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "p2": { + "anyOf": [ + { + "$ref": "#/properties/statistics/properties/players/anyOf/0/properties/p1/anyOf/0" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "p1", + "p2" + ], + "type": "object" + }, + { + "type": "null" + } +] - changed
Output schema / properties / statistics / properties / players / descriptionPrevious value: -"Null when coverage is none — the match exists and holding nothing is the honest answer."New value: +"Null when coverage is none. The match exists, and holding nothing is the honest answer."
- Changed
get_player2 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_player_rankings8 fields changed- changed
Input schema / properties / as_of / descriptionPrevious value: -"YYYY-MM-DD — the record in force on this date. Omit for the latest known."New value: +"YYYY-MM-DD. The record in force on this date. Omit for the latest known." - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / rankings / items / properties / player_id / descriptionPrevious value: -"Roster player id — null on listing rows for players outside our roster."New value: +"Roster player id. Null on listing rows for players outside our roster." - changed
Output schema / properties / rankings / items / properties / player_name / descriptionPrevious value: -"Name as the ranking publisher printed it (listing rows)."New value: +"Player name as it appears in the ranking (listing rows)." - changed
Output schema / properties / rankings / items / properties / previous_rank / descriptionPrevious value: -"Rank at the preceding snapshot week (ATP/WTA only; null elsewhere)."New value: +"Rank at the preceding snapshot week (ATP/WTA only, null elsewhere)." - changed
Output schema / properties / rankings / items / properties / rank_movement / descriptionPrevious value: -"The circuit's own signed weekly movement (ITF systems only)."New value: +"Signed weekly rank movement (ITF systems only)." - changed
Output schema / properties / rankings / items / properties / rating / descriptionPrevious value: -"UTR only; null elsewhere."New value: +"UTR only, null elsewhere."
- Changed
get_rankings9 fields changed- changed
Input schema / properties / as_of / descriptionPrevious value: -"YYYY-MM-DD — serves the newest published week at or before this date. Omit for latest."New value: +"YYYY-MM-DD. Serves the newest published week at or before this date. Omit for latest." - changed
Input schema / properties / system / descriptionPrevious value: -"Ranking system to list. utr has no listing — it is a rating, not a ranking."New value: +"Ranking system to list. utr has no listing, because it is a rating, not a ranking." - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / rankings / items / properties / player_id / descriptionPrevious value: -"Roster player id — null on listing rows for players outside our roster."New value: +"Roster player id. Null on listing rows for players outside our roster." - changed
Output schema / properties / rankings / items / properties / player_name / descriptionPrevious value: -"Name as the ranking publisher printed it (listing rows)."New value: +"Player name as it appears in the ranking (listing rows)." - changed
Output schema / properties / rankings / items / properties / previous_rank / descriptionPrevious value: -"Rank at the preceding snapshot week (ATP/WTA only; null elsewhere)."New value: +"Rank at the preceding snapshot week (ATP/WTA only, null elsewhere)." - changed
Output schema / properties / rankings / items / properties / rank_movement / descriptionPrevious value: -"The circuit's own signed weekly movement (ITF systems only)."New value: +"Signed weekly rank movement (ITF systems only)." - changed
Output schema / properties / rankings / items / properties / rating / descriptionPrevious value: -"UTR only; null elsewhere."New value: +"UTR only, null elsewhere."
- Changed
get_recent_results14 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Either participant's country — the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match."New value: +"Either participant's country: the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match." - changed
Input schema / properties / player / descriptionPrevious value: -"Player ids (from search_players), max 50 — keeps matches where ANY listed player is either participant."New value: +"Player ids (from search_players), max 50. Keeps matches where ANY listed player is either participant." - changed
Input schema / properties / to / descriptionPrevious value: -"Latest play date: YYYY-MM-DD or ISO-8601; must not precede from."New value: +"Latest play date: YYYY-MM-DD or ISO-8601. Must not precede from." - changed
Input schema / properties / tour / descriptionPrevious value: -"Tour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used."New value: +"Tour filter. Each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used." - changed
Output schema / properties / matches / items / properties / event_status_updated_at / descriptionPrevious value: -"The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced — never backfilled."New value: +"The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced. Never backfilled." - changed
Output schema / properties / matches / items / properties / round_code / descriptionPrevious value: -"Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed."New value: +"Round in the normalized vocabulary (F, SF, QF, R16 ... Q). Null when the label is unrecognised, never guessed." - added
Output schema / properties / matches / items / properties / scheduled_timeAdded value: +{ + "description": "Scheduled start, UTC ISO-8601. Null when no start time is set yet.", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / matches / items / properties / status / descriptionPrevious value: -"One of live, upcoming or completed."New value: +"One of live, upcoming, completed or cancelled." - changed
Output schema / properties / matches / items / properties / tour / descriptionPrevious value: -"atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events)."New value: +"atp, wta, challenger, itf or juniors. Null when no tour is recorded (exhibitions, team events)." - changed
Output schema / properties / matches / items / properties / tournament_id / descriptionPrevious value: -"Stable tournament id — pass to get_tournament. Null where uncatalogued."New value: +"Stable tournament id. Pass to get_tournament. Null where uncatalogued." - changed
Output schema / properties / matches / items / properties / win_probability_p1 / descriptionPrevious value: -"Model probability that player 1 wins, 0-1. Requires the ULTRA plan; null otherwise."New value: +"Model probability that player 1 wins, 0-1. Requires the ULTRA plan, null otherwise." - changed
Output schema / properties / matches / items / requiredPrevious value: -[ - "id", - "tour", - "tournament", - "tournament_id", - "round", - "round_code", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "event_status", - "event_status_updated_at", - "withdrew", - "has_analysis", - "has_market", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "scheduled_time", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "event_status_updated_at", + "withdrew", + "has_analysis", + "has_market", + "win_probability_p1" +] - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
get_tournament6 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / tournament / properties / category / descriptionPrevious value: -"Tournament category (grand_slam, masters_1000, tour_finals, atp_500, atp_250, wta_1000, wta_500, wta_250, wta_125, challenger, itf, juniors). Set only where the catalogues agree unambiguously — null otherwise, never derived from the name."New value: +"Tournament category (grand_slam, masters_1000, tour_finals, atp_500, atp_250, wta_1000, wta_500, wta_250, wta_125, challenger, itf, juniors). Set only where the category is unambiguous. Null otherwise, never derived from the name." - changed
Output schema / properties / tournament / properties / city / descriptionPrevious value: -"Host city, from a curated table — null where not curated."New value: +"Host city, from a curated table. Null where not curated." - changed
Output schema / properties / tournament / properties / country / descriptionPrevious value: -"Host country, ISO-3166 alpha-2 — null where not curated."New value: +"Host country, ISO-3166 alpha-2. Null where not curated." - changed
Output schema / properties / tournament / properties / id / descriptionPrevious value: -"Stable tournament id — the same id match objects carry as tournament_id."New value: +"Stable tournament id, the same id match objects carry as tournament_id."
- Changed
get_upcoming_matches14 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Either participant's country — the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match."New value: +"Either participant's country: the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match." - changed
Input schema / properties / player / descriptionPrevious value: -"Player ids (from search_players), max 50 — keeps matches where ANY listed player is either participant."New value: +"Player ids (from search_players), max 50. Keeps matches where ANY listed player is either participant." - changed
Input schema / properties / to / descriptionPrevious value: -"Latest play date: YYYY-MM-DD or ISO-8601; must not precede from."New value: +"Latest play date: YYYY-MM-DD or ISO-8601. Must not precede from." - changed
Input schema / properties / tour / descriptionPrevious value: -"Tour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used."New value: +"Tour filter. Each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used." - changed
Output schema / properties / matches / items / properties / event_status_updated_at / descriptionPrevious value: -"The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced — never backfilled."New value: +"The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced. Never backfilled." - changed
Output schema / properties / matches / items / properties / round_code / descriptionPrevious value: -"Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed."New value: +"Round in the normalized vocabulary (F, SF, QF, R16 ... Q). Null when the label is unrecognised, never guessed." - added
Output schema / properties / matches / items / properties / scheduled_timeAdded value: +{ + "description": "Scheduled start, UTC ISO-8601. Null when no start time is set yet.", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / matches / items / properties / status / descriptionPrevious value: -"One of live, upcoming or completed."New value: +"One of live, upcoming, completed or cancelled." - changed
Output schema / properties / matches / items / properties / tour / descriptionPrevious value: -"atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events)."New value: +"atp, wta, challenger, itf or juniors. Null when no tour is recorded (exhibitions, team events)." - changed
Output schema / properties / matches / items / properties / tournament_id / descriptionPrevious value: -"Stable tournament id — pass to get_tournament. Null where uncatalogued."New value: +"Stable tournament id. Pass to get_tournament. Null where uncatalogued." - changed
Output schema / properties / matches / items / properties / win_probability_p1 / descriptionPrevious value: -"Model probability that player 1 wins, 0-1. Requires the ULTRA plan; null otherwise."New value: +"Model probability that player 1 wins, 0-1. Requires the ULTRA plan, null otherwise." - changed
Output schema / properties / matches / items / requiredPrevious value: -[ - "id", - "tour", - "tournament", - "tournament_id", - "round", - "round_code", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "event_status", - "event_status_updated_at", - "withdrew", - "has_analysis", - "has_market", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "scheduled_time", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "event_status_updated_at", + "withdrew", + "has_analysis", + "has_market", + "win_probability_p1" +] - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Added
player_stats - Changed
search_archive_matches10 fields changed- changed
Input schema / properties / level / descriptionPrevious value: -"Source tier code: G=grand slam, M=masters, A=tour, F=finals, D=davis cup, C=challenger, O=olympics, or a futures category code (e.g. 15)."New value: +"Tier code: G=grand slam, M=masters, A=tour, F=finals, D=davis cup, C=challenger, O=olympics. Or a futures category code (e.g. 15)." - changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / results / items / properties / event_date / descriptionPrevious value: -"The tournament START date — per-match dates do not exist in this era’s records."New value: +"The tournament START date. Per-match dates do not exist in this era's records." - changed
Output schema / properties / results / items / properties / level / descriptionPrevious value: -"Source tier code: G, M, A, F, D, C, O, or a futures category code."New value: +"Tier code: G, M, A, F, D, C, O, or a futures category code." - changed
Output schema / properties / results / items / properties / outcome / descriptionPrevious value: -"completed, retired, walkover, default or abandoned — parsed, null when unparseable."New value: +"completed, retired, walkover, default or abandoned. Parsed, null when unparseable." - changed
Output schema / properties / results / items / properties / tour / descriptionPrevious value: -"atp or wta — the results archive covers those two tours."New value: +"atp or wta. The results archive covers those two tours." - changed
Output schema / properties / results / items / properties / winner / descriptionPrevious value: -"The winner — a stored field in the corpus, never an inference."New value: +"The winner, a stored field in the corpus, never an inference." - changed
Output schema / properties / results / items / properties / winner / properties / entry / descriptionPrevious value: -"Draw entry where recorded (WC, Q, LL, …) — null for direct acceptances."New value: +"Draw entry where recorded (WC, Q, LL, ...). Null for direct acceptances." - changed
Output schema / properties / results / items / properties / winner / properties / player_id / descriptionPrevious value: -"Corpus person id — pass to search_archive_players results to join bios. NOT a roster player id."New value: +"Corpus person id. Join it to search_archive_players results for bios. NOT a roster player id."
- Changed
search_archive_players4 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / players / items / properties / career_high_rank / descriptionPrevious value: -"Career-high rank, from the corpus’s own weekly tables."New value: +"Career-high rank, from the archive's weekly ranking tables." - changed
Output schema / properties / players / items / properties / id / descriptionPrevious value: -"Corpus person id — the id archive match rows carry as winner/loser player_id. NOT a roster id."New value: +"Corpus person id, the id archive match rows carry as winner/loser player_id. NOT a roster id."
- Changed
search_players2 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message."
- Changed
search_tournaments6 fields changed- changed
Output schema / properties / message / descriptionPrevious value: -"Human-readable summary. Identical to the text content, so either half can be used alone."New value: +"Human-readable summary of the result, safe to relay to the user verbatim." - changed
Output schema / properties / ok / descriptionPrevious value: -"True when the call returned data. False for a tier wall, a missing or rejected key, or an empty result — all of which are normal states with a clear remedy, not failures."New value: +"True when the request succeeded, including when the answer is an empty list. False for a missing or rejected key, a plan that does not include this data, an unknown id, a rate limit or a network error. The message then says what to do. check_api_status is the exception: it is true whenever the API answered, and reports API key problems in the message." - changed
Output schema / properties / tournaments / items / properties / category / descriptionPrevious value: -"Tournament category (grand_slam, masters_1000, tour_finals, atp_500, atp_250, wta_1000, wta_500, wta_250, wta_125, challenger, itf, juniors). Set only where the catalogues agree unambiguously — null otherwise, never derived from the name."New value: +"Tournament category (grand_slam, masters_1000, tour_finals, atp_500, atp_250, wta_1000, wta_500, wta_250, wta_125, challenger, itf, juniors). Set only where the category is unambiguous. Null otherwise, never derived from the name." - changed
Output schema / properties / tournaments / items / properties / city / descriptionPrevious value: -"Host city, from a curated table — null where not curated."New value: +"Host city, from a curated table. Null where not curated." - changed
Output schema / properties / tournaments / items / properties / country / descriptionPrevious value: -"Host country, ISO-3166 alpha-2 — null where not curated."New value: +"Host country, ISO-3166 alpha-2. Null where not curated." - changed
Output schema / properties / tournaments / items / properties / id / descriptionPrevious value: -"Stable tournament id — the same id match objects carry as tournament_id."New value: +"Stable tournament id, the same id match objects carry as tournament_id."
4 tool updates
- Changed
get_live_matches4 fields changed- added
Output schema / properties / matches / items / properties / event_status_updated_atAdded value: +{ + "description": "The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced — never backfilled.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / has_analysisAdded value: +{ + "description": "Whether a model thesis or profile exists for this match (added 2026-09-02, every tier). Filter on this before calling get_match_analysis, which reports the same absence. Null only when the server predates the field.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / matches / items / properties / has_marketAdded value: +{ + "description": "Whether a match-winner market is mapped to this match (added 2026-09-02, every tier). Filter on this before calling get_match_odds, which reports the same absence. Null only when the server predates the field.", + "type": [ + "boolean", + "null" + ] +} - changed
Output schema / properties / matches / items / requiredPrevious value: -[ - "id", - "tour", - "tournament", - "tournament_id", - "round", - "round_code", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "event_status", - "withdrew", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "event_status_updated_at", + "withdrew", + "has_analysis", + "has_market", + "win_probability_p1" +]
- Changed
get_match4 fields changed- added
Output schema / properties / match / properties / event_status_updated_atAdded value: +{ + "description": "The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced — never backfilled.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / match / properties / has_analysisAdded value: +{ + "description": "Whether a model thesis or profile exists for this match (added 2026-09-02, every tier). Filter on this before calling get_match_analysis, which reports the same absence. Null only when the server predates the field.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / match / properties / has_marketAdded value: +{ + "description": "Whether a match-winner market is mapped to this match (added 2026-09-02, every tier). Filter on this before calling get_match_odds, which reports the same absence. Null only when the server predates the field.", + "type": [ + "boolean", + "null" + ] +} - changed
Output schema / properties / match / requiredPrevious value: -[ - "id", - "tour", - "tournament", - "tournament_id", - "round", - "round_code", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "event_status", - "withdrew", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "event_status_updated_at", + "withdrew", + "has_analysis", + "has_market", + "win_probability_p1" +]
- Changed
get_recent_results4 fields changed- added
Output schema / properties / matches / items / properties / event_status_updated_atAdded value: +{ + "description": "The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced — never backfilled.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / has_analysisAdded value: +{ + "description": "Whether a model thesis or profile exists for this match (added 2026-09-02, every tier). Filter on this before calling get_match_analysis, which reports the same absence. Null only when the server predates the field.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / matches / items / properties / has_marketAdded value: +{ + "description": "Whether a match-winner market is mapped to this match (added 2026-09-02, every tier). Filter on this before calling get_match_odds, which reports the same absence. Null only when the server predates the field.", + "type": [ + "boolean", + "null" + ] +} - changed
Output schema / properties / matches / items / requiredPrevious value: -[ - "id", - "tour", - "tournament", - "tournament_id", - "round", - "round_code", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "event_status", - "withdrew", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "event_status_updated_at", + "withdrew", + "has_analysis", + "has_market", + "win_probability_p1" +]
- Changed
get_upcoming_matches4 fields changed- added
Output schema / properties / matches / items / properties / event_status_updated_atAdded value: +{ + "description": "The instant the current event_status was recorded, UTC ISO-8601 (added 2026-08-19). Null while the status has never changed since the field was introduced — never backfilled.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / has_analysisAdded value: +{ + "description": "Whether a model thesis or profile exists for this match (added 2026-09-02, every tier). Filter on this before calling get_match_analysis, which reports the same absence. Null only when the server predates the field.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / matches / items / properties / has_marketAdded value: +{ + "description": "Whether a match-winner market is mapped to this match (added 2026-09-02, every tier). Filter on this before calling get_match_odds, which reports the same absence. Null only when the server predates the field.", + "type": [ + "boolean", + "null" + ] +} - changed
Output schema / properties / matches / items / requiredPrevious value: -[ - "id", - "tour", - "tournament", - "tournament_id", - "round", - "round_code", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "event_status", - "withdrew", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "event_status_updated_at", + "withdrew", + "has_analysis", + "has_market", + "win_probability_p1" +]
17 tool updates
- Added
get_archive_career - Added
get_archive_match - Added
get_charting_match - Added
get_charting_player - Changed
get_fixtures1 field changed- added
Input schema / properties / tourAdded value: +{ + "description": "Tour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used.", + "enum": [ + "atp", + "wta", + "challenger", + "itf", + "juniors" + ], + "type": "string" +}
- Added
get_h2h - Changed
get_live_matches9 fields changed- added
Input schema / properties / countryAdded value: +{ + "description": "Either participant's country — the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match.", + "maxLength": 3, + "minLength": 3, + "type": "string" +} - added
Input schema / properties / playerAdded value: +{ + "description": "Player ids (from search_players), max 50 — keeps matches where ANY listed player is either participant.", + "items": { + "type": "integer" + }, + "maxItems": 50, + "type": "array" +} - added
Input schema / properties / tourAdded value: +{ + "description": "Tour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used.", + "enum": [ + "atp", + "wta", + "challenger", + "itf", + "juniors" + ], + "type": "string" +} - added
Output schema / properties / matches / items / properties / event_statusAdded value: +{ + "description": "How the match ended (or paused) when it did not run its course: Retired, Cancelled, Walk Over, Postponed or Interrupted. Null means completed normally OR never resolved. Branch settlement logic here.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / round_codeAdded value: +{ + "description": "Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / tourAdded value: +{ + "description": "atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / tournament_idAdded value: +{ + "description": "Stable tournament id — pass to get_tournament. Null where uncatalogued.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / withdrewAdded value: +{ + "description": "Completed matches only: which player retired or conceded the walkover, 1 or 2. Null means \"not a withdrawal, or no evidence\", never a guess.", + "type": [ + "number", + "null" + ] +} - changed
Output schema / properties / matches / items / requiredPrevious value: -[ - "id", - "tournament", - "round", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "withdrew", + "win_probability_p1" +]
- Changed
get_match6 fields changed- added
Output schema / properties / match / properties / event_statusAdded value: +{ + "description": "How the match ended (or paused) when it did not run its course: Retired, Cancelled, Walk Over, Postponed or Interrupted. Null means completed normally OR never resolved. Branch settlement logic here.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / match / properties / round_codeAdded value: +{ + "description": "Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / match / properties / tourAdded value: +{ + "description": "atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / match / properties / tournament_idAdded value: +{ + "description": "Stable tournament id — pass to get_tournament. Null where uncatalogued.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / match / properties / withdrewAdded value: +{ + "description": "Completed matches only: which player retired or conceded the walkover, 1 or 2. Null means \"not a withdrawal, or no evidence\", never a guess.", + "type": [ + "number", + "null" + ] +} - changed
Output schema / properties / match / requiredPrevious value: -[ - "id", - "tournament", - "round", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "withdrew", + "win_probability_p1" +]
- Added
get_match_statistics - Added
get_player_rankings - Added
get_rankings - Changed
get_recent_results11 fields changed- added
Input schema / properties / countryAdded value: +{ + "description": "Either participant's country — the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match.", + "maxLength": 3, + "minLength": 3, + "type": "string" +} - added
Input schema / properties / fromAdded value: +{ + "description": "Earliest play date: YYYY-MM-DD (a whole UTC day) or ISO-8601 datetime.", + "type": "string" +} - added
Input schema / properties / playerAdded value: +{ + "description": "Player ids (from search_players), max 50 — keeps matches where ANY listed player is either participant.", + "items": { + "type": "integer" + }, + "maxItems": 50, + "type": "array" +} - added
Input schema / properties / toAdded value: +{ + "description": "Latest play date: YYYY-MM-DD or ISO-8601; must not precede from.", + "type": "string" +} - added
Input schema / properties / tourAdded value: +{ + "description": "Tour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used.", + "enum": [ + "atp", + "wta", + "challenger", + "itf", + "juniors" + ], + "type": "string" +} - added
Output schema / properties / matches / items / properties / event_statusAdded value: +{ + "description": "How the match ended (or paused) when it did not run its course: Retired, Cancelled, Walk Over, Postponed or Interrupted. Null means completed normally OR never resolved. Branch settlement logic here.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / round_codeAdded value: +{ + "description": "Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / tourAdded value: +{ + "description": "atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / tournament_idAdded value: +{ + "description": "Stable tournament id — pass to get_tournament. Null where uncatalogued.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / withdrewAdded value: +{ + "description": "Completed matches only: which player retired or conceded the walkover, 1 or 2. Null means \"not a withdrawal, or no evidence\", never a guess.", + "type": [ + "number", + "null" + ] +} - changed
Output schema / properties / matches / items / requiredPrevious value: -[ - "id", - "tournament", - "round", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "withdrew", + "win_probability_p1" +]
- Added
get_tournament - Changed
get_upcoming_matches11 fields changed- added
Input schema / properties / countryAdded value: +{ + "description": "Either participant's country — the lowercase 3-letter IOC-style code the Player object returns (e.g. ned, sui, gre), NOT ISO-3166. Players with no recorded country never match.", + "maxLength": 3, + "minLength": 3, + "type": "string" +} - added
Input schema / properties / fromAdded value: +{ + "description": "Earliest play date: YYYY-MM-DD (a whole UTC day) or ISO-8601 datetime.", + "type": "string" +} - added
Input schema / properties / playerAdded value: +{ + "description": "Player ids (from search_players), max 50 — keeps matches where ANY listed player is either participant.", + "items": { + "type": "integer" + }, + "maxItems": 50, + "type": "array" +} - added
Input schema / properties / toAdded value: +{ + "description": "Latest play date: YYYY-MM-DD or ISO-8601; must not precede from.", + "type": "string" +} - added
Input schema / properties / tourAdded value: +{ + "description": "Tour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used.", + "enum": [ + "atp", + "wta", + "challenger", + "itf", + "juniors" + ], + "type": "string" +} - added
Output schema / properties / matches / items / properties / event_statusAdded value: +{ + "description": "How the match ended (or paused) when it did not run its course: Retired, Cancelled, Walk Over, Postponed or Interrupted. Null means completed normally OR never resolved. Branch settlement logic here.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / round_codeAdded value: +{ + "description": "Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / tourAdded value: +{ + "description": "atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / tournament_idAdded value: +{ + "description": "Stable tournament id — pass to get_tournament. Null where uncatalogued.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / withdrewAdded value: +{ + "description": "Completed matches only: which player retired or conceded the walkover, 1 or 2. Null means \"not a withdrawal, or no evidence\", never a guess.", + "type": [ + "number", + "null" + ] +} - changed
Output schema / properties / matches / items / requiredPrevious value: -[ - "id", - "tournament", - "round", - "player1", - "player2", - "score", - "status", - "surface", - "indoor", - "serving", - "winner", - "win_probability_p1" -]New value: +[ + "id", + "tour", + "tournament", + "tournament_id", + "round", + "round_code", + "player1", + "player2", + "score", + "status", + "surface", + "indoor", + "serving", + "winner", + "event_status", + "withdrew", + "win_probability_p1" +]
- Added
search_archive_matches - Added
search_archive_players - Added
search_tournaments
12 tool updates
- First observed
check_api_status - First observed
get_fixtures - First observed
get_live_matches - First observed
get_match - First observed
get_match_analysis - First observed
get_match_events - First observed
get_match_odds - First observed
get_match_score - First observed
get_player - First observed
get_recent_results - First observed
get_upcoming_matches - First observed
search_players
Related MCP Connectors
ATP and WTA tennis since 2007: sets, draws, rankings, head to head, surface Elo, sportsbook lines.
Football fixtures, live scores, standings, lineups, teams and players for 117 leagues and cups
Live scores, fixtures, standings, team profiles and news for 2000+ football and basketball leagues.
Live football scores, fixtures, standings, lineups and player stats for 1400+ leagues.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceTournament software for tennis, padel, pickleball and more: fair draws, live standings, scores and dropout handling.MIT

PropLineofficial
AlicenseAqualityAmaintenanceLive sports betting odds, cross-book +EV, and graded player-prop resolution across 13 books.11790 npm1MIT- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to answer tennis tactical questions using shot-by-shot charted match data, producing game plans, serve and return tendencies, scouting reports, match forecasts, and explanations of why a match turned. Exposes read-only tools for player reports, head-to-head game plans, match breakdowns, and tactical leaderboards, each with confidence margins and links to full pages.MIT
- AlicenseBqualityCmaintenanceProvides AI agents with live, grounded sports data including model probabilities, track records, and European soccer and tennis arbitrage opportunities, so they answer from real numbers instead of stale guesses.1366 npm1MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.