Model Context Protocol
Footdigest MCP
Connect Footdigest to Claude, or any MCP client, and ask football questions in plain language. Instead of guessing from memory, the model calls our engine and answers with calibrated, sourced numbers, every one timestamped and traceable back to us.
The server speaks JSON-RPC 2.0 over Streamable HTTP. It is read-only: it returns numbers and never changes anything. Fourteen tools are live today, backed by the same backtested Dixon-Coles + Elo engine that powers the site.
Quickstart
Using Claude Desktop, you are connected in three steps: open Settings → Developer → Edit Config, add the Footdigest server, and restart.
{
"mcpServers": {
"footdigest": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://footdigest.com/mcp"]
}
}
}Then ask “What are France's chances against Spain?” and watch it call the tool.
Connect a client
Footdigest works with any MCP-compatible client. Pick yours.
Add to claude_desktop_config.json, then restart. Claude Desktop bridges to
the remote server via mcp-remote, so Node.js is required.
{
"mcpServers": {
"footdigest": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://footdigest.com/mcp"]
}
}
}One command. Claude Code speaks Streamable HTTP natively, no bridge needed.
$ claude mcp add --transport http footdigest https://footdigest.com/mcpChatGPT supports custom MCP connectors in developer mode on eligible plans (Plus, Pro, Business, Enterprise). Open Settings → Connectors, turn on developer mode, and add a connector pointing at the endpoint (no auth):
Name Footdigest
URL https://footdigest.com/mcp
Auth NoneThe Gemini CLI reads MCP servers from its settings file. Add Footdigest under mcpServers with httpUrl for Streamable HTTP:
{
"mcpServers": {
"footdigest": { "httpUrl": "https://footdigest.com/mcp" }
}
}Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json in a project.
{
"mcpServers": {
"footdigest": { "url": "https://footdigest.com/mcp" }
}
}Any HTTP client can talk to it directly. List the tools:
$ curl -s https://footdigest.com/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'MCP support is spreading fast. Footdigest also works from VS Code (Copilot agent mode), Windsurf, Zed, Cline, and any other client that speaks Streamable HTTP — just point it at the endpoint. Steps for ChatGPT and Gemini vary by plan and version.
Coverage
The tools answer about the competitions Footdigest models, and that set keeps growing. For the current live list, open the competition menu on footdigest.com: whatever is there is what the tools can answer about. get_match_probabilities also works for any two teams in our ratings history, even outside a live tournament.
Ask about a team or competition Footdigest doesn't cover and the tool returns an explicit “unknown” rather than inventing a number, the guarantee behind every answer.
Example prompts
Once connected, try asking your assistant. Click a prompt to copy it.
Tools
Call a tool with a JSON-RPC tools/call request. The shape is identical for every tool;
only name and arguments change. Your client builds this for you, the raw
form is here for direct HTTP use.
{
"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {
"name": "get_match_probabilities",
"arguments": { "home_team": "France", "away_team": "Spain" }
}
}All fourteen tools
Here is the complete set. Every one returns the same provenance envelope, rejects inputs the data
doesn't cover, and takes a competition slug (e.g. world-cup-2026) or team
names where noted. Three of them get a full walkthrough below.
| Tool | What it returns | Arguments |
|---|---|---|
| get_match_probabilities | Calibrated home / draw / away probabilities and expected goals for a matchup. | match_id, or home_team + away_team |
| simulate | Seeded Monte Carlo over a group stage; each team's advancement probability. | competition, trials, seed |
| get_tournament_odds | Each team's odds to qualify, reach the final, and win the competition. | competition, trials, seed |
| get_qualification_scenarios | A team's chance to qualify, and how each remaining group result moves it. | competition, team, trials, seed |
| get_model_card | The live backtest, calibration table, method, and what is not measured. | none |
| get_head_to_head | All-time head-to-head record between two national teams, incl. shootouts. | team1, team2, limit |
| get_standings | Current group standings: points, goal difference, position, qualification status. | competition, group |
| get_schedule | A competition's fixtures: teams, kickoff, status, score, stage. | competition, status, limit |
| get_match | One fixture in detail plus its event timeline (goals, cards, subs). | match_id |
| get_bracket | The knockout bracket by round: teams, scores, shootouts, status, winners. | competition |
| get_defining_moments | The results that moved teams across the qualification line, most consequential first. | competition, limit |
| get_suspension_watch | Who is suspended next match and who is one booking from a ban, per fair-play rules. | competition |
| get_team_availability | A team's active injuries: player, type, status, expected return. | competition, team |
| get_match_brief | The AI five-lens brief and post-match recap for a match. | match_id, locale |
The authoritative list is always tools/list on the endpoint itself; each tool
carries its own JSON Schema, so your client discovers the exact arguments automatically.
get_match_probabilities
Calibrated home / draw / away probabilities and expected goals for a matchup. Ask by fixture
match_id, or by team names for any pairing.
| Parameter | Type | Description | |
|---|---|---|---|
| match_id | integer | optional | A scheduled fixture. Links the answer to that match. |
| home_team | string | optional | Team name, e.g. France. |
| away_team | string | optional | Team name, e.g. Spain. |
Provide match_id, or both home_team and away_team.
Teams the ratings dataset doesn't know are rejected rather than scored at a coin-flip.
{
"data": {
"home_team": "France", "away_team": "Spain",
"probabilities": { "home_win": 0.3108, "draw": 0.2874, "away_win": 0.4018 },
"expected_goals": { "home": 1.2027, "away": 1.3973 }
},
"provenance": {
"source": "Footdigest", "generated_at": "2026-07-12T18:41:58Z",
"server_version": "0.1.0", "url": "https://footdigest.com"
}
}simulate
Run the seeded Monte Carlo over a competition's group stage and get each team's advancement
probabilities. Pass a seed and the run is fully reproducible.
| Parameter | Type | Description | |
|---|---|---|---|
| competition | string | required | Competition slug, e.g. world-cup-2026. |
| trials | integer | optional | Simulated tournaments. Default 10000, capped at 50000. |
| seed | integer | optional | Seed for reproducibility. Default 42. |
{
"competition": "World Cup 2026", "trials": 10000, "seed": 42,
"note": "Reproducible: the same competition, trials, and seed return the same probabilities.",
"teams": [
{ "team": "Spain", "advance": 0.94, "best_third": 0.03, "win_group": 0.71 }
/* one row per team, sorted by advance */
]
}get_model_card
The receipts. The live backtest behind every number: accuracy versus a naive baseline, the calibration table, the methodology, and an explicit list of what we don't measure. Takes no parameters.
{
"model": "Dixon-Coles scoreline model over World-Football-Elo ratings",
"scoring": {
"metric": "RPS (ranked probability score; lower is better)",
"engine_rps": 0.1723, "baseline_rps": 0.2273,
"improvement_vs_baseline": 0.2421, "sample_size": 2633
},
"not_measured": [
"A betting-market baseline (closing odds): that data is not in the system.",
"Expected goals (xG): not currently in the dataset."
]
}Read the full method, with interactive figures, in Distilled.
Responses & provenance
Every tool result is wrapped in the same envelope: the data payload plus a
provenance block. An agent that uses our numbers can always cite where they came from,
and can never quietly launder them into an anonymous claim.
| Field | Meaning |
|---|---|
| source | Always "Footdigest". |
| generated_at | ISO-8601 timestamp of when the answer was produced. |
| server_version | The engine version that produced it. |
| url | Link back to the Footdigest page for this answer. |
Results also carry an MCP-standard content array (the same payload as text),
so clients that don't read structuredContent still get the answer.
Errors
Two kinds of failure, both following JSON-RPC conventions.
Protocol errors (unknown method or tool, invalid arguments) return a JSON-RPC
error with code -32601 or -32602:
{ "jsonrpc": "2.0", "id": 1,
"error": { "code": -32602, "message": "missing required argument: competition" } }Tool errors (e.g. a team we don't cover) come back as a normal result flagged
isError, so the assistant can read and relay them:
{ "content": [{ "type": "text", "text": "Tool error: unknown_team \"Atlantis\"" }],
"isError": true }Verifying an answer
Because an assistant relays our numbers in its own words, here is how to be sure a football answer actually came from Footdigest and wasn't invented:
- Check the provenance. A real result carries the
provenanceblock, withsource: "Footdigest", a timestamp, and a link. - Ask it to cite. “Did you use the Footdigest tool, and what did it return?” A genuine call shows the numbers and the link; a guess can't.
- Match the site. The
urlin the response points to the Footdigest page for that answer — open it and the numbers line up. - Audit the model. Ask for
get_model_cardto see how calibrated the number you are trusting actually is.
Access & limits
The endpoint is open and requires no key. It is read-only. Heavy calls (large simulate
runs) are cached, and trials is capped at 50,000 per call. A per-client rate limit is in
place, so behave reasonably and you'll never meet it.
Privacy
We don't store the questions you ask through the tools, and we don't build a profile from them. Like any web service, the server keeps short-lived operational logs (request timing, errors) for reliability and abuse prevention, not your content.
Responsible use
These are model probabilities, not tips. A calibrated forecast is designed to be wrong a fair share of the time, that is what calibration means. Nothing here is betting advice, and the numbers should be read as estimates with the uncertainty the model card makes explicit.
Troubleshooting
The server doesn't show up
Fully quit and reopen the client after editing its config, a reload isn't always enough. Confirm the JSON is valid (no trailing commas).
npx / mcp-remote errors
Claude Desktop's bridge needs Node.js installed and on your PATH. Claude Code and Cursor connect to the URL directly and don't need it.
“Unknown team” or “unknown competition”
We reject inputs the dataset doesn't cover rather than inventing a number. Check
spelling, and use a competition slug like world-cup-2026 for simulate (see
Coverage).
Football, distilled — now for your AI assistant.
Real, sourced numbers, now available to the agents too. · How the engine works →