Skip to main content
Glama
livetennisapi

livetennisapi-mcp

livetennisapi-mcp

MCP server for the Live Tennis API.

Give Claude, Cursor, Zed or any MCP client live tennis scores, players and fixtures — for ATP, WTA, Challenger, ITF and juniors. Odds, rankings, match statistics, charting and model win-probability tools are included, and require the PRO and ULTRA plans.

CI npm license

Documentation · Get a free API key


Setup

Claude Code

claude mcp add livetennis -e LIVETENNISAPI_KEY=twjp_… -- npx -y livetennisapi-mcp

Claude Desktop — add to claude_desktop_config.json:

{
  "mcpServers": {
    "livetennis": {
      "command": "npx",
      "args": ["-y", "livetennisapi-mcp"],
      "env": { "LIVETENNISAPI_KEY": "twjp_…" }
    }
  }
}

Cursor / Zed / others — same command, same env var. No install step; npx fetches it on demand.

Get a free key (no card) at livetennisapi.com, or a paid plan at pricing.

Related MCP server: SportScore

Try it

"What tennis matches are live right now?" "Who's winning the Alcaraz match, and what does the model give him?" "Show me Sinner's ranking and recent results." "What are the current odds on match 18953?" "What's the all-time head-to-head between Borg and McEnroe?" "List Navratilova's Grand Slam finals from the archive." "Who was ATP #1 the week Alcaraz first entered the top 10?" "How is Sabalenka serving in her live match — aces, hold rate, break points?"

Tools

Tool

Does

Plan

get_live_matches

Matches in progress, with live scores

FREE

get_upcoming_matches

Matches starting soon

FREE

get_match

Full detail for one match

FREE

get_match_score

Current score only — fastest read

FREE

search_players

Find players by name

FREE

get_player

Profile, ranking, country, handedness

FREE

get_fixtures

Forward schedule

FREE

search_tournaments

Tournament catalogue — surface, location, category

FREE

get_tournament

One tournament by its stable id

FREE

get_recent_results

Completed matches and winners

BASIC

search_archive_matches

Results archive (1968–2022) — historical results with ranks and seeds at the time

BASIC

get_archive_match

One archive result, with serve stats where the era recorded them

BASIC

search_archive_players

Archive bios — hand, DOB, career-high rank

BASIC

get_archive_career

Career W-L, titles and serve aggregates over the archive

BASIC

get_h2h

Cross-era head-to-head — archive + current, one record

BASIC

get_match_events

Breaks, games, sets, momentum runs

PRO

get_match_odds

Match-winner prices — bid / ask / mid

PRO

get_rankings

Full published ranking table per system (ATP, WTA, ITF circuits), any week

PRO

get_player_rankings

Point-in-time ranking records for specific players, as of any date

ULTRA

get_match_statistics

In-play statistics — aces, serve split, hold/break %, break points

ULTRA

get_charting_player

Career shot-level profile from the Match Charting Project

ULTRA

get_charting_match

One charted match, every stat family, per-set split

ULTRA

get_match_analysis

Model thesis, win probability, key factors

ULTRA

check_api_status

Reachability + which plan your key is on

The six BASIC history tools are also unlocked by any History plan, which works on top of a free key. The results archive (1968–2022) — ATP and WTA, main draws, qualifying and the ITF/futures tiers — ends exactly where our own results begin (2023), so search_archive_matches answers "Borg's Wimbledon finals" and get_recent_results answers "yesterday's scores"; get_h2h spans both in one call.

Tier awareness

The API gates endpoints by plan and returns a bare 403 {"error":"upgrade_required"}. Handed that, a model will usually invent a reason or retry pointlessly.

So every tool that can hit a tier wall returns a plain-English explanation — as a normal result, not an error — naming the tier required and where to upgrade. The assistant can then tell you something true and actionable:

This data requires the ULTRA plan, and the configured API key is on a lower tier. Nothing is wrong with the key — the endpoint is simply not included in the current plan. Upgrade in place at https://livetennisapi.com/subscribe/upgrade

check_api_status probes upward to report which plan your key is actually on, so you can diagnose that without guessing.

Plans

FREE

BASIC

PRO

ULTRA

Matches, scores, players, fixtures, tournaments

Completed-match listings (results)¹

Results archive (1968–2022) + head-to-head¹

Match events, odds + rankings listing

Model analysis, as-of rankings, match statistics + charting

$0 — no card

$9.99/mo

$29.99/mo

$99.99/mo

¹ Also unlocked by any History plan, which works on top of a free key.

Request quotas

FREE

BASIC

PRO

ULTRA

Requests per minute

30

60

300

600

Requests per day

100

1,000

10,000

500,000

FREE is 100 requests/day, so poll no faster than every 15 minutes on a free key; for an always-on dashboard, BASIC is the plan to recommend. Every response carries X-RateLimit-Limit / -Remaining / -Reset headers, and the tools relay the three distinct 429 shapes honestly — per-minute (retry shortly), daily cap (the error names the exact reset instant), and the abuse block (don't retry; fix the loop).

Hosted endpoint

Most people should use the stdio server above — your key never leaves your machine. For clients that can only speak HTTP, there is also a hosted Streamable-HTTP endpoint:

https://mcp.livetennisapi.com/mcp

Send your key as Authorization: Bearer twjp_…, X-API-Key: twjp_…, or ?token= if your client cannot set headers. Tools are listable without a key, so directories can introspect the server; calling one needs a key.

It is multi-tenant and holds no key of its own: every request builds its own server bound to the key that request presented, and there is deliberately no fallback to the host's environment. The endpoint applies its own transport-level limit per caller — 60 req/min anonymous, 300 keyed. That limit only protects this host process; it is not your API quota, which is enforced upstream per key and tier (see the quota table above).

Self-hosting it: deploy/install-http.sh and deploy/TUNNEL.md.

Use with Claude

As a connector. In Claude, add a custom connector and paste the endpoint with your key as a query parameter — no OAuth, nothing to install:

https://mcp.livetennisapi.com/mcp?token=twjp_…

?token= exists for clients that cannot set request headers. The tradeoff, stated plainly: a key in a URL is not written to our logs, but it is visible to the CDN in front of the endpoint and is stored in the connector's configuration. Prefer Authorization: Bearer twjp_… wherever your client lets you set a header.

From the Messages API. Claude can call the endpoint directly. Both halves are required — the server and a matching toolset entry; sending mcp_servers alone is rejected as a validation error:

client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    betas=["mcp-client-2025-11-20"],
    mcp_servers=[{
        "type": "url",
        "name": "livetennisapi",
        "url": "https://mcp.livetennisapi.com/mcp",
        "authorization_token": os.environ["LIVETENNISAPI_KEY"],
    }],
    tools=[{"type": "mcp_toolset", "mcp_server_name": "livetennisapi"}],
    messages=[{"role": "user", "content": "What tennis is live right now?"}],
)

The authorization_token is sent as a bearer token, which is exactly what this server already accepts — no separate credential to obtain.

Use with Codex

One command:

codex mcp add livetennisapi \
  --url https://mcp.livetennisapi.com/mcp \
  --bearer-token-env-var LIVETENNISAPI_KEY

Or write it to ~/.codex/config.toml yourself — Codex shares that file across the CLI, the IDE extension and the desktop app:

[mcp_servers.livetennisapi]
url = "https://mcp.livetennisapi.com/mcp"
bearer_token_env_var = "LIVETENNISAPI_KEY"

Use bearer_token_env_var, not bearer_token: it keeps the key in your environment rather than committing it to a config file.

There is also a Codex plugin, on its own marketplace:

codex plugin marketplace add livetennisapi/livetennisapi-codex-plugin

That registers the marketplace; install the plugin from Codex's plugin picker. Source: livetennisapi-codex-plugin.

The stdio route works too, unchanged: npx -y livetennisapi-mcp.

Bundled skill: Polymarket / Kalshi tennis trading data

The Claude Code plugin (.claude-plugin/plugin.json) also ships the polymarket-tennis Agent Skill under skills/polymarket-tennis/. It teaches Claude the observe-only polymarket-tennis Python package (market discovery, market-to-match matching, joined price/live-score view), the free-tier budget (30 req/min, 100 requests/day), and the verbatim retirement/walkover settlement rules for Polymarket, Polymarket US and Kalshi. Canonical copy lives in the polymarket-tennis repo; this one is mirrored for plugin installs. No order execution, ever.

Notes

  • Read-only. Every tool is a GET; nothing here can modify anything.

  • Your key stays local with the stdio server. It is read from the environment by the server process on your machine and sent only to api.livetennisapi.com.

  • Requires Node 20+.

Development

npm install
npm run build
LIVETENNISAPI_KEY=twjp_… node dist/index.js   # speaks MCP over stdio
node dist/http.js                             # speaks MCP over HTTP, port 8081

npm test               # protocol + transport isolation + rate limiting
npm run test:mutation  # proves those tests fail when the code breaks

test:mutation is worth understanding before changing src/http.ts. It reintroduces each bug the tests claim to catch and asserts the suite goes red. It is not ceremony: the first version of the rate-limit test passed while the limiter was bucketing every caller together.

Built on the official livetennisapi client.

Everything in the Live Tennis API developer surface:

Install

Source

Package

Python client

pip install livetennisapi

repo

package

JavaScript / TypeScript client

npm install livetennisapi

repo

package

MCP server for LLM agents (this repo)

npx livetennisapi-mcp

package

Vercel AI SDK tools

npm install livetennisapi-ai

repo

Break-point starter — Python

repo

Break-point starter — Node

repo

Break-point starter — Go

repo

Affiliate program

Know developers who need tennis data? The affiliate program pays 51% recurring commission for the life of every referred subscription — 30-day cookie, and the people you refer get 10% off.

Licence

MIT — see LICENSE. Use of the API service is governed by the Terms of Service.

Available Tools

24 tools
check_api_statusAPI status and planA
Read-onlyIdempotent
Inspect

Check whether the Live Tennis API is reachable and which plan the configured key is on. Useful for diagnosing why other tools are refusing data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
tierNoDetected plan: FREE, BASIC, PRO or ULTRA. Null when no key is configured.
has_keyNoWhether a key was supplied with this call.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
reachableNoTrue when the API answered its health check.
api_versionNoAPI version reported by the health check.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide strong behavioral hints (read-only, idempotent, non-destructive). Description adds specific context (reachability, plan check) without contradicting. High transparency overall.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely concise: two sentences, front-loaded with action, no unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Low complexity: no parameters, output schema exists, annotations rich. Description efficiently conveys purpose and diagnostic context. Complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters, so description is not required to elaborate on param semantics. Schema coverage is 100% (empty schema). Baseline score of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb+resource: 'Check whether the Live Tennis API is reachable and which plan'. Distinguishes from sibling data-fetching tools (get_fixtures, get_match, get_upcoming_matches) by being 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides context on when to use ('diagnosing why other tools are refusing data'), but does not explicitly state exclusions or alternatives. Given simplicity, this is adequate.

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 aggregatesA
Read-onlyIdempotent
Inspect

One player's whole career over the results archive (1968–2022): W-L record overall and by surface/level/year, titles, and summed serve statistics with honest coverage — the corpus records serve stats from 1991 only, so matches_with_stats states 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesPlayer name fragment, min 3 chars — must resolve to exactly one person.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
spanNoCareer span inside the archive.
serveNoSummed serve stats + derived ratios. matches_with_stats states the coverage; ratios are null where the denominator is zero.
recordNoThe W-L record.
by_yearNoPer-season W-L.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
player_nameNoThe resolved player.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, but the description adds valuable caveats: serve stats only exist from 1991, matches_with_stats quantifies coverage, ambiguous names yield candidate lists, and a plan requirement exists. These go beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense but well-organized, front-loading the core purpose and then adding necessary caveats. Every clause adds value, with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers data scope, statistics included, coverage limitations, ambiguity resolution, and plan requirements. With an output schema present, detailing return values is unnecessary, making this complete for a tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes the 'name' parameter with minLength and 'must resolve to exactly one person.' The description adds the behavioral detail that an ambiguous fragment returns a candidate list, which is not in the schema, thus adding meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves one player's whole career aggregates from the results archive, listing specific statistics (W-L by surface/level/year, titles, serve stats) and the date range (1968–2022). This distinct focus differentiates it from siblings like get_player or get_archive_match.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context for when to use the tool (career-level aggregation) and a key constraint: the name must resolve to exactly one person, with ambiguous fragments returning a candidate list. It does not explicitly name alternative tools or state when not to use this over others, but the context is sufficient.

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 detailA
Read-onlyIdempotent
Inspect

One result from the results archive (1968–2022), with per-match serve statistics where the era recorded them — stats are null for most rows before 1991, honestly, never synthesised. Requires the BASIC plan or any History plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
archive_match_idYesArchive match id, as returned by search_archive_matches.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
statsNoPer-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.
resultNoThe archive result.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and non-destructive. The description adds meaningful context about data availability ('stats are null for most rows before 1991') and truthfulness ('never synthesised'), which goes beyond annotations and helps set expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences cover purpose, scope, data caveats, and plan requirements without redundancy. The 'honestly' adverbial aside is slightly informal but does not waste space; it reinforces the 'never synthesised' claim.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-fetch tool with an output schema, the description covers the key aspects: scope, historical period, data quality, and access plan. It leaves no major gaps, though it might have mentioned the relationship to search_archive_matches, which the schema already covers.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the schema clearly documents the single parameter (archive_match_id). The description does not add any additional parameter information, 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as returning 'One result from the results archive (1968–2022)', which with the name get_archive_match specifies a single-match retrieval. It distinguishes from list-oriented siblings like search_archive_matches by emphasizing 'one result' and the historical range.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: 'One result from the results archive' suggests it is for fetching a specific archived match, but it does not explicitly contrast with sibling tools or state when not to use it. The plan requirement (BASIC or History) is a condition, not an alternative guidance.

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 familyA
Read-onlyIdempotent
Inspect

Every Match Charting Project 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–2026), mostly matches with no counterpart in the live tables. Requires the ULTRA plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
charting_match_idYesCharting match id — its own id space, not a match_id.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
genderNo
mcp_idNoThe Match Charting Project's own row identifier.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
playersNoBoth players as charted.
familiesNoEvery stat family, per player, with the per-set split.
charting_match_idNoThe charted match.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds valuable context: results are 'exactly as charted' including per-set splits, and data coverage is described as mostly lacking live-table counterparts. This goes beyond the annotation baselines to clarify the raw nature and scope of the data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences front-load the core purpose, then clarify the id space and plan requirement. No redundancy or filler; every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a single parameter, full schema coverage, and an output schema present, the description sufficiently explains what the tool does, the data scope, and access constraints. It covers purpose, id-space nuance, and plan requirement, making it complete for a tool of this simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 reinforces that charting_match_id is its own id space and adds a date range (1960–2026), but the schema already states 'not a match_id'. No significant additional semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves every Match Charting Project stat family for a single charted match, for both players, with per-set splits. It also distinguishes from live-table matches by noting charting ids are their own id space, which separates it from sibling tools like get_match and get_match_statistics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides strong contextual guidance: charting ids are a separate id space (1960–2026) and mostly have no live-table counterpart, implying use for charting data rather than live matches. It also notes the ULTRA plan requirement. However, it does not explicitly name alternative tools or state when not to use this tool, 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_charting_playerCharting: player career profileA
Read-onlyIdempotent
Inspect

Career shot-level profile from the Match Charting Project: serve placement (deuce/ad × wide/body/T), return depth and outcomes, net play, clutch break/game/set-point serving, winners and errors by wing, rally-length tendencies — summed over the player's charted matches. COVERAGE IS CURATED (11,646 charted matches back to the 1960s, concentrated on the majors), not full-slate. An ambiguous name returns the candidates to choose from. Requires the ULTRA plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesPlayer name fragment, min 3 chars — must resolve to one charted person.
genderNoDisambiguates a name charted on both tours.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
playerNoThe resolved charted player.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
coverageNoA reminder that charting coverage is curated, not full-slate.
familiesNoPer-family summed numeric columns — raw sums over the player's charted Total rows.
matches_chartedNoThe sample every summed field covers.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only/idempotent; the description adds coverage scope, ambiguous-name resolution behavior, and plan restrictions. It does not contradict annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense paragraph that front-loads the main purpose, lists specific data points, and follows with coverage and plan caveats. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers what it returns, its data coverage, ambiguity handling, and access restrictions. With an output schema present, this is sufficient for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already gives both parameters full descriptions. The description adds that ambiguous names return candidates, enhancing understanding of the name parameter; gender's role is inferred from the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as returning a 'Career shot-level profile from the Match Charting Project' and enumerates specific stat categories. This specific resource and data type distinguish it from sibling tools like get_player or get_archive_career.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context about when this tool is appropriate: when needing shot-level charted career stats. It warns about curated coverage and the ULTRA plan requirement, which implies boundaries, but it does not explicitly name alternative tools or state when not 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_fixturesFixture scheduleB
Read-onlyIdempotent
Inspect

Upcoming scheduled tennis fixtures, earliest first — the forward schedule.

ParametersJSON Schema
NameRequiredDescriptionDefault
tourNoTour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used.
limitNoMaximum fixtures to return (1-200).

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
fixturesNoScheduled fixtures, earliest first.

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint. The description adds useful behavioral context by noting the results are 'earliest first' and represent the 'forward schedule'. However, it does not mention pagination, limit behavior, or how open-world results might be incomplete, so it adds only moderate value beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that conveys the core purpose and ordering. Every word adds value, with no filler or redundant explanation. It is appropriately sized for such a simple read-only list tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, has a full output schema, and rich annotations, so the description does not need to explain return values or safety. However, given the context of 24 sibling tools, especially the ambiguous get_upcoming_matches, the description does not fully disambiguate its role in the broader toolset. It clearly separates from live/recent but not from upcoming matches, leaving an important completeness gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — both 'tour' and 'limit' have detailed descriptions covering allowed values, defaults, and exclusions (e.g., exhibition events excluded when tour filter used). The tool description provides no additional parameter information, so it earns the baseline 3 for schema-driven semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns 'Upcoming scheduled tennis fixtures, earliest first' — a specific resource (fixtures) with temporal scope and ordering. However, it does not distinguish this from the sibling tool 'get_upcoming_matches', which likely covers the same or overlapping purpose, so it lacks full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no explicit guidance on when to use this tool versus alternatives. It does not mention that live matches should go to get_live_matches or that past results belong to get_recent_results, nor does it clarify the relationship with get_upcoming_matches. The only implied use is for upcoming fixtures, but no exclusions or alternative recommendations are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_h2hHead-to-headA
Read-onlyIdempotent
Inspect

The all-time record between two players, across BOTH halves of the product: the results archive (1968–2022) plus our own completed matches (2023 onward). Names are the keys — an ambiguous fragment returns the candidate list to choose from rather than guessing. 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
player1YesFirst player name (fragment, min 3 chars), e.g. "federer".
player2YesSecond player name (fragment, min 3 chars), e.g. "nadal".

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
totalsNoThe headline record.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
playersNoThe resolved names; null when no player matches the fragments.
meetingsNoIndividual meetings, newest first, capped at 200.
by_surfaceNoDecided wins per surface; keys are surface names plus "unknown".

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations (readOnly, idempotent), the description discloses meaningful behaviors: totals count only meetings with a known winner, walkovers/retirements are included, each meeting carries its outcome, and ambiguous names return candidate lists. This adds significant context for edge cases and data semantics, exceeding what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized at four sentences, with the main purpose front-loaded. Every sentence serves a purpose: scope, name handling, counting methodology, and access requirement. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a clear output schema and only two simple parameters, the description covers the tool's purpose, data coverage, edge-case handling, and plan requirement. No significant gaps remain for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents both parameters with examples and minLength. The description adds that names are 'keys' and that ambiguous fragments return a candidate list, enriching the meaning of the name parameters beyond basic schema descriptions. Schema coverage is 100%, so this is a bonus.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'The all-time record between two players,' specifying the data scope (archive 1968–2022 and completed matches 2023 onward). This distinguishes it from sibling tools like get_match or get_player, which focus on individual matches or player profiles.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context for when to use the tool: for head-to-head comparisons between two named players. It also explains the candidate-list behavior for ambiguous fragments. However, it does not explicitly name alternative tools or state when not to use this tool, only that it requires a BASIC plan.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_live_matchesLive matchesA
Read-onlyIdempotent
Inspect

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".

ParametersJSON Schema
NameRequiredDescriptionDefault
tourNoTour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used.
limitNoMaximum matches to return (1-200).
playerNoPlayer ids (from search_players), max 50 — keeps matches where ANY listed player is either participant.
countryNoEither 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

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
matchesNoThe live matches, most relevant first.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, covering safety. The description adds a bit of context about live scores and tour coverage, but does not disclose behaviors like data delay or filtering nuances beyond the schema. With annotations present, this is adequate but not exceptional.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the primary function, then scope, then usage guidance. Every word earns its place; no fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with a rich schema and output schema, the description fully covers purpose and usage. The annotations and schema handle safety and parameters, so nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with detailed descriptions for all four parameters, so the baseline is 3. The description adds no extra parameter meaning (e.g., format, edge cases) beyond the schema, so it stays at baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists tennis matches currently in progress with live scores, covering major tours. This distinguishes it from siblings like get_upcoming_matches and get_recent_results by emphasizing the 'currently in progress' scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly tells users when to use this tool ('what tennis is on right now'), providing a clear usage cue. However, it does not mention when not to use it or name specific alternatives, so it falls short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_matchMatch detailA
Read-onlyIdempotent
Inspect

Full detail for one match by id: players, score, surface, round and status. Includes market prices on PRO and model analysis on ULTRA.

ParametersJSON Schema
NameRequiredDescriptionDefault
match_idYesMatch id, as returned by get_live_matches, get_upcoming_matches or get_recent_results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
matchNoThe match.
marketNoMatch-winner market. Requires the PRO plan; absent otherwise.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
analysisNoModel analysis. Requires the ULTRA plan; absent otherwise.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds meaningful context by specifying what data is included and that market prices are on PRO and model analysis on ULTRA, informing the agent about tier-dependent response content without contradicting annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, front-loaded with the core purpose, and lists all key included fields. It is concise and well-structured with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple get-by-id tool, the description is complete: it covers all included fields, tier-dependent extras, and the output schema exists to handle return structure. The context signals indicate low complexity, and the description adequately covers it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with match_id fully documented (including provenance from other match-listing tools). The description adds only 'by id', which is redundant but harmless. Baseline 3 is appropriate since the schema carries the burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Full detail for one match by id' and lists specific content (players, score, surface, round, status). This differentiates it from siblings like get_match_score (score only) and get_match_analysis (analysis only), with the added mention of market prices and model analysis.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear context for when to use: to fetch full details of a single match by id. The parameter description adds guidance on where the id comes from (get_live_matches, get_upcoming_matches, get_recent_results). It does not explicitly exclude alternatives, but the context is strong enough for an AI agent to select this over more specialized tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_match_analysisModel analysisA
Read-onlyIdempotent
Inspect

Model analysis for a match: predicted win probability, the model's thesis and the key factors behind it. Requires the ULTRA plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
match_idYesMatch id, as returned by get_live_matches, get_upcoming_matches or get_recent_results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
thesisNoNarrative view.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
profileNoQuantitative view.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is known. The description adds the ULTRA plan requirement and specifies the output contents, which is valuable context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one sentence that front-loads the core purpose and provides key contents and the plan requirement. Every phrase adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a comprehensive output schema and safe read-only annotations, the description covers the core aspects. It includes the plan requirement and return contents, making it adequate for a single-parameter analysis tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema fully documents match_id with a description of where to obtain it, so schema coverage is 100%. The tool description does not add further parameter meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool provides model analysis for a match, specifically predicted win probability, the model's thesis, and key factors. This distinguishes it from sibling tools like get_match_score or get_match_odds.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use for obtaining model analysis but does not explicitly state when to use it over alternatives or mention exclusions. The ULTRA plan requirement is a prerequisite, not usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_match_eventsMatch timelineA
Read-onlyIdempotent
Inspect

Timeline of events for a match — breaks, games won, sets won, momentum runs. Requires the PRO plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum events to return (1-200).
match_idYesMatch id, as returned by get_live_matches, get_upcoming_matches or get_recent_results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
eventsNoEvents in chronological order.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark it as read-only, idempotent, and non-destructive. The description adds that it requires the PRO plan, an access constraint not covered by annotations. It also clarifies the event categories, but doesn't discuss ordering or pagination behavior beyond what the schema's limit parameter implies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with an added access constraint, immediately front-loading the tool's purpose. No redundant words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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 not be described. The description covers the event types and the PRO plan requirement; combined with parameter descriptions and annotations, the tool is fully contextualized for a straightforward read-only operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema contains descriptions for both parameters (100% coverage), so the description adds no additional semantic value for match_id or limit. The baseline score of 3 applies as the schema sufficiently documents parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool provides a timeline of events for a match, listing specific event types (breaks, games won, sets won, momentum runs). This differentiates it from sibling tools like get_match or get_match_score, which likely provide summary or score data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context that this tool is for timeline events, but does not explicitly instruct when to use it over alternatives. There is no mention of when not to use it or which sibling tool to choose for other needs, so guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_match_oddsMatch market pricesA
Read-onlyIdempotent
Inspect

Match-winner market prices for a match — implied probability per player, with bid, ask and mid. Requires the PRO plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum price points to return (1-200).
match_idYesMatch id, as returned by get_live_matches, get_upcoming_matches or get_recent_results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
marketNoThe match-winner market.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already indicate a safe read-only, idempotent operation. The description adds meaningful context beyond the annotations by specifying the PRO plan requirement and detailing the output structure (bid, ask, mid, implied probability). This provides useful operational context without contradicting 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that conveys the essential purpose and output format, then adds the PRO requirement. Every word earns its place with no redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with a fully documented schema and an output schema, the description is complete: it explains the market type, the per-player probabilities, the pricing components, and the access requirement. No critical information is missing for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already has 100% parameter coverage, describing match_id and limit with defaults and constraints. The description does not add additional parameter semantics beyond that, 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns match-winner market prices with implied probability per player, bid, ask, and mid. This goes beyond a tautology and distinguishes it from sibling tools like get_match and get_match_score, which focus on other match data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for retrieving odds on a specific match, and the mention of 'Requires the PRO plan' is a useful precondition. However, it does not explicitly state when to use this tool versus alternatives like get_match or get_upcoming_matches, nor does it mention exclusions or when not 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_match_scoreMatch scoreA
Read-onlyIdempotent
Inspect

Current score for one match — the fastest, lowest-latency read. Use this when you only need the score and already know the match id.

ParametersJSON Schema
NameRequiredDescriptionDefault
match_idYesMatch id, as returned by get_live_matches, get_upcoming_matches or get_recent_results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
scoreNoThe current score.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds valuable context about latency ('fastest, lowest-latency read') and currency ('Current score'), which goes beyond the annotations. However, it doesn't discuss edge cases like invalid match IDs or real-time update behavior, which are partly covered by 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences, front-loaded with the purpose and followed by usage guidance. No wasted words; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, one-parameter read-only tool with comprehensive annotations and an output schema, this description is complete. It states what it does, when to use it, and the schema covers the parameter source. No additional context is necessary.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description for match_id is 100% covered, explaining it is 'as returned by get_live_matches, get_upcoming_matches or get_recent_results.' The tool description adds no extra parameter meaning beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Current score for one match'—a specific verb and resource. It also differentiates from siblings by highlighting it as the 'fastest, lowest-latency read' and specifying the use case, which distinguishes it from tools like get_match or get_archive_match.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use it: 'Use this when you only need the score and already know the match id.' This implies when not to use it, but it does not explicitly name alternative tools, so it falls just 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 statisticsA
Read-onlyIdempotent
Inspect

In-play (or final) statistics for one match, in TWO families kept deliberately separate: DERIVED is rebuilt from the point-by-point record (holds/breaks, break points, service/return points); MEASURED is counted upstream and 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
match_idYesMatch id, as returned by get_live_matches, get_upcoming_matches or get_recent_results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
statisticsNoThe statistics.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, idempotentHint), the description adds substantial behavioral context: the derived vs. measured family distinction, the variability of measured coverage by tour, and the omission (not zero-filling) of absent fields. This exceeds annotation coverage and provides meaningful operational nuance.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long and front-loads the core purpose. Each sentence earns its place, packing in the two families, coverage caveat, omission policy, and plan requirement without redundancy. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with an output schema, annotations, and rich context, the description fully covers the essential behavioral aspects (families, coverage variability, missing fields) and the plan requirement. An agent has everything needed to select and invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema description coverage at 100% for the single parameter (match_id, already described as returned by other endpoints), the description adds no parameter-specific semantics. The baseline of 3 applies because the schema carries the full parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as returning statistics for one match, with a specific verb ('get') and resource ('match statistics'). It distinguishes itself from sibling tools (score, events, analysis, odds) by focusing on the two statistic families and their unique characteristics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving match statistics, and explicitly states the ULTRA plan requirement, which is a clear prerequisite. However, it does not name alternative tools for different needs or provide explicit 'when not to use' guidance, though the context is sufficient for most cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_playerPlayer profileA
Read-onlyIdempotent
Inspect

One player's profile: ranking, country, handedness, date of birth and cached stats.

ParametersJSON Schema
NameRequiredDescriptionDefault
player_idYesPlayer id, as returned by search_players.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
playerNoThe player.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, openWorld, idempotent, and non-destructive hints, so the safety profile is clear. The description adds a meaningful behavioral trait by noting 'cached stats,' which alerts the agent that the data may be cached and not real-time. This goes beyond what annotations state, providing useful context for freshness expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core purpose ('One player's profile') and then lists key attributes. Every word earns its place, with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (one parameter, no nested objects), has a full output schema, and clear annotations. The description covers what the tool returns at a high level, which is sufficient for an agent to understand the tool's scope. Missing usage guidance is a separate dimension (scored low), but overall completeness relative to complexity is high.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers 100% of parameters, and the player_id description 'Player id, as returned by search_players' adds practical guidance on where to obtain the id. The tool description itself does not add further parameter detail, but the schema is already sufficient, meeting the baseline for schema_description_coverage > 80%.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: retrieving a single player's profile, with a specific list of attributes (ranking, country, handedness, date of birth, cached stats). This is specific and distinct from sibling tools like search_players or get_archive_career, though it does not explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a player's profile is needed but provides no explicit guidance on when to use this tool versus alternatives. It does not mention any exclusions, prerequisites, or edge cases, leaving the agent to infer context from the tool name and sibling list.

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 dateA
Read-onlyIdempotent
Inspect

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 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
as_ofNoYYYY-MM-DD — the record in force on this date. Omit for the latest known.
systemNoRestrict to one system. Omit for every system held for the player.
player_idsYesRoster player ids, as returned by search_players. Max 50.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
coverageNoWhat resolved against what was asked (players_resolved, systems_resolved, oldest_available per system). Read before trusting an empty result.
rankingsNoOne record per player × system held.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/openWorld/idempotent annotations, the description discloses the as-of lookup semantics (newest record on or before, never after), per-system data shape (ATP/WTA rank+points vs UTR rating), data availability start date for ITF/UTR, and plan requirement. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each serving a distinct purpose: core definition, differentiation from current data, system-specific details, and coverage/access constraints. Front-loaded with the most important information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is well-specified with a rich description covering historical semantics, system behavior, data coverage, and access requirements. The existing output schema covers return values, so the description's omissions are acceptable. There are minor unknowns like behavior before history begins, but the description explicitly notes the start date, so completeness is high.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for all three parameters, so baseline is 3. The description adds critical semantics beyond the schema: the 'newest record in force ON OR BEFORE as_of — never one dated after it' rule clarifies edge cases, and 'Systems are never collapsed' clarifies how the system parameter behaves. This goes beyond the basic baseline, though the schema already explains each parameter adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('get') and resource ('player rankings'), and immediately scopes it to 'SPECIFIC players' and 'point-in-time' historical records. It explicitly contrasts with the API's other current-value ranking fields, distinguishing it from siblings like get_rankings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It establishes when to use this tool: when historical point-in-time rankings for specific players are needed, and explicitly notes that every other ranking field returns current values. It also adds a prerequisite (ULTRA plan). However, it does not name a specific alternative tool (e.g., get_rankings) or state exclusions like 'use get_rankings for current rankings'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_rankingsRankings listingA
Read-onlyIdempotent
Inspect

The FULL published ranking table in rank order for one system — 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
as_ofNoYYYY-MM-DD — serves the newest published week at or before this date. Omit for latest.
limitNoMaximum ranking rows to return (1-200).
systemYesRanking system to list. utr has no listing — it is a rating, not a ranking.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
rankingsNoThe table in rank order.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint and other annotations, the description adds meaningful behavioral details: rows carry null player_id for non-roster players to avoid silent holes, ITF data starts on 2026-07-29, and PRO plan access is required. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences, front-loaded with the core purpose, and adds relevant caveats without redundancy. Every sentence contributes value, making it efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 are covered. The description covers data coverage (ITF start date), row-level behavior (null player_id), the alternative tool, and the PRO plan. The minor inconsistency between 'FULL table' and the limit parameter prevents a perfect score, but overall it is highly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 restates as_of semantics but does not add significant new parameter-level meaning beyond what the schema already describes. The 'FULL' phrasing could conflict with the limit parameter, though the schema clarifies the limit behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists the FULL published ranking table in rank order for one system, with the specific date semantics (newest week at or before as_of). It distinguishes itself from the sibling tool get_player_rankings by focusing on the full table rather than specific players.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'For point-in-time records of SPECIFIC players use get_player_rankings', giving a clear alternative and when-to-use guidance. It also notes the PRO plan requirement, which sets expectations for availability.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recent_resultsRecent resultsA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoLatest play date: YYYY-MM-DD or ISO-8601; must not precede from.
fromNoEarliest play date: YYYY-MM-DD (a whole UTC day) or ISO-8601 datetime.
tourNoTour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used.
limitNoMaximum matches to return (1-200).
playerNoPlayer ids (from search_players), max 50 — keeps matches where ANY listed player is either participant.
countryNoEither 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

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
matchesNoCompleted matches, most recent first.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations cover read-only, idempotent, open-world, and non-destructive behavior, and the description adds useful context: the plan prerequisite and that results include final scores and winners. No contradiction with annotations, and the extra context earns a 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short, purposeful sentences, immediately stating the core function and then adding filter and plan information. No wasted or redundant content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Combined with the complete schema, output schema, and annotations, the description covers the tool's core purpose, filter options, and access requirement. The only slight gap is the vague term 'recently' without a default time window clarification, but the from/to parameters fill that gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides 100% parameter descriptions, so the description's mention of filterable options (tour, player, nationality, play date) adds no new meaning. Baseline 3 is appropriate because the schema carries the parameter semantics fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the resource as recently completed tennis matches with final scores and winners, which distinguishes it from live, upcoming, or archive match tools. However, the action verb is implicit rather than explicit ('List' or 'Get'), so it stops 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.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states the tool is filterable and mentions the plan requirement, giving a sense of when it applies. However, it does not explicitly compare with sibling tools such as get_archive_matches or get_live_matches, nor does it state when not 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_tournamentTournament detailA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tournament_idYesStable tournament id, as returned by search_tournaments or carried on a match as tournament_id.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
tournamentNoThe tournament.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds context beyond that by noting the ID is stable and carried on match objects, and that some fields (host city/country and category) are provided only 'where curated', indicating possible data incompleteness. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that explains the purpose, the input identifier, and the output fields without any wasted words. It is well-structured and immediately scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with one parameter and an output schema, the description conveys the core purpose, the required identifier, and the expected data content. It is complete enough for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already fully documents the single parameter (tournament_id) with a clear description, achieving 100% coverage. The tool description adds little beyond repeating that the ID is carried on match objects, 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as retrieving a single tournament by its stable ID and distinguishes it from siblings like search_tournaments. It specifies the resource (tournament) and the key identifier (tournament_id), along with the kind of data returned (name, tour, surface, indoor, etc.).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the appropriate context: use this tool when you already have a stable tournament_id, such as one carried on match objects. It does not explicitly mention alternatives or exclusions, but the context is clear and the parameter schema reinforces the source of the ID.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_upcoming_matchesUpcoming matchesB
Read-onlyIdempotent
Inspect

List tennis matches scheduled to start soon, with players and tournament.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoLatest play date: YYYY-MM-DD or ISO-8601; must not precede from.
fromNoEarliest play date: YYYY-MM-DD (a whole UTC day) or ISO-8601 datetime.
tourNoTour filter; each name covers its doubles variants. Exhibition/team events carry no tour and are excluded whenever the filter is used.
limitNoMaximum matches to return (1-200).
playerNoPlayer ids (from search_players), max 50 — keeps matches where ANY listed player is either participant.
countryNoEither 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

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
matchesNoMatches due to start, soonest first.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the read-only, idempotent, and non-destructive nature. The description adds minimal behavioral context by specifying the matches are upcoming ('scheduled to start soon'), but does not disclose additional traits such as default time window, ordering, or dynamic nature beyond what openWorldHint already implies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no redundant information. It fits the tool's simplicity and is appropriately concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With strong annotations and full schema coverage, the description covers the core purpose. However, it lacks usage guidance and doesn't differentiate from sibling scheduling tools, leaving an agent to infer when 'upcoming' applies as opposed to 'fixtures' or 'live' matches.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% parameter descriptions, so the baseline is 3. The description does not provide additional parameter meaning; it only vaguely references 'players and tournament' which maps to the player and tour parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool lists tennis matches with a time scope ('scheduled to start soon') and includes players and tournament. It uses a specific verb and resource, but does not explicitly distinguish itself from sibling tools like get_live_matches or get_fixtures, so it gets a 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. Sibling tools such as get_live_matches, get_fixtures, and get_recent_results suggest overlapping functionality, but the description gives no usage context or exclusions.

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)A
Read-onlyIdempotent
Inspect

Search the results archive — completed-match RESULTS from 1968 through 2022: ATP and WTA, main draws, qualifying and the ITF/futures tiers. Winner/loser-shaped records with final score, 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 our own results (get_recent_results) begin. Requires the BASIC plan or any History plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoLatest tournament START date, YYYY-MM-DD.
fromNoEarliest tournament START date, YYYY-MM-DD.
tourNoatp or wta.
levelNoSource 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).
limitNoMaximum results to return (1-200).
roundNoRound code, e.g. F for finals.
player_nameNoCase-insensitive fragment of EITHER player's name, min 3 chars, e.g. "borg".

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
resultsNoArchive results, newest tournament first.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive behavior. The description adds value beyond annotations by specifying the record shape (winner/loser with final score, seeds, ranks at match time), the historical cutoff, and the plan requirement. It does not contradict any annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences: the first concisely states purpose and scope, the second gives usage context and boundary. No redundant wording; every clause carries meaningful content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description fully covers what an agent needs: the tool's scope, the distinction from recent results, the output shape, and access requirements. Combined with rich schema (7 params, 100% covered) and output schema present, it is sufficiently complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with each parameter already described. The description adds no extra parameter-level meaning, so the baseline of 3 applies. It does mention general output shape but not specific parameter usage beyond what schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool searches the completed-match results archive with specific scope: ATP/WTA, main draws, qualifying, ITF/futures tiers, and date range 1968–2022. It clearly distinguishes from recent results by naming get_recent_results as the successor for post-2022 data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: 'Use this for historical questions' and states the archive ends where get_recent_results begins, directly naming the alternative. Also mentions the required plan level, giving a clear prerequisite for invocation.

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 biosA
Read-onlyIdempotent
Inspect

The people of the results archive (1968–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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tourNoatp or wta.
limitNoMaximum players to return (1-200).
queryYesFull or partial player name, min 3 chars, e.g. "navratilova".

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
playersNoMatching archive people, ordered by name.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (read-only, idempotent, non-destructive), so the description adds value by explaining that IDs are corpus person IDs not roster IDs, and enumerates the returned fields. It could further elaborate on open-world behavior, but annotations mitigate that need.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, all informative: the first describes the data scope and fields, the second clarifies ID semantics and provides an alternative, and the third gives the plan requirement. There is no filler or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, the description doesn't need to explain return structure. It covers the historical scope, ID distinction, alternative tool, and plan requirement, making it complete for a search tool with this simplicity. The sibling distinction is especially useful in a large toolset.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description does not add additional meaning to the query, tour, or limit parameters beyond what the schema already provides, but it does clarify the context of how the query maps to archive player identities.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the resource (people in the results archive 1968–2022) and specifies the exact return fields (hand, date of birth, country, height, career-high rank). It also distinguishes itself from the sibling tool search_players by noting the id type and scoping to archive players.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use this tool vs. the alternative: 'for current players use search_players'. It also discloses the plan requirement ('Requires the BASIC plan or any History plan'), giving clear prerequisites and context for invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_playersSearch playersA
Read-onlyIdempotent
Inspect

Search tennis players by name. Returns id, country, ranking and tour. Use the returned id with get_player.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum players to return (1-200).
queryYesFull or partial player name, e.g. "alcaraz".

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
playersNoMatching players, best match first.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only and safe behavior. The description adds value by stating the return fields (id, country, ranking, tour) and recommending using the id with get_player, which goes beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short, front-loaded sentences with no redundant information. Every sentence adds value: what it does, what it returns, and how to use the result.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, the presence of an output schema, and strong annotations, the description is sufficiently complete. It could explicitly state that it searches current players (not archive), but the sibling context and return fields imply this.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage, fully documenting both 'query' and 'limit'. The description does not add any parameter-level meaning beyond the schema, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches tennis players by name, with a specific verb and resource. It also mentions the return fields and links to get_player, distinguishing it from other search tools like search_tournaments or 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: use this tool to find a player ID, then use that ID with get_player. It does not explicitly mention exclusions or alternatives, but the purpose is well-defined and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_tournamentsTournament catalogueA
Read-onlyIdempotent
Inspect

Search the tournament catalogue — the stable id space that match objects carry as tournament_id. Returns surface, indoor, host city/country and category where curated.

ParametersJSON Schema
NameRequiredDescriptionDefault
tourNoRestrict to one tour.
limitNoMaximum tournaments to return (1-200).
queryNoFull or partial tournament name, e.g. "wimbledon". Omit to list all.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesTrue 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.
messageYesHuman-readable summary. Identical to the text content, so either half can be used alone.
tournamentsNoMatching tournaments, name order.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld, lowering the bar. The description adds valuable context: return fields (surface, indoor, host city/country, category) and the caveat 'where curated', indicating data may be sparse. It also notes the id space is stable, which is useful for caching and mapping.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the action. Each phrase earns its place: 'stable id space', 'where curated', and the field list. No redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and only three optional params, the description covers purpose, return fields, and id-mapping context. It is complete enough for an agent to invoke the tool correctly without additional elaboration.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has 100% coverage: tour enum, limit with default/max, and query with example. The description adds no param-specific meaning beyond that, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Search the tournament catalogue', a specific verb+resource pairing. It further distinguishes from sibling tools by framing the catalogue as 'the stable id space that match objects carry as tournament_id', clarifying its role relative to get_tournament and search_archive_matches.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies when to use this tool: to resolve tournament_id values or search tournaments by name/field. It does not explicitly name alternatives or state exclusions, but the stable-id-space framing and field listing give enough context for an agent to choose it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 10 tool updatesv1.4.0
    • Addedget_charting_match
    • Addedget_charting_player
    • Changedget_fixtures1 field changed
      • addedInput schema / properties / tour
        Added 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"
        +}
    • Changedget_live_matches9 fields changed
      • addedInput schema / properties / country
        Added 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"
        +}
      • addedInput schema / properties / player
        Added 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"
        +}
      • addedInput schema / properties / tour
        Added 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"
        +}
      • addedOutput schema / properties / matches / items / properties / event_status
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / round_code
        Added value: +{
        +  "description": "Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / tour
        Added value: +{
        +  "description": "atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / tournament_id
        Added value: +{
        +  "description": "Stable tournament id — pass to get_tournament. Null where uncatalogued.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / withdrew
        Added 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"
        +  ]
        +}
      • changedOutput schema / properties / matches / items / required
        Previous 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"
        +]
    • Changedget_match6 fields changed
      • addedOutput schema / properties / match / properties / event_status
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / match / properties / round_code
        Added value: +{
        +  "description": "Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / match / properties / tour
        Added value: +{
        +  "description": "atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / match / properties / tournament_id
        Added value: +{
        +  "description": "Stable tournament id — pass to get_tournament. Null where uncatalogued.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / match / properties / withdrew
        Added 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"
        +  ]
        +}
      • changedOutput schema / properties / match / required
        Previous 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"
        +]
    • Addedget_match_statistics
    • Addedget_player_rankings
    • Addedget_rankings
    • Changedget_recent_results11 fields changed
      • addedInput schema / properties / country
        Added 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"
        +}
      • addedInput schema / properties / from
        Added value: +{
        +  "description": "Earliest play date: YYYY-MM-DD (a whole UTC day) or ISO-8601 datetime.",
        +  "type": "string"
        +}
      • addedInput schema / properties / player
        Added 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"
        +}
      • addedInput schema / properties / to
        Added value: +{
        +  "description": "Latest play date: YYYY-MM-DD or ISO-8601; must not precede from.",
        +  "type": "string"
        +}
      • addedInput schema / properties / tour
        Added 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"
        +}
      • addedOutput schema / properties / matches / items / properties / event_status
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / round_code
        Added value: +{
        +  "description": "Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / tour
        Added value: +{
        +  "description": "atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / tournament_id
        Added value: +{
        +  "description": "Stable tournament id — pass to get_tournament. Null where uncatalogued.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / withdrew
        Added 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"
        +  ]
        +}
      • changedOutput schema / properties / matches / items / required
        Previous 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"
        +]
    • Changedget_upcoming_matches11 fields changed
      • addedInput schema / properties / country
        Added 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"
        +}
      • addedInput schema / properties / from
        Added value: +{
        +  "description": "Earliest play date: YYYY-MM-DD (a whole UTC day) or ISO-8601 datetime.",
        +  "type": "string"
        +}
      • addedInput schema / properties / player
        Added 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"
        +}
      • addedInput schema / properties / to
        Added value: +{
        +  "description": "Latest play date: YYYY-MM-DD or ISO-8601; must not precede from.",
        +  "type": "string"
        +}
      • addedInput schema / properties / tour
        Added 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"
        +}
      • addedOutput schema / properties / matches / items / properties / event_status
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / round_code
        Added value: +{
        +  "description": "Round in the normalized vocabulary (F, SF, QF, R16 … Q); null when the label is unrecognised, never guessed.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / tour
        Added value: +{
        +  "description": "atp, wta, challenger, itf or juniors. Null when the feed never stated one (exhibitions, team events).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / tournament_id
        Added value: +{
        +  "description": "Stable tournament id — pass to get_tournament. Null where uncatalogued.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / matches / items / properties / withdrew
        Added 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"
        +  ]
        +}
      • changedOutput schema / properties / matches / items / required
        Previous 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"
        +]
  2. 15 tool updatesv1.3.0
    • Addedget_archive_career
    • Addedget_archive_match
    • Addedget_h2h
    • Addedget_live_matches
    • Addedget_match_analysis
    • Addedget_match_events
    • Addedget_match_odds
    • Addedget_match_score
    • Addedget_player
    • Addedget_recent_results
    • Addedget_tournament
    • Addedsearch_archive_matches
    • Addedsearch_archive_players
    • Addedsearch_players
    • Addedsearch_tournaments
  3. 7 tool updatesv1.2.1
    • Addedcheck_api_status
    • Removedget_live_matches
    • Addedget_match
    • Removedget_match_analysis
    • Removedget_match_events
    • Removedget_recent_results
    • Removedsearch_players
  4. 9 tool updatesv1.2.0
    • Changedget_fixtures2 fields changed
      • addedInput schema / properties / limit / description
        Added value: +"Maximum fixtures to return (1-200)."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "fixtures": {
        +      "description": "Scheduled fixtures, earliest first.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "event_date": {
        +            "description": "Scheduled start, ISO timestamp.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "player1": {
        +            "description": "Name of player 1.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "player2": {
        +            "description": "Name of player 2.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "round": {
        +            "description": "Round within the event.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "tournament": {
        +            "description": "Event name.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          }
        +        },
        +        "required": [
        +          "event_date",
        +          "tournament",
        +          "round",
        +          "player1",
        +          "player2"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "message": {
        +      "description": "Human-readable summary. Identical to the text content, so either half can be used alone.",
        +      "type": "string"
        +    },
        +    "ok": {
        +      "description": "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.",
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "ok",
        +    "message"
        +  ],
        +  "type": "object"
        +}
    • Changedget_live_matches2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum matches to return"New value: +"Maximum matches to return (1-200)."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "matches": {
        +      "description": "The live matches, most relevant first.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "id": {
        +            "description": "Match id. Pass to get_match, get_match_score, get_match_events or get_match_odds.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "indoor": {
        +            "description": "True when played indoors.",
        +            "type": [
        +              "boolean",
        +              "null"
        +            ]
        +          },
        +          "player1": {
        +            "description": "Name of player 1.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "player2": {
        +            "description": "Name of player 2.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "round": {
        +            "description": "Round within the event, e.g. \"QF\".",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "score": {
        +            "description": "Formatted score line, e.g. \"6-4 3-6 2-1\".",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "serving": {
        +            "description": "1 or 2 while a point is in play, otherwise null.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "status": {
        +            "description": "One of live, upcoming or completed.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "surface": {
        +            "description": "Court surface, e.g. hard, clay, grass.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "tournament": {
        +            "description": "Event name, e.g. \"Wimbledon\".",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "win_probability_p1": {
        +            "description": "Model probability that player 1 wins, 0-1. Requires the ULTRA plan; null otherwise.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "winner": {
        +            "description": "1 or 2 once decided, otherwise null.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "tournament",
        +          "round",
        +          "player1",
        +          "player2",
        +          "score",
        +          "status",
        +          "surface",
        +          "indoor",
        +          "serving",
        +          "winner",
        +          "win_probability_p1"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "message": {
        +      "description": "Human-readable summary. Identical to the text content, so either half can be used alone.",
        +      "type": "string"
        +    },
        +    "ok": {
        +      "description": "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.",
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "ok",
        +    "message"
        +  ],
        +  "type": "object"
        +}
    • Changedget_match_analysis2 fields changed
      • addedInput schema / properties / match_id / description
        Added value: +"Match id, as returned by get_live_matches, get_upcoming_matches or get_recent_results."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "message": {
        +      "description": "Human-readable summary. Identical to the text content, so either half can be used alone.",
        +      "type": "string"
        +    },
        +    "ok": {
        +      "description": "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.",
        +      "type": "boolean"
        +    },
        +    "profile": {
        +      "additionalProperties": false,
        +      "description": "Quantitative view.",
        +      "properties": {
        +        "expected_closeness": {
        +          "description": "How close the model expects the match to be.",
        +          "type": [
        +            "number",
        +            "null"
        +          ]
        +        },
        +        "key_factors": {
        +          "description": "Drivers behind the model view.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "volatility_rating": {
        +          "description": "Expected swing in the match state.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "win_probability_p1": {
        +          "description": "Model probability player 1 wins, 0-1.",
        +          "type": [
        +            "number",
        +            "null"
        +          ]
        +        }
        +      },
        +      "required": [
        +        "win_probability_p1",
        +        "expected_closeness",
        +        "volatility_rating",
        +        "key_factors"
        +      ],
        +      "type": "object"
        +    },
        +    "thesis": {
        +      "additionalProperties": false,
        +      "description": "Narrative view.",
        +      "properties": {
        +        "confidence": {
        +          "description": "Model confidence, 0-1.",
        +          "type": [
        +            "number",
        +            "null"
        +          ]
        +        },
        +        "pick_side": {
        +          "description": "Player the model favours, 1 or 2.",
        +          "type": [
        +            "number",
        +            "null"
        +          ]
        +        },
        +        "reasoning": {
        +          "description": "Narrative reasoning.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "state": {
        +          "description": "Current state of the thesis.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        }
        +      },
        +      "required": [
        +        "pick_side",
        +        "confidence",
        +        "state",
        +        "reasoning"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "ok",
        +    "message"
        +  ],
        +  "type": "object"
        +}
    • Addedget_match_events
    • Removedget_match_odds
    • Removedget_match_score
    • Changedget_recent_results2 fields changed
      • addedInput schema / properties / limit / description
        Added value: +"Maximum matches to return (1-200)."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "matches": {
        +      "description": "Completed matches, most recent first.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "id": {
        +            "description": "Match id. Pass to get_match, get_match_score, get_match_events or get_match_odds.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "indoor": {
        +            "description": "True when played indoors.",
        +            "type": [
        +              "boolean",
        +              "null"
        +            ]
        +          },
        +          "player1": {
        +            "description": "Name of player 1.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "player2": {
        +            "description": "Name of player 2.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "round": {
        +            "description": "Round within the event, e.g. \"QF\".",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "score": {
        +            "description": "Formatted score line, e.g. \"6-4 3-6 2-1\".",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "serving": {
        +            "description": "1 or 2 while a point is in play, otherwise null.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "status": {
        +            "description": "One of live, upcoming or completed.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "surface": {
        +            "description": "Court surface, e.g. hard, clay, grass.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "tournament": {
        +            "description": "Event name, e.g. \"Wimbledon\".",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "win_probability_p1": {
        +            "description": "Model probability that player 1 wins, 0-1. Requires the ULTRA plan; null otherwise.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "winner": {
        +            "description": "1 or 2 once decided, otherwise null.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "tournament",
        +          "round",
        +          "player1",
        +          "player2",
        +          "score",
        +          "status",
        +          "surface",
        +          "indoor",
        +          "serving",
        +          "winner",
        +          "win_probability_p1"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "message": {
        +      "description": "Human-readable summary. Identical to the text content, so either half can be used alone.",
        +      "type": "string"
        +    },
        +    "ok": {
        +      "description": "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.",
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "ok",
        +    "message"
        +  ],
        +  "type": "object"
        +}
    • Changedget_upcoming_matches2 fields changed
      • addedInput schema / properties / limit / description
        Added value: +"Maximum matches to return (1-200)."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "matches": {
        +      "description": "Matches due to start, soonest first.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "id": {
        +            "description": "Match id. Pass to get_match, get_match_score, get_match_events or get_match_odds.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "indoor": {
        +            "description": "True when played indoors.",
        +            "type": [
        +              "boolean",
        +              "null"
        +            ]
        +          },
        +          "player1": {
        +            "description": "Name of player 1.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "player2": {
        +            "description": "Name of player 2.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "round": {
        +            "description": "Round within the event, e.g. \"QF\".",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "score": {
        +            "description": "Formatted score line, e.g. \"6-4 3-6 2-1\".",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "serving": {
        +            "description": "1 or 2 while a point is in play, otherwise null.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "status": {
        +            "description": "One of live, upcoming or completed.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "surface": {
        +            "description": "Court surface, e.g. hard, clay, grass.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "tournament": {
        +            "description": "Event name, e.g. \"Wimbledon\".",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "win_probability_p1": {
        +            "description": "Model probability that player 1 wins, 0-1. Requires the ULTRA plan; null otherwise.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "winner": {
        +            "description": "1 or 2 once decided, otherwise null.",
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "tournament",
        +          "round",
        +          "player1",
        +          "player2",
        +          "score",
        +          "status",
        +          "surface",
        +          "indoor",
        +          "serving",
        +          "winner",
        +          "win_probability_p1"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "message": {
        +      "description": "Human-readable summary. Identical to the text content, so either half can be used alone.",
        +      "type": "string"
        +    },
        +    "ok": {
        +      "description": "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.",
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "ok",
        +    "message"
        +  ],
        +  "type": "object"
        +}
    • Addedsearch_players
  5. 7 tool updatesv1.0.4
    • First observedget_fixtures
    • First observedget_live_matches
    • First observedget_match_analysis
    • First observedget_match_odds
    • First observedget_match_score
    • First observedget_recent_results
    • First observedget_upcoming_matches

TDQS

A3.9/5.0
Disambiguation3/5

Most tools are distinct, but get_upcoming_matches and get_fixtures are nearly synonymous (both list upcoming scheduled matches), and get_match already includes the score that get_match_score returns. These overlaps can cause misselection. The rest are well-differentiated.

Naming Consistency4/5

Consistent snake_case verb_noun pattern with get_ for data retrieval, search_ for queries, and check_ for status. Minor inconsistencies: get_fixtures uses a plural noun while similar list endpoints use get_live_matches, and get_archive_career vs get_player are similar in structure. Overall predictable.

Tool Count4/5

19 tools is slightly above the ideal range but justifiable for a comprehensive tennis API covering live, historical, players, tournaments, match details, odds, and analysis. No obvious redundancy beyond the two close pairs, so it earns its place.

Completeness4/5

Covers the domain thoroughly: live, upcoming, recent results, historical archive, player profiles, tournaments, match details, events, odds, analysis, and status. Minor gaps like the lack of a general player list (only search) or a tournament-specific match schedule are workarounds but not dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides access to comprehensive sports data from 5 major leagues (NBA, NFL, MLB, EPL, NHL) including teams, players, games, statistics, standings, injuries, and betting odds through 67+ endpoints. Enables users to query sports information and analytics through natural language.
    12
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Gives your MCP host (Claude Desktop, Cursor, Continue, Zed) access to live scores, match details, standings, top scorers, knockout brackets and player stats across football, basketball, cricket and tennis. Backed by the free public SportScore API — no key, no signup, CORS-open.
    8
    131
    10
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A unified MCP server that aggregates 32 sports API providers into a single service, providing 336 tools for scores, stats, odds, esports, and more across 70+ sports.
    100
    146
    22
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to access comprehensive sports data including football, basketball, American football, and hockey leagues via 11 tools, with no API key required.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/livetennisapi/livetennisapi-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server