# Sportsdata Mcp

> Free, open-source sports-data MCP server — ~500 tools across 28 providers: cross-book betting odds, official league stats, racing, fantasy. Claude Desktop / Cursor / any MCP client.

- **Type:** MCP server
- **Install:** `agentstack add mcp-danieltomaro13-sportsdata-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [DanielTomaro13](https://agentstack.voostack.com/s/danieltomaro13)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [DanielTomaro13](https://github.com/DanielTomaro13)
- **Source:** https://github.com/DanielTomaro13/sportsdata-mcp
- **Website:** https://sportsdata-ai.com

## Install

```sh
agentstack add mcp-danieltomaro13-sportsdata-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# sportsdata-mcp

[](https://github.com/DanielTomaro13/sportsdata-mcp/actions/workflows/ci.yml)
[](https://github.com/DanielTomaro13/sportsdata-mcp/releases/latest)
[](./LICENSE)
[](https://glama.ai/mcp/servers/DanielTomaro13/sportsdata-mcp)

[](https://cursor.com/en/install-mcp?name=sportsdata&config=eyJjb21tYW5kIjogInV2eCIsICJhcmdzIjogWyJzcG9ydHNkYXRhLW1jcCIsICJzZXJ2ZSJdfQ==)

**Free & open source (MIT).** Live sports data and cross-book betting odds as
MCP tools — ~500 tools across 28 providers, in Claude Desktop, Cursor, or any
MCP client. Zero config: install, run `setup`, and the full catalogue serves.

An [MCP](https://modelcontextprotocol.io) server that exposes sports-data APIs
(bookmakers, league/governing-body feeds, aggregators) as tools, configurable so
you only load the tool groups you need. A capability-tag system makes tools from
different providers interchangeable wherever they answer the same question — so
the model can compare odds across bookies or stats across data sources with one
discovery call.

The catalogue spans bookmakers, league/governing-body feeds, and stats
aggregators, and it keeps growing. New providers are added by dropping a YAML
spec into `src/sportsdata_mcp/specs/` — the engine needs no code changes — so
the exact provider and tool counts move over time. Run `sportsdata-mcp
list-groups` for the live inventory, and three meta-tools (group discovery,
capability lookup, resource listing) are always on regardless of what you
enable.

## Install

**One-liner** (any MCP client config, via [uv](https://docs.astral.sh/uv/)):

```bash
uvx sportsdata-mcp serve        # or: pip install sportsdata-mcp
```

**Prebuilt app** (no Python needed): grab the latest
[release](https://github.com/DanielTomaro13/sportsdata-mcp/releases/latest)
(macOS + Windows), unzip, and run `sportsdata-mcp setup` — it writes the config
for Claude Desktop / Cursor for you. The macOS build is unsigned for now:
right-click → Open the first time.

From source:

```bash
git clone https://github.com/DanielTomaro13/sportsdata-mcp.git
cd sportsdata-mcp
pip install -e .                # add ".[dev]" for the test + lint toolchain
```

## Quickstart

```bash
sportsdata-mcp version          # print version info
sportsdata-mcp list-groups      # see every available tool group
sportsdata-mcp lint             # validate the packaged specs
sportsdata-mcp doctor           # probe enabled groups for reachability + auth
sportsdata-mcp serve            # start the MCP stdio server (default command)
sportsdata-mcp update-specs     # OTA-refresh provider specs (signed bundle); --clear reverts
```

Provider endpoints drift (e.g. Entain rotates its GraphQL persisted-query hashes).
`update-specs` fetches a **signed** spec bundle and applies it into an overlay under
`~/.sportsdata/spec-overlay`, which the loader prefers over the packaged copy — so a drift
fix doesn't need a whole new app build. The bundle is Ed25519-verified against a baked key
(a product build refuses an unsigned/forged bundle; anti-rollback refuses a stale replay).
Publish one with `scripts/publish-spec-bundle.py`; point `--url` / `$SPORTSDATA_SPEC_FEED_URL`
at the asset. Restart the server after applying.

Enable tool groups with a config file or the `SPORTSDATA_MCP_GROUPS` env var:

```bash
SPORTSDATA_MCP_GROUPS="afl.public.core,sportsbet.racing,entain.graphql" sportsdata-mcp serve
```

See [`examples/`](./examples) for Claude Desktop / Claude Code config snippets,
a worked cross-bookie [odds-comparison prompt](./examples/comparator-prompt.md),
and an [NBA shot-chart + box-score walkthrough](./examples/nba-prompt.md) that
shows the `nba_stats_call` dispatcher pattern end to end.

## Configuration

Config is resolved in this order (first hit wins):

1. `--config ` flag
2. `$SPORTSDATA_MCP_CONFIG`
3. `./sportsdata-mcp.yaml`
4. `~/.config/sportsdata-mcp/config.yaml`
5. built-in defaults

```yaml
# sportsdata-mcp.yaml
enabled_groups:
  - afl.public.core
  - sportsbet.racing
  - entain.graphql

providers:                      # all optional; sensible defaults apply
  sportsbet:
    request_timeout_seconds: 30
    rate_limit_rps: 10          # sustained requests/sec (token bucket)
    max_response_bytes: 0       # 0 = no cap (default); set a positive byte count to guard context

secrets: {}                     # for authenticated providers; prefer env vars in prod
```

A provider whose auth reads `env: SOME_VAR` is satisfied by the real environment
variable first, then by a `secrets: { SOME_VAR: "..." }` entry of the same name
(a local-dev convenience — keep real secrets in the environment in production).

### Environment variables

| Variable | Effect |
| --- | --- |
| `SPORTSDATA_MCP_GROUPS` | Comma-separated group list; overrides `enabled_groups`. |
| `SPORTSDATA_MCP_CONFIG` | Path to a config file (see resolution order above). |
| `SPORTSDATA_MCP_MAX_BYTES` | Global response-size cap in bytes for every provider that doesn't set its own `max_response_bytes`. `0` (the default) means no cap. |
| `SPORTSDATA_LICENSE` | **Dormant** — the product is free; nothing requires a licence. The signed-entitlement machinery remains for anyone self-hosting gated premium feeds (see below). |
| `SPORTSDATA_ENTITLEMENT_URL` / `SPORTSDATA_ENTITLEMENT_PUBKEY` | Only relevant with the dormant entitlement gate above. Normally unset. |

### The (dormant) entitlement gate

This project used to be a paid product. It's free now — **no licence exists or is
needed, and every group serves by default** — but the signed-entitlement machinery
(Ed25519-verified feed grants, offline caching, 15-min revalidation) is kept dormant
rather than deleted: it's tested, harmless when unset, and useful to anyone
self-hosting this server who wants to gate premium feeds for their own users. Set
`SPORTSDATA_LICENSE` + `SPORTSDATA_ENTITLEMENT_URL` against your own issuing service
to activate it; leave them unset (the default) and nothing changes.

**Keyed feeds.** A few providers need an upstream credential you supply yourself —
e.g. `DATAGOLF_KEY` for DataGolf, `X_BEARER_TOKEN` for Twitter/X. Everything else
needs no key at all.

Meta-tools (`list_available_groups`, `list_tools_by_capability`, `list_resources`)
are always registered regardless of what is enabled, so a fresh install can still
guide the model to turn groups on.

**On the response-size cap.** There is **no cap by default** — every tool returns
whatever the upstream API sends. If you want to guard the model's context window you
can opt in to a cap: precedence is `providers..max_response_bytes` >
`SPORTSDATA_MCP_MAX_BYTES` > the default (`0`, unlimited). Be aware that very large
payloads (e.g. Sportsbet's full `*_event_markets` firehose, ~2 MB) won't fit in
Claude's ~200 K-token context regardless — for those, prefer a narrower tool such as
`sportsbet_sports_card` with `includeTopMarkets: true`.

## Tool groups

Run `sportsdata-mcp list-groups` for live counts and descriptions.

### AFL — `api.afl.com.au`

| Group | Tools | Notes |
|---|---:|---|
| `afl.public.core` | 22 | Competitions, seasons, rounds, fixtures, ladders, match stats |
| `afl.public.broadcasting` | 9 | Broadcast regions, guides, providers |
| `afl.public.content` | 8 | News/articles, videos, photos |
| `afl.premium.cfs` | 1 | CFS premium ops — needs the anonymous `x-media-mis-token` |
| `afl.premium.statspro` | 1 | StatsPro ops — needs the `x-media-mis-token` |
| `afl.premium.keyserver` | 1 | HLS video URL signing |

### Sportsbet — `sportsbet.com.au`

| Group | Tools | Notes |
|---|---:|---|
| `sportsbet.racing` | 15 | Race meetings, racecards, results, futures, SRMs |
| `sportsbet.sports` | 14 | Sport events, markets, prices, SGMs |
| `sportsbet.cross` | 12 | Live status, commentary, ladders, promos, video |
| `sportsbet.results` | 2 | Resulted events by date |
| `sportsbet.graphql` | 1 | Persisted GraphQL gateway (`apigw/sportsbook/graph`) |

### Entain / Ladbrokes — `ladbrokes.com.au`

| Group | Tools | Notes |
|---|---:|---|
| `entain.rest` | 13 | Navigation quick-links and REST surfaces |
| `entain.graphql` | 1 | 127 persisted GraphQL ops (`gql/router`) |
| `entain.cdn` | 1 | Contentful CMS entries (promotions, major-event nav) |

### PointsBet — `pointsbet.com.au`

| Group | Tools | Notes |
|---|---:|---|
| `pointsbet.sports` | 10 | Sports catalogue, competition/event feeds, full event markets, in-play, search |
| `pointsbet.racing` | 11 | Meetings, racecards, results, futures, SRMs, tips, form |
| `pointsbet.content` | 3 | Promotions, promo-code splash, + `pointsbet_content_call` over the static CMS/nav assets |

### TAB — `tab.com.au`

| Group | Tools | Notes |
|---|---:|---|
| `tab.racing` | 9 | Dates, meetings, racecards (fixed + parimutuel), form, next-to-go, jackpots, futures |
| `tab.sports` | 9 | Sports/competitions tree, full match markets + SGM, focused match markets, next-to-go, results, multi-builder |
| `tab.discovery` | 4 | Featured/live recommendations + `tab_cms_call` over the CMS content feeds |

### Unibet — `unibet.com.au`

| Group | Tools | Notes |
|---|---:|---|
| `unibet.racing` | 1 | `unibet_racing_call` — persisted-GraphQL: meetings, race cards, form, futures, specials |
| `unibet.sport` | 3 | `unibet_kambi_call` over the Kambi offering API (groups, events, bet offers, in-play, bet-builder) + live stats + odds ladder |

### BetR — `betr.com.au` (BlueBet platform)

| Group | Tools | Notes |
|---|---:|---|
| `betr.racing` | 8 | Next-to-jump, today's/grouped racecards, race card, form, fluctuations, movers |
| `betr.sport` | 7 | Event types, competition categories, event markets, match detail, popular SGMs |
| `betr.content` | 4 | Promotions + featured racing + popular market links |

### Pinnacle — `pinnacle.com` (sharp odds)

| Group | Tools | Notes |
|---|---:|---|
| `pinnacle.sports` | 13 | Sports/leagues, full + highlighted + live + per-league matchups, carousel, matchup detail, straight + parlay markets (American-odds prices) |
| `pinnacle.reference` | 4 | Enums, market-label dictionary, teaser definitions, API status |

### Betfair Exchange — `betfair.com.au` (exchange odds)

| Group | Tools | Notes |
|---|---:|---|
| `betfair.exchange` | 3 | `bymarket` + `byevent` back/lay price feeds (the sharpest odds) + cash-out availability |
| `betfair.navigation` | 1 | `bynode` catalogue graph (sport → meeting → event → market) |
| `betfair.inplay` | 5 | Live scores, event details, timeline (single + batch), scores+broadcast |

### Dabble — `dabble.com.au` (iOS app backend)

| Group | Tools | Notes |
|---|---:|---|
| `dabble.sport` | 5 | Discover any competition (active list / name lookup / sports), then its fixtures (embedded markets + decimal odds) + the full per-fixture book (400+ markets + Pick'em props) |

The Australian social-betting app's backend, read directly. Reached by **posing
as the iOS app** — the spec bakes the app's `User-Agent` + `x-device-id` +
`x-app-version` so the public feeds return JSON anonymously. **AU-only** and
Cloudflare-fronted (403s from non-AU IPs, like the other AU books). Works for
**any** competition — `dabble_active_competitions` lists the ~269 currently-bettable
ones across all sports. Read-only odds — no bet placement.
Composes with the other books via `sport.event_markets` / `sport.prices`.

### SuperCoach — `supercoach.com.au` (News Corp / Champion Data fantasy)

| Group | Tools | Notes |
|---|---:|---|
| `supercoach.fantasy` | 6 | One uniform surface across **all 7 games** (afl/nrl/epl/nba/nbl/nfl/bbl) × **2 modes** (`classic` + `draft`): competition state, the full per-player feed (price + `ppts1` projection + ownership + matchup; draft adds `predraft_rank`), fixtures (with H2H odds), club + single-player catalogues, leagues |

News Corp / Champion Data's salary-cap fantasy game. Every feed lives under
`/{year}/api/{sport}/classic/v1/…` — pass `sport` (one of the seven) and `year`
(the season key: current calendar year for afl/nrl, currently `2025` for the
others, which run across the new year). **No auth, not geo-blocked** (runs in CI).
The core `supercoach_players` feed is per-round and large (~1–3 MB); use `ppts1`
(the real projection), not `ppts`. Adds the **fantasy / projections** angle via
`stats.fantasy_projections` alongside Data Golf. See
[documentation/SuperCoach.md](documentation/SuperCoach.md).

### NBL — `nbl.com.au` (Australian National Basketball League)

| Group | Tools | Notes |
|---|---:|---|
| `nbl.basketball` | 14 | Seasons, teams, ladder, schedule (scores), players + rosters, per-player season stats + game-log box scores, team stats, season stat leaders (sortable), and news |

The league's own site data API — a Redis-cached proxy (**"rosetta"**) over Genius
Sports stats at `prod.rosetta.nbl.com.au/get/…`. **No token**, but **referer-gated**
(403s without an `nbl.com.au` Origin + Referer — both baked into the spec). Every
response is enveloped `{type, count, source, data:[…]}`. Season-scoped by `year`
(the season start year: 2025 = NBL26, current); stat-leaders takes the season UUID
from `nbl_seasons`. Distinct from the SuperCoach `nbl` fantasy feed — this is the
official box-score source. See [documentation/NBL.md](documentation/NBL.md).

### WTA — `wtatennis.com` (Women's Tennis Association, official)

| Group | Tools | Notes |
|---|---:|---|
| `wta.tennis` | 8 | Official WTA API: singles/doubles rankings, player catalogue + profiles + match history, tournament calendar + per-edition results + entry lists (seeds) |

The WTA's **official** data API (`api.wtatennis.com/tennis/…`) — public Spring REST,
**no auth/key, no geo-block**, runs in CI. Rankings need `type`+`metric`
(rankSingles+singles or rankDoubles+doubles); tournaments are keyed by
`tournamentGroup.id` + `year` (Australian Open = group 901). Fills the tennis gap on
the stats side, composing with the bookmakers' live tennis markets. See
[documentation/WTA.md](documentation/WTA.md). (ATP has no equivalent open API —
atptour.com is Cloudflare bot-protected — so it isn't modelled.)

### Racing and Sports — `racingandsports.com.au`

| Group | Tools | Notes |
|---|---:|---|
| `racingandsports.racing` | 3 | Today's race meetings (all codes, verified) + sports match list + per-race odds (token) |

### Data Golf — `datagolf.com` (needs a key)

| Group | Tools | Notes |
|---|---:|---|
| `datagolf.general` | 3 | Player list, tour schedule, current event field |
| `datagolf.predictions` | 11 | DG rankings, pre-tournament (+ archive) + in-play model probabilities, skill + approach-skill ratings, player/live SG decompositions, live strokes-gained, live hole stats, DFS projections |
| `datagolf.betting` | 3 | Outright + matchup + all-pairings odds across ~13 books (incl. model line) |
| `datagolf.historical` | 9 | Archived raw round data, event-level results (finishes/earnings/points), historical bookmaker odds (outrights + matchups) and DFS results |

Needs a Data Golf API key in the `DATAGOLF_KEY` env var (a personal subscription
key — sourced via the `static_query` auth scheme, never stored in the repo).

### FanDuel — `fanduel.com` (US)

| Group | Tools | Notes |
|---|---:|---|
| `fanduel.racing` | 4 | `fanduel_racing_call` (full-query GraphQL: featured/today races + odds, single-race card, tracks, pools, talent picks) + messages/quick-links/promotions |
| `fanduel.sportsbook` | 2 | `fanduel_sb_call` (REST: event pages + markets, in-play, promos, configs via the `_ak` key) + live scores |

### NRL — `mc.championdata.com`

| Group | Tools | Notes |
|---|---:|---|
| `nrl.public.core` | 4 | Champion Data match centre: competitions, fixture, per-match player stats, app settings |

Plus the `nrl://stats/definitions` resource (dictionary of every NRL stat code).

### NBA — `cdn.nba.com` + `stats.nba.com`

| Group | Tools | Notes |
|---|---:|---|
| `nba.public.cdn` | 5 | Open CDN JSON: today's scoreboard, full schedule, live box score + play-by-play, odds |
| `nba.stats` | 2 | `nba_daily_lineups` + `nba_stats_call`, the dispatcher over t

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [DanielTomaro13](https://github.com/DanielTomaro13)
- **Source:** [DanielTomaro13/sportsdata-mcp](https://github.com/DanielTomaro13/sportsdata-mcp)
- **License:** MIT
- **Homepage:** https://sportsdata-ai.com

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** yes
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-danieltomaro13-sportsdata-mcp
- Seller: https://agentstack.voostack.com/s/danieltomaro13
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
