Skip to content
Data
Skill

/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

From plugin
livetennisapi
1591 skill1 MCP
Install
$ npx -y skills add livetennisapi/livetennisapi-mcp --skill polymarket-tennis --agent claude-code

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

Read more
Ships withlivetennisapi

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.

Get the whole plugin
Stats
159
Stars
56
Forks
Active
Maintenance
TypeScript
Language
MIT
License
9h ago
Last commit
1mo ago
Created

Repo: livetennisapi/livetennisapi-mcp