Skip to main content
Glama
0xBrsm

HexSet MCP Server

by 0xBrsm
README.md
# HexSet

HexSet implements a hex-tile trading and building game based on the rules of
*Settlers of Catan*: a NumPy rules engine, heuristic bots, ONNX model
inference, a browser interface, HTTP and MCP interfaces, Gymnasium and
PettingZoo adapters, and batched environments for training and evaluation.

The engine covers resource production, construction, development cards, the
robber, victory conditions and player trading. It owns the rules, information
sets, encoding, game loops, seating and board pairing, records and replay, and
trade evaluation. A training project supplies the model runtime and the
learning algorithm through those interfaces; neural-network training and
checkpoint export are maintained separately, in the sibling HexN project.

Games are hosted here even when the opponent comes from elsewhere: HexSet owns
the rules, the legal actions and the ledger, and Catanatron is an external
reference opponent seated at a HexSet table.

## Documentation

Start with [guide.md](docs/guide.md); the rest are listed by name.

| Document | Contents |
| --- | --- |
| [api.md](docs/api.md) | JSON routes, seat tokens, client identity and reclaim |
| [evaluation.md](docs/evaluation.md) | Designing a comparison, the intervals the runners report, experiment records |
| [guide.md](docs/guide.md) | Running games, bundled opponents, trade rounds, implementing a bot, records, bench commands |
| [heximax.md](docs/heximax.md) | The built-in search bot: strength, search, evaluation, endpoint pins |
| [mcp.md](docs/mcp.md) | MCP tools and their semantics |
| [onnx.md](docs/onnx.md) | The ONNX model contract, and checking a file against it |
| [server.md](docs/server.md) | Running the server: configuration, Docker, saved games |
| [testing.md](docs/testing.md) | Markers, optional extras, what CI covers |
| [trading.md](docs/trading.md) | Trading's three parts: the table's rules, a gate's own `TradeParams`, the shared protocol |
| [training.md](docs/training.md) | Batched collection, model runtimes, PettingZoo and Gymnasium adapters |
| [worlds.md](docs/worlds.md) | Cached votes over sampled worlds |

## Heximax

**Heximax** is HexSet's built-in search bot and the default opponent. It uses
a budgeted expectimax/max^n search over the seat's information set, with move
weights that adapt to public trading activity.

| Matchup | Heximax wins | Win rate (95% CI) |
| --- | --- | --- |
| 2 player, variant | 686 / 800 | **85.75%** (83.2-88.3%) |
| 2 player, standard | 627 / 800 | **78.38%** (75.6-81.2%) |
| 4 player, 1 Heximax seat | 451 / 800 | **56.38%** (53.1-59.7%) |

All games against Catanatron's depth-two alpha-beta player (AB2), hosted in
the HexSet engine. The duel variant (`rules.DUEL_VARIANT_GAME`) is
[colonist.io's ranked 1v1 format](https://blog.colonist.io/ranked-1v1-comprehensive-strategy-guide-colonist-io/),
and it is a *two-seat* game type: a `GameType` carries the seat counts its
ruleset is played at, so the engine will not deal it to a four-seat table.
[docs/heximax.md](docs/heximax.md) has the search, the evaluation terms, the
measurement conditions and the endpoint pins.

## Installation

Requires Python 3.11 or later. From the repository root:

```sh
pip install -e .
```

The base installation requires only NumPy. Install extras for the interfaces
you use:

| Extra | Provides |
| --- | --- |
| `.[server]` | ONNX Runtime for embedded model opponents; Heximax needs only the base install |
| `.[clients]` | ONNX Runtime for standalone model clients |
| `.[gym]` | Gymnasium and PettingZoo environments |
| `.[catanatron]` | Catanatron integration, pinned to a specific Git commit |
| `.[export]` | ONNX and ONNX Runtime libraries; no training or export command is included |
| `.[test]` | pytest |

Extras can be combined, for example `pip install -e ".[server,gym,test]"`.

## Play in a browser

```sh
python -m hexset.server.web
```

The server opens a browser at `http://127.0.0.1:8770`. Share a game's URL to
invite other players. Each new game starts with its creator seated and the
remaining seats open. Fill them with people or bots, or close unused seats
with the picker's `none` option. Play waits until every seat is filled or
closed. Closed seats can be reopened before the first move; the participating
seats are fixed once play starts.

The opponent picker lists `heximax`, `catanatron` when its extra is installed,
and the models found in `models/`. A compatible `.onnx` file dropped there
appears in the next listing under its filename stem; the requirements are the
[ONNX model contract](docs/onnx.md).

The trade modal supports bank and port trades, offers to other players,
and responses to their offers. How many cards a player trade moves is each
seat's own declared limit — a manual seat is bounded only by the cards it
holds. A bot makes as many
offers a turn as its own gate asks for and waits for manual seats to answer
before continuing. A seat with no resource cards passes automatically.

Games have a public spectator view that reveals all hands, development
cards, and victory points. Anyone with the game URL can access it, including
players at that table. Seat-specific responses filter hidden information,
but the public view means a server game does not enforce secrecy between
participants.

Running it anywhere but a local default -- ports, Docker, journals and the
recovery rules -- is [docs/server.md](docs/server.md).

## Repository layout

| Path | Contents |
| --- | --- |
| `hexset/` | Rules, board topology, state, ledger, encoding, records, search, and arena |
| `hexset/bots/` | Heximax, bot protocols, random policy and shared evaluation |
| `hexset/bench/` | Duels, throughput measurements, record generation, and weight fitting |
| `hexset/catanatron/` | Seats a Catanatron `Player` as a bot at a HexSet table: board, state and action translation |
| `hexset/server/` | HTTP and MCP server, sessions, journals, and static browser UI |
| `hexset/clients/` | Runtime-independent policy, trade, and search interfaces; ONNX inference; bot clients |
| `hexset/gym/` | Lane, PettingZoo, and Gymnasium environments |
| `tests/` | Engine and integration tests |
| `models/` | Local ONNX opponents |
| `docs/` | The documents indexed above |

## Tests

```sh
pip install -e ".[test,server,export,catanatron,gym]"
pytest
pytest -m slow
```

The default run excludes tests marked `slow`; `pytest -m ""` runs every
marker. Tests for an optional dependency skip themselves when it is absent, so
which extras are installed decides what a green run covered:
[docs/testing.md](docs/testing.md) maps each extra to what it tests, and covers
the browser tests, which need a Chromium download beyond their extra.

## License and attribution

HexSet is licensed under GPL-3.0-only. See [LICENSE](LICENSE). Development
history is in [CHANGELOG.md](CHANGELOG.md); each release is also one commit
here, whose message is that version's entry.

Dependencies are installed from PyPI or from git, never vendored into this
repository, and each carries its own licence; the set and their extras are
declared in [pyproject.toml](pyproject.toml). Catanatron is GPL-3.0, and the
base evaluator in `hexset/catanatron/speedups.py` is derived from it — that
file names the upstream revisions it reproduces. The browser interface in
`hexset/server/static/index.html` loads no third-party scripts, stylesheets or
web fonts; its system font stack names fonts on the user's device rather than
bundling them.

CATAN and SETTLERS OF CATAN are trademarks of Catan GmbH and Catan Studio.
HexSet is not affiliated with, endorsed by, or sponsored by either company.
The names identify the game whose rules this project implements.