Skip to main content
Glama

liquipedia-mcp

A small, careful Python client and MCP server for the Liquipedia LPDB v3 API: match results (with every single game), upcoming matches, matches in a time range, and league/group/Swiss standings.

  • Core library (liquipedia_mcp.client, .matches, .standings, .format) usable without MCP. It returns structured dataclasses, so you can format answers yourself (in any language).

  • MCP server (liquipedia-mcp) that exposes the core as five read-only tools, returning English text for the model plus the structured data.

  • Built to respect Liquipedia: a hard 60 requests/hour budget, caching, no automatic retries, a mandatory identifying User-Agent and attribution on every result. See Respecting Liquipedia.

Bring your own key. This project is meant to be self-hosted by each user with their own LPDB API key. There is no public instance, and you must not run one with your key (see below).

Verified wikis: rocketleague and leagueoflegends. Other LPDB wikis (e.g. dota2, counterstrike) are accepted, but the data pitfalls described below were only verified for those two.

Installation

Requires Python 3.11+. The package is not on PyPI; install it from this repository:

pip install "git+https://github.com/LionScherer/liquipedia-mcp"
# or run it without installing:
uvx --from "git+https://github.com/LionScherer/liquipedia-mcp" liquipedia-mcp --help

For development:

git clone https://github.com/LionScherer/liquipedia-mcp && cd liquipedia-mcp
pip install -e ".[dev]"
pytest && ruff check .

The tests use recorded/reconstructed API answers in tests/fixtures and never touch the network, so they need no API key.

Related MCP server: liquipedia-dota2-mcp

Get your own API key

  1. Read Liquipedia's API terms and request access at https://liquipedia.net/api. The free plan is for public, open-source projects that serve the esports community.

  2. Keep the key secret. It belongs in an environment variable or a git-ignored .env file, never in code or in a repository.

Configuration

Variable

Required

Meaning

LIQUIPEDIA_API_KEY

yes

Your LPDB API key. Sent only in the Authorization header; never logged.

LIQUIPEDIA_USER_AGENT

yes

Identifies your project and how to reach you, e.g. "<your-project>/<version> (<contact>)" → "esports-helper/1.2 (https://github.com/you/esports-helper; you@example.org)".

LIQUIPEDIA_MAX_REQUESTS_PER_HOUR

no

Lower the per-process budget (1–60, default 60). Values above 60 are refused.

LIQUIPEDIA_LOCKOUT_SECONDS

no

Pause after an HTTP 429 (default 600, minimum 60).

The server refuses to start when the key is missing or when the User-Agent is empty, still the placeholder, a generic library default (python-httpx/…, curl/…, …) or has no contact (e-mail address or URL). liquipedia-mcp/<version> is appended automatically.

See .env.example.

Use with an MCP client

Claude Desktop (or any client using the mcpServers format)

{
  "mcpServers": {
    "liquipedia": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/LionScherer/liquipedia-mcp", "liquipedia-mcp"],
      "env": {
        "LIQUIPEDIA_API_KEY": "your-key",
        "LIQUIPEDIA_USER_AGENT": "my-assistant/1.0 (https://github.com/you/my-assistant)"
      }
    }
  }
}

Streamable HTTP (local only)

liquipedia-mcp --transport streamable-http --host 127.0.0.1 --port 8000
# MCP endpoint: http://127.0.0.1:8000/mcp

The default bind address is 127.0.0.1. Binding to any other address is refused unless you pass --allow-remote.

⚠️ Never expose this server to the internet. Every tool call is paid for with your API key. A public endpoint lets strangers use your key, which violates Liquipedia's terms and can get the key revoked. If you need remote access, keep it inside your own private network or behind authentication you control.

Tools

Tool

What it does

Requests

get_results(wiki, team?, tournament?, max_tier=1, include_minor_types=false, limit=5)

Finished matches, newest first, with series score, winner by name, every game score (incl. overtime). Champion picks + MVP for ≤ 3 LoL matches.

1

get_upcoming(wiki, team?, tournament?, max_tier=1, include_minor_types=false, limit=10)

Scheduled matches from now on, soonest first. TBD pairings are left out.

1

get_matches_between(wikis, start_utc, end_utc, max_tier=1, include_minor_types=false, team?)

Everything in a time range (≤ 31 days), several wikis in one request. Up to 50 matches with a known time, plus day-only matches (see below).

1

get_standings(wiki, team? | tournament?)

Current table of a team (finds the phase itself) or all groups of a tournament (exact name).

2–3

get_match_details(wiki, team, opponent?, limit=1)

Every game of the team's latest match(es): scores, OT, length, kills, maps, MVP, champions.

1

Tier filters (1=S, 2=A, 3=B, 4=C, 5=D) only apply to general queries; with a team or tournament, all tiers are included. A tier filter keeps exactly tiers 1..max_tier: unranked events (liquipediatier -1) never pass, and minor tier types (Qualifier, Showmatch, Misc, Monthly, Weekly, Biweekly, Daily, Charity) are left out unless include_minor_types=true. Regular tournaments have an empty tier type and always stay in.

Matches whose time is not announced yet (dateexact=0) only carry a day; the 00:00 in their date is a placeholder (the structured result has date_exact=false and day). get_matches_between treats them as whole UTC days: they are included only if their day lies completely inside the range, or the range lies completely inside that day. A range like 13:35 to 01:35 the next day therefore leaves the second day's day-only matches out and says how many were skipped. Exact and day-only matches are limited separately, so day-only matches cannot push exact ones out; a cut-off list says "… and N more". In the text, more than five unplayed day-only matches of one tournament stage and day become one line ("FIFAe World Cup 2026 – Group A: 16 matches on 2026-10-20, times not announced yet"); the structured data still lists every match. Tool descriptions tell the model to read each match line on its own, never invent totals, never present unplayed matches as 0–0, and to cite Liquipedia.

Use as a library

import asyncio
from liquipedia_mcp import LiquipediaClient
from liquipedia_mcp.matches import get_results
from liquipedia_mcp.standings import get_standings


async def main():
    async with LiquipediaClient.from_env() as client:  # one client per process
        results = await get_results(client, "rocketleague", team="Team Falcons", limit=3)
        for m in results.matches:
            print(
                m.date,
                m.score_line,
                "winner:",
                m.winner_name,
                [(g.score1, g.score2, g.overtime) for g in m.games],
            )
        print(results.source.text)  # keep the attribution!

        table = await get_standings(client, "leagueoflegends", team="T1")
        print(table.to_dict())


asyncio.run(main())

All results are dataclasses with to_dict() (JSON-ready). Highlights:

  • Match.winner_name is computed explicitly (from the scores, or LPDB's winner for forfeits). Pass names, not indices, to language models: index-based winners were reproducibly attributed to the wrong team.

  • Opponent.score is None for unplayed matches (LPDB stores -1 placeholders).

  • StandingsGroup.started is False before the first match; placements are then cleared and leader is None.

  • liquipedia_mcp.format contains the English formatter used by the server.

You can inject your own HTTP function (LiquipediaClient(..., fetch=my_fetch)), which is how the tests run without a network.

Respecting Liquipedia

Liquipedia is run by volunteers and Team Liquid, and the API is a shared resource. This package is deliberately conservative:

  • Request budget. At most 60 requests per hour per process (sliding window), as allowed by the API terms. You can lower it, not raise it. When it is used up, the call fails with a clear error instead of sending a request. Cached answers keep working. If you run several processes with the same key, lower the budget so their sum stays within the limit.

  • No automatic retries. Errors are reported, never retried in a loop. After an HTTP 429, all requests pause for 10 minutes (configurable, or longer if the server sends Retry-After).

  • Caching. Successful answers are cached for 5 minutes (time-range queries 10 minutes); errors are cached for 1 minute so that polling clients cannot hammer the API. The cache is size-bounded and in memory.

  • Few, precise requests. One request per match query (multiple wikis are combined with |), field projection via query=…, standings in 2–3 requests.

  • Identification. A User-Agent naming your project and contact is mandatory, plus liquipedia-mcp/<version>. Responses are requested gzip-compressed.

  • No background traffic. There are no health checks, warm-ups or polling loops; requests only happen when a tool is called.

  • Safe queries. Team and tournament names are validated before they are placed in LPDB conditions: [, ], {, }, |, ::, leading operators (!, <, >, ~) and stand-alone AND/OR are rejected; wiki names must match ^[a-z0-9]+$; limits are clamped.

  • Key hygiene. The key is read from the environment only, is never logged and never appears in repr() or error messages. .env is git-ignored.

  • Attribution. Every result carries Source: Liquipedia (liquipedia.net), CC-BY-SA 3.0 both in the text and as a structured source field.

Your obligations as a downstream user

Data from Liquipedia is licensed under CC-BY-SA 3.0. If you show or publish it (in a chat answer, a bot message, a website…), credit Liquipedia and keep the license notice; derived data must stay under the same license. Do not strip the source field when you re-format results. Follow Liquipedia's API terms for your own key.

Data pitfalls handled

Discovered against real LPDB answers (Rocket League and League of Legends, July–September 2026):

  • order=date DESC without [[finished::1]] returns the matches furthest in the future first, so results, upcoming matches and time ranges are separate queries.

  • winner is a string ("1", "2", ""), finished an integer. Unplayed scores are -1; undetermined opponents have empty names. Neither is ever shown as a result.

  • Round names come from match2bracketdata.header; wiki shorthands like !l4!x are dropped instead of guessed (the section, e.g. "Playoffs", remains).

  • Player names like Diaz_(Brazilian_Player) are cleaned to Diaz.

  • Single games marked notplayed/np or without two valid scores are skipped.

  • Standings store one row per team per round, unsorted; only the latest round counts. Tables exist before the first match with placements 1..n; those are reported as "not started". Only definitestatus is used (currentstatus is "down" for everyone before the start). Bo1 Swiss stages keep game records at 0–0; then only match records are shown.

  • For team standings, the current phase is the played one with the latest end date, not the highest page id (which picked a January cup over a September league).

Example output

From the test fixtures (reconstructed API answers), as the MCP server returns it:

Latest results – Rocket League (S-Tier only), newest first:
1. 2026-09-14 18:30 UTC | RLCS 2026 - World Championship | Playoffs, Grand Final | Bo7
   Result: Team Falcons 4–1 Karmine Corp. Winner: Team Falcons.
   Games (Team Falcons–Karmine Corp): G1 1–0 (OT, DFH Stadium, 6:21), G2 2–1 (Mannfield), G3 0–3 (Champions Field), G4 1–0 (OT, Utopia Coliseum), G5 3–2 (Urban Central)
2. 2026-09-14 15:00 UTC | RLCS 2026 - World Championship | Playoffs | Bo7
   Result: Karmine Corp 4–0 Gentle Mates. Winner: Karmine Corp.
   Games (Karmine Corp–Gentle Mates): G1 1–0 (DFH Stadium), G2 1–0 (OT, Mannfield), G3 1–0 (Neo Tokyo), G4 1–0 (Forbidden Temple)
Source: Liquipedia (liquipedia.net), CC-BY-SA 3.0
Upcoming matches – Rocket League (S-Tier only), in chronological order:
1. 2026-10-24 14:00 UTC | RLCS 2027 - Paris Open | Swiss Stage, Round 1 | Bo5
   Team Falcons vs Karmine Corp – not played yet
2. 2026-10-25 (time TBA) | RLCS 2027 - Paris Open | Swiss Stage | Bo5
   NRG vs Gentle Mates – not played yet
(1 match(es) with opponents not determined yet were left out.)
Source: Liquipedia (liquipedia.net), CC-BY-SA 3.0
Standings – T1 (League of Legends)

LCK 2026 – Rounds 3-5 – Legend Group
1. Gen.G – matches 12–1 – games 25–6 – advanced
2. T1 – matches 10–3 – games 20–3 – advanced  (queried team)
3. Hanwha Life Esports – matches 8–5 – games 17–12 – advanced
4. Dplus KIA – matches 4–9 – games 10–19
5. KT Rolster – matches 1–12 – games 4–24 – eliminated
(Records are W–L.)
Leader: Gen.G
This stage is finished.

Next up for T1 (not started): 2026 World Championship – Swiss Stage

Source: Liquipedia (liquipedia.net), CC-BY-SA 3.0

License

  • Code: MIT, see LICENSE. © 2026 Lion Scherer.

  • Data retrieved through this software: © Liquipedia contributors, CC-BY-SA 3.0. The MIT license of the code does not apply to the data.

This project is not affiliated with or endorsed by Liquipedia or Team Liquid.

Available Tools

5 tools
get_match_detailsMatch detailsA
Read-onlyIdempotent

Every game of a team's most recent finished match(es): game scores, overtime, game length, kills and maps where available, MVPs and League of Legends champion picks per player. Optionally only matches against a given opponent. Use this for follow-up questions like 'was it close?' or 'who played which champion?'. Cite Liquipedia as the source.

ParametersJSON Schema
NameRequiredDescriptionDefault
teamYesExact team name as on Liquipedia.
wikiYesLiquipedia wiki id, e.g. 'rocketleague' or 'leagueoflegends'.
limitNoNumber of matches (1-3).
opponentNoExact team name as on Liquipedia, e.g. 'Team Falcons', 'T1'.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds useful behavioral context: scope is limited to 'most recent finished' matches, the opponent filter is optional, and it instructs citing Liquipedia. It omits anything on limits beyond the schema's max of 3 or the return shape, so a 3 is fair.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Content is front-loaded: what is returned comes first, the opponent option next, usage cues and the citation note last. Three sentences, each carrying information, with no filler. Slightly dense enumeration of fields, but nothing that should be cut.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must convey return contents, and it does so thoroughly (scores, overtime, length, kills, maps, MVPs, champion picks). Combined with annotations covering the read-only profile, an agent has enough to call it correctly; only a brief note on the 1-3 match limit would fully close the gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters (team, wiki, limit, opponent) are already documented in the schema. The description reinforces the optional-opponent filtering intent but adds no syntax or format detail beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific resource and the exact granularity returned: game-level details (scores, overtime, length, kills, maps, MVPs, champion picks) for a team's most recent finished matches. This clearly distinguishes it from outcome-level siblings like get_results and get_matches_between by content depth. It stops short of naming those siblings explicitly, so it falls just under a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete usage context via example follow-up questions ('was it close?', 'who played which champion?') and notes the optional opponent filter, which helps an agent decide when to reach for this over summary tools. There is no explicit when-not guidance or named alternative, so it is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_matches_betweenMatches in a time rangeA
Read-onlyIdempotent

All matches between two UTC timestamps (max. 31 days), in chronological order, for one or more wikis in a single request – e.g. 'what's on this weekend' or 'what happened yesterday'. Finished matches show score and winner; the others are marked 'not played yet' and have no score. Without a team only top-tier matches (max_tier, no qualifiers/showmatches unless include_minor_types) are returned. Matches whose time is not announced count as whole days: they are included only if their UTC day lies fully inside the range (or the range inside that day), and many of them are summarised per tournament stage. Up to 50 matches with a known time are listed; the text says when the list was cut off. Cite Liquipedia as the source.

ParametersJSON Schema
NameRequiredDescriptionDefault
teamNoExact team name as on Liquipedia, e.g. 'Team Falcons', 'T1'.
wikisYesOne or more wiki ids separated by '|' or ',', e.g. 'rocketleague|leagueoflegends'.
end_utcYesISO 8601 end, e.g. 2026-10-26T00:00Z.
max_tierNoOnly used without team/tournament: include tiers 1..max_tier (1=S only, 2=S+A, ...). Default 1. Unranked events are never included.
start_utcYesISO 8601 start, e.g. 2026-10-24T00:00Z.
include_minor_typesNoOnly used with the tier filter: also include qualifiers, showmatches and weekly/monthly/misc events. Default false.

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnly/openWorld/idempotent annotations: it discloses the finished-vs-'not played yet' return semantics, top-tier filtering and how include_minor_types changes it, the whole-day handling for unannounced times, the 50-match cap with a cutoff notice, and the citation requirement. This is unusually rich behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose (time range, wikis, count) before moving to filtering and edge-case rules, so the most important information comes first. The later sentences are dense and somewhat run-on, but each carries distinct, non-redundant rules.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by describing return shape (score/winner for finished, 'not played yet' otherwise, per-stage summaries, 50-match cutoff notice). Combined with its handling of the 31-day and unannounced-time constraints, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds interaction meaning the schema lacks: it explains that max_tier and include_minor_types only take effect 'without a team' and how the tier filter interacts with minor event types. It stops short of covering wikis/team syntax beyond what the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('all matches between two UTC timestamps ... for one or more wikis') and adds scope constraints (max 31 days, chronological order). It clearly reads as a time-range list tool, but it never names its closest siblings (get_upcoming, get_results) to sharply delimit itself from them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete usage framing ('what's on this weekend', 'what happened yesterday') and states the default filtering behavior when no team is supplied, which helps an agent decide when this tool fits. However, it offers no explicit when-to-use-this-vs-alternative guidance against get_upcoming or get_results.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_resultsLatest match resultsA
Read-onlyIdempotent

Finished matches, newest first, with the series score, the winner by name and the score of every single game (e.g. 3–2 OT), so you can tell close series from one-sided ones. Filter by team and/or exact tournament name; without either, only top-tier matches (max_tier, no qualifiers/showmatches unless include_minor_types) are returned. With 3 matches or fewer, League of Legends champion picks and MVPs are included. Read each line on its own and do not invent totals. Cite Liquipedia as the source.

ParametersJSON Schema
NameRequiredDescriptionDefault
teamNoExact team name as on Liquipedia, e.g. 'Team Falcons', 'T1'.
wikiYesLiquipedia wiki id, e.g. 'rocketleague' or 'leagueoflegends'.
limitNoNumber of matches.
max_tierNoOnly used without team/tournament: include tiers 1..max_tier (1=S only, 2=S+A, ...). Default 1. Unranked events are never included.
tournamentNoExact tournament name as on Liquipedia (no fuzzy matching).
include_minor_typesNoOnly used with the tier filter: also include qualifiers, showmatches and weekly/monthly/misc events. Default false.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnly, idempotent, openWorld), and the description goes well beyond them: it discloses the default top-tier-only filtering, the conditional enrichment of champion picks and MVPs when 3 or fewer matches return, and two output-handling rules (read each line independently, do not invent totals). That is rich behavioral context for a read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Content is front-loaded: what returns first, then filter behavior, then the conditional detail, then output rules. Six sentences is on the long side but each carries distinct information; the closing citation/anti-totals instructions are publisher requirements rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-format burden and does so: line-by-line results, series score, winner, per-game scores, plus the low-count enrichment case. Filters, defaults, and the required wiki argument are all covered, so an agent has everything needed to call and interpret it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value the schema fields do not: it explains the interaction rules — that max_tier and include_minor_types are inert unless no team/tournament filter is supplied, and that team and tournament combine as an AND/OR filter set rather than independent switches.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('finished matches') and immediately enumerates the payload: series score, winner by name, and every game's score. This content profile distinguishes it from get_upcoming (future matches) and get_match_details (single-match depth) without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operating context: filter by team and/or exact tournament name, and without either filter only top-tier matches return. It does not name when to prefer get_match_details or get_matches_between instead, so an agent must infer the boundary from the payload description rather than being routed explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_standingsStandingsA
Read-onlyIdempotent

League, group or Swiss standings. Preferred: pass the team – this finds the phase the team is currently playing in (works when you only know 'Worlds' or 'LCK') and names its next phase if one is scheduled. Alternatively pass the exact tournament name to get all groups of its newest stage. Each row: placement, team, match record, game record (when meaningful), advanced/eliminated if decided. If a table is 'Not started yet', there is no leader. Cite Liquipedia as the source.

ParametersJSON Schema
NameRequiredDescriptionDefault
teamNoExact team name as on Liquipedia, e.g. 'Team Falcons', 'T1'.
wikiYesLiquipedia wiki id, e.g. 'rocketleague' or 'leagueoflegends'.
tournamentNoExact tournament name as on Liquipedia (no fuzzy matching).

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnly, idempotent, openWorld), but the description adds real behavioral context: team lookups resolve the current phase and name a scheduled next phase, tournament lookups return all groups of the newest stage, and a 'Not started yet' table has no leader. The row-level contents are also disclosed. Remaining gap is any note on result size or ambiguity when multiple phases match.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The preferred path is front-loaded in the first sentence after the resource statement, and each following sentence adds distinct information (alternate mode, row fields, edge case, citation). It is dense but has no filler; only slightly long.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does so: it enumerates row fields and handles the degenerate 'Not started yet' case, plus both input modes. An agent has everything needed to call and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, and the description earns above that by explaining the semantic relationship between team and tournament (two mutually alternative entry points) and the practical advantage of each, information the schema descriptions do not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the exact resource ('League, group or Swiss standings') and immediately explains the two retrieval modes, which maps cleanly onto the two optional parameters. It is clearly distinct from siblings like get_results and get_upcoming, though it opens with a noun phrase rather than an explicit verb.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states a preference ('Preferred: pass the team'), explains why that path is preferable (finds the phase the team is currently playing in, works when you only know 'Worlds' or 'LCK'), and gives the explicit alternative condition ('Alternatively pass the exact tournament name'). The when-to-use decision is fully specified.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_upcomingUpcoming matchesA
Read-onlyIdempotent

Scheduled matches from now on, soonest first (times in UTC; 'time TBA' when only the day is known). Filter by team and/or exact tournament; without either, only top-tier matches (max_tier, no qualifiers/showmatches unless include_minor_types). These matches have no result yet: never present them with a score. Pairings with undetermined (TBD) opponents are left out. Cite Liquipedia as the source.

ParametersJSON Schema
NameRequiredDescriptionDefault
teamNoExact team name as on Liquipedia, e.g. 'Team Falcons', 'T1'.
wikiYesLiquipedia wiki id, e.g. 'rocketleague' or 'leagueoflegends'.
limitNoNumber of matches.
max_tierNoOnly used without team/tournament: include tiers 1..max_tier (1=S only, 2=S+A, ...). Default 1. Unranked events are never included.
tournamentNoExact tournament name as on Liquipedia (no fuzzy matching).
include_minor_typesNoOnly used with the tier filter: also include qualifiers, showmatches and weekly/monthly/misc events. Default false.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, openWorld), and the description adds real output conventions: times in UTC, 'TBA' when only the day is known, exclusion of TBD pairings, and the attribution requirement. These are useful behaviors beyond structured fields, though return shape beyond date/time is not detailed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core scope and output order, then layered with filter behavior and caveats in a single dense paragraph. Every sentence carries information, though the tier/qualifier clause is slightly compressed and requires a second read.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-param, no-output-schema read tool, the description covers ordering, time format, filter defaults, score-handling, and TBD exclusion, which is everything an agent needs to call and interpret it correctly. Remaining details (list size) live in the schema's limit parameter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents team, tournament, max_tier, and include_minor_types fully, including the tier semantics and the 'only used without team/tournament' coupling. The description's parameter content largely restates that; it elaborates the default tier behavior but adds little the schema does not already provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ('Scheduled matches from now on, soonest first') and immediately separates itself from the results siblings by stating 'These matches have no result yet: never present them with a score.' An agent can tell it apart from get_results without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for when to apply filters ('Filter by team and/or exact tournament') and what the default behavior is without them ('only top-tier matches'). It stops short of explicitly naming alternatives (e.g. use get_results for finished games) or stating exclusions, so it is strong but not fully routing-aware.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 5 tool updatesv0.1.0
    • First observedget_match_details
    • First observedget_matches_between
    • First observedget_results
    • First observedget_standings
    • First observedget_upcoming

TDQS

A4.1/5.0

Scored across 5 tools

Disambiguation4/5

Most tools target distinct query patterns: get_results for finished matches by team/tournament, get_upcoming for future matches, get_standings for tables, get_matches_between for date ranges, and get_match_details for deep per-game stats. However, get_results and get_matches_between both return finished match scores, and get_results sometimes includes champion picks/MVPs that get_match_details specializes in, creating mild overlap.

Naming Consistency5/5

All tools use a consistent get_ prefix with snake_case noun phrases (get_results, get_standings, get_upcoming, get_matches_between, get_match_details). The pattern is predictable with no mixed conventions.

Tool Count5/5

Five tools is well-scoped for a match-data server, covering results, standings, upcoming fixtures, date-range queries, and detailed game stats without redundancy or bloat.

Completeness4/5

The set covers core match lifecycle needs: finished results, upcoming fixtures, standings, time-range queries, and detailed game breakdowns. Minor gaps remain, such as direct tournament/team/player lookup or roster information, but agents can work around most common esports queries.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Provides MCP tools to query Liquipedia esports data (matches, teams, players, tournaments, placements, standings) via the Liquipedia v3 API and MediaWiki action API.
    8
    6 npm
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Read-only MCP server for sourced Dota 2 tournament, team, player, schedule, and result data from Liquipedia, with revision-level metadata and caching.
    5
    2 npm
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables MCP clients to discover tournaments, inspect events, entrants, sets, standings, and streams for any game on start.gg using natural language.
    15
    42 npm
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Provides live football data from API-Football over HTTP, enabling queries for upcoming matches, recent results, current standings, injuries, live matches, and team search through MCP tools.
    -