> ## Documentation Index
> Fetch the complete documentation index at: https://docs.therundown.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Data MCP design

> Architecture, data contracts, limits, and release criteria for the local TheRundown data MCP scaffold.

Status: local 0.2.3 scaffold, September 12, 2026. Owner: TheRundown. The
[official public repository](https://github.com/TheRundown/data-mcp) is the
canonical source, and its versioned bundle accompanies the [local setup guide](/data-mcp).

## Scope

Make an agent's first authenticated sports-data query explicit and reproducible. Six read-only tools cover reference discovery, date-based market discovery, event selection, futures pages, and per-affiliate main-line snapshots. They wrap existing Product V2 endpoints and inherit the calling key's entitlements and billing.

```text theme={null}
MCP client → local stdio process → HTTPS Product API
                ↑
       process environment key
       X-TheRundown-Key upstream
```

The official MCP SDK owns protocol negotiation, framing, cancellation, and tool schema validation. This scaffold registers tools with strict Zod input schemas, human-readable titles, and object-root output schemas. It has no HTTP listener, OAuth provider, remote session store, or published package identity. The documentation MCP remains a separate service.

## Contract

| Tool | Product API request | Projection |
| - | - | - |
| `list_sports` | `GET /api/v2/sports` | ID and name. |
| `list_affiliates` | `GET /api/v2/affiliates` | ID and name; retired 27 removed. |
| `list_markets` | `GET /api/v2/markets`, or `GET /api/v2/sports/{sport_id}/markets/{date}` | Catalog definitions, or date-scoped available markets with `hide_closed_markets=1`. |
| `list_events` | `GET /api/v2/sports/{sport_id}/events/{date}` | Summaries from the `events` envelope, with canonical IDs and available market IDs. |
| `get_main_lines` | `GET /api/v2/events/{event_id}` | Select the exact event from its `events` envelope, then flatten per-affiliate main-line prices. |
| `list_futures` | `GET /api/v2/sports/{sport_id}/futures` | Scoped competition events, public schedule/settlement fields, open per-affiliate main lines, and upstream cursor metadata. |

Dated event tools require 1–12 canonical market IDs and 1–10 affiliate IDs, defaulting to `[1,2,3]` and `[19,23]`, and force `main_line=true&hide_closed=true&include=all_periods`. Date-based `list_markets` requires `sport_id`, uses only `hide_closed_markets=1` and a bounded offset, and rejects `live`. `list_futures` defaults to market `[1141]` and affiliates `[19,23]`; it accepts only bounded market/book filters, a 1–200 page limit, `include_settled`, and the returned opaque forward cursor. No tool accepts a key, URL, host, path, or arbitrary query parameter. Date inputs must be real calendar dates; event IDs cannot contain path delimiters. Affiliate 27 remains off even if a stale upstream catalog returns it.

Dated price projection preserves participant identity/type, market/period, line ID/value, affiliate ID, price, main-line state, and upstream update time. Futures omit line IDs and return only public event identity, schedule, settlement, market IDs, and open per-affiliate main lines. Main lines belong to each affiliate; different books can have different main values. Missing line values remain null (for example, moneyline). The scaffold does not calculate best price, implied probability, edge, or consensus, so it never mixes exchange/prediction-market quotes into sportsbook ranking.

The result envelope is `{source_url, retrieved_at, usage, data}` in structured content and JSON text. Source URLs are reproducible and credential-free. Catalog, date-market, event, and main-line pagination provides `items`, `total`, `page`, `limit`, and `next_page`; each local page is a fresh upstream snapshot, not a stable cursor or billing optimization. Futures preserves upstream `count`, `total`, `has_more`, and `next_cursor`; a cursor page is still metered and may be partial. Catalog presence and empty market responses are not evidence of full or absent coverage. Null line values remain null, and sanitized `401`, `403`, and `429` outcomes remain distinct from an empty scoped result.

The six tool titles and object-root `data` schemas are: `List sports` →
`{sports: [{sport_id, sport_name}]}`; `List affiliates` →
`{affiliates: [{affiliate_id, affiliate_name}]}`; `List markets` →
`{items: [market], total, page, limit, next_page}`; `List events` →
`{items: [event], total, page, limit, next_page}`; `Get main lines` →
`{event, items: [main_line], total, page, limit, next_page}`; and `List
futures` → `{events: [future_event], meta: {count, total, has_more,
next_cursor}}`. The public projection defines the nested market, event, line,
and future fields; clients should validate the advertised schema rather than
assuming the full Product API response is returned.

The local server exposes `therundown://brief`, which states the event-first,
price-evidence, missing-data, and runtime-ID rules and includes the first
conversation. Initialization, tool and resource listing, and an exact brief
read require no key and make no Product API call. Product tool calls return
`missing_credentials` before network activity when no key is configured. The
conversation is a usage example within that resource, not a replacement for
its complete scope guidance.

## Request and credential boundaries

* The executable uses one fixed HTTPS Product origin and GET-only paths. Redirects fail rather than forwarding a key to another origin.
* The key comes from the process environment and is sent only in `X-TheRundown-Key`. The server does not read a repository `.env` automatically, log request headers, or return raw error bodies. Configured key text is redacted from tool output. Recommended integrations use this header boundary, not a query key.
* Keyless discovery is limited to initialization, the initialized notification, tool/resource listings, and the exact `therundown://brief` read. Discovery does not validate a Product key or entitlement; Product tool calls require a credential and fail before upstream activity when it is absent.
* One request may be in flight. Extra concurrent calls return `busy`; calls are not queued and there are no automatic retries. Clients control request cadence and should respect `429`/`Retry-After` and the calling plan's quota.
* A 15-second deadline and MCP cancellation abort the fetch/body read. Upstream bodies are capped at 4 MiB before JSON parsing. Large requests fail explicitly instead of returning silent partial odds.
* Only allowlisted usage/entitlement headers are returned. `401`, `403`, `404`, and `429` get useful, sanitized messages. Transport and unexpected errors get a generic error; stdout is reserved for MCP.

An API key can incur data-point usage even for read-only tools. Local page limits trim tool output only; the futures limit is forwarded upstream, but each cursor page remains metered. The client should present tool calls and costs to its user according to its normal permissions model.

## Verification

The local 0.2.3 source has 52 offline tests: 37 stdio tests in the local
server suite and 15 hosted-adapter tests. They cover keyless MCP
initialization/discovery, strict schemas, titled tools and object-root outputs,
all 36 catalog identities, dated market discovery, PGA/F1/team-sport futures
scope, closed/sentinel/retired quote filtering, cursor metadata, usage
headers, errors, cancellation/timeouts, and bounded response handling. The
extracted 0.2.3 bundle passed its 37 local offline tests on Node 22. The stdio
smoke client checks the actual executable; network calls happen only when
explicitly running `npm run smoke` with a key.

The smoke client defaults to pre-match markets 1/2/3 for sport 3 and affiliates 19/23. An eligible key can opt into the combined pre-match/live check with `THERUNDOWN_SMOKE_LIVE=1`, adding 41/42/43. `THERUNDOWN_SMOKE_SPORT_ID` and `THERUNDOWN_SMOKE_DATE` scope a dated check. An Ultra+ key can opt into one bounded futures page with `THERUNDOWN_SMOKE_FUTURES=1`; it requests market 1141 and affiliates 19/23 for the selected sport. It validates the exact six-tool contract before data requests. The dated mode selects an event whose summary reports a requested market ID and spaces its two Product API calls by one second for Free-plan compatibility; futures mode makes one bounded `list_futures` call. Both report the UTC check time, requested scope, selected event ID where available, source URLs, counts, and usage. Require positive event and visible-price counts. Record this output without keys or full customer payloads. An empty date is inconclusive. A successful narrow check says nothing about other sports, sources, freshness guarantees, or WebSocket delivery.

## Publication sequence

1. Keep the tested source commit immutable. From that exact commit, create a separate website artifact change using `bundle.py`; it must produce the versioned ZIP, checksum, and manifest with matching source hashes.
2. Deploy the website artifact and verify the public ZIP, checksum, manifest, and finite smoke proof before merging the guide that links to it. Keep the package private until that download is available.
3. Choose distribution: a versioned package or MCPB for local clients, or an operated Streamable HTTP service. Provide reproducible installation, a license decision, ownership metadata, and a support/update policy.
4. A hosted service needs MCP authentication, per-user upstream-key isolation, request/rate budgets, secret redaction, Origin validation, session isolation and bounded shutdown. Implement the MCP authorization specification; do not treat a caller's MCP access token as a Product API key or blindly pass it to the upstream API. The local scaffold's process has no HTTP listener; the deployed hosted endpoint (`https://mcp.therundown.io/mcp`, live since 2026-09-10) serves the same tools through a separately operated Streamable HTTP adapter — see the [hosted endpoint section](/data-mcp#hosted-endpoint).
5. Publish a real artifact and valid `server.json` using a verified namespace, then submit registry metadata. Do not create metadata pointing to a nonexistent npm package or remote URL. Confirm directory-specific prerequisites before submitting.
6. Verify the registry entry, install from the public artifact, and record a working listing URL before claiming availability in public materials.

References: [official SDK server guide](https://github.com/modelcontextprotocol/typescript-sdk/blob/v1.x/docs/server.md), [MCP tool specification](https://modelcontextprotocol.io/specification/2025-06-18/server/tools), [MCP authorization](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization), [registry quickstart](https://modelcontextprotocol.io/registry/quickstart), [TheRundown OpenAPI](https://docs.therundown.io/openapi.yaml).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.