/polymarket-tennis
Build observe-only Polymarket and Kalshi tennis market tooling on the polymarket-tennis Python package (MIT) plus the Live Tennis API free tier. Use when asked for a Polymarket tennis bot or market watcher, a Kalshi tennis trading bot, tennis prediction-market data, Gamma API
$ npx -y skills add livetennisapi/livetennisapi-mcp --skill polymarket-tennis --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/polymarket-tennis
Context preview
The summary Claude sees to decide when to auto-load this skill.
Build observe-only Polymarket and Kalshi tennis market tooling on the polymarket-tennis Python package (MIT) plus the Live Tennis API free tier. Use when asked for a Polymarket tennis bot or market watcher, a Kalshi tennis trading bot, tennis prediction-market data, Gamma API
SKILL.md
polymarket-tennis.SKILL.mdname: polymarket-tennis
description: Build observe-only Polymarket and Kalshi tennis market tooling on the polymarket-tennis Python package (MIT) plus the Live Tennis API free tier. Use when asked for a Polymarket tennis bot or market watcher, a Kalshi tennis trading bot, tennis prediction-market data, Gamma API tennis markets, matching a market to a live match, break-point or serving state next to market prices, or how a tennis retirement, walkover, or cancelled match settles (venue rule text, never hard-coded). Covers the real package API (GammaClient, LiveTennisClient, discover_tennis_markets, match_market, build_view, pmtennis CLI), the free-tier request budget (30/min, 100/day), the outcome and event_status fields, and the verbatim 2026 settlement matrix. No order execution, wallets, or strategy advice.
license: MIT
compatibility: Python 3.10+, pip install polymarket-tennis (single runtime dependency httpx). Live match data needs a free Live Tennis API key in LIVETENNIS_API_KEY; Polymarket Gamma and Kalshi market reads are keyless.
metadata:
author: Live Tennis API (hello@livetennisapi.com)
version: "0.1.0"
homepage: https://github.com/livetennisapi/polymarket-tennis
attribution: Vendor-authored. The live-score side of every join comes from the Live Tennis API; judge accordingly.
Polymarket / Kalshi tennis trading data
> **Vendor-authored, observe-only.** This skill is maintained by the team behind the > [Live Tennis API](https://livetennisapi.com). It teaches the `polymarket-tennis` > package, which reads public market data and live scores. It contains no order > execution, no wallet or private-key handling, no CLOB client, and no strategy > advice. Execution is permanently out of scope. Nothing here is financial advice.
Hard guardrails (apply to every file you write with this skill)
1. **Observe-only.** Never add order placement, wallet, private-key, or CLOB code to anything built on this package. If the user wants execution, it belongs in their own code behind a clearly separated seam, using the venue's own official interfaces, and this skill does not write it. 2. **Never hard-code a settlement rule.** Retirement and walkover payouts differ by venue (polymarket.com vs Polymarket US vs Kalshi) and by tour (ATP/WTA vs ITF). Read the market's own text — Gamma `description` (`market.raw["description"]`), Kalshi `rules_secondary` — and print it. The reference matrix in [references/settlement-rules.md](references/settlement-rules.md) is for the human, not for code branches. 3. **Respect the free tier: 30 requests/minute, 100 requests/day.** Every `LiveTennisClient` call costs one request; Gamma and Kalshi reads cost nothing. `pmtennis watch` is 1 request per poll at a 60 s default (minimum 30 s). A watcher that calls `live_matches()` + `fixtures()` per poll costs 2 per poll and must self-cap (the reference build caps at 96/day, `--interval 300`). 4. **Detect match endings with `outcome` and `event_status`, not `status`.** `status` is only the lifecycle (`upcoming|live|completed|cancelled`). `outcome` is `completed|retired|walkover|default|abandoned` and `null` until settled; `event_status` is the feed designator (`Retired`, `Walk Over`, `Cancelled`, `Postponed`, `Interrupted`); `withdrew` names who stopped. 5. **Never guess a market-to-match pairing.** `match_market` returns `None` on ambiguity; skip it. Use `override_match_id` / `--match-id` only when the user supplies the id explicitly. 6. **Tests stay offline.** Use trimmed fixtures and `httpx.MockTransport`; never put live calls in tests.
Quick start
pip install polymarket-tennis # Python 3.10+, depends only on httpx
pmtennis discover --matches-only --moneyline-only # keyless, Gamma only
export LIVETENNIS_API_KEY=ltapi_... # free, no card: https://livetennisapi.com/subscribe/free
pmtennis match atp-lehecka-fils-2026-08-17 # show the pairing decision + confidence
pmtennis watch atp-lehecka-fils-2026-08-17 # 1 request per poll, 60 s default
Env-var names differ between the two Live Tennis API tools: the Python package reads `LIVETENNIS_API_KEY`; the `livetennisapi-mcp` server/plugin reads `LIVETENNISAPI_KEY`. Same key value works in both.
Library form — every symbol below is exported from `polymarket_tennis.__init__`:
from polymarket_tennis import (
GammaClient, LiveTennisClient,
discover_tennis_markets, match_market, build_view,
)
with GammaClient() as gamma, LiveTennisClient() as lta:
markets = discover_tennis_markets(gamma, market_types={"moneyline"},
matches_only=True)
candidates = lta.live_matches() + lta.fixtures() # 2 free-tier requests
for market in markets:
decision = match_market(market, candidates)
if decision is None:
continue # ambiguous or no live counterpart — never guessed
view = build_view(market, decision.match)
print(view.render())Sample `view.render()` output:
Cincinnati Open: Jiri Lehecka vs Arthur Fils [atp-lehecka-fils-2026-08-17]
market: Jiri Lehecka 0.095 | Arthur Fils 0.905 (as of 12s ago)
live: Jiri Lehecka vs Arthur Fils 4-6 3-4 (15-40) serving: Jiri Lehecka [BREAK POINT] (as of 8s ago)
The package, in one screen
| Symbol | What it does | Network cost | |---|---|---| | `GammaClient()` | Polymarket Gamma API (keyless): `events()`, `event_by_slug()`, `market_by_id()`, `market_by_slug()`, `market()` | none against your key | | `LiveTennisClient(api_key=None)` | Live Tennis API; key from `LIVETENNIS_API_KEY`: `matches()`, `live_matches()`, `match(id)`, `fixtures()`, `players(search)` | 1 request per call | | `discover_tennis_markets(client, market_types=None, include_closed=False, matches_only=False, limit=100)` | normalized `TennisMarket` list from the `tennis` tag | Gamma only | | `find_market(client, id_or_slug)` | one `Tennis
Read more
name: polymarket-tennis description: Build observe-only Polymarket and Kalshi tennis market tooling on the polymarket-tennis Python package (MIT) plus the Live Tennis API free tier. Use when asked for a Polymarket tennis bot or market watcher, a Kalshi tennis trading bot, tennis prediction-market data, Gamma API tennis markets, matching a market to a live match, break-point or serving state next to market prices, or how a tennis retirement, walkover, or cancelled match settles (venue rule text, never hard-coded). Covers the real package API (GammaClient, LiveTennisClient, discover_tennis_markets, match_market, build_view, pmtennis CLI), the free-tier request budget (30/min, 100/day), the outcome and event_status fields, and the verbatim 2026 settlement matrix. No order execution, wallets, or strategy advice. license: MIT compatibility: Python 3.10+, pip install polymarket-tennis (single runtime dependency httpx). Live match data needs a free Live Tennis API key in LIVETENNIS_API_KEY; Polymarket Gamma and Kalshi market reads are keyless. metadata: author: Live Tennis API (hello@livetennisapi.com) version: "0.1.0" homepage: https://github.com/livetennisapi/polymarket-tennis attribution: Vendor-authored. The live-score side of every join comes from the Live Tennis API; judge accordingly.
Polymarket / Kalshi tennis trading data
> **Vendor-authored, observe-only.** This skill is maintained by the team behind the > [Live Tennis API](https://livetennisapi.com). It teaches the `polymarket-tennis` > package, which reads public market data and live scores. It contains no order > execution, no wallet or private-key handling, no CLOB client, and no strategy > advice. Execution is permanently out of scope. Nothing here is financial advice.
Hard guardrails (apply to every file you write with this skill)
1. **Observe-only.** Never add order placement, wallet, private-key, or CLOB code to anything built on this package. If the user wants execution, it belongs in their own code behind a clearly separated seam, using the venue's own official interfaces, and this skill does not write it. 2. **Never hard-code a settlement rule.** Retirement and walkover payouts differ by venue (polymarket.com vs Polymarket US vs Kalshi) and by tour (ATP/WTA vs ITF). Read the market's own text — Gamma `description` (`market.raw["description"]`), Kalshi `rules_secondary` — and print it. The reference matrix in [references/settlement-rules.md](references/settlement-rules.md) is for the human, not for code branches. 3. **Respect the free tier: 30 requests/minute, 100 requests/day.** Every `LiveTennisClient` call costs one request; Gamma and Kalshi reads cost nothing. `pmtennis watch` is 1 request per poll at a 60 s default (minimum 30 s). A watcher that calls `live_matches()` + `fixtures()` per poll costs 2 per poll and must self-cap (the reference build caps at 96/day, `--interval 300`). 4. **Detect match endings with `outcome` and `event_status`, not `status`.** `status` is only the lifecycle (`upcoming|live|completed|cancelled`). `outcome` is `completed|retired|walkover|default|abandoned` and `null` until settled; `event_status` is the feed designator (`Retired`, `Walk Over`, `Cancelled`, `Postponed`, `Interrupted`); `withdrew` names who stopped. 5. **Never guess a market-to-match pairing.** `match_market` returns `None` on ambiguity; skip it. Use `override_match_id` / `--match-id` only when the user supplies the id explicitly. 6. **Tests stay offline.** Use trimmed fixtures and `httpx.MockTransport`; never put live calls in tests.
Quick start
pip install polymarket-tennis # Python 3.10+, depends only on httpx pmtennis discover --matches-only --moneyline-only # keyless, Gamma only export LIVETENNIS_API_KEY=ltapi_... # free, no card: https://livetennisapi.com/subscribe/free pmtennis match atp-lehecka-fils-2026-08-17 # show the pairing decision + confidence pmtennis watch atp-lehecka-fils-2026-08-17 # 1 request per poll, 60 s default
Env-var names differ between the two Live Tennis API tools: the Python package reads `LIVETENNIS_API_KEY`; the `livetennisapi-mcp` server/plugin reads `LIVETENNISAPI_KEY`. Same key value works in both.
Library form — every symbol below is exported from `polymarket_tennis.__init__`:
from polymarket_tennis import (
GammaClient, LiveTennisClient,
discover_tennis_markets, match_market, build_view,
)
with GammaClient() as gamma, LiveTennisClient() as lta:
markets = discover_tennis_markets(gamma, market_types={"moneyline"},
matches_only=True)
candidates = lta.live_matches() + lta.fixtures() # 2 free-tier requests
for market in markets:
decision = match_market(market, candidates)
if decision is None:
continue # ambiguous or no live counterpart — never guessed
view = build_view(market, decision.match)
print(view.render())Sample `view.render()` output:
Cincinnati Open: Jiri Lehecka vs Arthur Fils [atp-lehecka-fils-2026-08-17] market: Jiri Lehecka 0.095 | Arthur Fils 0.905 (as of 12s ago) live: Jiri Lehecka vs Arthur Fils 4-6 3-4 (15-40) serving: Jiri Lehecka [BREAK POINT] (as of 8s ago)
The package, in one screen
| Symbol | What it does | Network cost | |---|---|---| | `GammaClient()` | Polymarket Gamma API (keyless): `events()`, `event_by_slug()`, `market_by_id()`, `market_by_slug()`, `market()` | none against your key | | `LiveTennisClient(api_key=None)` | Live Tennis API; key from `LIVETENNIS_API_KEY`: `matches()`, `live_matches()`, `match(id)`, `fixtures()`, `players(search)` | 1 request per call | | `discover_tennis_markets(client, market_types=None, include_closed=False, matches_only=False, limit=100)` | normalized `TennisMarket` list from the `tennis` tag | Gamma only | | `find_market(client, id_or_slug)` | one `Tennis
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.
Repo: livetennisapi/livetennisapi-mcp

