This is an implementation of Uwe Rosenberg's game Ora et Labora. Some interesting waypoints might be:
game- a stateless game logic library, available on npm licensed under GPL-3.web- this is the website that gets shot up to Vercel.
Kennerspiel exposes an MCP server with two endpoints, both backed by the same OAuth session:
- Hub:
https://kennerspiel.com/api/mcp— exposes every tool (list_my_games,get_game,join_game,get_legal_moves,make_move,undo_move,wait_for_my_turn,get_strategy_guide). Per-game tools take aninstance_idargument. This is the recommended endpoint for account-level integrations like claude.ai and ChatGPT: add it once and you can play any game from any conversation. - Per-game:
https://kennerspiel.com/instance/<uuid>/mcp— same play-the-game tools as the hub, butinstance_idis baked into the URL. The/mcpsuffix is optional: pasting plainhttps://kennerspiel.com/instance/<uuid>into Claude or ChatGPT works too (POST/JSON requests are routed to the MCP handler; browsers still get the HTML game page). Best for Claude Code projects pinned to one game.
Authentication uses standard OAuth 2.1 + PKCE; clients that support dynamic client registration (RFC 7591) connect without any manual setup. A single access token covers both the hub and every per-game endpoint, so the user only authorizes once.
- Sign in at kennerspiel.com and create an account if you don't have one.
- In claude.ai, open Settings → Integrations and click Add integration.
- Enter the MCP server URL:
https://kennerspiel.com/api/mcp - Claude will redirect you to Kennerspiel to log in and confirm access. Click Authorize.
- Done. Start a new conversation and tell Claude which game to join or play.
claude mcp add --transport http kennerspiel https://kennerspiel.com/api/mcpClaude Code opens a browser for the OAuth flow and redirects back automatically. Once connected, ask Claude to join a lobby by sharing the game URL, or check pending games with list_my_games.
To bind a Claude Code project to one specific game:
claude mcp add --transport http my-game https://kennerspiel.com/instance/<uuid>The same OAuth session is reused — no second authorization prompt.
ChatGPT supports MCP connectors for Plus, Pro, Business, and Enterprise accounts.
- Sign in at kennerspiel.com first.
- In chatgpt.com, open Settings → Connectors → Create.
- Enter the MCP server URL:
https://kennerspiel.com/api/mcp - ChatGPT discovers the OAuth endpoints automatically and redirects you to Kennerspiel to authorize.
- Done. Open a new chat and ask ChatGPT to join or play a game.
Developer mode must be enabled in your workspace (Workspace Settings → Permissions & Roles → Connected Data → Developer mode) before custom MCP connectors appear.
First complete the OAuth flow to obtain an access token (30-day TTL):
- Register your client at
https://kennerspiel.com/register(RFC 7591 dynamic registration). - Send the user through the authorization flow at
https://kennerspiel.com/authorizewithresponse_type=code,code_challenge_method=S256, andscope=play. - Exchange the returned code for a token at
https://kennerspiel.com/token.
Then pass the token in every Responses API call:
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4o",
tools=[{
"type": "mcp",
"server_label": "kennerspiel",
"server_url": "https://kennerspiel.com/api/mcp",
"require_approval": "never",
"headers": {
"Authorization": "Bearer <your-access-token>"
}
}],
input="List my Ora et Labora games and make a move if it's my turn."
)
print(response.output_text)The OAuth server metadata is published at https://kennerspiel.com/.well-known/oauth-authorization-server for clients that auto-discover endpoints.
| Tool | Endpoint | What it does |
|---|---|---|
list_my_games |
hub | Find all games you're seated in; filter to games waiting on your move |
join_game |
per-game | Claim a seat in this game's lobby |
get_game |
per-game | Read the current board state: rondel, tableaus, scores, turn order |
get_legal_moves |
per-game | Enumerate legal next tokens for a move (interactive drill-down) |
make_move |
per-game | Play one command, e.g. USE LR2 or BUILD G07 3 2 or COMMIT |
undo_move |
per-game | Retract the most recent command (use when teaching the model a better line) |
wait_for_my_turn |
per-game | Long-poll until it's your turn, rather than polling repeatedly |
get_strategy_guide |
per-game | Load the full France/long-2p coaching guide the model consults for decisions |
The AI holds seats and makes moves as your Kennerspiel account — human opponents see moves appear live in their browser just like any other player's.
The game logic must be published separately from the Docker image.
cd gamerm -rf node_modules- Bump the version number of the game appropriately (e.g. v0.6.9)
npm installnpm run buildnpm run testnpm publish