LeagueNight
Round-robin fixtures, standings and match-day plans for league organizers. Free.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"league-night": {
"url": "https://league-night.magicteams.ai/mcp"
}
}
}Remote endpoints
https://league-night.magicteams.ai/mcpstreamable-httpWhat it can do
Tool inventory
Tools (4)
🟢round_robin_schedule(teams, rounds, second_leg)
Compute a round-robin fixture list (circle method) for 2-100 teams: every pair meets once, or twice home-and-away with second_leg; odd counts get one bye per round. Use when you need who plays whom in each round. Do NOT use to assign times/courts for one match day (use match_day_plan) or to get calendar dates for a season (use season_plan).
Input Schema
{
"type": "object",
"properties": {
"teams": {
"type": "array",
"items": {
"type": "string",
"description": "Team name, e.g. \"Falcons\""
},
"minItems": 2,
"maxItems": 100,
"description": "Team names: 2-100 unique, non-empty names (trimmed), e.g. [\"Falcons\", \"Tigers\", \"Bears\"]"
},
"rounds": {
"type": "integer",
"minimum": 1,
"description": "Optional: return only the first N rounds, integer 1..max (max = teams-1 for even counts, teams for odd; doubled with second_leg). Default: all rounds"
},
"second_leg": {
"type": "boolean",
"description": "If true, append a mirrored second leg with home and away swapped (double round-robin). Default false"
}
},
"required": [
"teams"
]
}Output Schema
{
"type": "object",
"properties": {
"teams": {
"type": "array",
"items": {
"type": "string"
},
"description": "Cleaned (trimmed) team names in input order"
},
"legs": {
"type": "integer",
"enum": [
1,
2
],
"description": "Number of legs included in the returned rounds (1 or 2)"
},
"rounds": {
"type": "array",
"description": "Rounds in play order, each with its fixtures and any bye",
"items": {
"type": "object",
"properties": {
"round": {
"type": "integer",
"description": "Round number starting at 1"
},
"fixtures": {
"type": "array",
"description": "Fixtures in this round",
"items": {
"type": "object",
"description": "A fixture {home, away}, or {bye} for the team sitting out this round",
"properties": {
"home": {
"type": "string",
"description": "Home team name"
},
"away": {
"type": "string",
"description": "Away team name"
},
"bye": {
"type": "string",
"description": "Team with a bye (no game) this round"
}
}
}
}
},
"required": [
"round",
"fixtures"
]
}
},
"games_per_team": {
"type": "number",
"description": "Average games per team across the returned rounds (2 decimals)"
},
"total_games": {
"type": "integer",
"description": "Total fixtures (excluding byes) in the returned rounds"
},
"note": {
"type": "string",
"description": "Plain-English summary of the schedule (teams, rounds, byes, truncation)"
}
},
"required": [
"teams",
"legs",
"rounds",
"games_per_team",
"total_games",
"note"
]
}🟢standings_table(results, teams, points_win, points_draw)
Compute a league standings table from match results: played, W/D/L, goals for/against, goal difference and points, sorted by points, then goal difference, then goals for, then name. Use when you have scores and want the current table. Do NOT use to generate future fixtures (use round_robin_schedule).
Input Schema
{
"type": "object",
"properties": {
"results": {
"type": "array",
"description": "Completed match results in any order; may be empty if teams is given (zeroed table)",
"items": {
"type": "object",
"properties": {
"home": {
"type": "string",
"description": "Home team name, e.g. \"Falcons\""
},
"away": {
"type": "string",
"description": "Away team name (must differ from home), e.g. \"Tigers\""
},
"home_score": {
"type": "integer",
"minimum": 0,
"description": "Home team score, non-negative integer, e.g. 3"
},
"away_score": {
"type": "integer",
"minimum": 0,
"description": "Away team score, non-negative integer, e.g. 1"
}
},
"required": [
"home",
"away",
"home_score",
"away_score"
]
}
},
"teams": {
"type": "array",
"items": {
"type": "string",
"description": "Team name"
},
"minItems": 2,
"description": "Optional full roster (2+ unique names). Teams with no results appear with zeros; results involving teams not listed are skipped with a warning"
},
"points_win": {
"type": "number",
"minimum": 0,
"description": "Points awarded for a win, non-negative number. Default 3"
},
"points_draw": {
"type": "number",
"minimum": 0,
"description": "Points awarded for a draw, non-negative number. Default 1"
}
},
"required": [
"results"
]
}Output Schema
{
"type": "object",
"properties": {
"table": {
"type": "array",
"description": "Standings rows sorted by points, goal difference, goals for, then team name",
"items": {
"type": "object",
"properties": {
"team": {
"type": "string",
"description": "Team name"
},
"played": {
"type": "integer",
"description": "Games played"
},
"wins": {
"type": "integer",
"description": "Games won"
},
"draws": {
"type": "integer",
"description": "Games drawn"
},
"losses": {
"type": "integer",
"description": "Games lost"
},
"gf": {
"type": "integer",
"description": "Goals/points scored (for)"
},
"ga": {
"type": "integer",
"description": "Goals/points conceded (against)"
},
"gd": {
"type": "integer",
"description": "Goal difference (gf - ga)"
},
"points": {
"type": "number",
"description": "League points"
}
},
"required": [
"team",
"played",
"wins",
"draws",
"losses",
"gf",
"ga",
"gd",
"points"
]
}
},
"warnings": {
"type": "array",
"items": {
"type": "string"
},
"description": "Results skipped because a team was not in the roster (empty if none)"
},
"points_system": {
"type": "object",
"description": "Points scheme applied to compute the table",
"properties": {
"win": {
"type": "number",
"description": "Points per win"
},
"draw": {
"type": "number",
"description": "Points per draw"
}
},
"required": [
"win",
"draw"
]
}
},
"required": [
"table",
"warnings",
"points_system"
]
}🟢match_day_plan(games, courts, slot_minutes, start_time)
Compute a one-day timetable: lay an ordered list of games onto parallel courts and fixed-length time slots from a start time, giving each game a court and HH:MM start, plus the end time. Use when you already know the day's games. Do NOT use to decide who plays whom (use round_robin_schedule) or to size a whole season (use season_plan).
Input Schema
{
"type": "object",
"properties": {
"games": {
"type": "array",
"minItems": 1,
"description": "Games in the order they should be played (non-empty); e.g. one round's fixtures from round_robin_schedule",
"items": {
"type": "object",
"properties": {
"home": {
"type": "string",
"description": "Home team name, e.g. \"Falcons\""
},
"away": {
"type": "string",
"description": "Away team name, e.g. \"Tigers\""
}
},
"required": [
"home",
"away"
]
}
},
"courts": {
"type": "integer",
"minimum": 1,
"maximum": 12,
"description": "Number of courts/pitches usable at the same time, integer 1-12, e.g. 2"
},
"slot_minutes": {
"type": "integer",
"minimum": 10,
"maximum": 180,
"description": "Length of one game slot in minutes, integer 10-180, e.g. 40"
},
"start_time": {
"type": "string",
"pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
"description": "First game start, 24h HH:MM, e.g. \"09:00\" or \"18:30\""
}
},
"required": [
"games",
"courts",
"slot_minutes",
"start_time"
]
}Output Schema
{
"type": "object",
"properties": {
"start_time": {
"type": "string",
"description": "First slot start time, 24h HH:MM (echoed from input)"
},
"end_time": {
"type": "string",
"description": "Time the last slot finishes, 24h HH:MM (wraps past midnight)"
},
"courts": {
"type": "integer",
"description": "Number of courts used in parallel"
},
"slot_minutes": {
"type": "integer",
"description": "Length of each slot in minutes"
},
"timeline": {
"type": "array",
"description": "One entry per game, in input order",
"items": {
"type": "object",
"properties": {
"time_hhmm": {
"type": "string",
"description": "Start time 24h HH:MM"
},
"court": {
"type": "integer",
"description": "Court number starting at 1"
},
"home": {
"type": "string",
"description": "Home team name"
},
"away": {
"type": "string",
"description": "Away team name"
}
},
"required": [
"time_hhmm",
"court",
"home",
"away"
]
}
},
"total_minutes": {
"type": "integer",
"description": "Total duration from first start to last finish, in minutes"
},
"note": {
"type": "string",
"description": "Plain-English summary (slots, courts, after-midnight warning)"
}
},
"required": [
"start_time",
"end_time",
"courts",
"slot_minutes",
"timeline",
"total_minutes",
"note"
]
}🟢season_plan(teams, courts, slot_minutes, start_date, days_between_rounds, ...)
Estimate a season's size and calendar: total round-robin fixtures, games per match day (limited by courts, one slot per day), match days needed, every match-day date from start_date at a fixed interval, and the finish date. Use for "when will the season end?". Do NOT use for pairings (use round_robin_schedule) or one day's timetable (use match_day_plan).
Input Schema
{
"type": "object",
"properties": {
"teams": {
"type": "array",
"items": {
"type": "string",
"description": "Team name, e.g. \"Falcons\""
},
"minItems": 2,
"maxItems": 100,
"description": "Team names: 2-100 unique, non-empty names (trimmed), e.g. [\"Falcons\", \"Tigers\", \"Bears\"]"
},
"courts": {
"type": "integer",
"minimum": 1,
"maximum": 12,
"description": "Courts usable at the same time on each match day, integer 1-12; caps games per match day. E.g. 2"
},
"slot_minutes": {
"type": "integer",
"minimum": 10,
"maximum": 180,
"description": "Length of one game slot in minutes, integer 10-180 (validated and echoed in the note; each match day is one slot). E.g. 30"
},
"start_date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "First match day, YYYY-MM-DD, e.g. \"2026-10-04\""
},
"days_between_rounds": {
"type": "integer",
"minimum": 1,
"maximum": 60,
"description": "Days between consecutive match days, integer 1-60. Default 7 (weekly)"
},
"second_leg": {
"type": "boolean",
"description": "If true, plan a double round-robin (each pair meets twice). Default false"
}
},
"required": [
"teams",
"courts",
"slot_minutes",
"start_date"
]
}Output Schema
{
"type": "object",
"properties": {
"rounds_needed": {
"type": "integer",
"description": "Number of match days needed to play all fixtures"
},
"games_total": {
"type": "integer",
"description": "Total fixtures in the season (n(n-1)/2 per leg)"
},
"games_per_round": {
"type": "integer",
"description": "Games played per match day: min(floor(teams/2), courts)"
},
"per_team_games": {
"type": "integer",
"description": "Games each team plays over the season"
},
"dates": {
"type": "array",
"items": {
"type": "string",
"description": "Match-day date YYYY-MM-DD"
},
"description": "Every match-day date, YYYY-MM-DD, in order"
},
"finish_date": {
"type": "string",
"description": "Date of the last match day, YYYY-MM-DD"
},
"note": {
"type": "string",
"description": "Plain-English summary of the season plan and assumptions"
}
},
"required": [
"rounds_needed",
"games_total",
"games_per_round",
"per_team_games",
"dates",
"finish_date",
"note"
]
}Community
Evidence