Skip to main content
Glama
liga-record-mcp

liga-record-mcp

Liga Record MCP

An MCP server I built to learn how the Model Context Protocol works, on a problem I actually have: managing my team in Liga Record, the fantasy football game of Record, a Portuguese sports newspaper. The design rests on one split: the rulebook is arithmetic, so it lives in Python as pure functions (legal formations, the €40M budget, automatic substitutions), while judgement, like who to start or who to sell, stays with Claude. Claude gets 27 tools, 3 prompts for the weekly routine and the regulation as a resource generated from the same constants the code enforces, and every read carries an as_of timestamp so Claude can tell stored data from live data. The server is read-only on purpose: the site's buy and sell endpoints are known but not implemented, and a test checks it stays that way, so a transfer is always a human click. It later grew a points model, and a scheduled GitHub Action records its predictions before every round and scores them afterwards, so the model is only judged on calls made in advance.

Run it

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
.\.venv\Scripts\python.exe -m pytest -q

The editable install creates the liga-record-mcp launcher that .mcp.json points at, so Claude Code starts the server when you open this folder. That path is absolute, so edit it after cloning. The squad lives in data/squad.yaml (start from data/squad.example.yaml), and the loader checks it against the regulation on every read. Then ask something like "Is my current XI legal, and who comes on if Diogo Costa doesn't play?"

More on the design in docs/HOW-IT-WORKS.md.

Available Tools

9 tools
check_market_transferA

Check a real transfer: one squad player out, one market player in.

Both are player ids. Unlike check_transfer, the incoming player's price and position come from the live market rather than being described by hand — so the budget arithmetic uses their actual quote.

Inputs: in_id (required), out_id (required). Returns: object

check_transferA

Check one swap against §6.4 and §6.8.

The incoming player is described by hand because there is no market data yet — step 4 replaces these arguments with a lookup. window is one of in_season, closed (February) or reopened.

Inputs: out_id (required), in_club (required), in_name (required), in_value (required), +3 more. Returns: object

get_playerA

Find one squad player by id, or by name (partial and accent-insensitive).

Returns the match, or every candidate when the query is ambiguous — never a guess, since acting on the wrong player is worse than asking again.

Inputs: query (required). Returns: object

get_squadB

The 23 players under contract, with the money around them.

Carries as_of: say how fresh the data is rather than presenting a stored squad as live.

Inputs: no named parameters. Returns: object

project_priceB

What a player's quote does if they score round_points (§12.3-§12.4).

Scores of 1, 2 or 3 are not covered by the regulation and are treated as no movement — say so if it matters to the answer.

Inputs: player_id (required), round_points (required). Returns: object

search_marketA

Search the whole Liga Record player market, not just the squad.

position is required — one of GK, DEF, MID, FWD. The site's endpoint returns nothing without one.

max_owned_percent finds differentials: players few other teams hold. A high-scoring player owned by 40% of the league gains you nothing on the field; the same player owned by 3% is where places are won.

This one reads the live site, so it is the only tool here whose answer can change without anyone editing a file. Results are cached for 15 minutes — quotes only move when a round is scored.

Inputs: position (required), club, name, limit, +3 more. Returns: object

search_squadA

Filter the squad. position is one of GK, DEF, MID, FWD.

This searches the 23 players already owned, not the transfer market — the market needs the live source that step 4 adds.

Inputs: club, position, max_value, min_points. Returns: object

simulate_autosubsA

Apply the §11 automatic substitutions to a team sheet.

unavailable is the starters who did not play, or whose match was abandoned or postponed after the round closed. Substitutes come on in bench order, same position only, three at most, and a replaced captain passes the armband on.

Inputs: bench (required), starters (required), unavailable (required), captain. Returns: object

validate_selectionA

Check a team sheet against §6.13, §6.17 and §10.3(l).

Bench order matters — the first substitute listed is the first to come on. This is authoritative: trust it over your own count of the formation.

Inputs: bench (required), starters (required), captain, coach_id. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 9 tools

    Disambiguation5/5

    Each tool has a clear and distinct purpose. check_transfer vs check_market_transfer and search_squad vs search_market are differentiated by their descriptions, preventing confusion. The others (get, validate, simulate, project) are uniquely scoped.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern (check_transfer, get_squad, search_market, etc.), using lowercase with underscores. No mixed conventions or inconsistent verb usage.

    Tool Count5/5

    Nine tools cover the core operations of a fantasy football assistant without redundancy. Each tool serves a distinct function, and the count is neither too sparse nor overwhelming for the domain.

    Completeness4/5

    The toolset covers reads, searches, validation, simulation, and pricing projections, but lacks an explicit 'execute transfer' or 'update squad' action. However, given the assistant's advisory role, this is a minor gap that doesn't hinder typical workflows.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      A Model Context Protocol server that provides access to Fantasy Premier League data, allowing users to compare players, find team information, view gameweek data, and get FPL-related advice through Claude for Desktop and other MCP-compatible clients.
      23
      67 PyPI
      80
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables Claude to interact with Sleeper fantasy football leagues via MCP tools for roster, waiver, matchup, and transaction queries, plus a dashboard for daily reports, live scoring, and game-day alerts.
      79 npm
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      MCP server that gives Claude live access to Major League Soccer data — teams, matches, standings, rosters, and schedule-strength analytics — via the ESPN public API.
      11
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that equips AI assistants with 33 tools for Fantasy Premier League analytics, including fixtures, squad management, live scores, transfers, captaincy, and price movements, using async access to official FPL endpoints with TTL caching.
      3
      MIT