@vibekommandant/mcp
v1.0.0
Published
MCP server for VibeKommandant - play against Claude AI in real-time strategy
Maintainers
Readme
Kommandant MCP
MCP (Model Context Protocol) server for VibeKommandant - play against Claude!
Overview
This MCP server allows top-tier LLMs like Claude to control enemy generals in VibeKommandant. The game exposes its state as MCP resources and accepts commands as MCP tools.
Architecture
┌─────────────────────┐ WebSocket ┌─────────────────────┐
│ Browser Game │◄──────────────────►│ kommandant-mcp │
│ (Phaser 3) │ state/commands │ (Node.js server) │
└─────────────────────┘ └──────────┬──────────┘
│ MCP Protocol
┌──────────▼──────────┐
│ Claude/MCP Client │
│ (Claude Code, etc) │
└─────────────────────┘Quick Start
Option A: Play Against Claude Online (Recommended)
Connect your Claude to a cloud game - no local server needed!
1. Create a game at vibekommandant.com
- Click Multiplayer → Create Private Game
- Copy the game code (e.g.,
ABC12345)
2. Add to your Claude Code MCP config (~/.claude.json or project .mcp.json):
{
"mcpServers": {
"kommandant": {
"command": "npx",
"args": [
"@vibekommandant/mcp",
"--server=wss://api.vibekommandant.com",
"--room=ABC12345"
]
}
}
}3. Start Claude Code and play!
Option B: Local Development
1. Build the MCP Server
cd kommandant-mcp
npm install
npm run build2. Configure MCP in Game (Via UI - No Code Editing!)
- Start the game:
npm run devin the main project directory - Click the gear icon (⚙) in the main menu to open Settings
- Enter your MCP server URL (default:
ws://localhost:3001) - Click "Test Connection" to verify the server is running
- Go to Multiplayer and select "Claude AI" as your opponent
The game will automatically connect to the MCP server when you start a match against Claude!
3. Run the MCP Server
# In the kommandant-mcp directory
npm start
# or: node dist/index.js4. Run the Example Claude Opponent (Optional)
If you want to run a standalone Claude opponent script:
# Set your API key
export ANTHROPIC_API_KEY=your-key-here
# Run the opponent script
npx tsx examples/claude-opponent.tsAlternative: Manual Configuration
If you prefer editing config files directly, modify src/config/agentConfig.ts:
export const MCP_CONFIG: MCPConfig = {
ENABLED: true, // Enable MCP backend
SERVER_URL: 'ws://localhost:3001',
CONTROLLED_FACTION: 'enemy',
STATE_UPDATE_INTERVAL: 1000
};Using with Claude Code
Cloud Mode (Recommended)
Join an online game - no local setup required:
{
"mcpServers": {
"kommandant": {
"command": "npx",
"args": ["@vibekommandant/mcp", "--server=wss://api.vibekommandant.com", "--room=YOUR_GAME_CODE"]
}
}
}Local Mode
For local development, point to the built server:
{
"mcpServers": {
"kommandant": {
"command": "node",
"args": ["/path/to/vibekommandant/kommandant-mcp/dist/index.js"]
}
}
}CLI Flags
| Flag | Description |
|------|-------------|
| --server=URL | Cloud server WebSocket URL |
| --room=ID | Game room code to join |
| --faction=player\|enemy | Which faction to control (default: enemy) |
| --router=URL | Local router URL for LLM vs LLM battles |
Once configured, Claude Code can:
- Read game state via
game://stateresource - Query individual generals via
game://agents/{id}resource - Execute tactical commands (move, attack, flank, retreat, etc.)
- Deploy strategic abilities (drones, reinforcements)
Example Claude Code Prompts
"Read the game state and tell me about the battlefield situation"
"Move General 1 to coordinates (3000, 2000)"
"Have General 2 attack the nearest enemy"
"Request reinforcements for General 3"Using with Anthropic SDK
For programmatic control, see examples/claude-opponent.ts for a complete example using the Anthropic SDK.
import Anthropic from '@anthropic-ai/sdk';
import { MCPClient } from '@anthropic-ai/mcp';
// Connect to the MCP server
const mcp = new MCPClient('ws://localhost:3001');
// Read game state
const state = await mcp.readResource('game://state');
// Execute a command
await mcp.callTool('move_to', { generalId: 1, x: 3000, y: 2000 });MCP Resources
| Resource | Description |
|----------|-------------|
| game://state | Current game state with all controlled generals |
| game://tools | List of available commands with descriptions |
| game://agents/{id} | Specific general's battlefield state and personality |
MCP Tools
Strategic Tools (cooldown-based)
deploy_drone(generalId, targetX, targetY)- Scout an arearequest_reinforcement(generalId)- Spawn units at HQ
Tactical Tools
move_to(generalId, x, y)- Move officers in formationattack_nearest(generalId, x, y)- Engage nearest enemyflank(generalId, x, y)- Flanking maneuverretreat(generalId)- Fall back to safetyhold_position(generalId)- Stop all movementpush(generalId, direction)- Attack-move to map edge
Command Tools
set_roe(generalId, mode)- Set rules of engagementfollow_general(generalId, targetGeneralId)- Follow another generalsupport_general(generalId, targetGeneralId)- Coordinate attacks
Development
# Run in development mode
npm run dev
# Build for production
npm run build
# Type check
npm run typecheckConfiguration
The game's MCP configuration is in src/config/agentConfig.ts:
export const MCP_CONFIG: MCPConfig = {
ENABLED: false, // Enable/disable MCP
SERVER_URL: 'ws://localhost:3001', // WebSocket server URL
CONTROLLED_FACTION: 'enemy', // 'player' | 'enemy' | 'both'
STATE_UPDATE_INTERVAL: 1000 // State broadcast interval (ms)
};Tool Parameter Reference
Tactical Movement Tools
| Tool | Parameters | Description |
|------|------------|-------------|
| move_to | generalId: number, x: number, y: number | Move general's officers to coordinate |
| attack_nearest | generalId: number, x: number, y: number | Attack nearest enemy to coordinate |
| flank | generalId: number, x: number, y: number | Flanking maneuver to coordinate |
| retreat | generalId: number | Fall back toward HQ |
| hold_position | generalId: number | Stop movement, maintain position |
| push | generalId: number, direction: 'north'\|'south'\|'east'\|'west' | Attack-move to map edge |
Strategic Ability Tools
| Tool | Parameters | Cooldown | Description |
|------|------------|----------|-------------|
| deploy_drone | generalId: number, targetX: number, targetY: number | 60s | Scout area, reveals fog of war |
| request_reinforcement | generalId: number | 45s | Spawn 1-5 infantry at HQ |
Command Tools
| Tool | Parameters | Values |
|------|------------|--------|
| set_roe | generalId: number, mode: string | 'HOLD_FIRE', 'RETURN_FIRE', 'AGGRESSIVE' |
| follow_general | generalId: number, targetGeneralId: number | Target must be friendly general |
| support_general | generalId: number, targetGeneralId: number | Coordinate attacks with target |
| assist_general | generalId: number, targetGeneralId: number | Move to support target's position |
Game State Format
The game://state resource returns:
interface BattlefieldState {
myPosition: { x: number; y: number };
myHealth: number;
myOfficers: Array<{
id: number;
position: { x: number; y: number };
health: number;
unitCount: number;
squadType: 'infantry' | 'tank' | 'artillery';
roe: string;
}>;
nearbyEnemies: Array<{
type: 'unit' | 'officer' | 'general';
position: { x: number; y: number };
distance: number;
health: number;
}>;
nearbyAllies: Array<{...}>;
mapInfo: {
width: number;
height: number;
hqPosition: { x: number; y: number };
enemyHQPosition: { x: number; y: number };
};
}Troubleshooting
Game won't connect to MCP server
- Check server is running:
npm startinkommandant-mcp/directory - Verify WebSocket URL: Default is
ws://localhost:3001 - Test connection: Use the "Test Connection" button in game settings
- Check console: Browser console shows
[MCPBridge] Connected to MCP serveron success
Claude Code can't find the MCP server
- Build first: Run
npm run buildinkommandant-mcp/ - Check path: Ensure the path in your MCP config points to
kommandant-mcp/dist/index.js - Restart Claude Code: After changing MCP config, restart the application
Tool calls fail with "General not found"
- Ensure the game is running and generals are spawned
- General IDs start at 1 (not 0)
- Enemy generals have IDs 1-4, player generals have IDs 5-8
No game state available
- The game must be in a match (not menu/lobby) for state to be available
- State updates every 1 second (configurable via
STATE_UPDATE_INTERVAL)
