multi-agent-games
MCP server allowing two agents to play chess or Connect Four against each other, with a live rendered board and emotion signaling.
README
multi-agent-games
MCP server where two agents play a board game — chess or Connect Four —
against each other, with a live board rendered in a UI panel. Each agent identifies
itself with an x-player-id HTTP header; the first to join takes the first seat
(White / Red), the second takes the second seat (Black / Yellow).
Run
pnpm install
pnpm dev # tsx, no build (port 9006)
# or
pnpm build && pnpm start
curl http://localhost:9006/health # -> {"status":"ok"}
Override the port with PORT=9999 pnpm start.
How two agents connect
Each agent connects to http://localhost:9006/mcp and must send an
x-player-id header identifying itself. The id is captured when the MCP
session initializes and bound to that session for its lifetime.
Agent A --(x-player-id: alice)--> /mcp => seated White
Agent B --(x-player-id: bob) --> /mcp => seated Black
Both sessions share one game (state lives at module scope, not per-session), so the two agents play the same board.
Tools
| Tool | Input | Purpose |
|---|---|---|
new_game |
variant |
Switch the game to chess or connect4. Resets the board and clears both seats. |
join_game |
name? |
Take a seat (first → White/Red, second → Black/Yellow). Opens the board panel. |
make_move |
move |
Play a move on your turn. Chess: SAN (Nf3, O-O) or coordinate (e2e4, e7e8q). Connect4: the column 1–7. Rejects wrong-turn / illegal moves. |
set_emotion |
emotion, statement? |
Set your emotion (drives your virtual face) plus an optional one-sentence status (shown as a thinking cloud). Both visible to the opponent. |
get_opponent_emotion |
– | Fetch the opponent's current emotion + status statement. |
get_board |
– | Read current state: variant, turn, status, winner, history, the board (chess FEN/PGN or connect4 grid), and both players' emotions/statements. Polled by the UI. |
reset_game |
– | Reset the current variant's board and clear both seats. |
Emotions: neutral, happy, sad, angry, surprised, nervous, confident, thinking.
Game variants
The server starts in chess. Call new_game with variant: "connect4" (or back
to "chess") to switch — it resets the board and clears both seats, so the two
agents then re-join_game. Seats are always tracked as first/second internally and
labelled per variant: White/Black for chess, Red/Yellow for Connect Four (Red, the
first seat, moves first). Connect Four is a 7-column × 6-row board; drop a disc into
a column 1–7 and win with four in a row (horizontal, vertical, or diagonal).
Emotions & status clouds
Each agent can broadcast an emotion and a single-sentence statement via
set_emotion. The emotion renders as a virtual SVG face beside that player; the
statement renders as a thinking cloud next to the face. The opponent reads both
with get_opponent_emotion (or from get_board), so emotions are a shared
signalling channel — bluff, taunt, or telegraph as you like.
Run the widget on its own
Two ways to view the board UI without an MCP host (it auto-detects no host and renders a static demo board — no churn):
pnpm build && pnpm preview # static server -> http://localhost:9007
# or, with live reload while editing the UI:
pnpm ui:dev # Vite dev server (prints its own URL)
Override the preview port with PREVIEW_PORT=9999 pnpm preview. Preview URL params:
?game=connect4 to preview the Connect Four board, and ?emotion=<name> /
?blackEmotion=<name> to preview a specific face.
UI
new_game / join_game / make_move / reset_game carry _meta.ui.resourceUri
so invoking them opens the panel (ui://multi-agent-games/index.html). The widget polls
get_board every 1.5s and renders per variant: a chess board from FEN (flipped when
you are Black) or the Connect Four grid of dropped discs. It highlights the last
move and lists move history. Built as a single inlined HTML file via
vite-plugin-singlefile.
Notes
- Chess rules (legality, check, checkmate, stalemate, draws) are handled by
chess.js— not hand-rolled. Connect Four (drop, win detection, full-board draw) is a small built-in engine insrc/engine.ts. - Both variants are pluggable
Engines; the coordinator (src/game.ts) owns seating and the shared emotion channel and delegates the board to the active engine. - Missing
x-player-id=> tools error asking for the header.get_boardstill works (read-only) but you are treated as a spectator.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.