Skip to main content
Glama

civ6-mcp

An MCP server that lets LLM agents play full games of Civilization VI.

Connect any MCP-compatible client — Claude Code, Codex, Gemini CLI, or your own — to a running Civ 6 game. The agent reads game state, moves units, manages cities, conducts diplomacy, and ends turns, all through the game's own rule-enforcing APIs. No cheats, no vision model required.

Capabilities

76 tools covering the full gameplay loop:

  • Units — list, move, attack, fortify, found cities, build improvements, promote, upgrade

  • Cities — inspect, set production, purchase units/buildings with gold, manage focus

  • Map — explore terrain, resources, fog of war; get settle and district placement advice

  • Research — browse tech and civic trees, set research targets

  • Diplomacy — relationships, modifiers, delegations, embassies, alliances, peace deals

  • Trade — propose and respond to deals, manage trade routes and destinations

  • Government — swap policy cards, change governments, choose era dedications

  • Governors — appoint, assign to cities, promote

  • Religion — found pantheons and religions, select beliefs, track spread

  • Great People — recruit, patronize, reject

  • World Congress — vote on resolutions, manage diplomatic favor

  • Victory — track progress across all victory conditions

  • Game lifecycle — save, load, launch, restart, kill

Every turn, end_turn takes before/after snapshots and reports what happened: units damaged, cities grew, production completed, threats spotted near your cities.

Related MCP server: civ6-mcp

Quick start

1. Configure Civ 6

Enable the FireTuner debug interface and configure recommended settings:

Setting

Value

Why

Tuner

Enabled

Required — opens the TCP debug port the MCP server connects to. Disables achievements.

Auto End Turn

Disabled

The agent controls when turns end. Auto-end interferes with the blocker resolution flow.

Windowed mode

Recommended

Lets you watch the game while the agent plays. Required for OCR-based save loading.

Windows: All three settings are available in the in-game Options menu. The Tuner setting appears as "Tuner (disables achievements)" under gameplay options.

macOS: The Tuner setting is not exposed in the menu. Edit AppOptions.txt directly and set EnableTuner 1:

~/Library/Application Support/Sid Meier's Civilization VI/Firaxis Games/Sid Meier's Civilization VI/AppOptions.txt

Linux: Same as macOS — edit AppOptions.txt directly and set EnableTuner 1:

~/.local/share/aspyr-media/Sid Meier's Civilization VI/AppOptions.txt

Install the Civ 6 SDK — the tuner server is part of the SDK, not the base game:

  1. In Steam, go to Library → filter by Tools

  2. Find and install "Sid Meier's Civilization VI SDK"

Important notes:

  • Close FireTuner.exe (the SDK's GUI tool) before running civ6-mcp — the game only allows one tuner connection at a time

  • Do not run from WSL — the network bridging between WSL2 and Windows is unreliable and the tuner server locks up after failed connections

  • If the connection fails, restart the game — the tuner often hangs after a bad handshake and won't recover until the process is recycled

  • The native Linux port is required — the FireTuner debug interface is built into the native binary. Proton/Wine builds do not expose it.

  • The game runs as a single Civ6 process launched via Steam Linux Runtime (scout-on-soldier).

  • GUI automation (OCR-based menu navigation) requires X11. On Wayland, the game typically runs under XWayland which should work, but a native X11 session is most reliable.

Restart Civ 6. The game will listen on TCP port 4318 for connections.

2. Install

git clone https://github.com/lmwilki/civ6-mcp.git
cd civ6-mcp
uv sync

For GUI automation features (screenshot, OCR-based menu navigation):

# macOS
uv pip install 'civ6-mcp[launcher-macos]'

# Windows (uses built-in Windows OCR — no external binaries needed)
uv pip install 'civ6-mcp[launcher-windows]'

# Linux (Ubuntu/Debian)
sudo apt install xdotool tesseract-ocr
uv pip install 'civ6-mcp[launcher-linux]'

3. Test the connection

With Civ 6 running and a game loaded:

uv run python scripts/test_connection.py

You should see a successful handshake and a list of Lua states (GameCore_Tuner, InGame, etc.).

4. Configure your MCP client

The server runs over stdio. Point your client at it:

The repo includes .mcp.json — detected automatically:

cd civ6-mcp
claude

Add to your config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "civ6": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/civ6-mcp", "civ-mcp"]
    }
  }
}

Add to .codex/config.toml in the project root:

[mcp_servers.civ6]
command = "uv"
args = ["run", "--directory", "/path/to/civ6-mcp", "civ-mcp"]

Add to .gemini/settings.json in the project root:

{
  "mcpServers": {
    "civ6": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/civ6-mcp", "civ-mcp"]
    }
  }
}

The server speaks stdio JSON-RPC:

uv run civ-mcp

5. Play

Load a game in Civ 6, connect your client, and try:

Play my Civ 6 game. Start by getting an overview, then check units and
cities, and play through the turn.

The agent will orient with get_game_overview, scan the map for threats, move units, set production and research, handle diplomacy, and end the turn.

As a benchmark

Civilization VI is a compelling environment for evaluating LLM strategic reasoning. Games run 300+ turns with compounding decisions, incomplete information, and multiple competing objectives — a significant step up from single-turn or short-horizon tasks.

  • Multi-turn planning — decisions compound over hundreds of turns with delayed payoffs

  • Incomplete information — fog of war, hidden AI intentions, unexplored map

  • Resource management — balancing gold, production, science, culture, faith, and military

  • Opponent modeling — reading diplomatic signals, anticipating AI behavior

  • Strategic adaptation — responding to threats, shifting priorities mid-game

The MCP interface provides a clean abstraction: the model receives narrated game state as text and responds with tool calls. All game rules are enforced by the engine. A companion web app lets you replay sessions turn by turn.

How it works

Claude / Any MCP Client
    |  stdio (JSON-RPC)
    v
MCP Server (Python)    <- 70+ tools
    |
    |  Generates Lua code at runtime
    |  TCP :4318
    v
Civilization VI        <- Game is the TCP server

The server maintains a persistent TCP connection to Civ 6 via the FireTuner debug protocol. It generates Lua code, executes it inside the game's two Lua VMs (GameCore for reading state, InGame for issuing commands), parses the output, and returns narrated text to the LLM.

The repo includes an AGENTS.md playbook (symlinked as CLAUDE.md for Claude Code) with detailed instructions for agents: turn loop, combat, diplomacy, common pitfalls. See the devlog for the full development story, including reverse-engineering the FireTuner protocol and the many API quirks discovered along the way.

Requirements

  • macOS, Windows, or Linux with Civilization VI (Steam version, Gathering Storm DLC)

  • Python 3.12+ with uv

  • An MCP client (Claude Code, Codex, Gemini CLI, or any MCP-compatible client)

License

MIT

Available Tools

80 tools
appoint_governorA

Appoint a new governor.

Args:
    governor_type: e.g. GOVERNOR_THE_EDUCATOR (Pingala), GOVERNOR_THE_DEFENDER (Victor)

Requires available governor points. Use get_governors to see options.

Inputs: governor_type (required). Returns: result

assign_governorA

Assign an appointed governor to a city.

Args:
    governor_type: The governor type (from get_governors output)
    city_id: The city ID (from get_cities output)

Governor must already be appointed. Takes several turns to establish.

Inputs: city_id (required), governor_type (required). Returns: result

change_governmentA

Switch to a different government type.

Args:
    government_type: e.g. GOVERNMENT_CLASSICAL_REPUBLIC, GOVERNMENT_OLIGARCHY

Use get_policies to see current government. First switch after
unlocking a new tier is free (no anarchy).

Inputs: government_type (required). Returns: result

choose_dedicationA

Choose a dedication/commemoration for the current era.

Args:
    dedication_index: The index of the dedication (from get_dedications output)

Use get_dedications first to see available options and their bonuses.

Inputs: dedication_index (required). Returns: result

choose_pantheonA

Found a pantheon with the specified belief.

Args:
    belief_type: e.g. BELIEF_GOD_OF_THE_FORGE, BELIEF_DIVINE_SPARK

Use get_pantheon_beliefs first to see options. Requires enough faith
and no existing pantheon.

Inputs: belief_type (required). Returns: result

city_actionA

Issue a command to a city.

Args:
    city_id: City ID (from get_cities output)
    action: Currently supported: 'attack' (city ranged attack)
    target_x: Target X coordinate (required for attack)
    target_y: Target Y coordinate (required for attack)

For attack: city must have walls and not have fired this turn.
Range is 2 tiles from city center.

For captured/disloyal city decisions (city_id is ignored, uses pending city):
- 'keep': Keep the city (works for both captured and loyalty-flipped cities)
- 'reject': Reject/free a disloyal city (loyalty flip only)
- 'raze': Raze a captured city (military conquest only)
- 'liberate_founder': Liberate to original founder
- 'liberate_previous': Liberate to previous owner

Inputs: action (required), city_id (required), target_x, target_y. Returns: result

dismiss_popupA

Dismiss any blocking popup in the game UI.

Call this if you suspect a popup (e.g. historic moment, boost notification) is blocking interaction.

Inputs: no named parameters. Returns: result

end_turnA
Destructive

End the current turn.

Make sure you've moved all units, set production, and chosen research
before ending the turn.

All 5 reflection parameters are required and must be non-empty.
These form the per-turn diary — your persistent memory across sessions:
    tactical: What happened this turn — combat, movements, improvements.
    strategic: Current standing vs rivals — yields, city count, victory path.
    tooling: Tool issues or observations. Write "No issues" if none.
    planning: Concrete actions for the next 5-10 turns.
    hypothesis: Predictions — enemy behavior, resource needs, timelines.

IMPORTANT: Reflections are recorded BEFORE the AI processes its turn.
Anything that surfaces after end_turn (diplomacy proposals, AI movements,
events reported in the turn result) belongs in the NEXT turn's diary.
If end_turn is blocked and you call it again after resolving the blocker,
the diary entry from the first call is kept — do not repeat reflections.

Inputs: tooling, planning, tactical, strategic, +1 more. Returns: result

form_allianceA

Form an alliance with another civilization.

Args:
    other_player_id: The player ID (from get_diplomacy output)
    alliance_type: One of: MILITARY, RESEARCH, CULTURAL, ECONOMIC, RELIGIOUS

Requires declared friendship and Diplomatic Service civic.
Use get_trade_options to check alliance eligibility first.

Inputs: other_player_id (required), alliance_type. Returns: result

found_religionB

Found a religion with a chosen name, follower belief, and founder belief.

Args:
    religion_type: e.g. RELIGION_HINDUISM, RELIGION_BUDDHISM, RELIGION_ISLAM
    follower_belief: e.g. BELIEF_WORK_ETHIC, BELIEF_CHORAL_MUSIC
    founder_belief: e.g. BELIEF_STEWARDSHIP, BELIEF_CHURCH_PROPERTY

Requires your Great Prophet to have already activated on a Holy Site
(via UNITOPERATION_FOUND_RELIGION). Use get_religion_beliefs
first to see available options.

Inputs: religion_type (required), founder_belief (required), follower_belief (required). Returns: result

get_available_governmentsA
Read-only

Governments we have unlocked, with policy slot counts and their bonus.

get_policies reports only the CURRENT government, so nothing listed the
alternatives or what they do — which made change_government unusable in
practice. Slot counts matter because they determine how many policy cards of
each type can be slotted.

Inputs: no named parameters. Returns: result

get_builder_tasksA
Read-only

Get a prioritized task board for all your builders.

Scans your territory for tiles needing improvements and matches them
with idle builders. Like the builder lens in the UI — shows what to
build where and which builder is closest.

Priority tiers:
- URGENT: Pillaged improvements (yield loss), unimproved strategic resources
- HIGH: Unimproved luxury/bonus resources
- NORMAL: Empty tiles that could benefit from farms/mines/lumber mills

Call this before issuing builder orders each turn.

Inputs: no named parameters. Returns: result

get_citiesA
Read-only

List all your cities with yields, population, production, growth, and loyalty.

Each city shows its id (needed for production commands). Cities losing loyalty show warnings with flip timers.

Inputs: no named parameters. Returns: result

get_city_productionA
Read-only

List what a city can produce right now.

Args:
    city_id: City ID (from get_cities output)

Returns available units, buildings, and districts with production costs.
Call this when a city finishes building or to decide what to produce next.

Inputs: city_id (required). Returns: result

get_city_statesA
Read-only

List known city-states with envoy counts and types.

Shows envoy tokens available, each city-state's type (Scientific,
Industrial, etc.), how many envoys you've sent, and who is suzerain.
Use send_envoy to send an envoy.

Inputs: no named parameters. Returns: result

get_dedicationsA

Get current era age, available dedications, and active ones.

Shows era score thresholds, whether you're in a Golden/Dark/Normal age,
and lists available dedication choices with their bonuses.
Use choose_dedication to select one when required.

Inputs: no named parameters. Returns: result

get_diaryA
Read-only

Read diary entries for game memory.

Args:
    last_n: Number of most recent entries to return (default 5, max 50).
            Used when turn/from_turn/to_turn are not specified.
    turn: Return the single entry for this turn number.
    from_turn: Return entries from this turn onward (inclusive).
    to_turn: Return entries up to this turn (inclusive).

Auto-detects the current game from the live connection. Each game has
its own diary file (keyed by civ + random seed).

Call this at the start of a session or after context compaction to
restore strategic memory from previous turns.

Inputs: turn, last_n, to_turn, from_turn. Returns: result

get_diplomacyA
Read-only

Get diplomatic status with all known civilizations.

Shows diplomatic state (Friendly/Neutral/Unfriendly), relationship modifiers with scores and reasons, grievances, delegations/embassies, and available diplomatic actions you can take. Also shows visible enemy city details (name, population, loyalty, walls).

Inputs: no named parameters. Returns: result

get_district_advisorA
Read-only

Show best tiles to place a district with adjacency bonuses.

Args:
    city_id: City ID (from get_cities)
    district_type: e.g. DISTRICT_CAMPUS, DISTRICT_HOLY_SITE, DISTRICT_INDUSTRIAL_ZONE

Returns valid placement tiles ranked by adjacency bonus.
Use set_city_production with target_x/target_y to build the district.

Inputs: city_id (required), district_type (required). Returns: result

get_district_infoA
Read-only

What each district does: base yields, adjacency rules, and prerequisites.

Read from the game's own GameInfo tables, so it matches the installed ruleset
and DLC rather than a remembered table. Pair with get_district_advisor, which
gives the actual placement tiles and their adjacency totals for one district.

Inputs: no named parameters. Returns: result

get_empire_resourcesA
Read-only

Get a summary of all resources in and near your empire.

Shows owned resources (improved/unimproved) grouped by type, and unclaimed resources near your cities.

Inputs: no named parameters. Returns: result

get_game_overviewA
Read-only

Get a high-level summary of the current game state.

Returns turn number, civilization, yields (gold/science/culture/faith), current research and civic, and counts of cities and units. Call this first to orient yourself.

Inputs: no named parameters. Returns: result

get_global_settle_advisorA
Read-only

Find the best settle locations across the entire revealed map.

Unlike get_settle_advisor (which searches near a specific settler),
this scans all revealed land for the top 10 settle candidates.
Use this when deciding WHERE to send a settler, not just where to settle.

Inputs: no named parameters. Returns: result

get_governorsA
Read-only

Get governor status, appointed governors, and available types.

Shows governor points, currently appointed governors with assignments,
and governors available to appoint. Use appoint_governor to appoint one.

Inputs: no named parameters. Returns: result

get_gp_advisorA

Show best cities to activate a Great Person, ranked by suitability.

Args:
    unit_index: The Great Person unit's index (from get_units output).

Lists all cities with the matching district (e.g., campuses for Great Scientists),
showing which ones the GP can activate on, distance, city yield, and great work
slot availability for cultural GPs.

Inputs: unit_index (required). Returns: result

get_great_peopleA
Read-only

See available Great People and recruitment progress.

Shows which Great People are available, their recruitment cost, and which civilization (if any) is recruiting them.

Inputs: no named parameters. Returns: result

get_map_areaA
Read-only

Get terrain info for tiles around a point.

Args:
    center_x: X coordinate of center tile
    center_y: Y coordinate of center tile
    radius: How many tiles out from center (default 2, max 4)

Inputs: center_x (required), center_y (required), radius. Returns: result

get_notificationsA
Read-only

Get all active game notifications.

Shows action-required items (need your decision) and informational notifications. Action-required items include which MCP tool to use to resolve them. Call this to check what needs attention without ending the turn.

Inputs: no named parameters. Returns: result

get_pantheon_beliefsA
Read-only

Get pantheon status and available beliefs for selection.

Shows current pantheon (if any), faith balance, and all available
pantheon beliefs with their bonuses. Use choose_pantheon to found one.

Inputs: no named parameters. Returns: result

get_pathing_estimateA
Read-only

Estimate how many turns a unit needs to reach a destination.

Args:
    unit_id: The unit's composite ID (from get_units output)
    target_x: Destination X coordinate
    target_y: Destination Y coordinate

Returns estimated turns, path length, and reachable tiles this turn.

Inputs: unit_id (required), target_x (required), target_y (required). Returns: result

get_pending_diplomacyA
Read-only

Check for pending diplomacy encounters (e.g. first meeting with a civ).

Diplomacy encounters block turn progression. Call this if end_turn
reports the turn didn't advance. Returns any open sessions with their
dialogue text, visible buttons, and response guidance.

Inputs: no named parameters. Returns: result

get_pending_tradesA
Read-only

Check for pending trade deal offers from other civilizations.

Shows what each civ is offering and what they want in return.
Use respond_to_trade to accept or reject.

Inputs: no named parameters. Returns: result

get_policiesA
Read-only

Get current government, policy slots, and available policies.

Shows current government type, each policy slot with its type and current policy (if any), and all unlocked policies grouped by compatible slot type. Wildcard slots accept any policy type.

Inputs: no named parameters. Returns: result

get_purchasable_tilesA
Read-only

List tiles a city can purchase with gold.

Args:
    city_id: City ID (from get_cities)

Shows cost, terrain, and resources for each purchasable tile.
Tiles with luxury/strategic resources are listed first.

Inputs: city_id (required). Returns: result

get_reachable_tilesA
Read-only

List the tiles a unit can legally reach with its remaining movement.

Args:
    unit_id: The unit's composite ID (from get_units output)

Uses the engine's own reachable-movement calculation, so terrain and feature
costs, roads and railroads, river crossings, embarking, zone of control and
impassable terrain are all already applied. Prefer this over reasoning about
per-tile movement cost yourself — that omits river/road effects and there is
no impassable flag to read.

Each line: (x,y) terrain [feature] mv:<cost> [occupied by <unit> of player N]
A tile occupied by a hostile unit is an attack target, not a move
destination, so it will not appear here.

Inputs: unit_id (required). Returns: result

get_religion_beliefsA

Get religion founding status, available religions, and available beliefs.

Shows whether you've founded a religion, available religion types to choose,
and beliefs grouped by class (Follower, Founder, Enhancer, Worship).
Use found_religion to found a religion after your Great Prophet activates.

Inputs: no named parameters. Returns: result

get_religion_spreadA
Read-only

Get per-city religion breakdown across all visible cities.

Shows which religion is majority in each city, follower counts, and which religions are closest to religious victory.

Inputs: no named parameters. Returns: result

get_revealed_mapA
Read-only

The whole revealed map as a compact character grid, plus entity positions.

One character per tile so the full map fits in a bounded amount of text —
spatial structure is preserved, fine detail is not. Rows are printed north to
south; column index is x.

Legend: ' ' unrevealed, '~' water, 'M' mountain, '^' hills, 'g' grassland,
'p' plains, 'd' desert, 't' tundra, 's' snow, 'F' forest, 'J' jungle,
'W' marsh/floodplain.

Cities and units follow with exact coordinates and owner ids, since those are
what orders reference. Only revealed tiles and visible units appear — this
never exceeds what the player can actually see.

KEPT DELIBERATELY, for the entity lists rather than for the grid. The
`cities:` section is the only place any tool reports FOREIGN cities with
coordinates — get_city_states names city-states without positions, and
get_diplomacy gives a per-civ city count and none at all — so it is what
anything needing a target city coordinate has to read (the jev harness's spy
travel options come from here). The grid is for computing facts from, not for
pasting into a prompt: a measured probe put an ASCII map of this shape in
front of a model and frontier identification was 2/21, chance, while the same
fact counted and stated in words was 21/21.

Not cheap: the map is scanned in five row bands because one whole-map Lua
pass overran the FireTuner read, so this is five round-trips. Callers that
want it every turn should cache it for the turn.

The `visible units:` rows have the SAME line shape as the `cities:` rows, so
any parser has to scope itself to the section header rather than matching
"(x,y) name [player n]" line by line.

Inputs: no named parameters. Returns: result

get_settle_advisorA
Read-only

List best settle locations near a settler unit.

Args:
    unit_id: The settler's composite ID (from get_units output)

Scores locations by yields, water, defense, and resource value.
Returns top 5 candidates sorted by score.

Inputs: unit_id (required). Returns: result

get_spiesA
Read-only

List all your spy units with position, rank, city, and available missions.

Shows each spy's composite id (needed for spy_action), current location,
rank (Recruit/Agent/Special Agent/Senior Agent), XP, and which operations
are available at their current position.

Note: offensive missions only become available once the spy has physically
arrived in the target city. Use spy_action with action='travel' first.

Inputs: no named parameters. Returns: result

get_strategic_mapA
Read-only

Get fog-of-war boundaries and unclaimed resources across the map.

Shows how far explored territory extends from each city (in 6 directions), highlighting directions that need exploration. Also lists unclaimed luxury and strategic resources on revealed but unowned land.

Inputs: no named parameters. Returns: result

get_tech_civicsA
Read-only

Get technology and civic research status.

Shows current research, current civic, turns remaining, and lists of available technologies and civics to choose from.

Inputs: no named parameters. Returns: result

get_trade_destinationsA
Read-only

List valid trade route destinations for a trader unit.

Args:
    unit_id: The trader's composite ID (from get_units output)

Shows domestic and international destinations. Use unit_action
with action='trade_route' and target_x/target_y to start a route.

Inputs: unit_id (required). Returns: result

get_trade_optionsA
Read-only

See what both sides can trade — like opening the trade screen.

Args:
    other_player_id: The player ID (from get_diplomacy output)

Shows gold, resources, favor, open borders status, and alliance eligibility
for both you and the other civilization. Use before propose_trade to see
what's available.

Inputs: other_player_id (required). Returns: result

get_trade_routesA
Read-only

Get trade route capacity, active routes, and trader status.

Shows how many routes are active vs capacity, and lists all trader units with their positions and whether they're idle or on a route.

Inputs: no named parameters. Returns: result

get_unit_promotionsA
Read-only

List available promotions for a unit.

Args:
    unit_id: The unit's composite ID (from get_units output)

Shows promotions filtered by the unit's promotion class.
Only units with enough XP will have promotions available.

Inputs: unit_id (required). Returns: result

get_unitsA
Read-only

List all your units with position, type, movement, and health.

Each unit shows its id and idx (needed for action commands). Consumed units (e.g. settlers that founded cities) are excluded.

Inputs: no named parameters. Returns: result

get_victory_progressA
Read-only

Get victory condition progress for all civilizations.

Shows progress toward Science, Domination, Culture, Religious, Diplomatic, and Score victories. Includes space race VP, diplomatic VP, tourism vs domestic tourists, religion spread, capital ownership, and military strength. Call every 20-30 turns to track the race.

Inputs: no named parameters. Returns: result

get_wonder_advisorA
Read-only

Show best tiles to place a wonder with displacement cost analysis.

Args:
    city_id: City ID (from get_cities output)
    wonder_name: Wonder building type, e.g. BUILDING_CHICHEN_ITZA, BUILDING_ORSZAGHAZ

Returns valid placement tiles ranked by displacement cost (lowest = best):
tiles with no improvements or resources are preferred over productive tiles.
Also shows terrain, feature, river/coastal status, and any resources/improvements
that would be removed by placing the wonder there.
Use set_city_production with target_x/target_y to build the wonder.

Inputs: city_id (required), wonder_name (required). Returns: result

get_world_congressA
Read-only

Get World Congress status, active resolutions, and voting options.

Shows whether congress is in session, resolutions to vote on (with options A/B
and possible targets), turns until next session, and your diplomatic favor.
When in session, use queue_wc_votes to register votes before end_turn.

Inputs: no named parameters. Returns: result

kill_gameA
Destructive

Kill the Civ 6 game process and wait for Steam to deregister.

Only kills Civ 6 processes. Waits ~10 seconds for Steam to deregister
so the game can be relaunched cleanly.

Inputs: no named parameters. Returns: result

launch_gameA
Destructive

Launch Civ 6 via Steam.

Starts the game and waits for the process to appear (~15-30 seconds).
The game will be at the main menu after launch — use load_save or
restart_and_load to load a specific save.

NOTE: FireTuner connection is NOT available at the main menu.
Only in-game MCP tools work after a save is loaded.

Inputs: no named parameters. Returns: result

list_savesA
Read-only

List available save files (normal, autosave).

Returns indexed list of saves. Use load_save(save_index=N) to load one.
Call this before load_save to see what's available.

Inputs: no named parameters. Returns: result

load_game_saveA
Destructive

Load a save file by name. No need to call list_saves first.

Args:
    save_name: Save name without extension (e.g. "0_MCP_0079",
               "0A_GROUND_CONTROL", "AutoSave_0221", "quicksave").

Tries Lua-based loading first (fast, ~5s). If the save isn't found
via Lua (common for autosaves/quicksaves), falls back to OCR menu
navigation (~90s) after verifying the file exists on disk.

Inputs: save_name (required). Returns: result

load_saveA
Destructive

Load a save file by index from the most recent list_saves() result.

Args:
    save_index: Index number from list_saves output (1-based)

The game will reload entirely. Wait ~10 seconds after calling this,
then use get_game_overview to verify the loaded state.

Inputs: save_index (required). Returns: result

load_save_from_menuA
Destructive

Navigate the main menu to load a save via OCR-guided clicking.

Args:
    save_name: Autosave name (e.g. "AutoSave_0221"). If not provided,
               loads the most recent autosave.

Requires the game to be running and at the main menu. Uses macOS Vision
OCR to find and click menu elements. Takes 30-90 seconds.

After loading, wait ~10 seconds then call get_game_overview to verify.

Requires pyobjc: uv pip install 'civ6-mcp[launcher]'

Inputs: save_name. Returns: result

patronize_great_personA

Buy a Great Person instantly with gold or faith.

Args:
    individual_id: The individual's ID (from get_great_people output)
    yield_type: YIELD_GOLD (default) or YIELD_FAITH

Costs shown in get_great_people output under "Patronize:".
Requires enough gold/faith to cover the cost.

Inputs: individual_id (required), yield_type. Returns: result

promote_governorB

Promote a governor with a new ability.

Args:
    governor_type: The governor type (from get_governors output)
    promotion_type: The promotion type (from get_governors output, shown under each governor)

Requires available governor points. Use get_governors to see available promotions.

Inputs: governor_type (required), promotion_type (required). Returns: result

promote_unitA

Apply a promotion to a unit.

Args:
    unit_id: The unit's composite ID (from get_units output)
    promotion_type: e.g. PROMOTION_BATTLECRY, PROMOTION_TORTOISE

Use get_unit_promotions first to see available options.

Inputs: unit_id (required), promotion_type (required). Returns: result

propose_peaceA

Propose white peace to a civilization you're at war with.

Args:
    other_player_id: The player ID (from get_diplomacy output)

Requires being at war and past the 10-turn war cooldown.
The AI may accept or reject based on war score and relationship.

Inputs: other_player_id (required). Returns: result

propose_tradeA

Propose a trade deal to another civilization.

Args:
    other_player_id: The player ID (from get_diplomacy output)
    offer_gold: Lump sum gold to give them
    offer_gold_per_turn: Gold per turn to give them (30-turn duration)
    offer_resources: Comma-separated resource types to offer, e.g. "RESOURCE_SILK,RESOURCE_TEA"
    offer_favor: Diplomatic favor to offer
    offer_open_borders: True to offer our open borders
    request_gold: Lump sum gold to request from them
    request_gold_per_turn: Gold per turn to request (30-turn duration)
    request_resources: Comma-separated resource types to request
    request_favor: Diplomatic favor to request from them
    request_open_borders: True to request their open borders
    joint_war_target: Player ID of a third civ to declare joint war against
    mode: "send" to commit the deal, "test" to preview AI's counter-offer without committing

Examples: Gift 100 gold: offer_gold=100. Trade silk for 3 gpt: offer_resources="RESOURCE_SILK", request_gold_per_turn=3.
Mutual open borders: offer_open_borders=True, request_open_borders=True.
Test a deal first: mode="test" to see what the AI thinks is fair, then mode="send" to commit.

Inputs: other_player_id (required), mode, offer_gold, offer_favor, +9 more. Returns: result

purchase_itemA

Purchase a unit or building instantly with gold or faith.

Args:
    city_id: City ID (from get_cities output)
    item_type: UNIT or BUILDING
    item_name: e.g. UNIT_WARRIOR, BUILDING_MONUMENT
    yield_type: YIELD_GOLD (default) or YIELD_FAITH

Costs gold/faith immediately. Use get_city_production to see what's available.

Inputs: city_id (required), item_name (required), item_type (required), yield_type. Returns: result

purchase_tileA

Buy a tile for a city with gold.

Args:
    city_id: City ID
    x: Tile X coordinate
    y: Tile Y coordinate

Use get_purchasable_tiles first to see costs and options.

Inputs: x (required), y (required), city_id (required). Returns: result

queue_wc_votesA

Pre-configure World Congress votes for the upcoming session.

Args:
    votes: JSON array of vote objects, e.g.
        '[{"hash": -513644209, "option": 1, "target": 2, "votes": 5}]'
        hash = resolution type hash (from get_world_congress)
        option = 1 for A, 2 for B
        target = player ID for PlayerType resolutions (from get_world_congress
                 target list, e.g. [target=2] Portugal), or target value for
                 non-player resolutions. The handler resolves to the correct
                 0-based index at runtime.
        votes = max votes to allocate (will use as many as favor allows)

Call this BEFORE end_turn when get_world_congress shows 0 turns until next
session. Registers an event handler that fires during WC processing and
casts your votes with the specified preferences.

If you don't call this, end_turn will pause at the World Congress session
and return control to you for interactive voting.

Inputs: votes (required). Returns: result

recruit_great_personA

Recruit a Great Person using accumulated GP points.

Args:
    individual_id: The individual's ID (from get_great_people output, shown after ability)

Requires enough Great Person points for that class.
The GP spawns in your capital. Use get_great_people to check [CAN RECRUIT] status.

Inputs: individual_id (required). Returns: result

reject_great_personA

Pass on a Great Person (skip to the next one in that class).

Args:
    individual_id: The individual's ID (from get_great_people output)

Costs faith. The next Great Person in that class becomes available.
Use when you don't want the current GP and want to save points for a better one.

Inputs: individual_id (required). Returns: result

respond_to_diplomacyA

Respond to a pending diplomacy encounter.

Args:
    other_player_id: The player ID of the other civilization (from get_pending_diplomacy)
    response: "POSITIVE" (friendly) or "NEGATIVE" (dismissive)

First meetings typically have 2-3 rounds. The tool automatically detects
and closes goodbye-phase sessions (where dialogue text stops changing).
If SESSION_CONTINUES is returned, send another response for the next round.

Inputs: response (required), other_player_id (required). Returns: result

respond_to_tradeA

Accept or reject a pending trade deal.

Args:
    other_player_id: The player ID of the civilization (from get_pending_trades)
    accept: True to accept the deal, False to reject it

Use get_pending_trades first to see what's being offered.

Inputs: accept (required), other_player_id (required). Returns: result

restart_and_loadA
Destructive

Full game recovery: kill, relaunch, and load a save.

Args:
    save_name: Autosave name (e.g. "AutoSave_0221"). If not provided,
               loads the most recent autosave.

This is the recommended tool for recovering from game hangs (e.g. AI turn
processing stuck in infinite loop). Takes 60-120 seconds total:
1. Kills the game process
2. Waits for Steam to deregister (~10s)
3. Relaunches via Steam (~15-30s for process start + main menu)
4. Navigates menus via OCR to load the save (~30-60s)

After completion, wait ~10 seconds then call get_game_overview to verify.

Inputs: save_name. Returns: result

run_luaA
Destructive

Run arbitrary Lua code in the game. Advanced escape hatch — prefer built-in tools.

Args:
    code: Lua code to execute. Use print() for output, end with print("---END---").
    context: "gamecore" (default) for read-only state queries.
             "ingame" for commands and UI-dependent queries.

Context differences:
  gamecore: Players[], GameInfo.*, Map.*, Game.* — safe read-only access.
            CANNOT use: UI.*, UnitManager.*, CityManager.*, notifications.
  ingame:   All APIs including UI.*, UnitManager.*, CityManager.*.
            Use for: moving units, setting research, diplomacy actions.

Always use print() for output (not return).

Inputs: code (required), context. Returns: result

send_diplomatic_actionA

Send a proactive diplomatic action to another civilization.

Args:
    other_player_id: The player ID (from get_diplomacy output)
    action: One of: DIPLOMATIC_DELEGATION, DECLARE_FRIENDSHIP, DENOUNCE,
            RESIDENT_EMBASSY, OPEN_BORDERS,
            DECLARE_SURPRISE_WAR, DECLARE_FORMAL_WAR, DECLARE_HOLY_WAR,
            DECLARE_LIBERATION_WAR, DECLARE_RECONQUEST_WAR,
            DECLARE_PROTECTORATE_WAR, DECLARE_COLONIAL_WAR,
            DECLARE_TERRITORIAL_WAR

Delegations cost 25 gold and can be rejected if the civ dislikes you.
Embassies require Writing tech. Use get_diplomacy to see available actions.
Surprise war is always available if not allied/friends. Other war types
(casus belli) require specific civics and conditions.

Inputs: action (required), other_player_id (required). Returns: result

send_envoyA

Send an envoy to a city-state.

Args:
    player_id: The city-state's player ID (from get_city_states)

Requires available envoy tokens. Use get_city_states to see options.

Inputs: player_id (required). Returns: result

set_city_focusA

Set a city's citizen yield priority.

Args:
    city_id: City ID
    focus: One of: food, production, gold, science, culture, faith, default
           'default' clears all focus settings.

Cities automatically assign citizens to tiles. This biases the AI
toward the chosen yield type when assigning new citizens.

Inputs: focus (required), city_id (required). Returns: result

set_city_productionA

Set what a city should produce.

Args:
    city_id: City ID (from get_cities output)
    item_type: UNIT, BUILDING, DISTRICT, or PROJECT
    item_name: e.g. UNIT_WARRIOR, BUILDING_MONUMENT, DISTRICT_CAMPUS, PROJECT_LAUNCH_EARTH_SATELLITE
    target_x: X coordinate for district/wonder placement (required for districts — use get_district_advisor to find best tile)
    target_y: Y coordinate for district/wonder placement

Tip: call get_cities first to see your cities and their IDs.

Inputs: city_id (required), item_name (required), item_type (required), target_x, +1 more. Returns: result

set_policiesA

Set policy cards in government slots.

Args:
    assignments: Comma-separated slot assignments, e.g.
        "0=POLICY_AGOGE,1=POLICY_URBAN_PLANNING"
        Slots not listed keep their current policy. Use NONE to
        explicitly clear a slot (e.g. "2=NONE"). Use get_policies to
        see available policies and slot indices.

Wildcard slots can accept any policy type. Military slots accept
military policies, economic slots accept economic policies, etc.

Inputs: assignments (required). Returns: result

set_researchA

Choose a technology or civic to research.

Args:
    tech_or_civic: The type name, e.g. TECH_POTTERY or CIVIC_CRAFTSMANSHIP
    category: "tech" or "civic" (default: tech)

Tip: call get_tech_civics first to see available options.

Inputs: tech_or_civic (required), category. Returns: result

skip_remaining_unitsA

Skip all units that still have moves remaining.

Useful after diplomacy encounters invalidate all standing orders. Uses GameCore FinishMoves on each unit — fast, reliable, no async issues.

Inputs: no named parameters. Returns: result

spy_actionA

Send a spy to a city or launch a spy mission.

Args:
    unit_id: The spy's composite ID (from get_spies output)
    action: 'travel' to move spy to a city, or a mission type to launch a mission.
        Mission types: COUNTERSPY, GAIN_SOURCES, SIPHON_FUNDS, STEAL_TECH_BOOST,
        SABOTAGE_PRODUCTION, GREAT_WORK_HEIST, RECRUIT_PARTISANS,
        NEUTRALIZE_GOVERNOR, FABRICATE_SCANDAL
    target_x: X coordinate of the target city tile
    target_y: Y coordinate of the target city tile

Travel notes:
    - Valid targets: your own cities and city-states only.
    - Allied civ cities are NOT valid travel targets.
    - Travel is queued end-of-turn; spy position updates after turn ends.

Mission notes:
    - Spy must be physically IN the target city to launch any offensive mission.
    - Use 'travel' first, then end the turn, then launch the mission.
    - COUNTERSPY defends your own city (spy must be in your city).
    - get_spies shows which ops are available at the spy's current location.

Inputs: action (required), unit_id (required), target_x (required), target_y (required). Returns: result

unit_actionA

Issue a command to a unit.

Args:
    unit_id: The unit's composite ID (from get_units output)
    action: One of: move, attack, fortify, skip, found_city, improve, repair, remove_improvement, remove_feature, build_route, automate, heal, alert, sleep, delete, trade_route, activate, sacrifice_charges, teleport, spread_religion
    target_x: Target X coordinate (required for move/attack/trade_route/teleport)
    target_y: Target Y coordinate (required for move/attack/trade_route/teleport)
    improvement: Improvement type for builders (required for improve), e.g.
        IMPROVEMENT_FARM, IMPROVEMENT_MINE, IMPROVEMENT_QUARRY,
        IMPROVEMENT_PLANTATION, IMPROVEMENT_CAMP, IMPROVEMENT_PASTURE,
        IMPROVEMENT_FISHING_BOATS, IMPROVEMENT_LUMBER_MILL

For move/attack: provide target_x and target_y.
For trade_route: provide target_x and target_y of destination city.
For teleport: provide target_x and target_y of destination city. Traders only, must be idle (not on active route).
For improve: provide improvement name. Builder must be on the tile.
For repair: repairs a pillaged improvement on the builder's current tile. No improvement name needed.
For remove_improvement: demolishes an intact improvement on the builder's current tile (e.g. to replace a farm with a mine). Costs one charge.
For activate: activates a Great Person on their matching district.
For sacrifice_charges: Royal Society builder sacrifice — spends ALL builder charges to boost a district project (2% of cost per charge). Builder must be on the district tile.
For spread_religion: spreads religion at current tile. Missionaries/Apostles only.
For build_route: builds road/railroad on current tile. Military Engineers only. No charges used; costs 1 Iron + 1 Coal per railroad tile.
For fortify/skip/found_city/automate/heal/alert/sleep/delete: no target needed.
heal = fortify until healed (auto-wake at full HP).
alert = sleep but auto-wake when enemy enters sight range.
delete = permanently disband the unit.

Inputs: action (required), unit_id (required), target_x, target_y, +1 more. Returns: result

upgrade_unitA

Upgrade a unit to its next type (e.g. Slinger -> Archer).

Args:
    unit_id: The unit's composite ID (from get_units output)

Requires the right technology, enough gold, and the unit must have
moves remaining. The unit's movement is consumed by upgrading.

Inputs: unit_id (required). Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 80 tools

    Disambiguation5/5

    Each tool targets a distinct resource, action, or game system (e.g., get_cities vs get_units vs get_diplomacy). Even close pairs like load_save vs load_game_save are clearly differentiated by whether they take an index or a name.

    Naming Consistency5/5

    Almost all tools follow a consistent verb_noun snake_case pattern (get_cities, set_city_production, propose_trade). The only exceptions, unit_action and city_action, share the same noun_verb pattern and are therefore predictable.

    Tool Count1/5

    80 tools is far beyond a well-scoped set, even for a complex game like Civ 6. The sheer number overwhelms an agent and the rubric explicitly marks 25+ tools as too many.

    Completeness5/5

    The tool surface covers nearly every major Civ 6 system: cities, units, production, research, diplomacy, trade, religion, espionage, world congress, victory progress, and save management. There are no obvious dead ends or missing critical operations.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables LLMs to autonomously create characters, join matchmaking, and battle other LLMs in a turn-based game using 7 tools for status, abilities, and actions.
      ISC
    • A
      license
      A
      quality
      D
      maintenance
      An MCP server that lets LLM agents play full games of Civilization VI. It connects to a running game and provides tools for unit movement, city management, diplomacy, and more, all through the game's rule-enforcing APIs.
      76
      235
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Gives LLMs a genuine in-game seat in Civilization V, letting them scout, settle, negotiate, fight, and manage a civilization through tool calls with the same fog-of-war information a human player sees.
      4
      9
      1
      MIT