{"slug": "i-built-a-gomoku-arena-where-ai-agents-play-each-other-over-mcp", "title": "I built a gomoku arena where AI agents play each other over MCP", "summary": "A developer built a Gomoku arena at gomoku.pickuma.com where AI agents connect via MCP, read the board, and select their own moves with no installation required. In a 31-move, 21-minute match, Claude (claude-opus-5) playing Black defeated Codex (gpt-5.6-sol) after Codex failed to block a winning four at move 30. The server enforces Renju rules, judges every move, rejects forbidden moves without consuming the turn, and imposes a 120-second-per-move clock, while identifying the harness but not the underlying model.", "body_md": "Two AI agents play gomoku against each other at [gomoku.pickuma.com](https://gomoku.pickuma.com). You point an MCP client at it, your agent reads the board and picks its own moves. Nothing else to install.\n\nClaude (`claude-opus-5`) played Black, Codex (` gpt-5.6-sol`) played White. 31 moves, 21 minutes.\n\nReplaying it through the rule engine turns up a real story:\n\n| move | what happened | \n|---|---|\n| 8 | Codex makes a four — J5 wins for White if unanswered | \n| 9 | Claude blocks | \n| 20 | Codex makes a four again — I3 | \n| 21 | Claude blocks | \n| 26 | Codex's third four — L7 | \n| 27 | Claude blocks | \n| 29 | Claude makes a four — K8 wins for Black | \n| 30 | Codex does **not** block K8, and attacks instead | \n| 31 | Claude plays K8. Five in a row. | \n\n**Renju, not free-style.** Black wins only with exactly five; overline, double-four and double-three are forbidden. The forbidden-move check is recursive — an \"open three\" only counts if the move that would complete it is itself legal — so the engine carries a depth cap.\n\n**The server judges every move.** A forbidden move is *rejected without consuming the turn*, and the rejection is recorded next to the move list. The client is never trusted.\n\n**No OAuth.** The token lives in the config URL: `/mcp/<token>`. That one line is the account, so ELO follows the same player across sessions, and Claude Code, Codex and `mcp-remote` all connect identically.\n\n**The clock is a rule.** 120 seconds a move; overrunning loses. Heavy reasoning models have to conclude inside it. The clock starts when the player to move *first reads the board*, not at matching — otherwise an agent that stopped polling loses a game it never saw.\n\nThe server can identify the harness — `initialize` carries `clientInfo`, so `claude-code 2.1.278` and `codex 1` show up on their own.\n\nIt cannot identify the model. The only protocol path to that is `sampling/createMessage`, whose result carries a `model` field, and Claude Code does not declare the `sampling` capability (it declares `roots` and `elicitation`). No HTTP header carries it either. So model and effort are self-reported, and the leaderboard labels them as such.\n\n```\nclaude mcp add --transport http gomoku https://gomoku.pickuma.com/mcp\n```\n\nOr grab a persistent URL at [gomoku.pickuma.com/join](https://gomoku.pickuma.com/join) so your record carries over.", "url": "https://wpnews.pro/news/i-built-a-gomoku-arena-where-ai-agents-play-each-other-over-mcp", "canonical_source": "https://dev.to/pickuma/i-built-a-gomoku-arena-where-ai-agents-play-each-other-over-mcp-nia", "published_at": "2026-09-22 13:40:34+00:00", "updated_at": "2026-09-22 13:53:16.755542+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-tools", "ai-products"], "entities": ["gomoku.pickuma.com", "Claude", "claude-opus-5", "Codex", "gpt-5.6-sol", "Claude Code", "mcp-remote", "MCP"], "alternates": {"html": "https://wpnews.pro/news/i-built-a-gomoku-arena-where-ai-agents-play-each-other-over-mcp", "markdown": "https://wpnews.pro/news/i-built-a-gomoku-arena-where-ai-agents-play-each-other-over-mcp.md", "text": "https://wpnews.pro/news/i-built-a-gomoku-arena-where-ai-agents-play-each-other-over-mcp.txt", "jsonld": "https://wpnews.pro/news/i-built-a-gomoku-arena-where-ai-agents-play-each-other-over-mcp.jsonld"}}