pente-mcp
by uudruid74
README.md
# pente-mcp — an AI/MCP add-on for playing Pente
An **[MCP](https://modelcontextprotocol.io) server** that lets any MCP-capable
AI play **Pente**. It supports **two transports** with the same four tools:
- **Local** (default) — two agents on the **same machine** play each other
with a self-contained game engine and a local TCP socket. No website, no
PeerJS, no WebRTC, no public cloud, no internet.
- **Web** — play against the
[ChanBlake browser game](https://github.com/ChanBlake/pente) / a human over
the public PeerJS cloud (a human opens an invite URL in their browser).
This is an **add-on / integration layer**, not a fork of the game. The web mode
joins ChanBlake's own multiplayer rooms as a second player, exactly like a
human in another browser tab. **None of ChanBlake's game code is included
here** — it stays in his [repository](https://github.com/ChanBlake/pente).
In local mode the rules are reimplemented from scratch (deterministic game
math, not his AI).
| Tool | Role | What it does |
|---|---|---|
| `create(transport?)` | host | Open a table as **BLACK** (local: embedded engine + local socket; web: browser invite) |
| `join(target, transport?)` | guest | Join a table as **WHITE** (local: `target` = local port; web: `target` = room code) |
| `move(row, col)` | either | Play one stone, wait for the opponent reply |
| `view` | either | Dump the synchronized board + game state |
## Two transports
### Local (agent-vs-agent, same machine) — `transport="local"`
Two agents (e.g. Gopher and Zephyr) on the **same host** play each other with a
self-contained Python game engine (`pente_engine.py`) and a plain JSON-line TCP
socket (`pente_local.py`). The hosting MCP process owns the authoritative rules
and validates every move: legal moves, straddle captures, 5-in-row win, and
win-by-5-captures all resolve locally. **No internet required.**
```bash
# Agent A hosts (BLACK)
create(transport="local")
# -> { "transport": "local", "port": 9333, "i_am": "BLACK", ... }
# Agent B joins (WHITE) — same machine
join(target=9333, transport="local")
# -> { "transport": "local", "port": 9333, "i_am": "WHITE", "connected": true }
```
### Web (browser / remote) — `transport="web"`
Connect to ChanBlake's browser game over the public PeerJS cloud, so a human
(or another agent) playing in the browser is the opponent.
```bash
create(transport="web") # -> { "join_url": "https://chanblake.github.io/pente/?room=ABC234", ... }
join(target="ABC234", transport="web")
```
## What's in here
- **`pente_mcp.py`** — the stdio MCP server (create / join / move / view, both transports).
- **`pente_engine.py`** — pure-Python Pente rules (legal moves, captures, wins, pro-opening). Zero dependencies.
- **`pente_local.py`** — local TCP transport: `LocalHost` (embedded engine + server) and `LocalGuest` (client).
- **`pente_local_host_cli.py`** — run the local host engine as a JSON-lines subprocess.
- **`pente_scan.py`** — board threat scanner (open fours, capture frames, refillable gaps, winning squares).
- **`pente-bot.js` / `pente-host.js` / `webrtc-polyfill.js`** — Node adapters for the **web** transport (PeerJS/WebRTC).
- **`test/`** — headless tests (fake host + the local transport tests).
- **`docs/`** — the original design spec.
## Requirements
- **Local mode:** Python ≥ 3.11 with `mcp` (`pip install mcp`). No Node, no internet.
- **Web mode:** Node.js + `@roamhq/wrtc` shim + internet to the public PeerJS cloud (`0.peerjs.com:443`).
## Quickstart
```bash
pip install mcp
python pente_mcp.py # stdio MCP server (local transport is the default)
```
Register the server in your MCP client, then:
```bash
create(transport="local") # host a local game, BLACK
view() # full 19x19 board, whose_turn, captures, game_over
move(row=9, col=9) # your_move (+ their move if the opponent replied)
```
### Tests
```bash
python pente_engine.py # rules self-test
python test_local_rules.py # win + capture via the local host engine
python test_local_two_process.py # cross-process host + guest over TCP
python test_mcp_agent_vs_agent.py # two full MCP processes playing each other
```
All four must pass. They exercise moves, straddle captures, 5-in-row wins, and
win-by-captures over the local transport — with no website and no PeerJS cloud.
## Credit
The web mode connects to **ChanBlake's Pente**:
https://github.com/ChanBlake/pente — an unofficial, non-affiliated integration
layer. Only network moves are sent; this project cannot modify the game's files
or memory.
## Known limits
- **Local mode** supports **one active table** per MCP server process (single `_active` handle).
- **Web room codes:** the app strips `I`, `O` and `0`. `create` only emits codes from its alphabet.
- **Web transport is public-cloud only** (a local PeerServer + Node host doesn't register its peer due to WebRTC-in-Node); local mode exists precisely to avoid this.
## License
MIT — this integration layer. ChanBlake's game has its own license (see his repo).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues