chess-arbiter
Allows a Hermes agent to connect as a chess player to the arbiter MCP server, using tools to join a game, view the board and legal moves, make moves, manage draws, and resign while the arbiter enforces turn order, legality, and clocks.
Click on "Deploy 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., "@chess-arbiterstart a game as white against claude with a 10+5 clock and the spectator GUI"
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.
llm-chess
Two autonomous LLM agents play chess against each other. Not a chess engine with an AI bolted on — an arbitrated MCP server that both agents connect to as players, plus a live spectator GUI.
Built to answer a specific question: can Hermes beat Claude at chess when neither of them gets to cheat, and neither of them can see the other's reasoning?
How it works
┌──────────────┐ MCP (stdio) ┌─────────────────────┐
│ Hermes │──────────────────────────▶│ │
│ (player) │◀──────────────────────────│ chess-arbiter │
└──────────────┘ │ ── the rules ── │
│ turn enforcement │
┌──────────────┐ MCP (stdio) │ legality checks │
│ Claude │──────────────────────────▶│ clocks │
│ (player) │◀──────────────────────────│ move log / PGN │
└──────────────┘ └──────────┬──────────┘
│
┌─────────▼─────────┐
│ live spectator │
│ GUI (WebSocket) │
└───────────────────┘The arbiter is the single source of truth. Turn order, colour binding, move legality and the clocks are enforced outside both models, so a player cannot move twice, move out of turn, play an illegal move, or desync the position. A rejected move leaves the board untouched and returns an error the agent can read and recover from.
Both agents connect to the same arbiter through MCP tools. They see only the position — never each other's reasoning — which makes this a real test of chess ability rather than a test of who can talk the other into a loss.
Related MCP server: Chess MCP
Requirements
macOS, Linux, or Windows (developed and tested on macOS)
Python 3.10+
uv(recommended) or plainpipTwo players:
Hermes —
hermesCLI, with this arbiter registered as an MCP serverClaude —
claudeCLI (Claude Code), with this arbiter registered as an MCP server
Install
git clone https://github.com/kmount44/llm-chess.git
cd llm-chess
./scripts/install-mac.shThe installer creates a virtualenv, installs the package, and prints the exact MCP registration commands for both agents.
Manual install:
uv venv .venv
uv pip install --python .venv/bin/python -e .Registering the arbiter with each player
Each player runs its own arbiter process with its own identity. Colour is read from the game record, so the same registration works for either side.
Hermes — add to ~/.hermes/config.yaml:
mcp_servers:
chess:
command: "/ABSOLUTE/PATH/llm-chess/.venv/bin/chess-arbiter"
args: ["--client", "hermes"]
timeout: 60Restart Hermes afterwards — MCP servers are discovered at startup.
Claude Code:
claude mcp add chess -- /ABSOLUTE/PATH/llm-chess/.venv/bin/chess-arbiter --client claudeVerify with claude mcp list and hermes mcp list.
Playing a game
# start the spectator GUI and a game, then let the agents play
chess-play --white hermes --black claude --guiOpen the URL it prints (default http://127.0.0.1:8787) to watch the game live: board, move list, clocks, captured material, and each agent's status and transcript as it thinks.
Useful flags:
--white {hermes,claude,scripted} which agent plays white
--black {hermes,claude,scripted} which agent plays black
--moves N stop after N plies (default: until the game ends)
--per-move-seconds N time budget per move before the agent forfeits the turn
--tc MINUTES+INCREMENT e.g. --tc 10+5. Omit for untimed play.
--script "e4 e5 ..." the SAN line a `scripted` player follows
--gui / --no-gui start the spectator server (default: on)
--port PORT spectator GUI port
--dry-run exercise the whole pipeline with scripted moves, no LLM calls--dry-run is the fastest way to confirm the wiring before spending tokens.
scripted is also usable as a real opponent without --dry-run, which is how
you smoke-test one live agent against a deterministic line:
chess-play --white hermes --black scripted --moves 6 --no-gui -vVerified
These are real runs, not claims:
A live Hermes agent played
e4,Nf3,Bc4through the MCP arbiter against a scripted opponent, with commentary, and carried one session across all three of its turns.Two MCP clients playing one board over real stdio, with a rejected illegal move leaving the position untouched.
The spectator page rendering a position square-for-square against its FEN, and receiving a move played by a separate process without a reload.
A two-process race for the same ply, where exactly one writer wins.
Suite | Covers |
| Rule enforcement: turn order, colour binding, legality, clocks, race safety |
| Real MCP over stdio: discovery, two clients, recoverable errors |
| Agent adapters, prompts, forfeit policy, artifacts, "agent lied about moving" |
| The spectator API against the arbiter's store |
| The page in a real browser (Playwright) |
Gotchas worth knowing
hermes mcp addis interactive. It prompts for tool selection and cancels on a non-TTY. Pipe the answer:printf 'y\n' | hermes mcp add chess ....LLM_CHESS_HOMEdoes not reach agent MCP servers. Hermes spawns MCP subprocesses with a filtered environment, so a custom store path must be re-declared on the MCP entry (hermes mcp add ... --env LLM_CHESS_HOME=...). The driver warns when it sees the mismatch.--max-turns,-Qand--yoloarehermes chatflags, not top-level ones. At the top level Hermes fails argument parsing before the agent runs.Hermes prints its session id on stderr. Capturing it there is what makes per-side memory work; missing it silently degrades a game to stateless play, and nothing looks broken because the moves still land.
Fairness properties
Every player gets the same tools:
Tool | Purpose |
| Handshake: your colour, your opponent, the current position |
| FEN, board diagram, side to move, check state, clocks, material, history |
| Every legal move in the position, as SAN and UCI |
| Play a move (SAN or UCI). Rejected moves change nothing. |
| SAN list so far |
| Turn, clocks, result, whether the game is over |
| Objective facts only — material and mobility, no engine score |
| Draw handling |
| Resign |
Data and artifacts
Everything lives under $LLM_CHESS_HOME (default ~/.llm-chess):
chess.db— the game store: positions, move log, clock state, event feedgames/<game_id>.pgn— PGN written when a game finishesgames/<game_id>.log— the full transcript of both agents, for post-mortems
Fairness properties
These are the guarantees the design actually enforces, and the tests that prove them:
Property | Enforced by |
A player can only move its own colour |
|
A player can only move on its turn |
|
Illegal moves are rejected with no state change |
|
A finished game accepts no further moves |
|
Clocks are server-side, not agent-reported |
|
Neither agent sees the other's context | separate MCP processes, position-only tool surface |
Development
uv pip install --python .venv/bin/python -e ".[dev]"
.venv/bin/python -m pytest -qThe suite is 70 tests across five layers, and the split is deliberate:
File | Covers |
| Rule enforcement — turn order, colour binding, legality, clocks, and a two-process race for the same ply |
| Real MCP over stdio: tool discovery, two clients playing one board, recoverable errors |
| Agent adapters (Hermes/Claude argv and output parsing), prompts, forfeit policy, artifacts, and an agent that reports success without moving |
| The spectator API against the arbiter's store |
| The page in a real browser (Playwright). Skips if playwright is absent. |
The browser tests earn their keep: they caught two bugs the API tests could not
see — the client rendering from a field the API never sent, and plain uvicorn
shipping no WebSocket transport, which 404'd every live connection at handshake.
.venv/bin/python -m pip install playwright
.venv/bin/python -m playwright install chromium # if not already cachedCredits
Chess piece artwork is the Cburnett SVG set (Wikimedia Commons / Lichess), licensed CC BY-SA 3.0.
Licence
MIT (code). See above for the piece artwork.
Available Tools
11 toolsaccept_drawB
Accept your opponent's outstanding draw offer.
| Name | Required | Description | Default |
|---|---|---|---|
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full behavioral burden. It implies a precondition (an outstanding opponent offer) but does not disclose the resulting state change, whether the action is irreversible, permission requirements, or error behavior if no offer exists.
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 front-loaded sentence with no wasted words. It is appropriately sized for the action being described.
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?
Output schema exists, so return values need not be explained. However, for a game-mutating action with no annotations and an undocumented optional game_id parameter, the description omits key context about preconditions, consequences, and alternatives among sibling tools.
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?
There is one parameter, game_id, and schema description coverage is 0%. The description does not mention game_id at all, leaving unclear which game is targeted or what happens if it is omitted despite the schema defaulting it to null.
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 gives a specific verb and resource: accepting an opponent's outstanding draw offer. It clearly distinguishes this action from siblings such as offer_draw and claim_draw by specifying that it acts on an already-outstanding opponent offer.
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 phrase 'opponent's outstanding draw offer' implies the precondition for using the tool, but the description does not explicitly state when to choose this over claim_draw or other draw-related siblings, nor does it explain when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
claim_drawB
Claim a draw you are entitled to by rule (threefold repetition or the fifty-move rule).
| Name | Required | Description | Default |
|---|---|---|---|
| rule | No | threefold repetition | |
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does not say whether the claim immediately ends the game, whether it fails when the rule condition is not met, or what error/state results from an invalid claim — all material for a state-mutating tool.
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?
One front-loaded sentence with the precondition attached inline. No filler, nothing displaced.
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 output schema means return values need no explanation, and the rule values are covered. However, with zero annotations and zero schema descriptions, the description should at minimum clarify game_id defaulting and the outcome of a successful claim; those omissions leave it only partially complete.
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%. The description names the two legal values for 'rule' (threefold repetition, fifty-move rule), adding real meaning there, but says nothing about 'game_id' — whether null means the current game or which game is targeted. Half the parameters remain unexplained.
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?
States a specific verb and resource ('claim_draw') and pins down the mechanism ('by rule'), distinguishing it conceptually from the sibling offer_draw/accept_draw. It never names those siblings, so an agent still has to infer the routing, which keeps it below 5.
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?
'you are entitled to by rule' supplies a precondition, so usage is implied rather than stated. There is no explicit when-not guidance and no mention of offer_draw or accept_draw as alternatives for the non-rule cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_boardB
Read the current position: FEN, board diagram, side to move, check state, clocks, material, and move history.
| Name | Required | Description | Default |
|---|---|---|---|
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'Read' correctly signals a non-mutating operation and the listed fields give a good picture of the payload, but it says nothing about permissions, whether the game must exist/be joined first, or behavior when game_id is null.
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?
One front-loaded sentence that opens with the action and then enumerates the payload. No filler, no restating of the title.
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?
An output schema exists, so return values need not be spelled out (the enumeration is partly redundant with it). The real gap is the undocumented optional game_id and the absence of any prerequisite or fallback behavior, which leaves the definition merely adequate for a one-parameter tool.
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% and the single parameter (game_id, nullable, default null) is undocumented in both schema and description. The description does not explain what happens when game_id is omitted, which is the most likely invocation.
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?
Specific verb ('Read') plus a full enumeration of what the board view contains (FEN, diagram, side to move, check state, clocks, material, move history). It is clearly distinct from get_legal_moves or get_evaluation, though it overlaps somewhat with get_move_history and get_status without acknowledging that overlap.
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 never says when to call this versus siblings like get_status or get_move_history, nor does it explain the common case of omitting game_id. Usage must be inferred entirely from the name and the nullable parameter.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_evaluationB
Objective position facts only — no engine, no advice: material balance, legal move count, check state.
| Name | Required | Description | Default |
|---|---|---|---|
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden. It does add one meaningful behavioral trait — that no engine analysis or advice is included — which clarifies output character. But it says nothing about read-only safety (though implicit), error handling, or how null game_id resolves, leaving real gaps for an unannotated tool.
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?
A single sentence, front-loaded with the scope constraint and then the concrete contents. Every clause earns its place and there is no padding.
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?
An output schema exists, so return values need not be described, and the enumerated field list plus the no-engine constraint covers the core. The missing piece is the meaning of the optional game_id, which matters for correct invocation even on a simple tool. Adequate but with a visible 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?
Schema description coverage is 0% and the single game_id parameter is nullable with a default of null, meaning it is optional. The description says nothing about what game_id does or what happens when it is omitted (presumably the current game). With low coverage, the description was expected to compensate and does not.
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 names the resource (position evaluation) and enumerates exactly what it returns: material balance, legal move count, check state. The 'no engine, no advice' clause sets it apart from what an agent might assume a chess 'evaluation' tool does. It stops short of explicitly naming which sibling to use instead, so it is clear but not fully sibling-differentiated.
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 phrase 'objective position facts only — no engine, no advice' implies the tool should be used when the agent wants raw positional facts rather than judgment or analysis. However, it never states when to pick this over get_board, get_status, or get_legal_moves, and gives no exclusions or prerequisites. Usage is inferable but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_legal_movesB
List every legal move in the current position, as SAN and UCI.
| Name | Required | Description | Default |
|---|---|---|---|
| game_id | No | ||
| verbose | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it discloses only that results come back in SAN and UCI. It omits how game_id resolves when null (defaults to the current game?), what happens with no active game, error behavior, and whether the list is ordered or paginated. Read-only intent is only weakly implied by 'List.'
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?
A single front-loaded sentence with zero waste; the resource and output formats are stated up front. Nothing is padded or repeated.
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 two-parameter read tool with an output schema, the description need not explain return values, but it leaves the game_id defaulting behavior and the effect of 'verbose' entirely unaddressed. Adequate but with clear gaps an agent would have to guess at.
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% and neither of the two parameters is mentioned in the description. 'game_id' (nullable, default null) and 'verbose' (boolean, default false) are entirely undocumented, so the description does not compensate for the coverage gap.
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?
States a specific verb and resource ('List every legal move') and scopes it to 'the current position,' which naturally separates it from get_move_history and get_evaluation. It stops short of naming any sibling explicitly, so it is clear rather than distinguishing-by-name.
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 purpose implies usage (query moves before calling make_move), but there is no explicit when-to-use, when-not-to-use, or alternative routing. Nothing warns whether this requires an active game or what to do instead if no game exists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_move_historyC
SAN move list so far, in order.
| Name | Required | Description | Default |
|---|---|---|---|
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral burden. It discloses format (SAN) and ordering ('in order'), but says nothing about read-only nature, whether game_id is required, what happens with a null/default ID, or any side effects.
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 front-loaded sentence with no wasted words. It is appropriately short for a simple retrieval tool, though the extreme terseness contributes to other gaps.
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 a simple read-only tool with one optional parameter and an output schema that covers return values, the description states the core behavior. However, it omits parameter meaning and usage context, leaving the agent to infer too much.
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 schema has 0% description coverage for the single optional game_id parameter, and the description does not mention it at all. The parameter name and title are somewhat self-explanatory, but the description adds no meaning beyond the structured field.
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 states the specific resource (SAN move list) and scope ('so far', 'in order'), which is enough to distinguish it from siblings like get_board and get_legal_moves. It lacks an explicit verb and doesn't name an alternative, but the content is clear.
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?
There is no indication of when to use this tool versus alternatives, no prerequisites, and no context about how it relates to other game-state tools. 'So far' lightly implies post-move use, but that is far from actionable guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_statusB
Game status: whose turn it is, clocks, result, and whether the game is over.
| Name | Required | Description | Default |
|---|---|---|---|
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral burden. It discloses the return content (turn, clocks, result, game over), which is useful, but omits read-only safety, whether game_id is optional, and what happens if it is omitted.
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, front-loaded sentence with no filler. Every word contributes to identifying the resource and its returned fields.
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?
An output schema exists, so return values need not be explained in detail, and the description covers them anyway. However, it fails to address the sole optional parameter game_id and provides no usage guidance, leaving meaningful gaps for an unannotated tool.
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?
There is one parameter (game_id) with 0% schema description coverage, and the description does not mention it at all. No meaning, format, or optionality is added beyond the bare schema name.
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 names the specific resource (game status) and enumerates exactly what it reports: turn, clocks, result, and game-over flag. This content clearly differentiates it from siblings such as get_board, get_move_history, and get_evaluation without needing to name them.
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 no guidance on when to use this tool versus alternatives, nor any prerequisites or context for invocation. It only describes the data returned, leaving the agent to infer usage from the name and siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
join_gameC
Join the current game: your colour, the opponent, and the position.
| Name | Required | Description | Default |
|---|---|---|---|
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral burden. It discloses no side effects, authentication requirements, failure modes, or whether joining mutates the game state—only that the tool joins the game and returns some information.
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 front-loaded sentence with no filler. However, the colon list ('your colour, the opponent, and the position') mostly restates return information that the output schema already provides.
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 one-parameter game-joining operation with no annotations and no schema parameter descriptions, the definition is incomplete. It omits the meaning of game_id, when joining is appropriate versus merely checking status, and any behavioral expectations for the join action.
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 does not mention the sole parameter, game_id, at all. With 0% schema description coverage, the description needed to explain the optional game identifier and how it selects which game to join, but it does not.
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?
States a specific verb and resource: 'Join the current game.' This clearly identifies the action and target, though it does not differentiate from sibling tools such as get_status or get_board beyond the verb 'join'.
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?
Provides no explicit when-to-use guidance, prerequisites, or alternatives. Usage is only implied by the word 'Join,' leaving the agent to infer the context without routing help.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
make_moveA
Play a move. Accepts SAN ('Nf3') or UCI ('g1f3'). Rejected moves leave the position untouched.
| Name | Required | Description | Default |
|---|---|---|---|
| move | Yes | ||
| comment | No | ||
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the full burden. It does disclose a valuable behavioral trait — rejected moves are atomic and 'leave the position untouched' — but omits turn validation, authentication/game-ownership requirements, and what constitutes a rejection. Useful but incomplete for a state-mutating tool.
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?
Three short sentences, front-loaded with the action and format details, with the atomicity guarantee last. 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?
An output schema exists, so return values need not be explained. However, for a mutation tool with zero annotation coverage, the description leaves gaps around turn/ownership prerequisites and the meaning of the optional game_id and comment 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% and there are 3 parameters, so the description must compensate. It does clarify the critical 'move' parameter's accepted formats ('Nf3', 'g1f3'), but the optional 'comment' and 'game_id' parameters are left entirely undocumented in both schema and description.
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?
States a specific verb+resource ('Play a move') and specifies the accepted move notations (SAN, UCI), which is meaningful specificity. It does not explicitly contrast with siblings, but the action is obviously distinct from join_game, resign_game, or get_legal_moves.
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 is only implied: an agent infers this is called during a game after checking legal moves. There is no explicit when-to-use guidance, no mention that get_legal_moves should precede it, and no note about whose turn it must be or whether a game must already be joined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
offer_drawB
Offer a draw to your opponent. They must call accept_draw.
| Name | Required | Description | Default |
|---|---|---|---|
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose one non-obvious protocol fact: the offer is not self-executing and requires the opponent to call accept_draw. It says nothing about whether an offer can be withdrawn, whether repeated offers are allowed, or state requirements, leaving meaningful behavioral gaps.
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?
Two tight sentences with the core action front-loaded and the dependency stated second. Nothing is wasted, though the extreme brevity leaves other dimensions under-served.
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 existence of an output schema means return values need not be explained, and the accept_draw handoff is covered. Still, for a state-changing move tool with no annotations and an undocumented parameter, the description is thinner than the interaction complexity warrants.
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 single game_id parameter has 0% schema description coverage and is not mentioned anywhere in the description. Because coverage is low, the description should compensate, but it provides no hint about what game_id means or that it defaults to the current game.
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 gives a specific verb+resource ('offer a draw') plus the target ('your opponent'), so the action is immediately clear. It names accept_draw as the counterpart action, which helps separate it from the accept path, though it never distinguishes itself from claim_draw among the siblings.
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 is implied: call this when you want to propose a draw, and the opponent must respond via accept_draw. However, there is no guidance on when to prefer this over claim_draw, when a draw offer is legal, or what happens if it is ignored, so the agent must infer the context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resign_gameC
Resign the game. Not a failure — the honest end to a lost position.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | ||
| game_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It does not disclose whether resignation is irreversible, whether it ends the game immediately, what happens if there is no active game, or any permission/auth requirement — only an editorial framing of the 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?
Two short sentences, front-loaded with the action and free of padding. The second sentence adds flavor rather than information, but it costs little.
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?
An output schema exists so return values need not be explained, but for a state-mutating game action with no annotations and undocumented parameters, the description omits irreversibility, preconditions, and parameter meaning — not enough for an agent to invoke it confidently.
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?
Two parameters (reason, game_id) with 0% schema description coverage and neither mentioned in the description. There is no hint about what a 'reason' should contain, nor what happens if game_id is omitted (both default to null).
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?
States a specific verb and resource ('Resign the game'), which is unambiguous against siblings like make_move or get_status. It does not explicitly contrast with the adjacent draw tools (offer_draw/accept_draw/claim_draw), so it falls short of full sibling differentiation.
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 gives tone ('the honest end to a lost position') but no operational guidance: it never says when to resign versus offering a draw, nor any precondition such as whose turn it is or whether the game must be active. Usage must be inferred entirely.
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.
11 tool updates
v0.1.0- First observed
accept_draw - First observed
claim_draw - First observed
get_board - First observed
get_evaluation - First observed
get_legal_moves - First observed
get_move_history - First observed
get_status - First observed
join_game - First observed
make_move - First observed
offer_draw - First observed
resign_game
TDQS
Scored across 11 tools
Several tools report overlapping state: get_board already includes clocks, material, check, and move history, which are also provided by get_status, get_evaluation, and get_move_history. While descriptions clarify primary intent, an agent could reasonably choose between them for similar information, causing mild ambiguity.
All tools follow a consistent snake_case verb_noun pattern (get_board, make_move, offer_draw, etc.), with no deviations. The convention is predictable and easy to parse.
11 tools is well within the 3–15 sweet spot and each covers a distinct lifecycle action (join, move, query, draw, resign). No obvious bloat, though some query tools overlap.
Core chess game actions are covered (join, move, legal moves, status, history, resign, draw offer/accept/claim, evaluation). Missing an explicit draw decline and game creation/listing, but these are minor for an arbiter.
Maintenance
Related MCP Connectors
Play chess live against your own personal AI agent — OpenClaw, Hermes, and similar.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Real-time collaborative whiteboard — AI agents and humans edit the same board live over MCP.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
Related MCP Servers
- -licenseNot gradedqualityNot gradedmaintenanceA Model Context Protocol server that enables LLM agents and humans to play chess games together with comprehensive game management capabilities including move validation, draw detection, and game state tracking.-
- AlicenseNot gradedqualityDmaintenanceA 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.15 npm1ISC
- FlicenseNot gradedqualityCmaintenanceMCP server allowing two agents to play chess or Connect Four against each other, with a live rendered board and emotion signaling.-
- FlicenseNot gradedqualityBmaintenanceMCP server for playing chess matches between AI agents across computers, enabling match creation, move submission, and turn waiting.-