croissant-mcp
Fetches recent games from the Lichess API and integrates with local En Croissant database files to provide opening preparation and review capabilities.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@croissant-mcpWhat am I due to review today, and what do opponents actually play there?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
croissant-mcp
An MCP server that gives Claude programmatic access to a local En Croissant installation, so opening prep can be driven from a conversation instead of by hand in the GUI.
Quickstart
Requires Python 3.13+, uv, and a local En Croissant install (developed against 0.15.0).
git clone https://github.com/cheungbrenden/croissant-mcp
cd croissant-mcp
uv syncRegister the server once, user-level, so it's available in any session:
claude mcp add --scope user croissant-mcp -- uv run --directory /path/to/croissant-mcp croissant-mcpThen ask for prep in a conversation:
What am I due to review today, and what do opponents actually play there?
Nothing else to configure — the Lichess handle is derived from the
<handle>_lichess.db3 filename and paths from the standard macOS locations.
USAGE.md has the full tool list, with honest status marks for what
is built and what isn't.
Related MCP server: Chess MCP
Why this exists
En Croissant is a Tauri desktop app. Its 64 backend commands are registered via
tauri_specta::collect_commands!() and reachable only over Tauri's IPC bridge —
there is no CLI, HTTP API, or headless mode. (tauri_plugin_cli is registered,
but its config declares a single positional file arg: that's file-association
handling, not a scripting interface.)
It doesn't need one. Everything the app persists is in open formats:
~/Library/Application Support/org.encroissant.app/
db/<name>.db3 SQLite — Games, Players, Events, Sites, Info
db/<name>.pgn the PGN the database was imported from
db/<name>.ecsi proprietary position index (magic bytes "ECSI", v4)
engines/stockfish/ the UCI engine binary
~/Documents/EnCroissant/*.pgn repertoire files
~/Library/WebKit/org.encroissant.app/.../LocalStorage/localstorage.sqlite3
FSRS training state, keyed deck-<repertoire path>-<n>,
values UTF-16. Not in the PGN.So this project reads En Croissant's files, never its code. It is not a fork and has no upstream relationship.
Start with USAGE.md — what you can ask for and what's built yet. Design records (build order, test seams, domain vocabulary) live in docs/.
Developed against En Croissant 0.15.0. The app registers
tauri_plugin_updater and updates itself, and every format above is internal and
undocumented. Startup asserts the shapes we depend on so a format change fails
loudly instead of being misread.
The sidecar is not a live export. It's the file the database was imported
from, so the two can drift: the Lichess pair matches exactly (190/190), the
chess.com pair does not (3525 PGN events against a GameCount of 3521). Treat
equivalence as an invariant to check, never a property to rely on. Because of
this — and because a game played ten minutes ago isn't in it at all — recent
games come from the Lichess API and the sidecar is the bulk/offline fallback.
How repertoires and decks work
Read from En Croissant's own source rather than inferred by experiment.
Start header — [Start "[0,0,0]"] is a JSON array of child indices from the
tree root, written as JSON.stringify(game.start) and read as
JSON.parse(Start ?? "[]"). It marks where training begins, not where the file
begins: buildFromTree skips any node whose path is a prefix of start. The
Vienna file starts at [0,0,0], which is why its deck drills from move 3
(f4, e5, Nf3) and never asks for 1.e4 or 2.Nc3.
Deck key suffix — deck-${file}-${game}, where game is the index of the
game within the PGN file. -0 is the first game; a multi-game repertoire gets
one deck per game.
Cards are built eagerly, and adding lines is safe. On open, if the deck is
empty En Croissant builds cards for the whole tree. If the deck is non-empty it
calls syncDeck, which reconciles against the tree, reports added/removed
counts, and preserves existing cards and the review log. So writing new lines
into a repertoire and reopening it schedules the new positions without
disturbing existing scheduling. Logs are only wiped by the explicit Reset button.
A position's drilled answer is always its first child. buildFromTree uses
item.node.children[0].san and ignores the rest. Whatever move we write first at
a node is the move you'll be drilled on — variation order is semantic, not
cosmetic.
Cards are only created for positions where it's your turn (halfmove parity
against Orientation), leaf nodes are skipped, and positions are deduplicated by
full FEN with the first occurrence winning — so transpositions collapse to one
card.
Scope
Lichess only; chess.com is historical and opt-in. Blitz only by default, since that's the bulk of most players' game history.
Your own win rate is not a ranking signal anywhere. A typical two-year window holds only a few dozen blitz games per colour, which makes any per-position percentage noise. Ranking is on coverage instead: deterministic, and it needs no sample size.
What it deliberately does not do
Two things on disk are closed formats:
The move BLOB.
length(Moves)equalsPlyCountexactly — one byte per ply, an index into the generated legal moves for each position. Decoding it means reproducing En Croissant's move generator ordering byte-for-byte. Avoided entirely by reading the.pgnsidecar instead.The
.ecsiindex. Powers fast position search over large databases. No substitute here; brute-force PGN scanning covers the personal databases (130 KB and 7.6 MB) and the Lichess explorer API covers reference statistics.
Indexed search over a multi-gigabyte master database is the one capability this
project cannot reach. If that ever becomes a real need, it's a separate project
(extract the Rust search core from En Croissant as a [[bin]] target) — not a
requirement here.
What it does to your data
Read-only against
.db3. ThePawnHomecolumn and the.ecsiindex are derived; hand-written rows would desync them. To add games, write PGN and import through the GUI.Repertoire files under
~/Documents/EnCroissant/are the one place this project writes at all.
Development
uv sync
uv run pytestAvailable Tools
8 toolsadd_line_to_repertoireA
Merge a line of SAN moves (from the starting position) into a repertoire.
Joins branches that already exist instead of duplicating them, and never reorders existing variations — the first variation at a position is the answer the user gets drilled on, so reordering would change what they're tested on. New positions are scheduled automatically when the file is next opened; existing cards and review history are untouched.
En Croissant must be closed: it holds repertoire files open and would silently overwrite this change. The previous contents are backed up first.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| moves | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | File name without extension, e.g. 'Vienna Game'. |
| path | Yes | Absolute path. Never rename or move this file — En Croissant keys training state by absolute path, and a rename orphans the review history. |
| main_line | Yes | The main line in SAN. |
| move_count | Yes | Total moves recorded across all variations. |
| orientation | Yes | Which colour this repertoire trains: 'white' or 'black'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses side effects: it joins existing branches, never reorders variations (and explains why), schedules new positions automatically, leaves existing cards untouched, and backs up previous contents. It also warns about the app's silent overwrite risk, providing critical context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three dense paragraphs, each adding critical information: purpose, behavioral details, and prerequisites/backup. No wasted sentences; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, side effects, prerequisites, and data integrity guarantees. As a 2-parameter mutation tool with an output schema, it is sufficiently complete without needing to describe return values. The description details all important behavioral traits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description clarifies that 'moves' are SAN moves from the starting position, adding meaning beyond the schema's bare 'array of strings'. However, 'name' is not explained (presumably the repertoire name), leaving that parameter ambiguous. With 0% schema coverage, description only partially compensates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence clearly states the verb ('Merge') and resource ('a line of SAN moves from the starting position into a repertoire'). It also differentiates from sibling tools by specifying the join behavior, making it the only write-oriented tool among lists/reads.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied rather than explicit. No alternative tools are mentioned or when-not-to-use guidance provided. The prerequisite ('En Croissant must be closed') is given, but the description does not directly say 'use this when you want to add a line' or contrast with other operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_training_statusA
Read the FSRS training state for a repertoire: what's due, what's never been seen, and what the file would schedule that isn't in the deck yet.
Read-only — never modifies training state. Safe while En Croissant runs, though a session in progress there may not have flushed to disk yet.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | Repertoire name. |
| unseen | Yes | Cards scheduled but never reviewed. |
| positions | Yes | Every position, one row each. |
| practiced | Yes | Cards reviewed at least once. |
| untrained | Yes | Expected cards the deck doesn't have yet. |
| reviews_logged | Yes | Total reviews in the log. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly: it declares read-only behavior, states that training state is never modified, and reveals a concurrency nuance (possible stale data if a session hasn't flushed). It also enumerates the output categories, giving a clear behavioral picture.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short paragraphs: the first states the purpose in a single sentence, the second adds critical safety and staleness context. Every sentence earns its place, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema is present, the description doesn't need to detail the return format. It adequately covers purpose, safety, concurrency, and output scope for a simple single-parameter read tool. No significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, and the description does not explicitly map the 'name' parameter to the repertoire name. However, the phrasing 'for a repertoire' strongly implies that the parameter is the repertoire name, adding some meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Read') and identifies the resource ('FSRS training state for a repertoire'), clearly distinguishing it from sibling tools like read_repertoire and list_repertoires. The scope is explicit and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context that this is read-only and safe to use while En Croissant runs, with a caveat about unflushed sessions. It does not explicitly name alternatives or say 'use this instead of read_repertoire', but the unique focus on training state makes the intended usage obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_databasesA
List the En Croissant game databases installed on this machine.
Reports each database's title, game count, size, and whether it has a .pgn sidecar. Read-only, and safe to call while En Croissant is running.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly states 'Read-only, and safe to call while En Croissant is running,' which is valuable transparency. It also outlines the output fields, giving a good sense of what to expect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded, using three short sentences to cover purpose, output contents, and safety. Every sentence adds value with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter list tool with an output schema, the description is complete. It identifies the resource, the type of information returned, and the safety profile, which is all an agent needs to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
This tool has zero parameters, so there are no parameter semantics to explain. The schema confirms this with 100% coverage, and the description adds meaningful details about what the output reports, making a baseline 4 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb and resource: 'List the En Croissant game databases installed on this machine.' It clearly establishes the tool's scope and distinguishes it from sibling tools that deal with repertoires, training status, or game searches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides useful context by stating the operation is read-only and safe to call while En Croissant is running. It does not explicitly mention alternatives or when not to use it, but with no sibling tool listing databases, the usage context is reasonably clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_repertoiresA
List the En Croissant repertoire files and which colour each trains.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the transparency burden. It states a listing operation, which implicitly indicates non-destructive read-only behavior, but it does not disclose additional behavioral traits such as authentication requirements, pagination, or whether it returns all repertoires. The presence of an output schema covers return structure, but the description itself adds limited context beyond the stated action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that front-loads the action ('List') and the resource ('En Croissant repertoire files'). Every word contributes to the meaning, and there is no redundant or extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (0 params), the presence of an output schema, and a clear one-sentence description that states both the action and the output content, the description is complete for an AI agent to select and invoke the tool. It adequately differentiates from sibling tools by mentioning 'En Croissant repertoire' specifically, which distinguishes it from generic list operations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters in the input schema, the baseline is 4. The description does not need to explain parameters since there are none, and the schema already covers the absence of inputs. No additional parameter meaning is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'List' and resource 'En Croissant repertoire files', and specifies what information is returned ('which colour each trains'). This clearly distinguishes it from siblings like list_databases and read_repertoire by narrowing the scope to repertoire files and their associated colours.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when one needs an overview of all repertoire files and their colours, but it does not explicitly mention alternative tools or contexts where this tool should be preferred. No exclusions or contrasts with sibling tools are provided, so guidance is only implied rather than clearly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
my_results_from_positionA
The user's W/D/L record from a position, across their rated blitz games.
Position matching ignores move counters and non-capturable en-passant squares, so transpositions count. Sample sizes here are small — report them, and never rank or conclude from the percentage alone.
| Name | Required | Description | Default |
|---|---|---|---|
| fen | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| wins | Yes | User wins from this position, their side. |
| draws | Yes | Draws. |
| games | Yes | The games that reached this position. |
| losses | Yes | User losses. |
| sample_size | Yes | wins+draws+losses. Quote this with any percentage — small samples are noise. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses meaningful behavioral details beyond the schema: position matching ignores move counters and non-capturable en-passant squares, so transpositions count, and sample sizes are small. With no annotations, this is valuable context. It does not discuss return format or side effects, but an output schema exists, reducing the need for that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences: one core purpose sentence followed by two caveats. It is front-loaded with the main function and contains no filler or redundancy. Excellent structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and an output schema, the description is quite complete: it covers data scope (rated blitz games), position matching behavior, and sample-size caveats. It does not discuss error conditions or alternatives, but these are not essential here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter (fen) has no schema description, and the tool description does not explicitly define FEN or provide an example. It only refers to 'position' and 'transpositions', which indirectly implies the param's meaning. With 0% schema coverage, the description should compensate more directly, so the score is moderate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns the user's W/D/L record from a position across rated blitz games. It specifies a particular resource (the record) and scope (position, blitz games), distinguishing it from siblings like list_repertoires or search_games.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool (querying the user's results from a position) and includes important interpretive guidance about small sample sizes. However, it does not explicitly name alternative tools or state 'when not to use', so it falls short of the most explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opponents_playA
What gets played from a position: by players at the user's own rating and speed (source='lichess', the default) or by masters (source='masters').
Defaults come from config so the pool matches the user's actual games — blitz around their rating band, not the site-wide average. Cached locally; a repeated query makes no network call.
| Name | Required | Description | Default |
|---|---|---|---|
| fen | Yes | ||
| source | No | lichess |
Output Schema
| Name | Required | Description |
|---|---|---|
| moves | Yes | Moves played from here, most common first. |
| source | Yes | 'masters' or 'lichess'. |
| speeds | Yes | Speed filter applied (lichess source only). |
| ratings | Yes | Rating band applied (lichess source only). |
| total_games | Yes | Games reaching this position in the selected pool. 0 means the position is simply rare there — not an error. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the transparency burden. It discloses two significant behaviors: 'Defaults come from config so the pool matches the user's actual games' and 'Cached locally; a repeated query makes no network call.' It does not explicitly state read-only behavior, but that is clearly implied. It could mention auth or rate limits, but for this simple query tool, the transparency is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately concise and front-loaded. The first sentence states the core purpose; the second explains the source variants. The second paragraph adds useful config/caching details without redundancy. No word is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple query tool with 2 parameters and an output schema, the description covers purpose, sources, defaults, and caching behavior. It does not explicitly compare to sibling tools or mention limitations/errors, but it is reasonably complete given the tool's simplicity and the presence of an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It fully explains the source parameter (lichess default vs masters) and the config-driven defaults. For fen, it only says 'from a position', which is minimal but somewhat informative. No FEN notation or examples are provided, so the description only partially compensates for the schema's lack of documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'What gets played from a position' and immediately distinguishes between two sources (lichess vs masters). This is a specific verb+resource+scope that differentiates it from sibling tools like my_results_from_position, which presumably focuses on the user's own results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on when to use the tool: to see what opponents play at the user's rating/speed or from masters. It explains the default source and config-based filtering, implying the intended use case. However, it does not explicitly name alternative tools or state when not to use this tool, which prevents a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_repertoireA
Read one repertoire's tree: its main line, orientation, and size.
At every position, the FIRST variation listed is the move En Croissant drills; later variations are recorded alternatives.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | File name without extension, e.g. 'Vienna Game'. |
| path | Yes | Absolute path. Never rename or move this file — En Croissant keys training state by absolute path, and a rename orphans the review history. |
| main_line | Yes | The main line in SAN. |
| move_count | Yes | Total moves recorded across all variations. |
| orientation | Yes | Which colour this repertoire trains: 'white' or 'black'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description takes on the burden of disclosing behavior. It adds a key behavioral trait: 'At every position, the FIRST variation listed is the move En Croissant drills; later variations are recorded alternatives.' This goes beyond the simple 'read' semantics and helps the agent understand the output ordering. It also lists what the tree contains (main line, orientation, size), providing valuable context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary purpose. The second sentence adds important behavioral detail without unnecessary expansion. Every word earns its place—no fluff, repetition, or ambiguity. This is a model of conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has one parameter, an output schema, and no annotations. The description covers the purpose and a key behavioral detail. The output schema likely explains return structure, so the description doesn't need to. It's reasonably complete for a read-only, single-parameter tool, though it could mention prerequisites like existence of the repertoire, but that's a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has only one parameter 'name' with no description. The tool description references 'one repertoire,' which implicitly clarifies that 'name' identifies the repertoire. Although it doesn't explicitly state this, for a single obvious parameter, the description compensates enough. The schema coverage is 0% by strict measure, but the parameter is simple and the context is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb and resource: 'Read one repertoire's tree: its main line, orientation, and size.' This distinguishes it from sibling tools like list_repertoires (which lists all repertoires) and add_line_to_repertoire (which modifies). The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when you need the tree of a specific repertoire, but it does not explicitly contrast with alternatives or provide exclusion criteria. For instance, it doesn't say 'use this instead of list_repertoires when you need details of one repertoire.' The context is clear but lacks explicit when-to-use guidance, so it earns an average score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_gamesA
Search the user's own rated Lichess games (blitz by default).
Filters are from the USER's side: colour is the colour they played, result is their result ('win', 'loss', 'draw'). Dates are 'YYYY.MM.DD'. Fetches live from the Lichess API, falling back to the local export.
| Name | Required | Description | Default |
|---|---|---|---|
| eco | No | ||
| since | No | ||
| until | No | ||
| colour | No | ||
| result | No | ||
| opponent | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| games | Yes | The matching games, newest first. |
| source | Yes | 'lichess-api' (live) or 'sidecar' (offline fallback). |
| sample_size | Yes | How many games matched. Always report this alongside any percentage — with ~30 blitz games per colour in a 2-year window, a bare percentage is misleading. |
| failed_to_parse | Yes | Games skipped as unreadable, never silently dropped. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the tool fetches live from the Lichess API with a fallback to local export, and notes the default blitz mode. However, it does not mention auth requirements, read-only status, or potential rate limits. The live-fetch disclosure is meaningful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences long, front-loaded with the core purpose, and every sentence provides necessary information: scope/default, filter semantics, and data source behavior. There is no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's scope, default behavior, filter semantics, date format, and data source. Since an output schema exists, return values need not be described. The main gaps are the lack of detail on 'opponent' and 'eco', but overall the description is quite complete for a search tool with 6 optional parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the semantics of colour, result, and date format for since/until, which are the most ambiguous. It does not explain eco or opponent, but these are relatively self-explanatory. Overall, it adds significant value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches the user's own rated Lichess games, with a specific verb ('Search') and resource ('user's own rated Lichess games'). It also mentions a default (blitz) which adds specificity and differentiates it from sibling tools that deal with databases and repertoires.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: it is for searching the user's own rated games, with an implicit filter scope from the user's perspective. It does not explicitly mention alternatives or when not to use this tool, but the context is strong enough to distinguish it from siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool targets a distinct resource or action: databases vs. repertoires vs. training state vs. game queries. Even the three position-related tools differ clearly: one searches games, one reports user results, one reports opponent moves.
Most tools follow a verb_noun pattern (list_databases, read_repertoire, add_line_to_repertoire, get_training_status, search_games). Two tools break the pattern with possessive noun phrases (my_results_from_position, opponents_play), which is a minor inconsistency.
Eight tools is well within the ideal 3–15 range for a focused chess training server. Each tool addresses a distinct part of the workflow without unnecessary bloat.
The set covers listing, reading, and adding repertoire lines, plus training status and position analysis—solid coverage for the core domain. Missing explicit update/delete operations for repertoire lines are workable gaps but not fatal for typical use.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Chess MCP for Claude: engine analysis, attack maps, game review. One URL, no install.
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- AlicenseCqualityCmaintenanceAn MCP server that enables natural language interaction with the Lichess chess platform, allowing users to play games, analyze positions, manage their account, and participate in tournaments through Claude.901517MIT
- AlicenseNot gradedqualityCmaintenanceA powerful chess engine and game server built with the Model Context Protocol (MCP). Play chess against AI, analyze positions, and integrate chess functionality into your AI applications.201ISC
- AlicenseAqualityBmaintenanceA hybrid AI chess coach MCP server that uses Stockfish for grounded evaluation and LLM for natural-language coaching, enabling game analysis, weakness diagnosis, and personalized drills from your own games.61MIT
- AlicenseAqualityCmaintenanceMCP server that exposes the Lichess public API through tools for querying player profiles, games, analysis, openings, puzzles, and tournaments, allowing natural-language chess questions without an API key.8MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cheungbrenden/croissant-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server