magicciv/tooling/claude-player-mcp/README.md
Natalie 91ef4bc21f feat(@projects/@magic-civilization): rename claude-player to player-api refactor
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-05-17 03:43:32 -07:00

2.8 KiB

@magic-civ/claude-player-mcp

Claude-Code-specific MCP transport for the generic Magic Civilization Player API. Lets Claude Code play one slot of the game directly — no API key, no second SDK layer.

This package is one client of the player API; the underlying Godot harness (scripts/player-api-server.sh + src/game/engine/scenes/headless/player_api_main.tscn) is client-agnostic and speaks JSON-Lines. Other consumers:

  • Plain Python / RL trainer / OpenSpiel adaptersubprocess.Popen the harness directly; example in scripts/player-api-example.py.
  • Shell smoke / regression testsscripts/claude-smoke-5endturn.sh, scripts/claude-demo-25turn.sh write JSON-Lines to stdin.

Wire-protocol contract: src/game/engine/docs/PLAYER_API.md.

What it does

Stdio-transport MCP server. Spawns scripts/player-api-server.sh as a child process on first tool invocation; reuses the harness across calls. Translates each MCP tool call into one JSON-Lines request to the harness and returns the response as MCP text content.

Tools exposed

Tool Args Returns
magic_civ_view none Fog-aware PlayerView JSON for player slot 0
magic_civ_act {action: PlayerAction} {events, view} after applying
magic_civ_end_turn none Sugar for magic_civ_act({type:"end_turn"})

Full PlayerAction taxonomy and view shape live in src/game/engine/docs/PLAYER_API.md.

Install + build

cd tooling/claude-player-mcp
npm install
npm run build         # emits dist/index.js with shebang

Wire into Claude Code

Add to your project's .mcp.json (or ~/.claude/.mcp.json for global):

{
  "mcpServers": {
    "magic-civ": {
      "command": "node",
      "args": ["./tooling/claude-player-mcp/dist/index.js"]
    }
  }
}

After reloading Claude Code, three new tools appear: magic_civ_view, magic_civ_act, magic_civ_end_turn.

Ask Claude Code to "play a turn of Magic Civilization" and it'll start calling them.

Env passed through to the harness

CP_SEED, CP_PLAYERS, CP_CLAUDE_SLOT, CP_MAP_SIZE, CP_MAP_TYPE, CP_OMNISCIENT, CP_TIMEOUT_SEC, CP_LOG_FILE. Set them in the MCP server entry's env block in .mcp.json for per-session overrides.

CP_SERVER overrides the path to the harness launcher if you need to test against a custom build.

CP_MCP_WIRE_LOG=1 mirrors every JSON-Lines request/response to stderr for debugging.

Architecture

Claude Code (stdio MCP client)
       │
       ▼ MCP / stdio
@magic-civ/claude-player-mcp (this package)
       │
       ▼ spawn() + JSON-Lines pipe
scripts/player-api-server.sh
       │
       ▼ flatpak Godot --headless
GdPlayerApi (api-gdext) → mc-player-api → mc-turn handlers

Owning objective: .project/objectives/p2-67-claude-player-api.md. Wire-protocol contract: src/game/engine/docs/PLAYER_API.md.