Koskamo

Zovo Tournament Maker MCP

Generates seeded tournament brackets, round robin schedules, and Swiss pairings with byes. It supports single and double elimination formats, timetable creation across courts, result recording for standings, and exports to printable PDF or CSV.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Zovo Tournament Maker MCP logo, by ZovoCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-01Published by Zovo
MCP endpoint (Streamable HTTP)
https://bracket-maker.zovo.one/mcp
Vendor documentation

What you can do with it

  • Make a single elimination bracket for 6 teams
  • Generate round robin schedule for 5 players on 2 courts
  • Create double elimination bracket for 8 players
  • Print landscape PDF bracket or download CSV schedule

Source and maintenance

Community listingRegistry 1.0.0

Protocol and capabilities

Server
bracket-maker 1.0.0
MCP protocol
2025-06-18
Tools
2 advertised
Resources
1 advertised
Resource templates
1 advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "resources": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Zovo Tournament Maker builds tournament brackets and schedules. generate_tournament_bracket makes a single elimination, double elimination, round robin or Swiss tournament for 2-128 players or teams, with standard seeding, correct byes, an optional timetable over several courts, a printable PDF and a CSV. calculate_bracket_standings takes the same inputs plus results played so far and returns the updated bracket or table and the next matches. Always pass the full participant list and every result so far. Never invent results.

Tools

2 advertised

generate_tournament_bracket — Generate tournament bracket
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the user wants a tournament bracket or schedule (tournament bracket maker, bracket generator, single elimination or double elimination bracket, round robin schedule generator, Swiss pairings, a bracket for 6, 10 or 12 teams with byes). Builds the full structure for 2-128 players or teams: standard seeding so top seeds meet last, byes for the top seeds when the field is not a power of two, optional third-place match, grand final reset, round robin via the circle method with balanced home/away, Swiss round 1, optional timetable over several courts, a printable PDF bracket and a CSV schedule. Results already known can be included to advance winners. Does not predict winners, fill in picks for famous tournaments, or schedule leagues with venue or travel constraints.

generate_tournament_bracket input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "format"
  ],
  "properties": {
    "paper": {
      "enum": [
        "letter",
        "a4"
      ],
      "type": "string",
      "description": "Paper size for the landscape PDF: letter (default) or a4. Example: a4"
    },
    "title": {
      "type": "string",
      "maxLength": 100,
      "description": "Tournament name for the bracket, PDF and CSV. Example: \"Friday Ping Pong Cup\""
    },
    "courts": {
      "type": "number",
      "description": "Courts, tables, boards or fields available at the same time (1-64), used for the timetable. Example: 3"
    },
    "format": {
      "enum": [
        "single_elimination",
        "double_elimination",
        "round_robin",
        "swiss"
      ],
      "type": "string",
      "description": "Tournament format: single_elimination (knockout), double_elimination (out after two losses, losers bracket, grand final), round_robin (everyone plays everyone once; league), swiss (fixed number of rounds, players with equal scores meet, no rematches). Example: single_elimination"
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "p1": {
            "type": "string",
            "maxLength": 80,
            "description": "First player or team in this result, e.g. \"Ann\"."
          },
          "p2": {
            "type": "string",
            "maxLength": 80,
            "description": "Second player or team, e.g. \"Bob\"."
          },
          "match": {
            "type": "string",
            "maxLength": 12,
            "description": "Match id from the bracket or schedule, e.g. \"M5\". Optional when p1 and p2 are given."
          },
          "score1": {
            "type": "number",
            "description": "Score of p1 (or of the match's first slot when only match is given), e.g. 21."
          },
          "score2": {
            "type": "number",
            "description": "Score of p2, e.g. 15."
          },
          "winner": {
            "type": "string",
            "maxLength": 80,
            "description": "Name of the winner, e.g. \"Ann\", or \"draw\" (round robin and Swiss only). Can be left out when both scores are given."
          }
        }
      },
      "maxItems": 600,
      "description": "Results already played, in any order for elimination formats and round by round for Swiss. Each needs the players (p1, p2) or a match id, plus a winner or both scores. Example: [{\"p1\":\"Ann\",\"p2\":\"Finn\",\"score1\":21,\"score2\":12}]"
    },
    "seeding": {
      "enum": [
        "standard",
        "random",
        "as_listed"
      ],
      "type": "string",
      "description": "standard (default): list order is the seed ranking, 1 plays the lowest seed, top seeds get the byes and seeds 1 and 2 can only meet in the final. random: a reproducible random draw (see random_seed), then placed like seeds. as_listed: fill the bracket top to bottom in list order, 1st vs 2nd, 3rd vs 4th, with byes spread evenly. Example: random"
    },
    "meetings": {
      "type": "number",
      "description": "Round robin only: 1 (default) = every pair meets once; 2 = home and away (double round robin). Example: 2"
    },
    "start_time": {
      "type": "string",
      "maxLength": 5,
      "description": "Start time of the first matches, 24-hour HH:MM (default 09:00). Example: \"18:30\""
    },
    "win_points": {
      "type": "number",
      "description": "Round robin / Swiss table points for a win (default 3 for round robin, 1 for Swiss). Example: 2"
    },
    "draw_points": {
      "type": "number",
      "description": "Points for a draw (default 1 for round robin, 0.5 for Swiss). Example: 1"
    },
    "loss_points": {
      "type": "number",
      "description": "Points for a loss (default 0). Example: 0"
    },
    "random_seed": {
      "type": "number",
      "description": "Draw number for random seeding (1-999999). The same participants and number always give the same draw. Example: 4821"
    },
    "participants": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 200
      },
      "maxItems": 200,
      "description": "Players or teams, 2-128 unique names. With standard seeding the order is the ranking: first = seed 1. Example: [\"Ann\",\"Bob\",\"Cy\",\"Dee\",\"Eve\",\"Finn\"]"
    },
    "swiss_rounds": {
      "type": "number",
      "description": "Swiss only: number of rounds (default log2 of the field, rounded up; maximum depends on the field size). Example: 5"
    },
    "break_minutes": {
      "type": "number",
      "description": "Changeover time between matches on a court, in minutes (0-120, default 0). Example: 5"
    },
    "match_minutes": {
      "type": "number",
      "description": "Length of one match in minutes (5-600). Giving this adds start times and courts to every match. Example: 20"
    },
    "grand_final_reset": {
      "type": "boolean",
      "description": "Double elimination only (default true): if the losers-bracket champion wins the grand final, a second deciding match is played, so nobody is out after one loss. Example: false"
    },
    "participant_count": {
      "type": "number",
      "description": "Use instead of participants when the user gives only a number: makes Team 1 ... Team N (2-128). Example: 12"
    },
    "third_place_match": {
      "type": "boolean",
      "description": "Single elimination only: add a third-place match between the semifinal losers. Example: true"
    }
  }
}
generate_tournament_bracket output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "kind",
    "title",
    "format",
    "format_label",
    "seeding",
    "random_seed",
    "participants",
    "counts",
    "bracket_size",
    "matches",
    "byes",
    "standings",
    "next_matches",
    "champion",
    "placements",
    "complete",
    "schedule",
    "swiss",
    "notes",
    "request",
    "results",
    "downloads"
  ],
  "properties": {
    "byes": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "kind": {
      "type": "string"
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "swiss": {
      "anyOf": [
        {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {}
        },
        {
          "type": "null"
        }
      ]
    },
    "title": {
      "type": "string"
    },
    "counts": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": "number"
      }
    },
    "format": {
      "type": "string"
    },
    "matches": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "request": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "seeding": {
      "type": "string"
    },
    "champion": {
      "type": [
        "string",
        "null"
      ]
    },
    "complete": {
      "type": "boolean"
    },
    "schedule": {
      "anyOf": [
        {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {}
        },
        {
          "type": "null"
        }
      ]
    },
    "downloads": {
      "type": "object",
      "required": [
        "pdf",
        "csv"
      ],
      "properties": {
        "csv": {
          "type": "string"
        },
        "pdf": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "standings": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "placements": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "place",
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "place": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    },
    "random_seed": {
      "type": [
        "number",
        "null"
      ]
    },
    "bracket_size": {
      "type": [
        "number",
        "null"
      ]
    },
    "format_label": {
      "type": "string"
    },
    "next_matches": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "participants": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "seed",
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "seed": {
            "type": "number"
          }
        },
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": false
}
generate_tournament_bracket annotations
{
  "title": "Generate tournament bracket",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
calculate_bracket_standings — Calculate bracket standings
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the user reports results of a tournament made with generate_tournament_bracket (or describes one) and wants the updated bracket, who advances, the standings table or what is next. Takes the same format and participants plus every result so far (winner or scores per match) and returns the advanced bracket, the round robin or Swiss table (points, head-to-head, score difference; Buchholz for Swiss), final places, the next Swiss round's pairings, and the next matches to play. Do not use to predict outcomes; it only records results the user gives.

calculate_bracket_standings input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "format"
  ],
  "properties": {
    "paper": {
      "enum": [
        "letter",
        "a4"
      ],
      "type": "string",
      "description": "Paper size for the landscape PDF: letter (default) or a4. Example: a4"
    },
    "title": {
      "type": "string",
      "maxLength": 100,
      "description": "Tournament name for the bracket, PDF and CSV. Example: \"Friday Ping Pong Cup\""
    },
    "courts": {
      "type": "number",
      "description": "Courts, tables, boards or fields available at the same time (1-64), used for the timetable. Example: 3"
    },
    "format": {
      "enum": [
        "single_elimination",
        "double_elimination",
        "round_robin",
        "swiss"
      ],
      "type": "string",
      "description": "Tournament format: single_elimination (knockout), double_elimination (out after two losses, losers bracket, grand final), round_robin (everyone plays everyone once; league), swiss (fixed number of rounds, players with equal scores meet, no rematches). Example: single_elimination"
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "p1": {
            "type": "string",
            "maxLength": 80,
            "description": "First player or team in this result, e.g. \"Ann\"."
          },
          "p2": {
            "type": "string",
            "maxLength": 80,
            "description": "Second player or team, e.g. \"Bob\"."
          },
          "match": {
            "type": "string",
            "maxLength": 12,
            "description": "Match id from the bracket or schedule, e.g. \"M5\". Optional when p1 and p2 are given."
          },
          "score1": {
            "type": "number",
            "description": "Score of p1 (or of the match's first slot when only match is given), e.g. 21."
          },
          "score2": {
            "type": "number",
            "description": "Score of p2, e.g. 15."
          },
          "winner": {
            "type": "string",
            "maxLength": 80,
            "description": "Name of the winner, e.g. \"Ann\", or \"draw\" (round robin and Swiss only). Can be left out when both scores are given."
          }
        }
      },
      "maxItems": 600,
      "description": "Results already played, in any order for elimination formats and round by round for Swiss. Each needs the players (p1, p2) or a match id, plus a winner or both scores. Example: [{\"p1\":\"Ann\",\"p2\":\"Finn\",\"score1\":21,\"score2\":12}]"
    },
    "seeding": {
      "enum": [
        "standard",
        "random",
        "as_listed"
      ],
      "type": "string",
      "description": "standard (default): list order is the seed ranking, 1 plays the lowest seed, top seeds get the byes and seeds 1 and 2 can only meet in the final. random: a reproducible random draw (see random_seed), then placed like seeds. as_listed: fill the bracket top to bottom in list order, 1st vs 2nd, 3rd vs 4th, with byes spread evenly. Example: random"
    },
    "meetings": {
      "type": "number",
      "description": "Round robin only: 1 (default) = every pair meets once; 2 = home and away (double round robin). Example: 2"
    },
    "start_time": {
      "type": "string",
      "maxLength": 5,
      "description": "Start time of the first matches, 24-hour HH:MM (default 09:00). Example: \"18:30\""
    },
    "win_points": {
      "type": "number",
      "description": "Round robin / Swiss table points for a win (default 3 for round robin, 1 for Swiss). Example: 2"
    },
    "draw_points": {
      "type": "number",
      "description": "Points for a draw (default 1 for round robin, 0.5 for Swiss). Example: 1"
    },
    "loss_points": {
      "type": "number",
      "description": "Points for a loss (default 0). Example: 0"
    },
    "random_seed": {
      "type": "number",
      "description": "Draw number for random seeding (1-999999). The same participants and number always give the same draw. Example: 4821"
    },
    "participants": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 200
      },
      "maxItems": 200,
      "description": "Players or teams, 2-128 unique names. With standard seeding the order is the ranking: first = seed 1. Example: [\"Ann\",\"Bob\",\"Cy\",\"Dee\",\"Eve\",\"Finn\"]"
    },
    "swiss_rounds": {
      "type": "number",
      "description": "Swiss only: number of rounds (default log2 of the field, rounded up; maximum depends on the field size). Example: 5"
    },
    "break_minutes": {
      "type": "number",
      "description": "Changeover time between matches on a court, in minutes (0-120, default 0). Example: 5"
    },
    "match_minutes": {
      "type": "number",
      "description": "Length of one match in minutes (5-600). Giving this adds start times and courts to every match. Example: 20"
    },
    "grand_final_reset": {
      "type": "boolean",
      "description": "Double elimination only (default true): if the losers-bracket champion wins the grand final, a second deciding match is played, so nobody is out after one loss. Example: false"
    },
    "participant_count": {
      "type": "number",
      "description": "Use instead of participants when the user gives only a number: makes Team 1 ... Team N (2-128). Example: 12"
    },
    "third_place_match": {
      "type": "boolean",
      "description": "Single elimination only: add a third-place match between the semifinal losers. Example: true"
    }
  }
}
calculate_bracket_standings output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "kind",
    "title",
    "format",
    "format_label",
    "seeding",
    "random_seed",
    "participants",
    "counts",
    "bracket_size",
    "matches",
    "byes",
    "standings",
    "next_matches",
    "champion",
    "placements",
    "complete",
    "schedule",
    "swiss",
    "notes",
    "request",
    "results",
    "downloads"
  ],
  "properties": {
    "byes": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "kind": {
      "type": "string"
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "swiss": {
      "anyOf": [
        {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {}
        },
        {
          "type": "null"
        }
      ]
    },
    "title": {
      "type": "string"
    },
    "counts": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": "number"
      }
    },
    "format": {
      "type": "string"
    },
    "matches": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "request": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "seeding": {
      "type": "string"
    },
    "champion": {
      "type": [
        "string",
        "null"
      ]
    },
    "complete": {
      "type": "boolean"
    },
    "schedule": {
      "anyOf": [
        {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {}
        },
        {
          "type": "null"
        }
      ]
    },
    "downloads": {
      "type": "object",
      "required": [
        "pdf",
        "csv"
      ],
      "properties": {
        "csv": {
          "type": "string"
        },
        "pdf": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "standings": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "placements": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "place",
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "place": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    },
    "random_seed": {
      "type": [
        "number",
        "null"
      ]
    },
    "bracket_size": {
      "type": [
        "number",
        "null"
      ]
    },
    "format_label": {
      "type": "string"
    },
    "next_matches": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "participants": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "seed",
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "seed": {
            "type": "number"
          }
        },
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": false
}
calculate_bracket_standings annotations
{
  "title": "Calculate bracket standings",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

1 advertised

bracket-maker-widget — Zovo Tournament Maker view

Advertised by the server during the last successful anonymous check.

Interactive view for Zovo Tournament Maker.

bracket-maker-widget URI
ui://widget/bracket-maker-v3-1.0.0-48943cb584443b6bd8df12fa10213ea8edc62c5b687c366931fe34eab939f688.html

MIME type: text/html;profile=mcp-app

bracket-maker-widget-legacy — Zovo Tournament Maker view (previous versions)

Advertised by the server during the last successful anonymous check.

bracket-maker-widget-legacy URI template
ui://widget/bracket-maker-{version}.html

MIME type: text/html;profile=mcp-app

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
363 ms
95th percentile latency
363 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 363 ms · metadata changed · 2 tool(s), 1 resource(s), 1 resource template(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http zovo-tournament-maker-mcp https://bracket-maker.zovo.one/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add zovo-tournament-maker-mcp --url https://bracket-maker.zovo.one/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable zovo-tournament-maker-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "zovo-tournament-maker-mcp": {
      "url": "https://bracket-maker.zovo.one/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "zovo-tournament-maker-mcp": {
      "type": "streamableHttp",
      "url": "https://bracket-maker.zovo.one/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start zovo-tournament-maker-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "zovo-tournament-maker-mcp": {
      "type": "http",
      "url": "https://bracket-maker.zovo.one/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http zovo-tournament-maker-mcp https://bracket-maker.zovo.one/mcp

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "zovo-tournament-maker-mcp": {
      "url": "https://bracket-maker.zovo.one/mcp"
    }
  }
}

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "zovo-tournament-maker-mcp": {
      "serverUrl": "https://bracket-maker.zovo.one/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Zovo Tournament Maker MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.