turnale

Run racket-sport tournaments from your AI assistant: fair draws, scores, live standings.

使うべきか

品質と安全性

B
説明の品質
95%
スキーマの完全性
90%
命名の品質
95%
ポイズニングのリスク
60%
権限の一致
100%
プロトコルへの準拠
100%

検出事項(7)

  • HIGHTool poisoning patterns detected
  • MEDIUMTool 'create_tournament' description contains placeholder textcreate_tournament 内
  • MEDIUMTool 'add_players' description contains placeholder textadd_players 内
  • LOWTool 'list_players' description lacks action verblist_players 内
  • LOWTool 'get_results' description lacks action verbget_results 内
  • INFOTool description contains placeholder or incomplete textcreate_tournament 内
  • INFOTool description contains placeholder or incomplete textadd_players 内

ツール定義とプロトコルへの準拠に関する自動分析に基づいています。

コンテキストコスト

~10,936トークン数(ツール定義)
~3.4 KB一般的なレスポンスサイズ
注意への影響は大きい(128k コンテキストの 8.54%)

これは、サーバーのツールがモデルのコンテキストに読み込まれるたびに消費されるおおよそのトークン数です。数が多いほど、ほかのタスクに使える注意が減ります。

インストール

ワンクリックインストール

これを `claude_desktop_config.json` ファイルに追加してください:

{
  "mcpServers": {
    "turnale": {
      "url": "https://mcp.turnale.app"
    }
  }
}

リモートエンドポイント

https://mcp.turnale.appstreamable-http

できること

ツール一覧

ツール(30)

🟢 読み取り専用🟡 書き込み🔴 削除⚪ 不明
🟢ping

Health check. Returns a static confirmation that the Turnale MCP server is reachable.

入力スキーマ

{
  "type": "object",
  "properties": {}
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    }
  },
  "required": [
    "ok",
    "message"
  ],
  "additionalProperties": false
}
🟡create_tournament(sport, format, name, discipline, players, ...)

Create a new tournament. Keep setup SHORT: ask the organiser only for sport, players, court count and start time — sensible defaults cover everything else. FORMAT: never ask an open 'which format?' question. If the organiser clearly named one, pass it; otherwise omit format — the call then returns a ready-to-show menu of options (nothing is created) for you to relay so the organiser can read and choose in one reply. Players can be added later with add_players. NEVER invent placeholder or fake player names ('Player 1', made-up names): if the organiser only knows the headcount, create with signup_open: true and signup_cap set to it — players add themselves by name via the page link. If the organiser gives a time budget instead of rounds (e.g. 'we have 2 hours'), derive rounds ≈ total minutes ÷ (match + break minutes) and confirm. If they ask for a format that is not listed, offer to note it with record_feedback. Returns the organiser key (tk_…): relay it with the warning that it cannot be recovered, plus the shareable page link.

入力スキーマ

{
  "type": "object",
  "properties": {
    "sport": {
      "type": "string",
      "enum": [
        "tennis",
        "padel",
        "pickleball",
        "badminton",
        "squash",
        "table_tennis"
      ],
      "description": "Write sport names to the organiser in words — 'table tennis', never the enum spelling 'table_tennis'."
    },
    "format": {
      "description": "Tournament format. round_robin: everyone plays everyone. groups_playoff: round-robin groups then a knockout. single_elimination: knockout with byes. americano/mexicano: rotating-partner doubles, points per round (mexicano pairs each round from standings). OMIT when the organiser hasn't clearly chosen — the call then returns a menu of explained options to show them instead of creating anything.",
      "type": "string",
      "enum": [
        "round_robin",
        "groups_playoff",
        "single_elimination",
        "americano",
        "mexicano"
      ]
    },
    "name": {
      "description": "Defaults to '<Sport> tournament 14 Aug 2026 (<location>)' — start date (or today) plus the location when known",
      "type": "string",
      "maxLength": 120
    },
    "discipline": {
      "description": "Ask the organiser — never infer it from the sport. Americano/mexicano are always doubles. Defaults to singles for the bracket formats when they truly have no preference.",
      "type": "string",
      "enum": [
        "singles",
        "doubles"
      ]
    },
    "players": {
      "maxItems": 128,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "gender": {
            "type": "string",
            "enum": [
              "m",
              "f",
              "x"
            ]
          },
          "level": {
            "type": "number",
            "minimum": -10000,
            "maximum": 10000,
            "description": "Any consistent numeric level/rating — used only for seeding and balancing"
          }
        },
        "required": [
          "name"
        ]
      }
    },
    "pairs": {
      "description": "Doubles: fixed pairs as [name, name] arrays. Omit to auto-pair.",
      "type": "array",
      "items": {
        "minItems": 2,
        "maxItems": 2,
        "type": "array",
        "items": {
          "type": "string"
        }
      }
    },
    "courts": {
      "description": "Default 2",
      "type": "integer",
      "minimum": 1,
      "maximum": 16
    },
    "court_names": {
      "maxItems": 16,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 60
      }
    },
    "start_time": {
      "description": "ISO datetime with offset, e.g. 2026-08-01T18:00:00+03:00. Must be within 365 days from today.",
      "type": "string"
    },
    "match_duration_minutes": {
      "type": "integer",
      "minimum": 5,
      "maximum": 240
    },
    "break_minutes": {
      "description": "Changeover between matches/rounds, shown separately from play time (default 0)",
      "type": "integer",
      "minimum": 0,
      "maximum": 60
    },
    "page_results_entry": {
      "description": "Allow anyone with the page link to enter scores courtside. Default TRUE — recreational tournaments run on whoever finishes their match first, and an organiser who has to type every result is the bottleneck. Pass false if the organiser wants to be the only one recording scores; switchable either way at any time via update_settings or the toggle on the page.",
      "type": "boolean"
    },
    "language": {
      "description": "Language of the tournament page, PDFs and player emails (ISO 639-1). Default en; set it to the language the organiser is writing in when it is in this list.",
      "type": "string",
      "enum": [
        "en",
        "bg",
        "hr",
        "cs",
        "da",
        "nl",
        "et",
        "fi",
        "fr",
        "de",
        "el",
        "hu",
        "it",
        "lv",
        "lt",
        "nb",
        "pl",
        "ro",
        "sk",
        "sl",
        "sv",
        "uk",
        "es",
        "pt",
        "ar",
        "bn",
        "zh",
        "hi",
        "id",
        "ja",
        "ko",
        "ru",
        "tr",
        "ur",
        "vi"
      ]
    },
    "seeding": {
      "description": "Default random",
      "type": "string",
      "enum": [
        "random",
        "level"
      ]
    },
    "group_count": {
      "type": "integer",
      "minimum": 2,
      "maximum": 8
    },
    "advance_per_group": {
      "type": "integer",
      "minimum": 1,
      "maximum": 4
    },
    "third_place_match": {
      "description": "Single elimination; default true",
      "type": "boolean"
    },
    "points_per_match": {
      "description": "Americano/mexicano; default 21",
      "type": "integer",
      "minimum": 4,
      "maximum": 64
    },
    "rounds": {
      "description": "Americano/mexicano; default from player count",
      "type": "integer",
      "minimum": 1,
      "maximum": 30
    },
    "location": {
      "description": "Venue/location shown to players on the page, e.g. club name + city",
      "type": "string",
      "maxLength": 160
    },
    "house_rules": {
      "description": "Organiser's house rules, shown on the tournament page (e.g. 'Golden point at deuce')",
      "maxItems": 12,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 200
      }
    },
    "signup_open": {
      "description": "Open self-signup: players add themselves on the shared page (name-only or signed in). Offer this when the organiser has no player list yet.",
      "type": "boolean"
    },
    "signup_cap": {
      "description": "Signup limit; beyond it players join a waitlist",
      "type": "integer",
      "minimum": 4,
      "maximum": 128
    },
    "level_scale": {
      "description": "How to read the numbers in `level`. absolute (default): one shared scale, a 3 is a 3 whoever holds it. by_group: men and women were each rated within their own group, so the numbers are not directly comparable — ask the organiser which they did rather than guessing. ignore: the numbers are notes, never used for the draw.",
      "type": "string",
      "enum": [
        "absolute",
        "by_group",
        "ignore"
      ]
    },
    "level_offset": {
      "description": "by_group only: how much stronger an m is than an f carrying the SAME number, in the organiser's own level units. Default 1 — a starting point to adjust, not a fact. Used for balancing only; never shown on the page or in standings.",
      "type": "number",
      "minimum": 0,
      "maximum": 1000
    },
    "gender_balance": {
      "description": "Americano/mexicano: prefer matches where both teams have the same make-up (MM v MM, MW v MW, WW v WW). Default prefer_symmetric. A preference, not a rule — an uneven field cannot supply it, and the draw says so rather than distorting the rotation.",
      "type": "string",
      "enum": [
        "prefer_symmetric",
        "off"
      ]
    },
    "level_gap_cap": {
      "description": "Opt-in: the largest level gap the organiser wants between opponents, in their own level units. Soft — the draw prefers to respect it and reports when it cannot. Pass 0 to clear.",
      "type": "number",
      "minimum": 0,
      "maximum": 1000
    }
  },
  "required": [
    "sport"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string"
    },
    "page_url": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "players_added": {
      "type": "number"
    },
    "draw_generated": {
      "type": "boolean"
    },
    "rounds_text": {
      "description": "Present when a draw was generated — show it to the organiser as-is.",
      "type": "string"
    },
    "summary": {
      "type": "string"
    }
  },
  "required": [
    "tournament_key",
    "page_url",
    "name",
    "players_added",
    "draw_generated",
    "summary"
  ],
  "additionalProperties": false
}
🟡add_players(tournament_key, players, request_id)

Add players to the roster in bulk (parse pasted lists or spreadsheets yourself and send structured entries — never invent placeholder names; use signup mode when names aren't known yet). Duplicate names are rejected for disambiguation. If an unlocked draw exists it is regenerated automatically.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "players": {
      "minItems": 1,
      "maxItems": 128,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "gender": {
            "type": "string",
            "enum": [
              "m",
              "f",
              "x"
            ]
          },
          "level": {
            "type": "number",
            "minimum": -10000,
            "maximum": 10000,
            "description": "Any consistent numeric level/rating — used only for seeding and balancing"
          }
        },
        "required": [
          "name"
        ]
      }
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    }
  },
  "required": [
    "tournament_key",
    "players"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "players_total": {
      "type": "number"
    },
    "added": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "players_total",
    "added",
    "summary"
  ],
  "additionalProperties": false
}
🟡update_player(tournament_key, player_name, new_name, gender, level, ...)

Rename a player or set their gender/level/note. Updates MANY in one call: pass `updates` with one object per player and never loop one-by-one — setting levels for a whole roster used to be one call per player, which on a phone meant approving each one and left the roster half-updated when some were mis-tapped. The whole batch applies or none of it does.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "player_name": {
      "description": "Single update; or use `updates` for several",
      "type": "string"
    },
    "new_name": {
      "type": "string",
      "maxLength": 120
    },
    "gender": {
      "type": "string",
      "enum": [
        "m",
        "f",
        "x"
      ]
    },
    "level": {
      "type": "number",
      "minimum": -10000,
      "maximum": 10000,
      "description": "Any consistent numeric level/rating — used only for seeding and balancing"
    },
    "note": {
      "type": "string",
      "maxLength": 500,
      "description": "Free note shown on the tournament page. Pass an empty string to clear it."
    },
    "updates": {
      "description": "Bulk edit — e.g. levels for a whole roster in one call",
      "minItems": 1,
      "maxItems": 128,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "player_name": {
            "type": "string"
          },
          "new_name": {
            "type": "string",
            "maxLength": 120
          },
          "gender": {
            "type": "string",
            "enum": [
              "m",
              "f",
              "x"
            ]
          },
          "level": {
            "type": "number",
            "minimum": -10000,
            "maximum": 10000,
            "description": "Any consistent numeric level/rating — used only for seeding and balancing"
          },
          "note": {
            "type": "string",
            "maxLength": 500,
            "description": "Free note shown on the tournament page. Pass an empty string to clear it."
          }
        },
        "required": [
          "player_name"
        ]
      }
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "player": {
      "type": "string"
    },
    "players": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "players",
    "summary"
  ],
  "additionalProperties": false
}
🔴remove_player(tournament_key, player_name, player_names, request_id)

Remove one or MANY players before any result is recorded (afterwards use withdraw_player or replace_player) — pass player_names to clear several in one call, never loop one-by-one. Regenerates an existing unlocked draw.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "player_name": {
      "type": "string"
    },
    "player_names": {
      "description": "Bulk removal — e.g. clearing mistaken placeholder names in one call",
      "minItems": 1,
      "maxItems": 128,
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "players_total": {
      "type": "number"
    },
    "removed": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "promoted": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Waitlisted players who took the freed spots"
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "players_total",
    "removed",
    "promoted",
    "summary"
  ],
  "additionalProperties": false
}
🟡set_pairs(tournament_key, pairs, auto, request_id)

Fix the doubles pairs: pass explicit pairs by name, or auto-pair (random or level-balanced). Only before results exist. Regenerates an existing unlocked draw.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "pairs": {
      "description": "Fixed pairs as [name, name] arrays",
      "type": "array",
      "items": {
        "minItems": 2,
        "maxItems": 2,
        "type": "array",
        "items": {
          "type": "string"
        }
      }
    },
    "auto": {
      "type": "string",
      "enum": [
        "random",
        "level_balanced"
      ]
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "pairs": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "pairs",
    "summary"
  ],
  "additionalProperties": false
}
🟡update_settings(tournament_key, name, start_time, match_duration_minutes, break_minutes, ...)

Change the tournament name, start time, match duration, break/changeover minutes, courts (count or names), house rules, or courtside score entry from the page. Court changes recompute the remaining schedule; played matches never move.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "name": {
      "type": "string",
      "maxLength": 120
    },
    "start_time": {
      "description": "ISO datetime with offset. Must be within 365 days from today.",
      "type": "string"
    },
    "match_duration_minutes": {
      "type": "integer",
      "minimum": 5,
      "maximum": 240
    },
    "break_minutes": {
      "description": "Changeover between matches/rounds, shown separately from play time",
      "type": "integer",
      "minimum": 0,
      "maximum": 60
    },
    "courts": {
      "type": "integer",
      "minimum": 1,
      "maximum": 16
    },
    "court_names": {
      "maxItems": 16,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 60
      }
    },
    "house_rules": {
      "maxItems": 12,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 200
      }
    },
    "location": {
      "description": "Venue/location shown to players; pass an empty string to clear it",
      "type": "string",
      "maxLength": 160
    },
    "page_results_entry": {
      "description": "Allow anyone with the page link to enter scores courtside. ON for new tournaments — pass false when the organiser wants to be the only one recording results, true to hand it back to the players.",
      "type": "boolean"
    },
    "signup_open": {
      "description": "Open or close self-signup on the page",
      "type": "boolean"
    },
    "signup_cap": {
      "type": "integer",
      "minimum": 4,
      "maximum": 128
    },
    "language": {
      "description": "Page/PDF/email language, ISO 639-1 (default en)",
      "type": "string",
      "enum": [
        "en",
        "bg",
        "hr",
        "cs",
        "da",
        "nl",
        "et",
        "fi",
        "fr",
        "de",
        "el",
        "hu",
        "it",
        "lv",
        "lt",
        "nb",
        "pl",
        "ro",
        "sk",
        "sl",
        "sv",
        "uk",
        "es",
        "pt",
        "ar",
        "bn",
        "zh",
        "hi",
        "id",
        "ja",
        "ko",
        "ru",
        "tr",
        "ur",
        "vi"
      ]
    },
    "level_scale": {
      "description": "How to read the numbers in `level`. absolute (default): one shared scale, a 3 is a 3 whoever holds it. by_group: men and women were each rated within their own group, so the numbers are not directly comparable — ask the organiser which they did rather than guessing. ignore: the numbers are notes, never used for the draw.",
      "type": "string",
      "enum": [
        "absolute",
        "by_group",
        "ignore"
      ]
    },
    "level_offset": {
      "description": "by_group only: how much stronger an m is than an f carrying the SAME number, in the organiser's own level units. Default 1 — a starting point to adjust, not a fact. Used for balancing only; never shown on the page or in standings.",
      "type": "number",
      "minimum": 0,
      "maximum": 1000
    },
    "gender_balance": {
      "description": "Americano/mexicano: prefer matches where both teams have the same make-up (MM v MM, MW v MW, WW v WW). Default prefer_symmetric. A preference, not a rule — an uneven field cannot supply it, and the draw says so rather than distorting the rotation.",
      "type": "string",
      "enum": [
        "prefer_symmetric",
        "off"
      ]
    },
    "level_gap_cap": {
      "description": "Opt-in: the largest level gap the organiser wants between opponents, in their own level units. Soft — the draw prefers to respect it and reports when it cannot. Pass 0 to clear.",
      "type": "number",
      "minimum": 0,
      "maximum": 1000
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "courts": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "promoted": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Waitlisted players a raised cap let in"
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "courts",
    "promoted",
    "summary"
  ],
  "additionalProperties": false
}
🟡promote_player(tournament_key, name, request_id)

Move a waitlisted player onto the active roster when a spot opens (signed-in players are notified by email). The cap can be raised with update_settings.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "name": {
      "type": "string"
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    }
  },
  "required": [
    "tournament_key",
    "name"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "status": {
      "type": "string"
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "name",
    "status",
    "summary"
  ],
  "additionalProperties": false
}
🔴generate_draw(tournament_key, seeding, group_count, advance_per_group, third_place_match, ...)

Generate (or regenerate) the draw and schedule. This IS the start action: the first draw moves the tournament from setup to active and closes self-signup — when the organiser says "start the tournament", call this. The result includes rounds_text — SHOW it to the organiser as-is, in whatever language they are writing to you in (it is English already, so relay it unchanged unless they are writing something else) so they can check who plays whom — and the seed that produced the draw: preview first, then confirm with that SAME seed to apply exactly the previewed draw. Free until the first result is recorded; after that this DISCARDS recorded results and requires BOTH confirm: true and discard_results: true. If the organiser asks for a format that is not supported, offer to note it with record_feedback. Optional overrides adjust the format first.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "seeding": {
      "type": "string",
      "enum": [
        "random",
        "level"
      ]
    },
    "group_count": {
      "type": "integer",
      "minimum": 2,
      "maximum": 8
    },
    "advance_per_group": {
      "type": "integer",
      "minimum": 1,
      "maximum": 4
    },
    "third_place_match": {
      "type": "boolean"
    },
    "points_per_match": {
      "type": "integer",
      "minimum": 4,
      "maximum": 64
    },
    "rounds": {
      "type": "integer",
      "minimum": 1,
      "maximum": 30
    },
    "discard_results": {
      "description": "Required (true) when results already exist — separate acknowledgement that this redraw destroys them",
      "type": "boolean"
    },
    "seed": {
      "description": "Draw seed returned by the preview — pass it back with confirm: true to apply exactly the previewed draw. Omit for a fresh draw.",
      "type": "integer",
      "minimum": 0,
      "maximum": 2147483647
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    },
    "confirm": {
      "description": "Omit or false: return a preview of what would change. True: apply it.",
      "type": "boolean"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "matches": {
      "type": "number"
    },
    "discarded_results": {
      "type": "number"
    },
    "rounds_text": {
      "type": "string"
    },
    "seed": {
      "type": "number"
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "matches",
    "discarded_results",
    "rounds_text",
    "seed",
    "summary"
  ],
  "additionalProperties": false
}
🟢get_briefing(tournament_key)

Compact full state of the tournament — settings, roster, progress, next matches, standings, page link. Call this first when resuming work in a new conversation with just the key.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "sport": {
      "type": "string"
    },
    "status": {
      "type": "string"
    },
    "discipline": {
      "type": "string"
    },
    "courts": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "start_time": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "players_total": {
      "type": "number"
    },
    "players": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "matches_played": {
      "type": "number"
    },
    "matches_pending": {
      "type": "number"
    },
    "next_up": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "match_id": {
            "type": "string"
          },
          "structure": {
            "type": "string"
          },
          "round": {
            "type": "number"
          },
          "state": {
            "type": "string"
          },
          "side_a": {
            "type": "string"
          },
          "side_b": {
            "type": "string"
          },
          "score": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "winner": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "retired": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "court": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "estimated_start": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "match_id",
          "structure",
          "round",
          "state",
          "side_a",
          "side_b",
          "score",
          "winner",
          "retired",
          "court",
          "estimated_start"
        ],
        "additionalProperties": false
      }
    },
    "standings_top": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      }
    },
    "page_url": {
      "type": "string"
    },
    "page_results_entry": {
      "type": "boolean",
      "description": "True when anyone with the page link can record scores courtside (the default for new tournaments). Turn it off with update_settings page_results_entry: false."
    },
    "format": {
      "type": "object",
      "properties": {},
      "additionalProperties": {}
    },
    "signup": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "aside": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "enum": [
                "fact",
                "joke"
              ]
            },
            "lead": {
              "type": "string"
            },
            "text": {
              "type": "string"
            }
          },
          "required": [
            "kind",
            "lead",
            "text"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ],
      "description": "Present ONLY when the tournament is set up, running, and asking nothing of the organiser — for answering 'what else can you do?', or any moment where they are plainly just chatting. NEVER volunteer it: not as a greeting, not after a result, not alongside a report. Say `lead` then `text`, nothing of your own in between. Both are English already: relay them unchanged unless the organiser is writing to you in another language. If they are, translate `lead` — but translate `text` ONLY when kind is 'fact'. A joke goes out in English word for word, whatever language you are speaking, because translating it destroys it."
    }
  },
  "required": [
    "name",
    "sport",
    "status",
    "discipline",
    "courts",
    "start_time",
    "players_total",
    "players",
    "matches_played",
    "matches_pending",
    "next_up",
    "standings_top",
    "page_url",
    "page_results_entry",
    "format",
    "signup",
    "aside"
  ],
  "additionalProperties": false
}
🟢list_players(tournament_key)

Full roster with status, level, and doubles partner.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "players": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      }
    },
    "total": {
      "type": "number"
    }
  },
  "required": [
    "players",
    "total"
  ],
  "additionalProperties": false
}
🟢list_matches(tournament_key, state, round, after_match_number, limit)

Matches with sides, scores, courts and times. Filter by state or round; paginate with after_match_number for large tournaments.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "state": {
      "type": "string",
      "enum": [
        "scheduled",
        "completed",
        "walkover",
        "retired",
        "cancelled",
        "bye"
      ]
    },
    "round": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "after_match_number": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "matches": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "match_id": {
            "type": "string"
          },
          "structure": {
            "type": "string"
          },
          "round": {
            "type": "number"
          },
          "state": {
            "type": "string"
          },
          "side_a": {
            "type": "string"
          },
          "side_b": {
            "type": "string"
          },
          "score": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "winner": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "retired": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "court": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "estimated_start": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "match_id",
          "structure",
          "round",
          "state",
          "side_a",
          "side_b",
          "score",
          "winner",
          "retired",
          "court",
          "estimated_start"
        ],
        "additionalProperties": false
      }
    },
    "next_after_match_number": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "matches",
    "next_after_match_number"
  ],
  "additionalProperties": false
}
🟢get_schedule(tournament_key, limit)

Upcoming matches in playing order with courts and estimated times.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "schedule": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "match_id": {
            "type": "string"
          },
          "structure": {
            "type": "string"
          },
          "round": {
            "type": "number"
          },
          "state": {
            "type": "string"
          },
          "side_a": {
            "type": "string"
          },
          "side_b": {
            "type": "string"
          },
          "score": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "winner": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "retired": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "court": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "estimated_start": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "match_id",
          "structure",
          "round",
          "state",
          "side_a",
          "side_b",
          "score",
          "winner",
          "retired",
          "court",
          "estimated_start"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "schedule"
  ],
  "additionalProperties": false
}
🟢get_standings(tournament_key)

Current standings per group/structure, tiebreak-ordered (wins → head-to-head → set diff → game diff; americano: total points).

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "standings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      }
    }
  },
  "required": [
    "standings"
  ],
  "additionalProperties": false
}
🟢get_results(tournament_key)

Final placements (or placements-so-far for a tournament that ended early).

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "status": {
      "type": "string"
    },
    "placements": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      }
    }
  },
  "required": [
    "status",
    "placements"
  ],
  "additionalProperties": false
}
🟢get_audit_log(tournament_key, limit, before_id)

Chronological record of every change (newest first) — the answer to "who changed that?". Paginate with before_id. Ids are global across all tournaments, so gaps between ids are normal.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 200
    },
    "before_id": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "entries": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      }
    },
    "next_before_id": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "entries",
    "next_before_id"
  ],
  "additionalProperties": false
}
🟢get_export(tournament_key)

Full structured export of the tournament document (players, draws, results) — for the organiser's own records or data portability.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "tournament": {
      "type": "object",
      "properties": {},
      "additionalProperties": {}
    }
  },
  "required": [
    "tournament"
  ],
  "additionalProperties": false
}
🟢get_pdf_link(tournament_key)

Download links for the printable PDF. pdf_url is the merged tournament document (match sheet with write-in score boxes, player sheet, standings/results when they exist) — hand this to the organiser. results_pdf_url and plan_pdf_url are deprecated pre-merge variants kept for comparison.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "pdf_url": {
      "type": "string"
    },
    "results_pdf_url": {
      "type": "string"
    },
    "plan_pdf_url": {
      "type": "string"
    },
    "page_url": {
      "type": "string"
    }
  },
  "required": [
    "pdf_url",
    "results_pdf_url",
    "plan_pdf_url",
    "page_url"
  ],
  "additionalProperties": false
}
🟢get_pdf(tournament_key, doc)

The printable PDF itself, returned as a base64 embedded resource — use this when the organiser wants the file handed to them and your client cannot fetch URLs. Default "sheet": the merged tournament document (match sheet with write-in score boxes, player sheet, standings/results when they exist). "results" and "plan" are deprecated pre-merge variants kept for comparison. For a lighter response, get_pdf_link returns download URLs instead.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "doc": {
      "type": "string",
      "enum": [
        "sheet",
        "results",
        "plan"
      ]
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "filename": {
      "type": "string"
    },
    "mime_type": {
      "type": "string"
    },
    "size_bytes": {
      "type": "number"
    },
    "pdf_url": {
      "type": "string"
    }
  },
  "required": [
    "filename",
    "mime_type",
    "size_bytes",
    "pdf_url"
  ],
  "additionalProperties": false
}
⚪record_results(tournament_key, results, request_id)

Record one or many results. Score is conversational text: "6-4 3-6 10-7" (sets) or "16-8" (americano points). Outcomes: completed (default), walkover, retired (partial score allowed), cancelled, reinstate — reinstate CLEARS a recorded result and returns the match to scheduled (the fix for a mis-entered score). Corrections simply re-record. Winner (a|b = first|second listed side) only needed when the score alone does not decide.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "results": {
      "minItems": 1,
      "maxItems": 100,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "match_id": {
            "type": "string"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "completed",
              "walkover",
              "retired",
              "cancelled",
              "reinstate"
            ]
          },
          "score": {
            "type": "string",
            "maxLength": 120
          },
          "winner": {
            "type": "string",
            "enum": [
              "a",
              "b"
            ]
          }
        },
        "required": [
          "match_id"
        ]
      }
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    }
  },
  "required": [
    "tournament_key",
    "results"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "recorded": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "match_id": {
            "type": "string"
          },
          "structure": {
            "type": "string"
          },
          "round": {
            "type": "number"
          },
          "state": {
            "type": "string"
          },
          "side_a": {
            "type": "string"
          },
          "side_b": {
            "type": "string"
          },
          "score": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "winner": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "retired": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "court": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "estimated_start": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "match_id",
          "structure",
          "round",
          "state",
          "side_a",
          "side_b",
          "score",
          "winner",
          "retired",
          "court",
          "estimated_start"
        ],
        "additionalProperties": false
      }
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "recorded",
    "summary"
  ],
  "additionalProperties": false
}
🟡replace_player(tournament_key, out_player_name, in_player, mode, request_id)

A substitute takes over a player's spot. During play: slot takeover — completed results stay, the change is shown ("Anna, for Kristjan from R3"). Before the first result: choose mode slot_swap (default) or regenerate (re-pair and redraw using levels). Unknown substitute names are added to the roster automatically.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "out_player_name": {
      "type": "string"
    },
    "in_player": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "maxLength": 120
        },
        "gender": {
          "type": "string",
          "enum": [
            "m",
            "f",
            "x"
          ]
        },
        "level": {
          "type": "number",
          "minimum": -10000,
          "maximum": 10000,
          "description": "Any consistent numeric level/rating — used only for seeding and balancing"
        }
      },
      "required": [
        "name"
      ]
    },
    "mode": {
      "type": "string",
      "enum": [
        "slot_swap",
        "regenerate"
      ]
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    }
  },
  "required": [
    "tournament_key",
    "out_player_name",
    "in_player"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "entry": {
      "type": "string"
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "entry",
    "summary"
  ],
  "additionalProperties": false
}
⚪withdraw_player(tournament_key, player_name, request_id, confirm)

Withdraw a player (or their pair) mid-tournament. Remaining matches become walkovers for the opponents; americano regenerates its future rounds instead. Preview first, confirm to apply.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "player_name": {
      "type": "string"
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    },
    "confirm": {
      "description": "Omit or false: return a preview of what would change. True: apply it.",
      "type": "boolean"
    }
  },
  "required": [
    "tournament_key",
    "player_name"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "affected_matches": {
      "type": "number"
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "affected_matches",
    "summary"
  ],
  "additionalProperties": false
}
🟡swap_partners(tournament_key, player_a, player_b, round, request_id, ...)

Exchange two players' places. Fixed-pair doubles: swaps partners between two pairs permanently (name one player from each pair). Americano/mexicano: pass `round` to swap two players' places in ONE unplayed round — the courtside patch for a late arrival, an injury, or two friends who want a game together. One of them may be sitting that round, which is how you put a late arrival on court. Preview first, confirm to apply: the preview names any partnership or meeting the swap would repeat. Results already played never move.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "player_a": {
      "type": "string"
    },
    "player_b": {
      "type": "string"
    },
    "round": {
      "description": "Americano/mexicano only: which round to patch. Omit to swap the next unplayed round.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    },
    "confirm": {
      "description": "Omit or false: return a preview of what would change. True: apply it.",
      "type": "boolean"
    }
  },
  "required": [
    "tournament_key",
    "player_a",
    "player_b"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "pairs": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "round": {
      "type": "number"
    },
    "repeats_partnership": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "repeats_meeting": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "summary"
  ],
  "additionalProperties": false
}
🟡reschedule(tournament_key, start_time, delay_minutes, move_match, request_id)

Shift the start time, add a delay, or move one match to a specific court/slot. Played matches never move.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "start_time": {
      "description": "New ISO start time",
      "type": "string"
    },
    "delay_minutes": {
      "type": "integer",
      "minimum": 1,
      "maximum": 600
    },
    "move_match": {
      "type": "object",
      "properties": {
        "match_id": {
          "type": "string"
        },
        "court_name": {
          "type": "string"
        },
        "slot": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        }
      },
      "required": [
        "match_id"
      ]
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "start_time": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "start_time",
    "summary"
  ],
  "additionalProperties": false
}
⚪end_tournament(tournament_key, request_id, confirm)

Finish the tournament. If matches are still pending it ends early and current standings freeze as the final results. Preview first, confirm to apply.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    },
    "confirm": {
      "description": "Omit or false: return a preview of what would change. True: apply it.",
      "type": "boolean"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "status": {
      "type": "string"
    },
    "placements": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      }
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "status",
    "placements",
    "summary"
  ],
  "additionalProperties": false
}
🔴undo_last_change(tournament_key, to_change_id, request_id, confirm)

Roll the tournament back. Without to_change_id: restore exactly how it was before the most recent change (tool call or courtside page entry). With to_change_id (an id from get_audit_log): restore to just before that change — it and every later change are discarded in one step, so a burst of unwanted calls unwinds with a single revert. Preview lists exactly what would be discarded; confirm: true applies. A follow-up plain undo restores what the previous undo discarded.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string",
      "description": "The tournament's organiser key (starts with tk_)"
    },
    "to_change_id": {
      "description": "A change id from get_audit_log — restore to just before this change, discarding it and everything after it. Omit to undo only the latest change.",
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991
    },
    "request_id": {
      "description": "Optional idempotency id — retrying a call with the same id never applies it twice",
      "type": "string",
      "maxLength": 64
    },
    "confirm": {
      "description": "Omit or false: return a preview of what would change. True: apply it.",
      "type": "boolean"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "undone_tool": {
      "type": "string",
      "description": "Tool behind the earliest discarded change"
    },
    "undone_summary": {
      "type": "string"
    },
    "undone_at": {
      "type": "string"
    },
    "discarded_count": {
      "type": "number"
    },
    "discarded": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      },
      "description": "Every change this rollback discards, oldest first"
    },
    "summary": {
      "type": "string",
      "description": "What happened, in one line"
    },
    "preview": {
      "description": "True when this is a preview — nothing was changed",
      "type": "boolean"
    }
  },
  "required": [
    "undone_tool",
    "undone_summary",
    "undone_at",
    "discarded_count",
    "discarded",
    "summary"
  ],
  "additionalProperties": false
}
🔴delete_tournament(tournament_key, confirm)

Soft-delete the whole tournament (recoverable by support for 7 days, then gone). Preview first; confirm: true to apply.

入力スキーマ

{
  "type": "object",
  "properties": {
    "tournament_key": {
      "type": "string"
    },
    "confirm": {
      "type": "boolean"
    }
  },
  "required": [
    "tournament_key"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "deleted": {
      "type": "boolean"
    },
    "summary": {
      "type": "string"
    }
  },
  "required": [
    "deleted",
    "summary"
  ],
  "additionalProperties": false
}
🟢record_feedback(category, feedback, related_tool)

Record a request for something Turnale does not support yet (a format, scoring variant, or feature), so it can be considered for the roadmap. Call this only when the organiser asked for something unsupported AND agreed to have it noted. Describe the missing capability in general terms — NEVER include player names, contact details, or tournament keys.

入力スキーマ

{
  "type": "object",
  "properties": {
    "category": {
      "type": "string",
      "enum": [
        "unsupported_format",
        "scoring_variant",
        "feature",
        "other"
      ]
    },
    "feedback": {
      "type": "string",
      "minLength": 10,
      "maxLength": 1000,
      "description": "What the organiser wanted, summarised without any personal data (max 1000 characters — room for the problem, the workaround tried, and the suggested scope)"
    },
    "related_tool": {
      "description": "The tool this relates to, if any",
      "type": "string",
      "maxLength": 60
    }
  },
  "required": [
    "category",
    "feedback"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "recorded": {
      "type": "boolean"
    },
    "summary": {
      "type": "string"
    }
  },
  "required": [
    "recorded",
    "summary"
  ],
  "additionalProperties": false
}
🟢suggest_format(players_estimate, discipline, courts, total_minutes, match_minutes, ...)

Recommend tournament formats in plain language, with the round/time math done by the engine. Call this FIRST when the organiser has not named a format, names one hesitantly, or comes from a background where americano/mexicano need explaining — then relay the `menu` text as-is instead of asking an open 'which format?' question. SINGLES OR DOUBLES IS A PREREQUISITE: omit `discipline` and this returns the question to put to the organiser rather than a menu, because it decides which formats exist at all (americano and mexicano are doubles). Never infer it from the sport. Needs no key.

入力スキーマ

{
  "type": "object",
  "properties": {
    "players_estimate": {
      "type": "integer",
      "minimum": 2,
      "maximum": 128
    },
    "discipline": {
      "description": "Ask the organiser before offering formats; never infer it from the sport. 'unknown' = you asked and they don't mind, which shows both kinds. OMIT to get the question itself back.",
      "type": "string",
      "enum": [
        "singles",
        "doubles",
        "unknown"
      ]
    },
    "courts": {
      "description": "Default 2",
      "type": "integer",
      "minimum": 1,
      "maximum": 16
    },
    "total_minutes": {
      "description": "The time budget, e.g. 120 for a two-hour evening",
      "type": "integer",
      "minimum": 30,
      "maximum": 600
    },
    "match_minutes": {
      "type": "integer",
      "minimum": 5,
      "maximum": 240
    },
    "vibe": {
      "description": "Social: everyone mixes and plays a lot. Competitive: a bracket and a winner.",
      "type": "string",
      "enum": [
        "social",
        "competitive"
      ]
    },
    "fixed_partners": {
      "description": "Doubles only: do pairs stay together all evening?",
      "type": "boolean"
    }
  },
  "required": [
    "players_estimate"
  ]
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "recommendations": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      }
    },
    "glossary": {
      "type": "object",
      "properties": {},
      "additionalProperties": {}
    },
    "menu": {
      "type": "string",
      "description": "Ready-to-show menu of the options — relay it to the organiser as-is. Do not compress it to bare format names."
    },
    "note": {
      "type": "string"
    }
  },
  "required": [
    "recommendations",
    "glossary",
    "menu",
    "note"
  ],
  "additionalProperties": false
}
🟢get_player_template

A blank Excel workbook the organiser fills in and hands back: Name, Level, Gender, Comments, one player per row, with a sheet explaining each column. Offer it when the organiser has no list ready, asks how to send their players, or would rather work in a spreadsheet than paste names into chat. Needs no key. The file comes back both as a download link and as an attachable file. Reading a filled-in sheet needs no tool: parse it yourself and send the rows to add_players.

入力スキーマ

{
  "type": "object",
  "properties": {}
}

出力スキーマ

{
  "type": "object",
  "properties": {
    "template_url": {
      "type": "string"
    },
    "filename": {
      "type": "string"
    },
    "mime_type": {
      "type": "string"
    },
    "size_bytes": {
      "type": "number"
    },
    "columns": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "note": {
      "type": "string"
    }
  },
  "required": [
    "template_url",
    "filename",
    "mime_type",
    "size_bytes",
    "columns",
    "note"
  ],
  "additionalProperties": false
}

推奨プロンプト

list_items
List all [items] available in turnale
想定されるツール: list_players
browse_collection
Show me the [collection] from turnale
想定されるツール: list_players
retrieve_data
Get details about [item] from turnale
想定されるツール: get_briefing
fetch_info
Fetch [information type] using turnale
想定されるツール: get_briefing
explore_workflow
List available [items], then get details for each one using turnale
想定されるツール: list_playersget_briefing

コミュニティ

このサーバーを評価する

エビデンス

最近の観測

検証済みバージョンは記録されていませんツール 30 件
検証済みバージョンは記録されていませんツール 30 件