football-docs README

The project's README from github.com/withqwerty/football-docs. As one markdown file: README.md.

football-docs

Searchable football data provider and tooling documentation for AI coding agents. Like Context7 for football data.

Who it's for: Developers and analysts who use AI coding tools (Claude Code, Cursor, VS Code Copilot) to work with football data. Works with any tool that supports MCP.

What it does: Gives your AI agent a searchable index of documentation for 24 football data providers and tools — event types, qualifier IDs, coordinate systems, API endpoints, data models, identity surfaces, and cross-provider comparisons for the data providers (StatsBomb, Opta, Wyscout, Impect, SkillCorner, Sportradar, TheSportsDB, FMDB Pro, TransferRoom, and more), plus the open-source libraries people build with (kloppy, mplsoccer, socceraction, soccerdata, floodlight, fast-forward, unravelsports, and more). Your agent looks up the real docs instead of guessing from training data.

Why not just let the AI figure it out? LLMs get football data specifics wrong constantly — Opta qualifier IDs, StatsBomb coordinate ranges, API endpoint URLs, library method signatures. These are mutable facts that change across versions. football-docs gives the agent verified, sourced documentation with provenance tracking so you know where every answer came from.

Strategy

football-docs is intended to be a community-owned, source-transparent Context7 for football data. The public operating contract is in STRATEGY.md: what belongs here, what must stay out, how we handle public-safe provider facts, and how contributors should prove retrieval quality.

Provider identity facts

football-docs is the public source for provider identity-surface facts: access shape, ID schemes, matching fields, provider quirks, and provenance rules. Curated provider identity notes belong here when they can be stated as public facts about the provider. They should say whether a fact comes from public docs, public page evidence, licensed feed shape, or a reviewed public-safe observation, and must not include credentials, local paths, internal tooling details, or restricted payloads from any private project.

MCP (Model Context Protocol) is a standard for connecting AI coding tools to external data sources.

Quick start

Claude Code

claude mcp add football-docs -- npx -y football-docs

Cursor

Settings → MCP → Add server. Use this config:

{
  "mcpServers": {
    "football-docs": {
      "command": "npx",
      "args": ["-y", "football-docs"]
    }
  }
}

VS Code / Copilot

Add to .vscode/mcp.json:

{
  "servers": {
    "football-docs": {
      "command": "npx",
      "args": ["-y", "football-docs"]
    }
  }
}

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "football-docs": {
      "command": "npx",
      "args": ["-y", "football-docs"]
    }
  }
}

Tools

Tool Description
search_docs Full-text search across all provider docs. Filter by provider. Results include provenance (source URL, version).
resolve_provider_id Resolve provider names and aliases to canonical indexed provider keys before searching.
get_provider_docs Retrieve docs for a resolved provider, optionally filtered by topic or category.
list_providers List all indexed providers and their doc coverage.
compare_providers Compare how different providers handle the same concept.
request_update Request a new provider, flag outdated docs, or suggest a better doc source. Queues locally and points to the matching public GitHub issue template.
resolve_entity Map a player, coach, referee, team, competition, season, stage or match to its IDs at every provider through the Reep register. Uses a local copy of the free register (REEP_DUCKDB_PATH), else the Reep API (REEP_API_KEY; keys are issued by hand on request to [email protected], with no self-service sign-up), else returns setup steps and a DuckDB query. See Reep through football-docs.

Provider filters use the indexed provider keys shown by list_providers, but common aliases are accepted. Examples: fbref, understat, ClubElo, football-data.co.uk, and engsoccerdata search free-sources; Sofascore searches soccerdata; ESPN, ESPN FC, and espn-soccer search espn; FMDB searches fmdb-pro; Transfer Room searches transferroom; Hudl Wyscout searches wyscout; Stats Perform / Opta F24 / WhoScored search opta; Metrica, Sportec / DFL, and TRACAB search databallpy; Second Spectrum searches kloppy; Hawk-Eye, SciSports, Signality, Respovision, GradientSports and OptaVision search fast-forward; unravel searches unravelsports; SportRadar API / Soccer Extended search sportradar; The Sports DB / TSDB search thesportsdb; StatsBomb Open Data searches statsbomb.

Example queries

Indexed providers

Provider Chunks Categories
fast-forward 250 overview, getting-started, data-model, coordinate-system, orientations, layouts, transformations, distributed-compute, api-reference, 12 provider format pages
StatsBomb 235 event-types, data-model, coordinate-system, api-access, api-endpoints, charting-lineups, xg-model, iq-metrics, player/team stats, player-mapping, identity-surfaces
unravelsports 202 overview, installation, quickstart, concepts, graph converters, pressing intensity, formation detection, models, utils, american-football
Wyscout 163 event-types, data-model, coordinate-system, api-access, api-endpoints, charting-analysis-metrics, glossary, identity-surfaces
kloppy 126 data-model, usage, provider-mapping, tracking-rendering, event-derived-metrics
floodlight 144 core data objects, io parsers (Tracab, DFL, Kinexon, Opta, SkillCorner, StatsBomb, StatsPerform, Second Spectrum), transforms, metrics, models, visualisation, guides
SportMonks 565 full v3 endpoint reference (fixtures, livescores, leagues, seasons, states, types, statistics, brackets), syntax and includes, filtering, rate limits, error codes, changelog, plus curated event-types, data-model, api-access, charting-season-stories, identity-surfaces
databallpy 63 data-model, overview, usage
mplsoccer 65 overview, pitch-types, visualizations
Impect 77 overview, data-model, event-types, coordinate-system, concepts, kpi-definitions, identity-surfaces
SkillCorner 49 api-access, api-endpoints, data-model, physical-data, coordinate-system, concepts, identity-surfaces
Free sources 62 overview, fbref, understat, contextual-story-joins, xg-timelines
soccerdata 40 overview, data-sources, usage
TransferRoom 43 api-access, api-endpoints, charting-availability, data-model, identity-surfaces
Opta 71 event-types, qualifiers, coordinate-system, api-access, charting-game-state, charting-lineups, charting-passmaps, charting-set-pieces, charting-shot-placement, identity-surfaces
FMDB Pro 35 api-access, api-endpoints, data-model, identity-surfaces
Sportradar 30 api-access, api-endpoints, data-model, charting-and-stories, integration-notes
socceraction 34 SPADL format, VAEP, Expected Threat
BeSoccer 14 api-access, api-endpoints
Driblab 30 api-access, api-endpoints, data-model
ESPN 20 api-access, scoreboard, match-summary, teams-and-standings, identity-and-coverage
Reep 26 overview, identity-and-ids, download-duckdb-csv, api
TheSportsDB 18 api-access, api-endpoints, livescore, identity-surfaces
FotMob 3 identity-surfaces
Soccerdonna 3 identity-surfaces
Transfermarkt 3 identity-surfaces

2,371 searchable chunks across 26 providers and tools.

ESPN coverage consists of curated, dated observations of ESPN-hosted soccer endpoints, checked for eng.1 and esp.1. These observations are not an official API contract or an open-data licence. See ESPN access notes for source status and coverage notes for the tested requests and limitations.

Impect documentation is built solely from the public ImpectAPI/open-data repository — a static Bundesliga 2023/24 snapshot, representative of Impect's structure and metric definitions rather than a complete or current mirror. Impect's commercial API is deliberately not documented here. Every enum value, KPI name and field name in docs/impect/ is validated against that repository in CI (pnpm impect:truth, src/__tests__/impect-open-data-validation.test.ts). Data source: Impect; use is subject to the repository's own Terms of Use.

Documentation validation

Docs for AI agents are only useful if they are correct, and prose about an API is exactly the kind of thing that drifts or gets invented. Where a machine-readable source of truth exists, this repo checks the docs against it in CI rather than trusting them.

Providers Ground truth Checked by
kloppy, socceraction, soccerdata, mplsoccer, floodlight, databallpy, skillcorner, fast-forward, unravelsports The installed package itself — enum members, importable symbols, class constants, Literal parameter vocabularies src/__tests__/provider-truth.test.ts
Wyscout, SkillCorner, FMDB Pro, Sportradar The vendor's own publicly published OpenAPI spec — endpoint paths and methods src/__tests__/provider-truth.test.ts
BeSoccer The vendor's published Postman collection — request vocabulary and parameters src/__tests__/provider-truth.test.ts
Driblab The vendor's published API guide — endpoint paths and methods. Field and group names are not in CI: the guide disagrees with the live API on them, so the docs follow the live API, checked by hand on 2026-09-22 src/__tests__/provider-truth.test.ts
Impect The public open-data repository src/__tests__/impect-open-data-validation.test.ts
Reep The public OpenAPI spec (endpoint paths and methods), and one release's manifest and column schema (CSV table list, columns used in the SQL examples, licence and exclusions) src/__tests__/provider-truth.test.ts, src/__tests__/reep.test.ts

ESPN has a separate observation check in src/__tests__/espn.test.ts. It validates documented endpoint paths, field-table names and types, and source URLs against data/espn-observations.json. These are selected structural observations, not a published specification. CI reads them offline and does not contact ESPN. Refresh manually with python3 scripts/observe_espn.py --scheduled-date YYYYMMDD, choosing a future fixture date and using permitted access. The script stores no raw responses. Review the diff, update the docs and dates, then rebuild the index.

Reep's snapshots age weekly, as a new release is cut each week. Run python3 scripts/check_reep_live.py to check every download link and list what has changed since the snapshots; the refresh steps are in specs/README.md.

Truth files live in data/provider-truth/ and are generated, not hand-written:

pnpm provider:truth      # rebuild every package truth file (needs python3.11)
pnpm openapi:truth       # rebuild every spec-derived truth file

The specs those derive from are snapshots of publicly published, unauthenticated vendor documentation. Source URLs, fetch dates and refresh instructions are in specs/README.md. Wyscout's v3 and v4 specifications merge into one truth file, because its docs span both. The v2 legacy specification is no longer mirrored: the docs describe v3 and v4, and no documented fact derives from the legacy surface.

Each package gets its own pinned venv — co-installing them makes pip silently downgrade conflicting versions, which would produce truth that disagrees with the docs. Bump a pin in scripts/gen_all_truth.sh and the matching version in providers.json together, then re-run and fix whatever the tests flag.

A doc that names an enum member or importable symbol which does not exist in the real package fails the build. scripts/gen_openapi_truth.py derives the same kind of facts from a vendor OpenAPI spec, for providers documented that way.

Not every vocabulary is an enum. fast-forward's coordinate systems, orientations and layouts are lowercase strings on Literal-annotated parameters, so the truth files also record what each parameter accepts, and a doc writing coordinates="statsbomb" fails the same way an invented enum member would.

Contributing

Contributions are welcome from everyone. There are three ways to help:

  1. Open an issue — request a new provider, flag outdated docs, or suggest a better doc source
  2. Use the request_update tool — AI agents can flag outdated or missing docs directly via the MCP server, which queues requests locally and points to the matching public GitHub issue template
  3. Open a PR — fix errors, add new providers, or improve existing docs

You don't need to be an expert. See CONTRIBUTING.md for the full guide.

For maintainers

Crawl pipeline

Provider doc sources are tracked in providers.json. The crawl pipeline discovers the best doc source (llms.txt > ReadTheDocs > GitHub README) and writes markdown with provenance frontmatter.

npm run discover                        # probe sources without crawling
npm run crawl                           # crawl all providers with sources
npm run crawl -- --provider kloppy      # crawl one provider
npm run ingest                          # rebuild search index from docs/
npm run ingest -- --provider kloppy     # re-ingest one provider (incremental)

Each crawled doc carries provenance metadata (source URL, source type, upstream version, crawl timestamp) that is surfaced in search results, so agents can distinguish between curated content and upstream documentation.

Cutting a release

Pushing the tag is the release. .github/workflows/release.yml runs on any v* tag and does the rest: it re-runs the full check suite, creates the GitHub Release, and publishes to npm.

# 1. Bump the version in package.json and server.json (three fields in total).
#    Land it on main through a pull request, as `chore: release vX.Y.Z`.
#
# 2. Tag the merge commit and push the tag.
git tag -a v0.11.0 -m "v0.11.0"
git push origin v0.11.0

Release notes come from the body of the chore: release vX.Y.Z commit, so write that message as the release notes you want readers to see. The workflow reads it from the second parent when the tag sits on a merge commit, strips the commit trailers, and falls back to GitHub's generated notes if the body is empty.

Three properties worth knowing, because each one exists to stop a specific failure:

There is no npm token in this repository. Publishing uses npm trusted publishing: the registry authenticates the workflow itself over OIDC, against a trust configuration on the package that names this repository and this workflow file. Publishing rights are bound to release.yml rather than to a secret that would work from anywhere it leaked to, and there is nothing to rotate.

That trust was configured once, with the npm CLI:

npm trust github football-docs \
  --repo withqwerty/football-docs \
  --file release.yml \
  --allow-publish

npm trust list football-docs shows it; npm trust revoke removes it. Renaming release.yml, or publishing from a different workflow, breaks the match — by design. Re-point it with npm trust github ... --file <new-name> if the file ever moves.

Trusted publishing generates provenance automatically, so the tarball on npm is attested to this repository and this workflow run without the workflow asking for it.

Two consequences worth knowing:

Note that prepublishOnly runs pnpm build && pnpm ingest, which rebuilds data/docs.db. Publishing by hand therefore leaves that file dirty in the working tree; the content is unchanged, only SQLite's page layout differs, so git checkout data/docs.db clears it.

License

MIT

football-docs (withqwerty/football-docs)

Searching Database…

What is this?An MCP server that gives AI coding agents a searchable, sourced documentation index for football data providers and tools — 'like Context7 for football data' — with 2,371 chunks across 26 providers, so the agent looks up real docs instead of guessing from training data.
Is it a library I import, or a service my AI tool connects to?Neither a library nor a hosted service: it's an MCP server your AI tool connects to and calls. Any MCP client works — Claude Code, Cursor, VS Code Copilot and Claude Desktop each have a ready quick start.
How do I hook it up to my coding agent?Add it as an MCP server in your client's config: Cursor via Settings -> MCP -> Add server, VS Code via .vscode/mcp.json, Claude Desktop via claude_desktop_config.json — the README's Quick start walks through each, including Claude Code.
Does anything need API keys or accounts?Browsing the docs needs nothing. Only resolveentity (cross-provider ID mapping via the Reep register) may need setup: a local Reep DuckDB copy (REEP_DUCKDB_PATH) or a Reep API key (REEP_API_KEY), which is issued by hand on request — there's no self-service sign-up.
Why use this instead of just asking the AI directly?Because LLMs get football data specifics wrong constantly — qualifier IDs, coordinate ranges and endpoint URLs are mutable facts that drift across versions. Here the agent retrieves verified docs, and every search result carries provenance (source URL, version) so you can check where a fact came from.
What tools does my agent get once it's connected?Seven MCP tools: searchdocs (full-text search with provenance), resolveproviderid (names and aliases to canonical keys), getproviderdocs (docs by provider, filterable by topic), listproviders, compareproviders (same concept across providers), resolveentity (map a player, team, competition or match to its IDs at every provider via Reep) and requestupdate (flag outdated docs or suggest better sources).
What does a typical query look like?Examples from the README: 'What is Opta qualifier 76?', 'How does StatsBomb represent shot events?', 'Compare Opta and Wyscout coordinate systems', 'Does SportMonks have xG data?'. Common aliases like WhoScored, FBref or Hudl Wyscout are accepted when filtering by provider.
Why is the author building this as a community project?The README frames it as a community-owned, source-transparent Context7 for football data. The operating contract lives in STRATEGY.md: what belongs in the index, how public-safe provider facts must be stated with provenance, and how contributors prove retrieval quality.
Does the identity data behind resolveentity stay current?Reep snapshots age weekly, since a new register release is cut each week. A bundled script checks every download link and lists what changed since the snapshots, and the refresh steps are documented in specs/README.md. Mirrored vendor specs likewise record fetch dates and refresh instructions.
Creator
withqwerty
Size
23.7 MB
Stars
196
Age
6mo
Commits · 90 Days