Koskamo

CourtSplit MCP

CourtSplit provides MCP tools for AI assistants to split court or venue costs across players, settle up balances with minimal payments, handle recurring session splits with varying attendance, and plan fair player rotations for pickup games. It performs pure arithmetic without processing payments or storing data.

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.

CourtSplit MCP logo, by MagicTeamsCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-07Published by MagicTeams
MCP endpoint (Streamable HTTP)
https://court-split.magicteams.ai/mcp
Vendor documentation

What its tools do

4 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

4 of 4 have a description · 4 of 4 declare behavior hints · 4 of 4 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Split a single court cost equally or by weights among players
  • Compute minimal payments to settle up shared expenses
  • Split costs for recurring sessions with varying attendance
  • Plan fair player rotations for pickup games

Source and maintenance

Community listingRegistry 1.0.0
Maintenance checked

Protocol and capabilities

Server
court-split 1.0.0
MCP protocol negotiated in check
2025-11-25
Tools
4 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": false
  }
}

Server-provided instructions

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

CourtSplit splits court and venue costs fairly, minimizes settle-up payments, accounts for recurring sessions with rotating attendance, and plans fair play rotations. All maths only; nothing stored.

Tools

4 advertised

split_costs — Split costs
Advertised by the server during the last successful anonymous check.
Advertised read-only

Split one total court or venue cost across players, equally or by relative weights, and show each player's share plus the fewest payments to settle up. Use for a single booking or event. For recurring sessions with changing attendance use split_series.

split_costs input schema
{
  "type": "object",
  "required": [
    "total_cost",
    "participants"
  ],
  "properties": {
    "shares": {
      "type": "array",
      "items": {
        "type": "number",
        "exclusiveMinimum": 0
      },
      "description": "Optional positive relative weights, one per participant in the same order, e.g. [2,1,1]; omit for an equal split"
    },
    "currency": {
      "type": "string",
      "description": "Currency code used only for display, e.g. USD, EUR, GBP (default USD)"
    },
    "total_cost": {
      "type": "number",
      "description": "Total court/venue cost in currency units, e.g. 96 for $96.00",
      "exclusiveMinimum": 0
    },
    "participants": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Player name, unique within the list, e.g. 'Asha'"
          },
          "paid": {
            "type": "number",
            "minimum": 0,
            "description": "Amount this player already paid toward the total, in currency units (default 0)"
          }
        }
      },
      "minItems": 2,
      "description": "At least 2 players with unique names; include 'paid' for anyone who already paid, e.g. [{\"name\":\"Asha\",\"paid\":96},{\"name\":\"Dev\"}]"
    }
  }
}
split_costs output schema
{
  "type": "object",
  "required": [
    "currency",
    "total_cost",
    "split",
    "per_head",
    "participants",
    "settle_up",
    "note"
  ],
  "properties": {
    "note": {
      "type": "string",
      "description": "Plain-language summary of the split"
    },
    "split": {
      "enum": [
        "equal",
        "weighted"
      ],
      "type": "string",
      "description": "Whether the split was equal or by relative weights"
    },
    "currency": {
      "type": "string",
      "description": "Currency code used for display"
    },
    "per_head": {
      "type": [
        "number",
        "null"
      ],
      "description": "Equal share per player, or null for a weighted split"
    },
    "settle_up": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "from",
          "to",
          "amount"
        ],
        "properties": {
          "to": {
            "type": "string",
            "description": "Player who receives"
          },
          "from": {
            "type": "string",
            "description": "Player who pays"
          },
          "amount": {
            "type": "number",
            "description": "Amount to transfer, rounded to cents"
          }
        }
      },
      "description": "Fewest payments that settle everyone (empty if nobody paid yet or all square)"
    },
    "total_cost": {
      "type": "number",
      "description": "Total cost that was split, rounded to cents"
    },
    "participants": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "paid",
          "owed",
          "balance"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Player name"
          },
          "owed": {
            "type": "number",
            "description": "This player's fair share of the cost"
          },
          "paid": {
            "type": "number",
            "description": "Amount this player paid"
          },
          "balance": {
            "type": "number",
            "description": "paid minus owed; positive = gets money back, negative = owes money"
          }
        }
      },
      "description": "Per-player paid, owed share and balance"
    }
  }
}
split_costs annotations
{
  "title": "Split costs",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
settle_up — Settle up
Advertised by the server during the last successful anonymous check.
Advertised read-only

Given a shared total and who already paid what, compute each player's balance and the minimal set of payments (who pays whom, how much) to settle everyone. Use when the question is 'who owes whom'. For recurring sessions with different attendees use split_series.

settle_up input schema
{
  "type": "object",
  "required": [
    "total_cost",
    "participants"
  ],
  "properties": {
    "shares": {
      "type": "array",
      "items": {
        "type": "number",
        "exclusiveMinimum": 0
      },
      "description": "Optional positive relative weights, one per participant in the same order, e.g. [2,1,1]; omit for an equal split"
    },
    "currency": {
      "type": "string",
      "description": "Currency code used only for display, e.g. USD, EUR, GBP (default USD)"
    },
    "total_cost": {
      "type": "number",
      "description": "Total court/venue cost in currency units, e.g. 96 for $96.00",
      "exclusiveMinimum": 0
    },
    "participants": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Player name, unique within the list, e.g. 'Asha'"
          },
          "paid": {
            "type": "number",
            "minimum": 0,
            "description": "Amount this player already paid toward the total, in currency units (default 0)"
          }
        }
      },
      "minItems": 2,
      "description": "At least 2 players with unique names; include 'paid' for anyone who already paid, e.g. [{\"name\":\"Asha\",\"paid\":96},{\"name\":\"Dev\"}]"
    }
  }
}
settle_up output schema
{
  "type": "object",
  "required": [
    "currency",
    "total_cost",
    "balances",
    "transfers",
    "transfer_count",
    "note"
  ],
  "properties": {
    "note": {
      "type": "string",
      "description": "Plain-language summary of the settlement"
    },
    "balances": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "paid",
          "owed",
          "balance"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Player name"
          },
          "owed": {
            "type": "number",
            "description": "This player's fair share of the cost"
          },
          "paid": {
            "type": "number",
            "description": "Amount this player paid"
          },
          "balance": {
            "type": "number",
            "description": "paid minus owed; positive = gets money back, negative = owes money"
          }
        }
      },
      "description": "Per-player paid, owed share and net balance"
    },
    "currency": {
      "type": "string",
      "description": "Currency code used for display"
    },
    "transfers": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "from",
          "to",
          "amount"
        ],
        "properties": {
          "to": {
            "type": "string",
            "description": "Player who receives"
          },
          "from": {
            "type": "string",
            "description": "Player who pays"
          },
          "amount": {
            "type": "number",
            "description": "Amount to transfer, rounded to cents"
          }
        }
      },
      "description": "Minimal list of payments that settles the group"
    },
    "total_cost": {
      "type": "number",
      "description": "Total shared cost, rounded to cents"
    },
    "transfer_count": {
      "type": "integer",
      "description": "Number of payments in transfers"
    }
  }
}
settle_up annotations
{
  "title": "Settle up",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
split_series — Split series
Advertised by the server during the last successful anonymous check.
Advertised read-only

Split a series of recurring sessions where attendance varies: each session's cost is shared only by that session's attendees, then payments already made are netted into balances and minimal settle-up transfers. Use for weekly games or leagues. For a single event use split_costs.

split_series input schema
{
  "type": "object",
  "required": [
    "sessions"
  ],
  "properties": {
    "players": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Optional full roster, so players who missed every session still appear with a zero balance"
    },
    "currency": {
      "type": "string",
      "description": "Currency code used only for display, e.g. USD (default USD)"
    },
    "payments": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "paid"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Player who paid, e.g. the person who fronted court fees"
          },
          "paid": {
            "type": "number",
            "minimum": 0,
            "description": "Total amount this player has paid across the series, in currency units"
          }
        }
      },
      "description": "Optional list of who already paid what across the series, e.g. [{\"name\":\"Asha\",\"paid\":120}]"
    },
    "sessions": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "cost",
          "attendees"
        ],
        "properties": {
          "cost": {
            "type": "number",
            "description": "Cost of this session in currency units, e.g. 60",
            "exclusiveMinimum": 0
          },
          "label": {
            "type": "string",
            "description": "Optional session label, e.g. 'Tue 7pm' (default 'session N')"
          },
          "attendees": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "description": "Unique names of players present at this session"
          }
        }
      },
      "minItems": 1,
      "description": "Sessions in order, each with its cost and the names who attended"
    }
  }
}
split_series output schema
{
  "type": "object",
  "required": [
    "currency",
    "total_cost",
    "session_count",
    "sessions",
    "players",
    "transfers",
    "note"
  ],
  "properties": {
    "note": {
      "type": "string",
      "description": "Explanation of how the series was split"
    },
    "players": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "paid",
          "owed",
          "balance",
          "sessions_played"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Player name"
          },
          "owed": {
            "type": "number",
            "description": "This player's fair share of the cost"
          },
          "paid": {
            "type": "number",
            "description": "Amount this player paid"
          },
          "balance": {
            "type": "number",
            "description": "paid minus owed; positive = gets money back, negative = owes money"
          },
          "sessions_played": {
            "type": "integer",
            "description": "Number of sessions this player attended"
          }
        }
      },
      "description": "Per-player paid, owed, balance and sessions attended"
    },
    "currency": {
      "type": "string",
      "description": "Currency code used for display"
    },
    "sessions": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "label",
          "cost",
          "attendees",
          "per_head"
        ],
        "properties": {
          "cost": {
            "type": "number",
            "description": "Session cost"
          },
          "label": {
            "type": "string",
            "description": "Session label"
          },
          "per_head": {
            "type": "number",
            "description": "Cost per attendee for this session"
          },
          "attendees": {
            "type": "integer",
            "description": "Number of attendees"
          }
        }
      },
      "description": "Per-session cost breakdown"
    },
    "transfers": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "from",
          "to",
          "amount"
        ],
        "properties": {
          "to": {
            "type": "string",
            "description": "Player who receives"
          },
          "from": {
            "type": "string",
            "description": "Player who pays"
          },
          "amount": {
            "type": "number",
            "description": "Amount to transfer, rounded to cents"
          }
        }
      },
      "description": "Fewest payments that settle everyone"
    },
    "total_cost": {
      "type": "number",
      "description": "Sum of all session costs"
    },
    "session_count": {
      "type": "integer",
      "description": "Number of sessions processed"
    }
  }
}
split_series annotations
{
  "title": "Split series",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
rotation_plan — Rotation plan
Advertised by the server during the last successful anonymous check.
Advertised read-only

Plan fair player rotations for pickup games: who plays on each court every round and who sits out, balancing games played across the roster. Use when more players show up than court spots. Does not split money; for costs use split_costs or split_series.

rotation_plan input schema
{
  "type": "object",
  "required": [
    "players",
    "capacity",
    "rounds"
  ],
  "properties": {
    "courts": {
      "type": "integer",
      "minimum": 1,
      "description": "Number of courts in use at once (default 1)"
    },
    "rounds": {
      "type": "integer",
      "maximum": 50,
      "minimum": 1,
      "description": "Number of rounds to schedule, 1-50"
    },
    "players": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 2,
      "description": "Unique roster names, at least capacity x courts of them, e.g. [\"Asha\",\"Dev\",\"Mira\",\"Sam\",\"Lee\",\"Kai\"]"
    },
    "capacity": {
      "type": "integer",
      "minimum": 1,
      "description": "Players per court: 2 for singles, 4 for doubles, 10 for 5v5 basketball"
    }
  }
}
rotation_plan output schema
{
  "type": "object",
  "required": [
    "format",
    "rounds",
    "fairness",
    "schedule",
    "note"
  ],
  "properties": {
    "note": {
      "type": "string",
      "description": "Whether the rotation is perfectly balanced"
    },
    "format": {
      "type": "string",
      "description": "Format label with players per side and courts, e.g. '2v2 on 2 court(s)' for capacity 4 (doubles), '1v1' for capacity 2; odd capacity shows 'N player(s) per court'"
    },
    "rounds": {
      "type": "integer",
      "description": "Number of rounds scheduled"
    },
    "fairness": {
      "type": "object",
      "required": [
        "min_games",
        "max_games",
        "spread"
      ],
      "properties": {
        "spread": {
          "type": "integer",
          "description": "max_games minus min_games"
        },
        "max_games": {
          "type": "integer",
          "description": "Most games any player gets"
        },
        "min_games": {
          "type": "integer",
          "description": "Fewest games any player gets"
        }
      },
      "description": "Games-played balance across the roster"
    },
    "schedule": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "round",
          "courts",
          "sitting"
        ],
        "properties": {
          "round": {
            "type": "integer",
            "description": "Round number starting at 1"
          },
          "courts": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Players on each court this round"
          },
          "sitting": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Players sitting out this round"
          }
        }
      },
      "description": "One entry per round"
    }
  }
}
rotation_plan annotations
{
  "title": "Rotation plan",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

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
209 ms
95th percentile latency
209 ms

Maintenance history

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

  • · probe · passed · 209 ms · metadata changed · 4 tool(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 courtsplit-mcp https://court-split.magicteams.ai/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 courtsplit-mcp --url https://court-split.magicteams.ai/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable courtsplit-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "courtsplit-mcp": {
      "url": "https://court-split.magicteams.ai/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "courtsplit-mcp": {
      "type": "streamableHttp",
      "url": "https://court-split.magicteams.ai/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start courtsplit-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "courtsplit-mcp": {
      "type": "http",
      "url": "https://court-split.magicteams.ai/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 courtsplit-mcp https://court-split.magicteams.ai/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://court-split.magicteams.ai/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": {
    "courtsplit-mcp": {
      "serverUrl": "https://court-split.magicteams.ai/mcp"
    }
  }
}

Let your agent find its tools

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