MCP server over a local En Croissant installation, for chess opening prep
croissant-mcp demonstrates solid tool design with clear naming, comprehensive descriptions, and well-structured schemas. All 8 tools follow verb_noun conventions (list_, read_, add_, get_, search_, position_, reference). Descriptions are detailed (100-300 chars typical), explaining WHAT, WHEN, and prerequisites. Input schemas use proper JSON Schema with types and descriptions for all parameters. Output schemas are documented via Pydantic BaseModel classes (DatabaseSummary, RepertoireDetail, TrainingStatus, PositionStatus). However, several parameters lack enum constraints where appropriate (e.g., 'colour' accepts free-form strings instead of enum ['white','black']; 'result' accepts free-form instead of enum ['win','loss','draw']; 'source' in reference tool lacks enum). Error handling is minimal, no recovery guidance or actionable error messages visible in tool definitions. No tool annotations (readOnlyHint/destructiveHint) despite clear risk levels documented in metadata.
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.
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.
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.
List the En Croissant repertoire files and which colour each trains.
The user's W/D/L from a position, plus the games it came from.
Enum constraints missing for filter parameters. 'colour' in search_games and position_stats, 'result' in search_games, 'source' in reference, and 'status' in PositionStatus accept free-form strings instead of enums. LLMs will hallucinate invalid values like 'red' or 'pending' instead of constrained options.
No error handling guidance in tool definitions. Tools lack recovery hints (e.g., 'If repertoire not found, call list_repertoires() first'). No actionable error messages visible, LLMs cannot self-correct on failures.
Tool annotations missing. Despite clear risk levels (READ_ONLY vs WRITE), no readOnlyHint or destructiveHint annotations present. LLMs cannot distinguish safe from risky operations without explicit hints.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | 2026-07-28+ | v2 |
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.
What gets played from a position, by masters or a filtered pool.
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.
Parameter format constraints not documented. 'since' and 'until' in search_games state 'YYYY.MM.DD format' in description but lack regex pattern or formal constraint. 'fen' in position_stats and reference lack FEN validation hints. LLMs may pass malformed values.
Output pagination not implemented. search_games and reference tools may return large result sets without limit/offset parameters or total count. Large responses risk context window exhaustion.