> ## 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 scaffold, September 6, 2026. Owner: TheRundown. The source bundle accompanies the [local setup guide](/data-mcp).

## Scope

Make an agent's first authenticated sports-data query explicit and reproducible. Five read-only tools cover reference discovery, event selection, and per-book main-line snapshots. They wrap existing Product V2 endpoints and inherit the calling key's entitlements and billing. They do not access ingestion workers, internal databases, account mutations, or sportsbook wagering endpoints.

```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. 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, name, API integration status; retired 27 removed.                                           |
| `list_markets`    | `GET /api/v2/markets`                         | Bare-array definitions, filtered locally by sport/live and paginated.                           |
| `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. |

Event tools require bounded canonical filters: 1–12 market IDs and 1–10 affiliate IDs. Defaults are `[1,2,3]` and `[19,23]`. Both force `main_line=true&hide_closed=true&include=all_periods`. 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.

Price projection preserves participant identity/type, market/period, line ID/value, affiliate ID, price, main-line state, and upstream update time. 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. Pagination provides `items`, `total`, `page`, `limit`, and `next_page`. Each page is a fresh upstream snapshot; local pagination is not a stable cursor or a billing optimization. Catalog presence and empty market responses are not evidence of full or absent coverage.

## 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.
* 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. A page limit trims agent output only. The client should present tool calls and costs to its user according to its normal permissions model.

## Verification

Offline tests exercise MCP initialization/discovery, strict schemas, header-only requests, raw-array market definitions, event envelopes, per-book line preservation, retirement filtering, usage headers, errors, cancellation/timeouts, and bounded response handling. 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. It validates the exact five-tool contract before data requests, selects an event whose summary reports a requested market ID, spaces its two Product API calls by one second for Free-plan compatibility, and reports the UTC check time, requested scope, selected event ID, source URLs, counts, and usage. Smoke acceptance uses an active date with both main-line/open filters. Require a selected event ID and positive visible prices. 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. Merge the tested source and guide, verify published links, and run the exact live smoke request. Keep the package private until an artifact release is deliberately prepared.
2. 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.
3. 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. No hosted URL is advertised by this scaffold.
4. 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.
5. Verify the registry entry, install from the public artifact, and record a working listing URL before changing outreach copy to claim availability. Outreach drafts are prepared under `operations/ai-discovery`; sending remains a separate action.

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).
