An MCP server for playing and analyzing Gomoku (Five in a Row) games with AI agents powered by LLMs via OpenRouter
Server defines 10 tools with reasonable descriptions and mostly complete schemas. Tool names follow verb_noun conventions well (restart, visualize, get_state, set_stone, etc.). Descriptions are detailed and well-formatted with emojis and usage guidance, averaging ~200 chars, within the productive range. However, critical gaps exist: (1) input schemas are present but lack detailed constraint documentation in parameter descriptions (e.g., x/y ranges stated as '0-14' but no min/max JSON Schema properties visible); (2) output schemas are inferred from return type hints but not formally documented in descriptions; (3) error handling guidance is minimal, set_stone lists potential ValueError conditions but no recovery guidance; (4) no tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk classifications in the server definition; (5) stateless composition is undermined by global gomoku_game state, creating implicit ordering dependencies agents may not understand. The analyze_threats and get_suggested_moves tools have strong descriptions that guide agent selection, but lack formal output schema documentation. Average tool quality sits solidly in the 'fair-to-good' range, most tools would function correctly, but LLM interaction could be smoother with stricter constraint documentation and error recovery patterns.
🔍 **CRITICAL: Call this BEFORE every move to understand threats on the board.** Analyzes the current board for threats and opportunities for BOTH players. This tool helps you identify: - Immediate winning moves (yours and opponent's) - Threats that MUST be blocked (open-4, closed-4) - Strong patterns to extend or block (open-3, closed-3) **Threat Priority Levels:** - OPEN_FOUR (priority 9): 4 stones with BOTH ends open (_XXXX_) - UNSTOPPABLE if not blocked - CLOSED_FOUR (priority 8): 4 stones with ONE end open (OXXXX_ or _XXXXO) - MUST BLOCK - OPEN_THREE (priority 7): 3 stones with BOTH ends open (_XXX_) - Becomes open-4 next turn - CLOSED_THREE (priority 5): 3 stones with ONE end open - Medium threat
📜 Returns a chronological list of all game states from the beginning. This can be used to: - Review the game's progression - Analyze past moves and strategies - Understand how the current position developed Each state in the list represents the board after one move.
📖 Returns the complete rules of the Gomoku game. Call this if you need a refresher on how Gomoku works.
📊 Retrieves the complete current state of the game. **IMPORTANT: Call this FIRST to understand the current game before making any move.** This provides structured data about: - The board layout (15x15 grid) - Whose turn it is (BLACK or WHITE) - All stones that have been played - Game status (ongoing, won, draw)
Output schemas are not formally documented. Return types are inferred from Python type hints (e.g., 'GomokuState', 'dict') but descriptions do not specify the structure, fields, or types agents should expect. This forces LLMs to guess at the output format and risks misuse in downstream tool calls.
Input parameter constraints are stated in descriptions but not in JSON Schema properties. For set_stone, 'x' and 'y' are described as '0-14' but no minimum/maximum properties are visible in the schema definition. For get_suggested_moves, 'count' has no minimum/maximum bounds. This invites invalid inputs from LLMs.
Tool annotations are missing. set_stone has Risk=WRITE and analyze_threats/get_suggested_moves are READ_ONLY, but no destructiveHint or readOnlyHint annotations are present in the tool definitions. This forces LLMs to infer write vs. read semantics from the description, increasing misuse risk.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 52 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 31 | - | v1 |
💡 **CRITICAL: Call this to get the best moves ranked by priority.** Returns the top N suggested moves based on tactical analysis. Each suggestion includes the position, priority score, and reasoning. **Priority Scale (1-10):** - 10: WIN - Complete 5-in-a-row (TAKE THIS IMMEDIATELY!) - 9: BLOCK LOSS - Stop opponent's open-4 or closed-4 (MUST DO!) - 8: CREATE WINNING THREAT - Make an open-4 yourself - 7: BLOCK OPEN-3 - Prevent opponent from creating open-4 - 6: CREATE OPEN-3 - Force opponent to respond - 5: BLOCK CLOSED-3 - Prevent opponent's sequence - 4: EXTEND PATTERNS - Build your own sequences - 3: STRATEGIC - Center control, connections
🎲 Gets the current turn status. Returns one of: - "BLACK": It's Black's turn to move - "WHITE": It's White's turn to move - "BLACK_WIN": Black has won the game - "WHITE_WIN": White has won the game - "DRAW": The game ended in a draw (board full, no winner)
✅ Provides a list of all valid (empty) positions where a stone can be placed. **RECOMMENDED: Call this after get_state() to see your options.** This helps you identify all possible next moves without trying invalid placements. Use this to narrow down your strategic choices to only legal moves.
🔄 Resets the game to its initial state. Use this when starting a completely new game. This clears the board of all stones and resets the move history. After calling this, BLACK will have the first move.
🎯 Places a stone for the specified player at the specified coordinates. **Call this AFTER analyzing the board with get_state() or visualize().**
👁️ Returns a text-based visual representation of the current game board. **IMPORTANT: Call this BEFORE making moves to see the current board layout.** This shows you where all the stones are placed in an easy-to-read grid format. Use this to understand the current game situation before deciding your next move.
Error handling lacks recovery guidance. set_stone documents that ValueError will be raised for invalid moves, but does not tell the LLM what to do next (e.g., 'Call get_valid_moves() to see legal positions' or 'Try a different coordinate'). This forces the agent to guess at recovery.
Global state (gomoku_game) creates implicit ordering dependencies. The tools assume all calls operate on a single global game instance. If agents intersperse multiple games or replay history, they will corrupt shared state. No tool explicitly documents this limitation or provides game_id scoping.
Output field naming inconsistencies and missing response documentation. analyze_threats returns a dict with keys like 'BLACK', 'WHITE', 'current_turn', 'recommended_action', but no schema specifies the structure of BLACK/WHITE threat summaries or guarantees which fields will be present. get_suggested_moves returns suggestions with 'position', 'priority score', and 'reasoning', but no formal schema.