Play backgammon with your favorite LLM.
A backgammon game that can be played through Claude Desktop (via MCP) or as a standalone web app.
packages/
├── game/ # Core game logic (Redux-based, framework-agnostic)
├── viewer/ # React UI components for the board
├── web-app/ # Standalone web app ("couch mode")
└── mcp-server/ # MCP server for Claude Desktop integration
- Node.js 18+
- pnpm (
npm install -g pnpm)
git clone <repo-url>
cd backgammon-mcp
pnpm installPlay backgammon locally in your browser - perfect for two humans on the same device.
# Start the development server
pnpm --filter @backgammon/web-app devOpen http://localhost:3000 in your browser.
Play backgammon with Claude as your opponent, or watch Claude play against itself.
The MCP server requires a built client UI bundle. This must be done before first use and after any changes to the viewer or client code.
# Build the client UI bundle (required)
pnpm --filter @backgammon/mcp-server build:clientThis creates packages/mcp-server/dist/client/index.html - a single-file bundle containing the interactive board UI.
Edit your Claude Desktop configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add the backgammon server:
{
"mcpServers": {
"backgammon": {
"command": "npx",
"args": [
"tsx",
"/ABSOLUTE/PATH/TO/backgammon-mcp/packages/mcp-server/src/server.ts"
]
}
}
}Important: Replace /ABSOLUTE/PATH/TO/backgammon-mcp with the actual full path to this repository.
After saving the config, restart Claude Desktop. You should see "backgammon" in the MCP servers list.
Ask Claude to start a game:
"Let's play backgammon! Start a new game where I play white and you play black."
Or watch an AI vs AI game:
"Start a backgammon game where you control both players and play against yourself."
Board redraws on every turn: The board UI redraws completely each time you or the model takes a turn. This is a known issue being discussed in modelcontextprotocol/ext-apps#430, so hopefully this can improve in the future.
End Turn doesn't automatically trigger the model: When you click "End Turn" in the view, the model doesn't automatically take its turn. The MCP Apps SDK's ui/message (at least in Claude Desktop) only populates the chat input but doesn't send it - you have to press return. Similarly, ui/update-model-context defers until the next user message. As a workaround, after clicking "End Turn", press return in the chat to prompt the model to take its turn.
# All packages
pnpm test
# Specific package
pnpm --filter @backgammon/game testpnpm typecheckpnpm lint-
game/: Pure game logic with no UI dependencies. Uses Redux Toolkit for state management. Exports reducers, actions, selectors, and type definitions.
-
viewer/: React components that render the backgammon board. Fully controlled - receives all state via props, emits events via callbacks. Uses CSS custom properties for theming.
-
web-app/: Standalone Vite + React app that combines the game logic and viewer. Uses Redux for state management.
-
mcp-server/: MCP server that exposes game tools and serves the viewer as an MCP App resource. The viewer is bundled as a single HTML file using vite-plugin-singlefile.