Run a tournament through an AI agent
Whistle.day is also an MCP server: the same 25 tools its own screens are built on, over one HTTP endpoint. Point an agent at it and it can create a tournament, add teams and courts, draw a stage, settle matches, put the tournament on your club's page, and hand you back a link and a QR code, without anybody touching the wizard.
Updated
- Tools
- 25
- create, draw, score, publish: nothing the app's own screens can't also do
- Endpoint
- /api/mcp
- one URL, Streamable HTTP
- Account
- None to make
- the first tool call mints one, remembered by the connection
- Sign-in
- Optional
- OAuth 2.1 with PKCE, for reaching an account you already have
Claude Desktop and Claude Code
Claude Code adds a remote server from the command line, one command and nothing to edit by hand:
Claude Desktop and claude.ai take the same URL as a custom connector, Settings → Connectors → Add custom connector, or the equivalent block in claude_desktop_config.json:
claude mcp add --transport http whistleday https://whistle.day/api/mcp{
"mcpServers": {
"whistleday": {
"type": "http",
"url": "https://whistle.day/api/mcp"
}
}
}ChatGPT
Settings → Connectors → Advanced → Developer mode, then create a connector: give it a name, paste the URL below, and set authentication to OAuth to work on your own account, or to none to start from nothing. ChatGPT lists the 25 tools once it connects.
https://whistle.day/api/mcpCursor, Windsurf, Cline, or anything else that reads an MCP config
The same shape every one of them expects for a remote server: no command, no local process, just the URL in mcp.json:
{
"mcpServers": {
"whistleday": {
"url": "https://whistle.day/api/mcp"
}
}
}Or skip the URL entirely
Whistle.day is listed on Smithery, so a client that installs from there gets the connection made for it rather than a URL to paste.
What an agent actually does with it
create_tournament is the only tool that asks for nothing first: it makes a temporary account and the connection remembers it, so every other tool works from then on with nothing to pass around. Two prompts, plan_a_tournament and enter_the_results, lay out the rest of the sequence: add the teams, add the courts, create a stage and generate its draw, publish, open a display. The second one is for the day itself: find what is live, settle it, move on.
Nothing here is a shortcut version of the app. generate_stage takes a dry_run so an agent can preview a draw before committing to it, and update_fixture triggers the same re-resolve the results screen does, so the tables, the next Swiss round and the playoff seeded from them come out right either way.
What the 25 tools cover
Setup: create_tournament (with sport presets for football, volleyball, chess, tennis, and more), add_entry (teams and seeds), add_court (pitches, tables, and display ordering), and list_tournaments.
Draws and formats: create_stage (round robin, single elimination, double elimination, Swiss), generate_stage with dry_run previews, list_stages, and list_pools.
Scoring and live play: list_fixtures (filter by live or ready), update_fixture (set scores, mark walkovers, assign courts), resolve_stage to recalculate standings and advance winners, and get_stage_table / list_standings for group and cross-pool tables.
Delivery: publish_tournament to take the day public, create_display for spectator projector panels, and create_handoff so a human organiser can claim full control.
Clubs: get_my_club, create_club, update_club and list_on_club run a club page, the one public address a club's tournaments are listed at. These four need a signed-in account: a club outlives the connection, and the temporary account does not.
No credential in the conversation, on purpose
The temporary account is tied to the connection's own session id, a header the transport carries and the model never sees. No tool returns a token and none asks for one, so a transcript that leaks has nothing in it that opens a tournament.
The cost is that a connection ends, and a client that reconnects is a stranger. create_handoff is how a tournament outlives it: it mints a link for whoever is actually running the day, they set an email and a password, and the agent's access stops the moment they do.
Sign in once instead
That temporary account is the right default for an agent setting up today's tournament from nothing, but it means list_tournaments on a fresh connection is always empty: there is nothing yet for it to find. A person who already has a Whistle.day account can sign in once in a browser and connect an agent to that account instead: most clients (Claude, ChatGPT) discover this automatically and offer a plain Sign in button rather than the URL above.
Once connected that way, an agent reaches everything that account owns or crews, the same tournaments the web app itself shows after signing in, not a narrower set, and create_tournament builds new ones under that real account rather than a fresh throwaway one. Nothing about what a tool can do changes; only whose tournaments it can see does.
Writing code instead of prompting
The tools sit on an ordinary HTTP API, and a script can call it directly: read a published tournament's tables and fixtures without an account, preview a draw, enter results, or pull a whole projector screen in one request. The API reference lists every endpoint with example requests and responses, and the same reference is available as an OpenAPI document for generating a client.
curl -X POST https://whistle.day/api/preview \
-H 'Content-Type: application/json' \
-d '{"format": "round_robin", "teams": 4}'Common questions
Does an agent need an account first?
No. create_tournament makes a temporary one automatically and the connection remembers it, unless the connection already signed in as a real account, in which case the tournament is created there.
Can it see other people's tournaments?
No, either way. An anonymous connection reaches only the tournaments it made itself. A signed-in connection reaches exactly what that account owns or is crew on, the same as signing in on the web, and nothing beyond it.
What transport does it use?
Streamable HTTP: one endpoint answers POST for a request, GET for the stream, and DELETE to end a session. No SSE fallback to configure separately.
Is it free?
Yes: the MCP server calls the same tournament engine the free web app runs on.
Is there an HTTP API as well?
Yes. The MCP tools are a layer over a JSON API that anything can call, documented at /api/docs and as OpenAPI at /api/openapi.json.
My agent reconnected and can't find the tournament it made. What then?
A temporary account lasts as long as the connection that made it. To keep a tournament, have the agent call create_handoff before it disconnects and open the link, or sign in first so everything is created on your own account. A session token issued by an earlier version of the server still works in the X-Whistle-Session header.