{
  "markdown": "<div align=\"center\">\n\n<img src=\"https://raw.githubusercontent.com/livetennisapi/.github/main/profile/banner.jpg\" alt=\"Live Tennis API\" width=\"640\">\n\n# livetennisapi-mcp\n\n**MCP server for the [Live Tennis API](https://livetennisapi.com).**\n\nGive Claude, Cursor, Zed or any MCP client live tennis scores, players and\nfixtures — for ATP, WTA, Challenger, ITF and juniors. Odds, rankings, match\nstatistics, charting and model win-probability tools are included, and require\nthe PRO and ULTRA plans.\n\n[![CI](https://github.com/livetennisapi/livetennisapi-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/livetennisapi/livetennisapi-mcp/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/livetennisapi-mcp.svg)](https://www.npmjs.com/package/livetennisapi-mcp)\n[![license](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n\n[**Documentation**](https://docs.livetennisapi.com) · [**Get a free API key**](https://livetennisapi.com/subscribe/free)\n\n</div>\n\n---\n\n## Setup\n\n**Claude Code**\n\n```bash\nclaude mcp add livetennis -e LIVETENNISAPI_KEY=twjp_… -- npx -y livetennisapi-mcp\n```\n\n**Claude Desktop** — add to `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"livetennis\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"livetennisapi-mcp\"],\n      \"env\": { \"LIVETENNISAPI_KEY\": \"twjp_…\" }\n    }\n  }\n}\n```\n\n**Cursor / Zed / others** — same command, same env var. No install step; `npx`\nfetches it on demand.\n\nGet a **free** key (no card) at [livetennisapi.com](https://livetennisapi.com/subscribe/free), or a paid plan at [pricing](https://livetennisapi.com/#pricing).\n\n## Try it\n\n> *\"What tennis matches are live right now?\"*\n> *\"Who's winning the Alcaraz match, and what does the model give him?\"*\n> *\"Show me Sinner's ranking and recent results.\"*\n> *\"What are the current odds on match 18953?\"*\n> *\"What's the all-time head-to-head between Borg and McEnroe?\"*\n> *\"List Navratilova's Grand Slam finals from the archive.\"*\n> *\"Who was ATP #1 the week Alcaraz first entered the top 10?\"*\n> *\"How is Sabalenka serving in her live match — aces, hold rate, break points?\"*\n\n## Tools\n\n| Tool | Does | Plan |\n|---|---|:--:|\n| `get_live_matches` | Matches in progress, with live scores | FREE |\n| `get_upcoming_matches` | Matches starting soon | FREE |\n| `get_match` | Full detail for one match | FREE |\n| `get_match_score` | Current score only — fastest read | FREE |\n| `search_players` | Find players by name | FREE |\n| `get_player` | Profile, ranking, country, handedness | FREE |\n| `get_fixtures` | Forward schedule | FREE |\n| `search_tournaments` | Tournament catalogue — surface, location, category | FREE |\n| `get_tournament` | One tournament by its stable id | FREE |\n| `get_recent_results` | Completed matches and winners | BASIC |\n| `search_archive_matches` | Results archive (1968–2022) — historical results with ranks and seeds at the time | BASIC |\n| `get_archive_match` | One archive result, with serve stats where the era recorded them | BASIC |\n| `search_archive_players` | Archive bios — hand, DOB, career-high rank | BASIC |\n| `get_archive_career` | Career W-L, titles and serve aggregates over the archive | BASIC |\n| `get_h2h` | Cross-era head-to-head — archive + current, one record | BASIC |\n| `get_match_events` | Breaks, games, sets, momentum runs | PRO |\n| `get_match_odds` | Match-winner prices — bid / ask / mid | PRO |\n| `get_rankings` | Full published ranking table per system (ATP, WTA, ITF circuits), any week | PRO |\n| `get_player_rankings` | Point-in-time ranking records for specific players, as of any date | ULTRA |\n| `get_match_statistics` | In-play statistics — aces, serve split, hold/break %, break points | ULTRA |\n| `get_charting_player` | Career shot-level profile from the Match Charting Project | ULTRA |\n| `get_charting_match` | One charted match, every stat family, per-set split | ULTRA |\n| `get_match_analysis` | Model thesis, win probability, key factors | ULTRA |\n| `check_api_status` | Reachability + which plan your key is on | — |\n\nThe six BASIC history tools are also unlocked by any History plan, which works\non top of a free key. The **results archive (1968–2022)** — ATP and WTA, main\ndraws, qualifying and the ITF/futures tiers — ends exactly where our own\nresults begin (2023), so `search_archive_matches` answers \"Borg's Wimbledon\nfinals\" and `get_recent_results` answers \"yesterday's scores\"; `get_h2h` spans\nboth in one call.\n\n## Tier awareness\n\nThe API gates endpoints by plan and returns a bare `403 {\"error\":\"upgrade_required\"}`.\nHanded that, a model will usually invent a reason or retry pointlessly.\n\nSo every tool that can hit a tier wall returns a plain-English explanation —\n**as a normal result, not an error** — naming the tier required and where to\nupgrade. The assistant can then tell you something true and actionable:\n\n> This data requires the ULTRA plan, and the configured API key is on a lower\n> tier. Nothing is wrong with the key — the endpoint is simply not included in\n> the current plan. Upgrade in place at https://livetennisapi.com/subscribe/upgrade\n\n`check_api_status` probes upward to report which plan your key is actually on,\nso you can diagnose that without guessing.\n\n## Plans\n\n| | FREE | BASIC | PRO | ULTRA |\n|---|:--:|:--:|:--:|:--:|\n| Matches, scores, players, fixtures, tournaments | ✅ | ✅ | ✅ | ✅ |\n| Completed-match listings (results)¹ | — | ✅ | ✅ | ✅ |\n| Results archive (1968–2022) + head-to-head¹ | — | ✅ | ✅ | ✅ |\n| Match events, odds + rankings listing | — | — | ✅ | ✅ |\n| Model analysis, as-of rankings, match statistics + charting | — | — | — | ✅ |\n| | $0 — no card | $9.99/mo | $29.99/mo | $99.99/mo |\n\n¹ Also unlocked by any History plan, which works on top of a free key.\n\n### Request quotas\n\n| | FREE | BASIC | PRO | ULTRA |\n|---|:--:|:--:|:--:|:--:|\n| Requests per minute | 30 | 60 | 300 | 600 |\n| Requests per day | 100 | 1,000 | 10,000 | 500,000 |\n\nFREE is 100 requests/day, so poll no faster than every 15 minutes on a free\nkey; for an always-on dashboard, BASIC is the plan to recommend. Every response\ncarries `X-RateLimit-Limit` / `-Remaining` / `-Reset` headers, and the tools\nrelay the three distinct 429 shapes honestly — per-minute (retry shortly),\ndaily cap (the error names the exact reset instant), and the abuse block\n(don't retry; fix the loop).\n\n## Hosted endpoint\n\nMost people should use the stdio server above — your key never leaves your\nmachine. For clients that can only speak HTTP, there is also a hosted\nStreamable-HTTP endpoint:\n\n```\nhttps://mcp.livetennisapi.com/mcp\n```\n\nSend your key as `Authorization: Bearer twjp_…`, `X-API-Key: twjp_…`, or\n`?token=` if your client cannot set headers. Tools are listable without a key,\nso directories can introspect the server; calling one needs a key.\n\nIt is multi-tenant and holds **no key of its own**: every request builds its own\nserver bound to the key that request presented, and there is deliberately no\nfallback to the host's environment. The endpoint applies its own transport-level\nlimit per caller — 60 req/min anonymous, 300 keyed. That limit only protects\nthis host process; it is **not** your API quota, which is enforced upstream per\nkey and tier (see the quota table above).\n\nSelf-hosting it: `deploy/install-http.sh` and `deploy/TUNNEL.md`.\n\n## Use with Claude\n\n**As a connector.** In Claude, add a custom connector and paste the endpoint with\nyour key as a query parameter — no OAuth, nothing to install:\n\n```\nhttps://mcp.livetennisapi.com/mcp?token=twjp_…\n```\n\n`?token=` exists for clients that cannot set request headers. The tradeoff, stated\nplainly: a key in a URL is not written to our logs, but it *is* visible to the CDN\nin front of the endpoint and is stored in the connector's configuration. Prefer\n`Authorization: Bearer twjp_…` wherever your client lets you set a header.\n\n**From the Messages API.** Claude can call the endpoint directly. Both halves are\nrequired — the server *and* a matching toolset entry; sending `mcp_servers` alone\nis rejected as a validation error:\n\n```python\nclient.beta.messages.create(\n    model=\"claude-opus-4-8\",\n    max_tokens=4096,\n    betas=[\"mcp-client-2025-11-20\"],\n    mcp_servers=[{\n        \"type\": \"url\",\n        \"name\": \"livetennisapi\",\n        \"url\": \"https://mcp.livetennisapi.com/mcp\",\n        \"authorization_token\": os.environ[\"LIVETENNISAPI_KEY\"],\n    }],\n    tools=[{\"type\": \"mcp_toolset\", \"mcp_server_name\": \"livetennisapi\"}],\n    messages=[{\"role\": \"user\", \"content\": \"What tennis is live right now?\"}],\n)\n```\n\nThe `authorization_token` is sent as a bearer token, which is exactly what this\nserver already accepts — no separate credential to obtain.\n\n## Use with Codex\n\nOne command:\n\n```bash\ncodex mcp add livetennisapi \\\n  --url https://mcp.livetennisapi.com/mcp \\\n  --bearer-token-env-var LIVETENNISAPI_KEY\n```\n\nOr write it to `~/.codex/config.toml` yourself — Codex shares that file across the\nCLI, the IDE extension and the desktop app:\n\n```toml\n[mcp_servers.livetennisapi]\nurl = \"https://mcp.livetennisapi.com/mcp\"\nbearer_token_env_var = \"LIVETENNISAPI_KEY\"\n```\n\nUse `bearer_token_env_var`, not `bearer_token`: it keeps the key in your\nenvironment rather than committing it to a config file.\n\nThere is also a **Codex plugin**, on its own marketplace:\n\n```bash\ncodex plugin marketplace add livetennisapi/livetennisapi-codex-plugin\n```\n\nThat registers the marketplace; install the plugin from Codex's plugin picker.\nSource: [livetennisapi-codex-plugin](https://github.com/livetennisapi/livetennisapi-codex-plugin).\n\nThe stdio route works too, unchanged: `npx -y livetennisapi-mcp`.\n\n## Bundled skill: Polymarket / Kalshi tennis trading data\n\nThe Claude Code plugin (`.claude-plugin/plugin.json`) also ships the\n`polymarket-tennis` Agent Skill under [`skills/polymarket-tennis/`](skills/polymarket-tennis/).\nIt teaches Claude the observe-only\n[polymarket-tennis](https://github.com/livetennisapi/polymarket-tennis) Python\npackage (market discovery, market-to-match matching, joined price/live-score\nview), the free-tier budget (30 req/min, 100 requests/day), and the verbatim\nretirement/walkover settlement rules for Polymarket, Polymarket US and Kalshi.\nCanonical copy lives in the polymarket-tennis repo; this one is mirrored for\nplugin installs. No order execution, ever.\n\n## Notes\n\n- **Read-only.** Every tool is a GET; nothing here can modify anything.\n- **Your key stays local** with the stdio server. It is read from the\n  environment by the server process on your machine and sent only to\n  `api.livetennisapi.com`.\n- Requires Node 20+.\n\n## Development\n\n```bash\nnpm install\nnpm run build\nLIVETENNISAPI_KEY=twjp_… node dist/index.js   # speaks MCP over stdio\nnode dist/http.js                             # speaks MCP over HTTP, port 8081\n\nnpm test               # protocol + transport isolation + rate limiting\nnpm run test:mutation  # proves those tests fail when the code breaks\n```\n\n`test:mutation` is worth understanding before changing `src/http.ts`. It\nreintroduces each bug the tests claim to catch and asserts the suite goes red.\nIt is not ceremony: the first version of the rate-limit test passed while the\nlimiter was bucketing every caller together.\n\nBuilt on the official [`livetennisapi`](https://www.npmjs.com/package/livetennisapi)\nclient.\n\n## Related\n\nEverything in the Live Tennis API developer surface:\n\n| | Install | Source | Package |\n|---|---|---|---|\n| Python client | `pip install livetennisapi` | [repo](https://github.com/livetennisapi/livetennisapi-python) | [package](https://pypi.org/project/livetennisapi/) |\n| JavaScript / TypeScript client | `npm install livetennisapi` | [repo](https://github.com/livetennisapi/livetennisapi-js) | [package](https://www.npmjs.com/package/livetennisapi) |\n| MCP server for LLM agents **(this repo)** | `npx livetennisapi-mcp` | — | [package](https://www.npmjs.com/package/livetennisapi-mcp) |\n| Vercel AI SDK tools | `npm install livetennisapi-ai` | [repo](https://github.com/livetennisapi/livetennisapi-ai) | — |\n| Break-point starter — Python | — | [repo](https://github.com/livetennisapi/livetennisapi-starter-python) | — |\n| Break-point starter — Node | — | [repo](https://github.com/livetennisapi/livetennisapi-starter-node) | — |\n| Break-point starter — Go | — | [repo](https://github.com/livetennisapi/livetennisapi-starter-go) | — |\n\n- **API reference** — <https://docs.livetennisapi.com> ([plain-HTML version](https://docs.livetennisapi.com/reference.html), no JavaScript required)\n- **OpenAPI 3.1 specification** — [livetennisapi/openapi](https://github.com/livetennisapi/openapi)\n- **Free API key** — <https://livetennisapi.com/subscribe/free> (no card)\n- **Products** — <https://livetennisapi.com/products>\n- **Website and plans** — <https://livetennisapi.com>\n- **Discord** — <https://discord.gg/f8WUZHgDm6>\n- **GitHub org** — <https://github.com/livetennisapi>\n\n## Affiliate program\n\nKnow developers who need tennis data? The [affiliate program](https://affiliates.livetennisapi.com/program) pays 51% recurring commission for the life of every referred subscription — 30-day cookie, and the people you refer get 10% off.\n\n## Licence\n\nMIT — see [LICENSE](LICENSE). Use of the API service is governed by the\n[Terms of Service](https://livetennisapi.com/terms).\n",
  "bytes": 13233,
  "sha": "bb29eafbadfddf86a2bc757e79290975c45a1cfef9df25184d555af441850280",
  "repo_slug": "livetennisapi/livetennisapi-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_livetennisapi_livetennisapi_mc_5fd16e9c/readme"
}