SETTO API

MCP server

Connect claude.ai, ChatGPT, Codex, Claude Code, Claude Desktop, Cursor, VS Code or any Streamable HTTP MCP client to SETTO. Sign in with your SETTO account or use a personal or organization API token; 38 tools read your tournaments, set them up, register and replace teams, set up their groups and knockout draws, record results, schedule their games and show what changed.

SETTO publishes a remote Model Context Protocol server at https://docs.setto.io/mcp. It exposes the External API as MCP tools, so an assistant can answer "how many teams are in the Cuarta Fuerza category?" by calling a tool instead of you pasting JSON into a chat, can set a tournament up when you ask (create it, add its categories, register the pairs, replace a player, withdraw a team), can set up its groups and its knockout draw and record the results you report, and can lay out a day of group games on your courts for you to approve. It accepts two kinds of credential: your SETTO account, through a sign-in the app runs for you (claude.ai, ChatGPT, Codex, Claude Code), or the same API token as the REST API, personal or organization. Signed in, or with a personal token, the assistant sees every tournament you manage; with an organization token, only that organization's.

Endpoint

PropertyValue
URLhttps://docs.setto.io/mcp
TransportStreamable HTTP
AuthSign in with your SETTO account (OAuth), or Authorization: Bearer setto_live_… with a personal or organization API token
AccessEvery call acts as one organizer — you when you signed in, a personal token's owner, or the admin who created an organization token — within the permissions granted. Reads need nothing more; setting tournaments up and drawing them needs «Gestionar torneos», recording results «Cargar resultados», applying a schedule «Programar partidos»
Registry nameio.setto.docs/mcp in the official MCP Registry (publication pending)

The server is a thin proxy: it forwards each tool call to the External API with your credential and hands the JSON back. Anything the API refuses — a tournament you cannot reach, a write you did not allow — the MCP server refuses too. Every tool call asks the API again, so disconnecting an app, revoking a token or leaving an organization takes effect on the next call.

Install

There are two ways in:

  • Sign in with your SETTO account — claude.ai, ChatGPT, Codex and Claude Code. Nothing to create first: the app opens SETTO, you approve what it may do at app.setto.io, and it acts as you. claude.ai and ChatGPT connect only this way.
  • An API token — any client that sends a header: Claude Code, Codex, Claude Desktop, Cursor and VS Code. Cursor connects only this way.

Sign in with your SETTO account

In claude.ai open Customize → Connectors, choose + Add → Add custom connector, paste https://docs.setto.io/mcp and sign in when claude.ai asks. Every Claude plan can add custom connectors (one on Free); on Team and Enterprise an owner adds it first. Claude Desktop uses the same connector.

The consent screen lists six permissions («Permisos») with every one the app asked for ticked: untick what you do not want to allow. You see and disconnect connected apps in Configuración → Conexiones. The whole flow, the permissions and troubleshooting are on Sign in with your SETTO account.

With an API token

Get a token first: in app.setto.io → Configuración → Tokens de API, keep the scope on Personal (or pick an organization) and create one; under Permisos, tick «Gestionar torneos» if the assistant should set tournaments up (their categories, groups and draws too), «Cargar resultados» if it should record and clear results, and «Programar partidos» if it should place games. Configuración → Conectar con IA walks through the same setup and, right after you create a token there, shows each client's config with that token already filled in. Without a token in place, the Cursor install connects to nothing and says nothing.

Neither button carries your token. Cursor reads it from the SETTO_API_TOKEN environment variable; VS Code asks for it once, masks it and stores it. For Claude Code, use the plugin or the one-liner below; for Codex and Claude Desktop, their tabs.

The plugin installs the MCP server and the setto-api skill in one step, and updates both with claude plugin update.

claude plugin marketplace add https://docs.setto.io/claude-plugin/marketplace.json
claude plugin install setto@setto

When the plugin is enabled, Claude Code asks for your SETTO API token in a masked field and keeps it in your system's secure credential store, never in a settings file. Start a session and run /mcp: setto should list 38 tools. If your Claude Code is too old for plugin prompts, or you prefer the token in your environment, use the one-liner in the next tab.

Tools

ToolEndpoint behind itWrites?
meGET /v1/external/meNo
list_tournamentsGET /v1/external/tournamentsNo
get_tournamentGET /v1/external/tournaments/{idx}No
list_divisionsGET /v1/external/tournaments/{idx}/divisionsNo
list_teamsGET /v1/external/tournaments/{idx}/teamsNo
get_roundGET /v1/external/rounds/{idx}No
get_scheduleGET /v1/external/tournaments/{idx}/scheduleNo
propose_pool_per_court_schedulePOST /v1/external/tournaments/{idx}/schedule/proposalsNo — it computes a plan and saves nothing
apply_schedule_placementsPOST /v1/external/tournaments/{idx}/schedule/placementsYes — game times, courts and lengths. Needs «Programar partidos»
list_activityGET /v1/external/activityNo — it reads «Actividad»: who changed what, through which app or token, and whether it went through
search_tournamentGET /v1/external/tournaments/{idx}/searchNo — finds categories, rounds, groups, teams and players by the name you say
create_tournamentPOST /v1/external/tournamentsYes — a draft tournament on the FREE plan, with its categories. Needs «Gestionar torneos»
update_tournamentPATCH /v1/external/tournaments/{idx}Yes — name, dates, timezone, public link, visibility, who submits results
publish_tournamentPOST /v1/external/tournaments/{idx}/publishYes — publishes a draft when it is ready
set_tournament_lifecyclePOST /v1/external/tournaments/{idx}/lifecycleYes — «Borrador de torneo», «Archivar», «Restaurar»
create_divisionPOST /v1/external/tournaments/{idx}/divisionsYes — adds a category
update_divisionPATCH /v1/external/tournaments/{idx}/divisions/{divisionIdx}Yes — edits a category
delete_divisionDELETE /v1/external/tournaments/{idx}/divisions/{divisionIdx}Yes — deletes a category with no teams and no games, after confirm: true
set_division_seedsPUT /v1/external/tournaments/{idx}/divisions/{divisionIdx}/seedsYes — «Cabezas de serie»
register_teamPOST /v1/external/tournaments/{idx}/registrationsYes — registers one team; no email is sent
register_teamsPOST /v1/external/tournaments/{idx}/registrations/batchYes — registers up to 50 teams, each on its own
update_teamPATCH /v1/external/tournaments/{idx}/teams/{teamIdx}Yes — name, registration status, category
remove_teamDELETE /v1/external/tournaments/{idx}/teams/{teamIdx}Yes — deletes a team with no games and no group and no payment trace, after confirm: true
update_playerPATCH /v1/external/tournaments/{idx}/players/{playerIdx}Yes — a player's name, email or phone
substitute_playerPOST /v1/external/tournaments/{idx}/teams/{teamIdx}/substituteYes — «Sustitución»: one player out, another in
preview_team_withdrawalPOST /v1/external/tournaments/{idx}/teams/{teamIdx}/withdraw/previewNo — shows what a «Baja» would do, game by game, and saves nothing
withdraw_teamPOST /v1/external/tournaments/{idx}/teams/{teamIdx}/withdrawYes — «Baja»: applies exactly the plan the preview showed
preview_division_formatPOST /v1/external/tournaments/{idx}/divisions/{divisionIdx}/format/previewNo — shows what a category's format («Formato») would keep and replace, and saves nothing
apply_division_formatPOST /v1/external/tournaments/{idx}/divisions/{divisionIdx}/formatYes — applies exactly the format the preview showed. Needs «Gestionar torneos»
append_elimination_roundPOST /v1/external/tournaments/{idx}/divisions/{divisionIdx}/rounds/appendYes — adds the knockout («Eliminatorias») after the group stage, keeping every group game
preview_poolsPOST /v1/external/tournaments/{idx}/rounds/{roundIdx}/pools/previewNo — «Configurar grupos»: the groups with their teams and games, and what they replace; saves nothing
apply_poolsPOST /v1/external/tournaments/{idx}/rounds/{roundIdx}/poolsYes — writes exactly the groups the preview showed
preview_drawPOST /v1/external/tournaments/{idx}/rounds/{roundIdx}/draw/previewNo — «Configurar eliminatorias»: the knockout's first round and what it replaces; saves nothing
apply_drawPOST /v1/external/tournaments/{idx}/rounds/{roundIdx}/drawYes — writes exactly the draw the preview showed
confirm_drawPOST /v1/external/tournaments/{idx}/rounds/{roundIdx}/draw/confirmYes — «Confirmar cuadro»: seats the teams the final group standings name. Sent again, it changes nothing
record_game_resultPOST /v1/external/tournaments/{idx}/games/{gameIdx}/resultYes — a game's result: its sets, a W.O., a retirement or «Doble W.O.». Needs «Cargar resultados»
clear_game_resultDELETE /v1/external/tournaments/{idx}/games/{gameIdx}/resultYes — «Borrar resultado», after confirm: true. Needs «Cargar resultados»
set_game_teamsPATCH /v1/external/tournaments/{idx}/games/{gameIdx}/teamsYes — who plays a game that has no result yet. While a side is still a group place («1ro Pool A»), both sides of a first-round game at once, or «Confirmar cuadro» seats them; an emptied slot shows its label again

Arguments mirror the parameters documented for each endpoint, including populate, limit/offset, the division filter and list_activity's cursor, which pages back from the newest row. Every tool states all four MCP hints: the reads (the proposal and the four previews included) are read-only, idempotent and non-destructive; a create (a tournament, a category, a registration) is not idempotent, since calling it twice adds two; an edit, a publish, the seeds, the knockout append and a result are idempotent and non-destructive; a delete, the lifecycle, «Sustitución», «Baja», the schedule write, applying a format, groups or a draw, «Confirmar cuadro», a game's teams and clearing a result are destructive and idempotent; and none of them reaches beyond your SETTO account (openWorldHint: false). Guides for the reads: list tournaments, get a tournament, list divisions, list teams, get a round.

Scheduling with an assistant

The assistant can fill a day of group games «un grupo por cancha»: each group plays its games back to back on one court, parallel courts carry different categories, the teams' time petitions decide each group's window, and nobody is booked in two places at once — not even a player registered in two categories. The proposal does not move games that are already scheduled; it only places the unscheduled ones around them. Applying is different: apply_schedule_placements can move any scheduled game that has not been played yet, so it writes exactly the placements you approve.

It always goes in this order, and the server's instructions teach it to the model:

  1. get_schedule — courts, categories, every game (and which ones are locked: played, scored or already started) and the approved petitions.
  2. propose_pool_per_court_schedule — a plan for one day. Nothing is saved. It lists the placements, any game it could not place, and every team it had to put outside a time it prefers.
  3. You review it. The assistant shows you each court's games with their times, the unplaced games and the petition misses, and waits for your yes.
  4. apply_schedule_placements — writes exactly what you approved. All or nothing: if anything would clash (a court, a team or a person twice at once, or a cannot play petition), nothing is written and the assistant gets the full list of offending games to show you.

The «Programar partidos» permission

Applying a schedule needs «Programar partidos» (schedule), one of the six permissions («Permisos») a sign-in or a token can carry:

  • Signed in with your SETTO account: leave «Programar partidos» ticked on SETTO's consent screen. The app then schedules any tournament you manage, for as long as you manage it.
  • A personal token: tick «Programar partidos» under Permisos when you create it in app.setto.io → Configuración → Tokens de API; the token list marks it «Programa partidos». It schedules any tournament you manage, for as long as you manage it.
  • An organization token with the permission can only be created by an organization ADMIN, and works only while that person is still an ADMIN of the organization.

Every other credential reads — including step 2, which writes nothing — and gets 403 INSUFFICIENT_SCOPE on step 4, which the assistant reports, with the fix for its kind of credential, instead of retrying. A signed-in app gets the permission by connecting again and leaving it ticked.

Use a read-only token, or untick «Programar partidos» when you sign in, wherever you only need answers, and keep a scheduling credential for the sessions where you plan days.

Setting a tournament up with an assistant

Ask in your own words — "create the Copa Primavera, padel, March 14 and 15 in Mexico City, with 4a varonil and 5a femenil", "register these eight pairs in 4a", "Luis Ruiz replaces Juan Pérez in his pair", "Pérez / Soto withdraw" — and the assistant turns it into the tools above. It creates tournaments on the FREE plan as a draft («Borrador»: 2 categories, 12 pairs or 24 singles), adds and edits categories and their seeds («Cabezas de serie»), registers teams one by one or up to 50 at a time, edits teams and players, replaces a player («Sustitución») and withdraws a team («Baja»). It publishes, takes back to draft, archives or restores a tournament only when you ask. Paid plans, prices, payments and fútbol tournaments stay in the dashboard.

The write contract

  • Names become ids by reading first. The assistant finds the tournament, category, team or player you name with list_tournaments and search_tournament. When two of the same kind fit (two players called Juan Pérez), the answer says ambiguous and the assistant asks you which one.
  • «Vista previa» before a withdrawal. preview_team_withdrawal writes nothing: it lists every game of the team and what the «Baja» does to it — a W.O. for a known rival, a pass («BYE») for a rival still to be decided, a placement game decided at once, or a game left as it is for you to record in the dashboard once its rival is known. Each game comes with that consequence in Spanish. The assistant shows you the list and waits for your yes.
  • Your yes is the confirmation. withdraw_team applies exactly the plan you saw: it carries the preview's confirmation, valid 15 minutes, for that team and that plan. If the tournament changed in between, nothing is written and the assistant previews again. A category or a team is deleted only after your yes too (confirm: true), and only while it holds nothing: a team with games leaves through a «Baja», which keeps its played results.
  • A retry never writes twice. Every create and team operation carries an idempotency key, so a call repeated after a timeout answers the first result instead of creating a second tournament or registering a pair twice.
  • Limits are yours to lift. A category or a team beyond what the plan holds is refused before anything is written, and the assistant tells you to upgrade in the dashboard («mejora el plan en el panel»). An organizer creates at most 20 tournaments a day through the API.
  • Everything lands in «Actividad». Every write, and every refusal, is recorded with who acted and through which app or token; list_activity reads it back. Registering sends no email, and no price, paid mark, payment record or refund changes; a withdrawal closes the team's unpaid payment links. When a replaced player's team has payment marks, the answer says «revisa los pagos de este equipo en el panel».

The «Gestionar torneos» permission

Setting tournaments up needs «Gestionar torneos» (manage), the same way scheduling needs «Programar partidos»: leave it ticked on SETTO's consent screen when you sign in, or tick it under Permisos when you create a token; an organization token with it works only while its creator is still an ADMIN. Without it every setup write answers 403 INSUFFICIENT_SCOPE, while the search and the withdrawal preview, which write nothing, keep working.

Draws and results with an assistant

Ask the way you would ask a colleague — "4a varonil plays a group stage and then a knockout, best of three sets", "make two groups", "move Los Tigres to group B", "the first two of each group go through", "confirm the draw", "6-3 6-4 for Pérez / López against Ruiz / Gómez" — and the assistant runs the same steps as the dashboard's «Formato», «Configurar grupos», «Configurar eliminatorias» and «Confirmar cuadro», then records the results. It works on the padel, tennis and pickleball categories of a regular tournament; qualifiers («Clasificatoria»), setting up consolation games, leagues and fútbol stay in the dashboard, while a result and a game's teams go in on any knockout game, third place and consolation included.

  1. The format (preview_division_format, then apply_division_format): a group stage («Fase de Grupos»), a knockout («Eliminatorias») or both, with 1, 2 or 5 sets. Rounds that keep their type keep their games and results, and a round that holds a result is never replaced. A category already playing its groups gets its knockout with append_elimination_round, which keeps every group game.
  2. The groups (preview_pools, then apply_pools): the category's accepted teams split into groups, the seeds («cabezas de serie») apart and the rest by lot, with every game. "Move Los Tigres to group B" is a new preview with the same lot: Los Tigres swap places with a team of group B, and everyone else stays where they were.
  3. The knockout draw (preview_draw, then apply_draw): after a group stage, places such as «1ro Pool A» or «2do de 1ros», filled by «Clasificación entre grupos» or «Clasificación de grupos»; in a straight knockout, the teams themselves, seeds first. Byes go to the best places, and the third-place game is optional. A draw takes up to 256 teams.
  4. «Confirmar cuadro» (confirm_draw), once every group game has its result: each place takes the team the final standings name.
  5. Results (record_game_result): the assistant reads the game first, so the sets go in its home and away order, then tells you what changed: the standings, or who moved on in the knockout.

The write contract for draws and results

  • You see every plan before it is written. A format, groups or a draw is previewed first and nothing is saved: the assistant shows you each group with its teams, the draw's first round and everything it would replace, and waits for your yes. The apply carries the preview's confirmation, valid 15 minutes, and writes exactly that plan; if the category changed in between, nothing is written and the assistant previews again.
  • Played games are never rebuilt. A format, groups or a draw that would replace games with results is refused, and a knockout with results is never drawn or seated again.
  • A withdrawn team is never seated. When the final standings put a withdrawn team («Baja») in the knockout, the assistant asks you who takes its place: another team of the category, or a BYE that sends its opponent straight through.
  • A stored result changes only on your word. When a game already has a result, the assistant shows it to you and asks before replacing it, and clearing a result («Borrar resultado») waits for your yes too. A withdrawn team's W.O.s stay, and a result a player submitted is approved or rejected in the dashboard.
  • Warnings come back in Spanish: a set count unusual for the round's format, a group result changed after the knockout was confirmed, or a tournament whose standings count no points yet.

The «Cargar resultados» permission

Recording and clearing results needs «Cargar resultados» (results): leave it ticked on SETTO's consent screen when you sign in, or tick it under Permisos when you create a token; an organization token with it works only while its creator is still an ADMIN. The format, the groups, the draw, its confirmation and a game's teams need «Gestionar torneos», and their previews, which write nothing, only «Leer». Without the permission a write answers 403 INSUFFICIENT_SCOPE, and the assistant tells you which one is missing.

How each client connects

ClientSign in with your SETTO accountAPI token
claude.aiYes — the only wayNo
ChatGPTYes — the only way, on the plans OpenAI allowsNo
CodexYesYes, from an environment variable
Claude CodeYesYes, or the plugin
Claude DesktopYes, through your claude.ai connectorsYes, through mcp-remote
VS CodeYesYes
CursorNot yetYes — the only way

Cursor finishes a sign-in by returning to a cursor:// address, and SETTO's sign-in only returns to https:// and local (http://localhost) addresses, so Cursor uses a token for now. Where neither way fits, two fallbacks work in every client:

  • The Agent Skill — setto-api teaches any agent the same endpoints and it makes plain HTTP calls.
  • The REST API directly — see the quickstart.

Security notes

  • No credential reaches the model. Signing in hands the access token to the app, never to the conversation, and a token belongs in the client's configuration. Never paste a token into a conversation — a pasted token ends up in the transcript and, depending on your setup, in logs.
  • Use the environment or the client's secret prompt. $SETTO_API_TOKEN in Claude Code, --bearer-token-env-var in Codex, ${env:…} in Cursor, an inputs prompt in VS Code. Do not commit an MCP config with a literal token in it. Claude Desktop's config is the exception that holds one: keep that file private, or use the custom connector.
  • Writes sit behind a permission and your confirmation. The schedule write (apply_schedule_placements) only sets game times, courts and lengths, cannot move a played game and refuses a schedule with a clash; it needs «Programar partidos». The setup writes (tournaments, categories, seeds, teams, players, «Sustitución», «Baja») and the draws (formats, groups, knockout draws, a game's teams) need «Gestionar torneos», and recording or clearing a result needs «Cargar resultados». None of them sends an email, and through them no price, paid mark, payment record or refund changes (a withdrawal closes the team's unpaid payment links). The destructive ones are annotated so, and most MCP clients ask for confirmation before running them, unless you have approved them to always run; a withdrawal, a format, groups and a draw also need the confirmation their preview hands out. Without those three permissions, a confused or prompt-injected model cannot change anything.
  • You can see and stop everything. Every change an app or a token makes is recorded in «Actividad», and an assistant can read it back with list_activity ("what did you change yesterday?"). Desconectar in Configuración → Conexiones cuts a signed-in app off at once; revoking a token in Tokens de API does the same for that token.
  • Scope what you can. Signing in, or a personal token, reaches every tournament you manage; an organization token reaches one organization and nothing else. Grant only the permissions you need. For anything shared — an assistant several people use, or one you do not fully control — prefer an organization token or a read-only one, and create a dedicated token so you can revoke it alone.
  • It counts against your rate limit. Tool calls are API requests: 120 per 60 seconds per token, shared with anything else using that token. See Rate limits.

Sample conversations

You: Which categories in Torneo Apertura 2026 still have unfinished games?

Assistant: calls list_tournaments with status: "IN_PROGRESS" — found Torneo Apertura 2026 (3c9b7f52-…).

calls list_divisions with that tournament and populate: "rounds" — three categories, five rounds between them.

calls get_round for each round with populate: "games" —

Cuarta Fuerza Varonil has 4 of 12 games still UPCOMING; Primera Fuerza Femenil is complete; Mixta B has 1 game left, scheduled for Saturday 10:00.

You: Schedule Saturday's group games for Cuarta Fuerza and Mixta B on courts 1 and 2, from 9:00, one group per court.

Assistant: calls get_schedule, then propose_pool_per_court_schedule with day: "2026-11-07", start: "09:00" and the two court idxs —

Court 1: Cuarta Fuerza group A, 6 games, 9:00–15:00. Court 2: Mixta B group A, 9:00–12:00, then group B, 12:00–15:00. Every game fits. One miss: Pérez / Gómez prefer to play after 11:00 and their first game is at 10:00. Apply it?

You: Yes.

Assistant: calls apply_schedule_placements with those 12 placements — done, 12 games scheduled.

You: Pérez / Soto withdraw from 4a varonil.

Assistant: calls search_tournament with q: "pérez soto", then preview_team_withdrawal —

They played 2 games (results stay). Game 7 against Ruiz / Gómez: a W.O. for Ruiz / Gómez. Game 12, a quarter-final whose rival is still to be decided: it becomes a bye, and whoever arrives goes straight through. Withdraw them?

You: Yes.

Assistant: calls withdraw_team with the preview's confirmation — done: one W.O. recorded, one bye set, the registration cancelled.

You: Make two groups in 4a varonil.

Assistant: calls search_tournament with q: "4a varonil", then list_divisions with populate: ["rounds"], then preview_pools with numberOfPools: 2 —

Grupo A: Pérez / López, Ruiz / Gómez, Soto / Díaz, Mora / Vega. Grupo B: Luna / Ríos, Cruz / Peña, Lara / Gil, Paz / Ortiz. 12 games, everyone once in their group; nothing is replaced. Apply it?

You: Move Cruz / Peña to group A first.

Assistant: calls preview_pools again with that pin and the same rngSeed — Grupo A: Pérez / López, Ruiz / Gómez, Cruz / Peña, Mora / Vega. Grupo B: Luna / Ríos, Soto / Díaz, Lara / Gil, Paz / Ortiz. Apply it?

You: Yes.

Assistant: calls apply_pools with the preview's confirmation — done: two groups, 12 games.

You: 6-3 6-4 for Pérez / López against Ruiz / Gómez.

Assistant: calls get_round to find the game and its home and away teams, then record_game_result with the sets in that order — recorded: Pérez / López win in two sets and lead Grupo A.

If a number looks wrong, ask the assistant which tool call produced it and check that endpoint by hand.

On this page