Skip to main content
Glama

Agentic MCP tools for Sid Meier's Civilization V: Brave New World

Give your agent a civilization. See what survives.

Civilization V armies gathering across a river and contested border, official game screenshot

Game image from Civilization V on Steam.

civ-v-llm-harness MCP server – quality and maintenance score on Glama

Built for agentic play

A rival settles the river first. Your peaceful science plan now has a border problem. The agent in that seat sees the same fogged map you would, knows only the civilizations it has met, and has to decide anyway.

This harness puts an AI agent in a real seat in Sid Meier's Civilization V. You own the game, you host the table, and the agent takes a human seat: across from you in hotseat or over LAN, in your chair against the game's AI, or beside other agents in one match. It plays by the same rules as everyone else at the table and sees no more than you would.

Ready to play? Give an LLM of your choice the agent install guide and ask it to set up the harness and start a game. The guide has the commands and checks; this page is for you. Give your agent the raw guide.

Requirements

Current release

Ways to play

Native Linux Steam build, Brave New World

2.13.1 · Lua runtime v335

Solo · hotseat · LAN · multi-LLM

On this page

Related MCP server: civ6-mcp

What you need

The game

Sid Meier's Civilization V with Brave New World on your own Steam account, as the native Linux build. Steam downloads it once you turn Proton off for the game.

A Linux desktop

x86_64 with a display. The game runs in a normal window on your screen. A Steam Deck works (docs/DECK_HOWTO.md).

An agent that speaks MCP

Claude Code, Codex CLI or any other MCP client, with whatever agent and budget you give it. Each agent at the table gets its own server.

Python 3.11 or newer

No compiler and no uv needed.

Setup is one sitting, and your agent does it. Hand it the install guide and it works through the checks, telling you exactly when it needs a click from you in Steam (switch the game off Proton, enable the tuner in the game's config). The game itself takes about two minutes to cold start.

Fair play

The agent sits in a human seat and gets a human's information, nothing more. That is the whole design.

  • Fog of war is fog. Fogged tiles carry no live units. Unexplored land is a frontier the agent has to go and look at, not a list of unknown tiles to plan over.

  • Unmet civilizations do not exist until the agent meets them. The AI's private plans stay private.

  • Diplomacy goes through the game's own screens. Deals, demands, peace terms, friendship, denouncement and leader conversations are the same ones the AI offers you, with the AI's actual replies. Between human seats (you and the agent, or two agents) everything goes over the trade table, as it does for you.

  • A seat is bound to its channel. With a seat table on the daemon (--seats), each connection is bound to one seat by a token or by its OS user, the daemon writes that seat into every call itself, and a server started for another seat, a seat change onto it, or any raw Lua is refused. Two agents in one hotseat see only their own seat (docs/AGENT_INSTALL.md, "Two agents, one game").

  • Refusals mirror the UI. If the game would not let you click it, the harness refuses it and says why. Every screen, hover and refusal reason a human reads is what the agent reads.

  • No back door. The raw Lua escape hatch is off unless you turn it on. docs/LIMITATIONS.md lists what is withheld and why, each item checked against the engine.

  • The whole game. Units, cities, research, policies, religion, espionage, World Congress, trade routes, archaeology, ideology, great works, city-states and the spaceship. No shortcut to a victory.

Built for how a model plays

The world reaches the agent as text shaped to its way of thinking, so it spends tokens on decisions rather than on scrolling. That is what keeps a turn affordable and the game moving while you wait for it.

  • Tiles as text, at the coordinates the move tools take. Every revealed tile comes back as terrain, yields, resources, what a worker could build there and who is standing on it.

  • The rules once, not on every row. reference is every unit, building, tech, policy, promotion, belief and terrain with its effect text, read once from the game's database (mods included). Lists carry names and live numbers only, so no hover is paid for twice.

  • One call per turn. turn(action="finish") ends the turn, waits, and comes back with the new turn's status, what happened in between, and the agent's own notes. briefing folds a whole turn into one compact read: about 2.5 KB for a 38-unit empire where the separate reads are 30 KB.

  • It sleeps through quiet turns, by its own choice. With skip_quiet_turns the agent asks to be left alone until something a human would look up for: combat of its own, a leader at the door with a decision, an empty city, happiness falling out of the comfortable band, a deal in its last turns (once), a threat beside a unit on the move. Other players' wars, alliances, denouncements and quests, a splash the harness already swept and a leader's plain remark are quiet. The agent picks how many turns to let pass; the harness only ever wakes it early.

  • Standing orders. notebook(action="give_order") hands a unit a short plan (walk there, build a farm; heal to 80%, go back, fortify) that runs itself at the start of each turn through the ordinary move tools. The moment anything unplanned happens it pauses and hands the unit back with a reason. It never attacks, declares war or ends the turn on its own.

  • Assignments and a notebook that survive amnesia. notebook(action="assign") gives a unit or city a role, a target and a done-when, and every briefing re-checks it against what the seat can see now. remember / recall keep the plan, threats and promises beside the game. Both outlive a context reset, so a model that forgets everything mid-game picks its own plan back up.

  • It looks before it leaps. The tactical view (state(what="unit", id, view="tactical")) is a unit's six neighbours with what a move would do there (attack, open with what the step costs and whose zone of control ends it, refused with why, enemy). state(what="compare") lays out a few production, research or worker options side by side with costs, turns and effects (a building already in the queue reads as queued, not refused). Neither picks for the agent.

  • Batches and safe retries. batch(actions=[...]) runs a list of orders and stops at the first refusal. An action_id makes a retried call a replay, never a second move.

  • A refusal says what to do instead. A mission name the engine does not have comes back with the nearest real ones and the unit's legal orders; a sleep where the unit can fortify names the equivalent; an end refused for units with movement left carries the exact skip orders for the next finish; a greyed button, a refused purchase, peace or ranged attack carries the engine's own sentence; a melee attack the engine drops without a word is named as a refused attack with the first closed gate the harness can read, not as an occupied plot. A refused building names the rule from the game's own table (a Windmill off flat land, Big Ben without Commerce, a resource the city lacks); a refused ideology tenet names its level gate, an unknown policy name comes back with the real names behind the shown ones, and a Great Prophet that has spread its religion is told that is what keeps it from a Holy Site. Every refusal is a next step, never a dead end.

  • A Great Person's withheld missions are explained. state(what="unit", id, view="actions").missing says why the engine greys a mission out: the Great Work slot census (filled / total, the buildings that carry one), the nearest plot where a concert tour or a trade mission plays, no moves left. A concert tour's reply says the tourism and who received it; a gift row names the city-state whose plot the unit stands on.

  • A notebook belongs to one game. Its file is keyed by the game's identity (the seat's starting plot and every slot's civilization, fixed when the map is made), so a new game that founds the same capital on the same turn never opens an older game's notes, assignments or standing orders; a notebook from before the key existed is taken over once, marked adopted, its orders paused until the seat looks at them.

  • A human seat is asked on the trade table. In hotseat, a Declaration of Friendship to another human is a deal that seat answers on its turn, war is the stock War button, denouncing is refused with why; nothing a human seat is sent is answered by its dormant AI. A proposal shows only on the seat it is sent to, and the answer to one echoes its items.

  • It knows when it has won, and when it has lost. The last spaceship part's reply says game_over and victory: "science", the spaceship screen reads complete, and the game_over gate names session(action="main_menu"); the engine's own end-turn blocker freezes at that moment and is not the read to trust. A capital taken ends with defeat: the last city, where it stood and who took it.

  • A turn is one call when nothing needs a look. turn(action="finish", actions=[...]) runs the closing orders and ends the turn together, ending nothing if an order is refused; a move's result carries revealed, what the move showed, so "move the scout and see" needs no second read.

  • It says what a human sees on the leader screen and on the map. Every war the seat is in comes with the Negotiate Peace gate (wars, the briefing's at_war rows: peace can be asked now, or why not) -- an agent sat twenty turns in a siege that one white-peace offer ended. A unit the engine moved while the others played is a unit_displaced event with where it went and what shares the tile it left. A frontier plot a foreign unit or city stands on says occupied, names the city, and stays in the reply however long the frontier is. A neighbour's Great General taking land is named with the plots it took, not just the headline. A turn no wait of ours opened still gets its turn-start work before its first order, and a turn that began while a leader screen was being answered is handed back unended with what it needs, never ended blind.

  • You can watch the seats think. python -m harness.spectator --ledger logs/calls.jsonl serves a page (a canvas map that stays at the frame on Huge maps, d3 for the zoom and the panels) where every plot a tool reply handed a model pulses in that seat's colour over a greyscale map, acts stay painted until the turn ends, the last seat's footprint ghosts through the next, and an Observer / Seat N switch cuts between the unfogged world and what one seat's replies contained. A seat view draws only what that seat's screen shows: never-seen plots black, fogged plots dimmed, other players' units only where visible. Read-only, records and replays with a scrubber (play/pause, speed, a slider whose ticks are the turn boundaries), and reads the game only when the world moves (docs/VISUALIZATION.md).

  • briefing measured live. Over four hotseat turns played both ways (docs/NOTES.md): 4.25 calls a turn against 8 with the separate reads, no refused order against two, about the same bytes.

  • The tactical view never guesses. Adjacency and map wrap come from the engine. One step's cost and the zone of control that ends it follow the engine's movement rules on the plots as seen; no turns-to-reach, which the engine cannot give safely. Nothing fogged is called safe.

  • A compare keeps a tile's own gain apart from the empire's (nothing until a city works it) and never calls a trade destination safe under fog.

  • A trade unit's second gate. Past the slot count the engine asks whether some city of yours can start a new route of that kind now; when it cannot, the briefing, compare and a refused production order quote the engine's own sentence ("no available sea trade routes") instead of offering to build or buy.

  • What an assignment review can report. on_track, condition_met, or needs_review with the observation behind it: a unit gone (an upgrade on its last plot is named; a unit our own order used up -- a Great Work written, a religion's last spread, a gift to a city-state -- is unit_spent with the reason, a plundered caravan says plundered; our own upgrade order carries the assignments and the open order onto the new id by itself), a reused id never followed, a city lost, a settle site now too close to a city, or a target out of sight kept as last seen, never assumed gone. notebook(action="amend") and notebook(action="close") do the rest.

  • What pauses a standing order. A hostile in sight, damage, an enemy on the destination, a refused step, no progress, or a direct command to that unit (never the command that created it).

  • What wakes skip_quiet_turns. Combat of our own, a leader message that asks something, an empty city, a happiness drop out of the comfortable band (or five at once), a deal in its last turns (once), a new strategic-resource shortfall, or a barbarian camp or hostile unit beside a unit on its way somewhere. A caller's wake_on words always wake; a fight between other players, their alliances, denouncements and quests, and a splash the harness swept never do.

  • After a context reset, a briefing carries the latest notes again and every assignment is re-checked.

What a game looks like

The agent plays through tool calls; you watch the game window. On its turn it checks what changed, inspects its cities and units, chooses actions the game permits, then ends the turn. In hotseat the window passes back to you and you take your turn as usual. Nine tools -- turn, state, order, question, answer, notebook, batch, session, reference -- and the loop is four lines:

turn(action="finish")                      -> the new turn: status, digest, notes; read `gate` first
question() -> answer(choice)               -> whatever the game asks, from its own `answers` rows
state(what="units", view="actions") ...  -> every reply that lists what can be done carries the order to copy
order(to="unit", id, action="move", args)  -> then notebook(action="remember") and turn(action="finish") again

When something blocks the turn, the status names it and hands back the rows that clear it. Refused orders explain why, the shape they should have had, and an example. The 145 one-tool-per-button names of the 1.x releases still answer, each reply naming the call to copy instead.

Turn 269, trimmed for width. It predates runtime v217; a status now also names the seat, carries the gate to clear first, happiness and any alerts, and lists automated or already-moving units under todo.ongoing:

{"turn": 269, "my_turn": true, "mode": "single", "blocking_name": "NO_ENDTURN_BLOCKING_TYPE",
 "todo": {"promotions": [], "research_unset": false, "cities": [], "units": []},
 "pending_popups": [], "game_over": false, "notifications": {"live": 2, "held": 99}}

What to expect

  • It is slow and it costs tokens. A developed empire means dozens of tool calls per turn. A game to victory is a long project; an evening is a few dozen turns. Quiet-turn skipping and standing orders are what keep that bill down.

  • Leave the window alone during the agent's turn. It drives the game's own screens the way a mouse would, and a stray click from you lands in its turn.

  • The game crashes sometimes. The Linux port does, with or without the harness. Quick saves every turn in solo (session(action="save") is one call elsewhere), the game's own autosaves and session(action="load_latest") make it a pause, not a loss. A supervisor can relaunch the game and rejoin a LAN game on its own.

  • You can read its mind. Every note the agent writes to itself and every assignment it gives a unit is a plain JSON file under ~/.local/share/civ5-harness/notes/, per game and seat. You can see what it planned before you find out whether it worked.

Ways to play

Mode

Who is where

Start it with

Solo

LLM in seat 0 versus the game's AI

harness.cli start-single --civ CIVILIZATION_ROME

Hotseat

You and the LLM(s) at one machine, turn by turn

harness.cli host-hotseat --humans 0 1 --nick 1=Claude

LAN

Each LLM runs its own game instance and joins like any player

scripts/launch_llm_client.sh, then harness.cli join-lan <host>

All three share the same tools. Several agents in one game each get their own MCP server, one per seat; every status names the seat it is playing, and session(action="seat") moves a server to another human seat without a restart. The agent cannot take over one of the built-in AI seats; the game does not expose that. To move a two-seat hotseat game along between sessions, scripts/hotseat_rounds.py alternates the seats and stops at the first turn that needs a decision.

The install guide walks through each mode. Saved states in saves/ reproduce late-game diplomacy, peace terms, Venice puppets and a combat lab if you want to drop a model into something interesting on turn one.

How it works

flowchart LR
    A["LLM client"] -->|stdio| B["MCP server<br/>nine tools"]
    B -->|Unix socket| C["tunerd<br/>one tuner connection"]
    C -->|TCP 4318| D["Civilization V<br/>preload shim + FireTuner"]

Civilization V ships a debugging channel, FireTuner, that is a remote Lua console into the game's own UI contexts. The harness keeps that channel open in multiplayer with a small preload shim, injects a Lua runtime that ports the stock UI's own logic (combat previews, trade legality, hovers), and drives every screen the way a mouse would. Because the network only carries player commands in a lockstep simulation, a real game instance is the only faithful client; that is why the LLM gets one. docs/ARCHITECTURE.md has the long version.

Honest limits

  • Linux only, native Steam build only, Brave New World only. No Windows, no macOS, no Proton.

  • With the tuner enabled the game listens on every interface by default. The install guide binds it to loopback; do not skip that on a shared network.

  • A blocker the engine raises without opening its chooser (the Maya Long Count, a stolen tech, a free Great Person, a dig) is asked and answered through question() / answer() since 2.2.0; anything still outside the nine tools makes the agent stop and ask you. docs/GAPS.md is the running audit.

  • The engine's movement-cost preview and path overlays crash the game when read, so one step's cost is computed from the engine's movement rules instead, and nothing beyond one step (turns to reach) is estimated.

  • No hosted CI by choice; the suite runs locally before every push.

Documentation

Development

sudo apt install lua5.4 liblua5.4-0   # luac for the runtime lint, liblua for the Lua tests
uv sync --group dev
scripts/check.sh            # 2114 tests: the shipped Lua under lupa, the Python layer against fake bridges; no game needed

CIV5_CALL_LOG=/path/calls.jsonl in the server's environment writes one line per tool call (bytes, trips, seconds, refusals, and client: CIV5_CLIENT when set, else the MCP client's name/version, so two models on one seat stay apart); scripts/ledger_report.py [--seat N] [--client codex] turns it into a per-turn table with a per-client footer. Off by default; scripts/llm_seat_loop.py sets both for the agent it runs.

python -m harness.spectator --ledger /path/calls.jsonl serves a live, read-only page (web/viz/, d3) of the game and the seats' attention: the whole map in greyscale, every plot a tool reply handed a model pulsing once in the seat's colour, acts staying painted for the turn, a ghost of the previous seat, a heatmap, and an Observer / Seat N switch. --record / --replay work without a game. See docs/VISUALIZATION.md.

The Lua runtime is one file per game domain under harness/lua/runtime/ (its README.md says which file owns what and how to add one); harness/runtime_source.py lists the load order and assembles what is injected. It carries its own version counter (RUNTIME_VERSION in bootstrap.lua), bumped on every change to any of those files, because a running game keeps the old runtime until a newer number arrives; the source digest re-injects a changed runtime even when the bump was forgotten. Commit subjects carry it as runtime vNNN.

Issues and milestones live on GitLab: https://gitlab.com/Tyler-Meador/civ-v-linux-mcp.

Authorship

This project was written by Claude, Anthropic's AI model, working in Claude Code under the direction of Ty Meador, who owns the game, ran every live session and decided what the harness should and should not do. Claude Fable 5.1 wrote most of it, with Claude Opus 5, Claude Sonnet 5 and Claude Opus 5.5 on other commits; the Co-Authored-By trailers in the git history say which model committed what. The fixes of 2.11.0 to 2.13.0 (2026-10-31) were drafted by Claude Opus 5.5 subagents and reviewed, corrected and committed by Claude Fable 5.1, so their trailers name the reviewer. That covers the reverse engineering of the FireTuner protocol and the game binary, the shim, the Lua runtime, the MCP server, the tests, the documentation and this README. Ty's contribution is the design brief, the live verification against the running game, the judgement calls recorded in docs/GAPS.md, and the standard that the seat may see only what a human sees.

License

MIT. Sid Meier's Civilization V, its assets and the stock UI Lua quoted in docs/ belong to Firaxis Games and Take-Two Interactive and are not covered by this licence; you need your own copy of the game.

Available Tools

9 tools
answerA

Answer what the game is asking: settle the one popup, leader screen or deal that question() shows, and nothing else. choice is the answers row's choice: an item's name (a TECH_, UNIT_, BUILDING_, POLICY_, PROMOTION_, BELIEF_ or goody name; liberate / annex / puppet / raze; a dig's choice number), a popup's or leader screen's button number, or on a leader screen accept / refuse (the deal on the table), leave (close it), accept_friendship. args carries the rest the popup needs (a promotion's unit_id, a dig's x and y, a stolen tech's player_id, a religion's beliefs and city). Dispatches on the gate: question() shows which question is up and hands back the rows to copy. It acts on the game as the popup's own button would -- an accepted deal, a razed city, a chosen tech cannot be taken back; a choice the popup does not offer, or an answer when nothing is asked, is refused with {ok: false, err, choices} and nothing happens. action_id: a retry with the same token replays the stored reply instead of answering twice. Not this tool: a decision with no popup up (research, production, a policy) is order; what a choice means is reference. Returns {ok, ...} with the popup's outcome and the gate that follows (still_pending and next when another leader waits; next also names the call that resumes the AIs' round when they are still moving), or the refusal.

NameRequiredDescriptionDefault
argsNowhat the popup needs beyond the choice: unit_id, x and y, player_id, beliefs, city
choiceYesthe `answers` row's choice: an item name, a button number, or accept / refuse / leave / accept_friendship
action_idNoa token of my choosing: a retry with the same action_id replays the stored result

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past the annotations: it discloses irreversibility ("an accepted deal, a razed city, a chosen tech cannot be taken back"), the refusal contract ({ok: false, err, choices} with nothing happening), and the action_id replay semantics for retries. The only friction is that destructiveHint=false sits oddly beside an irreversible city razing, and the idempotency token is the sole guard against double-answering, which the description does at least surface.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and the scope, then the choice vocabulary, then effects, then the refusal contract and routing. Dense and long, with heavy parentheticals and semicolon-chained clauses, but nearly every clause supplies decision-relevant information rather than restating the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description still explains the return value ({ok, ...} with the popup's outcome plus still_pending and next), the failure shape, and the follow-up call when AIs are still moving. Combined with the discovery pointer to question() and the sibling routing, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, yet the description still adds the value space: choice is an item name (TECH_, UNIT_, BUILDING_, POLICY_, PROMOTION_, BELIEF_ or goody), liberate/annex/puppet/raze, a dig choice number, a button number, or accept/refuse/leave/accept_friendship; args carries unit_id, x and y, player_id, beliefs, city. No enum exists in the schema, so this text is the only place those legal values are defined.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Answer what the game is asking: settle the one popup, leader screen or deal that question() shows" states a specific verb and a tightly bounded scope. It also names the things it acts on (popup, leader screen, deal) so the agent can tell it apart from batch/order/turn without reading the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing is given in both directions: use question() to discover what is pending, and "Not this tool: a decision with no popup up (research, production, a policy) is order; what a choice means is reference." That names the alternatives and the condition that selects them.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

batchA
Destructive

Many orders in one call, in order, with the turn left open: actions is a list of {tool, args} rows -- the rows every read hands back (actions, call): order, answer and notebook rows alike -- each run as that call and answered under results. The first refusal stops the rest by default, since the state the later rows were reasoned about is no longer certain (stop_on_refusal=false runs them all); the rows not run come back under skipped. force=true takes over this turn's claim when another client of my seat holds it (otherwise the first row is refused with turn_claim). Not inside: the turn's wait / finish / end, a load, the seat, the exit, a batch. Each row changes the game as its order would and cannot be undone; a row's own action_id replays. Use it for several orders already decided; use order for one, and turn(action='finish', actions=[...]) when the same rows should end the turn afterwards. Returns {ok, done, results: [one reply per row], skipped?, hint?}: ok is false when any row was refused.

NameRequiredDescriptionDefault
forceNotake over this turn's claim when another client of my seat holds it (default false: the first row is then refused with turn_claim)
actionsYesthe rows to run in order, [{tool, args}], as every read hands them back
stop_on_refusalNostop at the first refused row (default true); false runs them all

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructive=true, idempotent=false, readOnly=false, but the description adds substantial context beyond them: first refusal halts later rows by default because the reasoned-about state is no longer certain, stop_on_refusal=false runs everything, unrun rows appear under `skipped`, force=true overrides another client's turn claim (otherwise the first row is refused with turn_claim), each row is irreversible, and a row's own action_id replays. This is a rich disclosure of failure modes, claim semantics, and irreversibility that the annotations alone could not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first clause and every sentence carries operational information: payload format, default failure behavior, claim handling, exclusions, alternatives, and return shape. It is dense and parenthetical-heavy, making it harder to scan than necessary, but there is no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by describing the return shape ({ok, done, results, skipped?, hint?}) and the condition for ok=false. It also covers prerequisites (turn claim and force), failure semantics, exclusions, and alternatives, which is everything an agent needs to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already describes all three parameters, so the baseline is 3. The description adds some meaning beyond the schema: it states rows run 'in order,' explains the rationale for the default stop-on-refusal behavior, notes that each row is answered under `results`, and ties `force` to the turn_claim refusal outcome. It largely mirrors the schema wording for the parameters themselves, which keeps it from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Many orders in one call, in order, with the turn left open') and immediately defines the payload shape ({tool, args} rows). It distinguishes itself from siblings explicitly by naming `order` for a single order and `turn(action='finish', ...)` when the rows should also end the turn, and by listing what is not allowed inside a batch.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance ('Use it for several orders already decided; use order for one, and turn(action='finish', actions=[...]) when the same rows should end the turn afterwards') and explicit exclusions ('Not inside: the turn's wait / finish / end, a load, the seat, the exit, a batch'). The alternatives and the boundary conditions are both stated, leaving little to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

notebookA
Destructive

My memory, kept beside the game per seat and surviving a context reset or a restart: free-text notes, assignments (what a unit or city is for) and standing orders (a unit's plan the harness carries out over the coming turns). Use it for what future-me must know; the game itself holds no plan. Notes and assignments move nothing; a standing order does: give_order and resume_order run its first steps NOW (a move spends this turn's movement, a build starts) and carry on at the start of each of my turns. action, with its args -- remember {text, tag?, replace_id?}: write a note (returns it with its id; new notes ride on the next briefing / finish); recall {tag?, limit?}: list notes; forget {note_id}: delete a note for good. assign {role, purpose, unit_ids? / city_ids?}: give units or cities a purpose that shows in their state rows; assignments: list them; amend {assignment_id, purpose? / role?}; close {assignment_id}. give_order {unit_id, steps, interrupt?, purpose?, replace_id?}: steps is a list of at most 6, in order -- {kind: 'move', x, y}, {kind: 'build', build: 'FARM'}, {kind: 'heal', hp: 80}, {kind: 'hold', mission: 'fortify' | 'sleep' | 'alert'} (last) -- each step runs at most once per turn and the next starts as soon as one completes (a move that arrives starts its build the same turn); it never attacks, declares war or ends the turn, and pauses with a reason when a hostile comes near, the unit is hurt or a step is refused; one open order per unit (replace_id replaces it). orders: the plans with their status; cancel_order / resume_order {order_id}. Not this tool: a one-off move is order(to='unit'); a popup is answer; the board is state. Usable while it is not my turn. Returns {ok: true, ...} with the row written or the rows listed, or {ok: false, err, accepts, example} (an unknown action or a missing argument; nothing is written). A note written on a turn later than the one on screen (a save was loaded) comes back marked later_timeline.

NameRequiredDescriptionDefault
argsNothe action's arguments by name: text / tag / replace_id, note_id, role and purpose with unit_ids / city_ids, assignment_id, unit_id and steps, order_id
actionYesremember | recall | forget | assign | assignments | amend | close | give_order | orders | cancel_order | resume_order
action_idNoa token of my choosing: a retry with the same action_id replays the stored result

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true and readOnlyHint=false but say nothing about mechanics; the description supplies them: give_order runs its first step immediately, spends this turn's movement, starts a build, never attacks or ends the turn, and pauses with a reason on hostiles, damage or refusal. It adds the one-open-order-per-unit constraint, the 6-step cap, per-turn step cadence, error shape {ok:false, err, accepts, example} with the guarantee nothing is written, and the later_timeline marker after a save load.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose, exclusions and return shape are front-loaded and every clause carries operational information, but the middle section is a dense run-on with dashes and slashes that is harder to scan than the eleven-action surface warrants. Nothing is redundant, though the format could be more easily parsed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an eleven-action, three-parameter tool with no output schema and no nested objects, the description covers purpose, per-action arguments, execution side effects, failure behavior, and the save-load edge case. An agent has enough to call any action correctly on the first attempt.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so this exceeds baseline by documenting each action's argument set inline (remember text/tag/replace_id, assign role+purpose with unit_ids/city_ids, amend, close, order_id) and by spelling out the step grammar {kind:'move'|'build'|'heal'|'hold'} with their fields and the 'last' positional rule. The action_id replay-on-retry contract is also surfaced.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific metaphor made concrete: persistent free-text notes, assignments, and standing orders that survive a context reset. It then enumerates all eleven actions and explicitly separates itself from siblings ('a one-off move is order(to='unit'); a popup is answer; the board is state'), so an agent can route between notebook, order, answer and state without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the selection criterion directly ('Use it for what future-me must know; the game itself holds no plan') and gives explicit exclusions naming three sibling tools. It also gives a timing rule ('Usable while it is not my turn') and distinguishes note/assign (inert) from give_order/resume_order (executes now), which is the key branch decision.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

orderA
Destructive

An order to something I own: to the target kind, id which one, action the verb, args its arguments by name. It changes the game, and most of it cannot be undone (a disbanded unit, a declared war, a purchase). Not a read: state shows the board and hands back the rows, question / answer settle what a popup asks, turn(action='finish') ends the turn. to: actions -- unit: move, mission, promote, upgrade, disband, trade_route, plunder city: produce, purchase, dequeue, sell_building, buy_plot, specialist, work_plot, governor, status, strike, great_work empire: research, policy, ideology, switch_ideology, pantheon, religion, enhance_religion, reformation, faith_purchase civ: propose_deal, negotiate, peace, demand, friendship, declare_war, denounce, event city_state: gift_gold, gift_unit, gift_improvement (or a city-state screen button by its name: pledge, revoke_pledge, bully_gold, bully_unit, declare_war, make_peace) league: propose, repeal, vote spy: move, coup How: copy the rows a read hands back (actions, call) as they are; id is a unit, city, civ, city-state or spy id (empire and league take none); args holds what the row holds (a plot's x and y, an item's name, a deal's items, an amount). An order runs whole or not at all. action_id: a token of mine; a retry with the same one replays the stored reply instead of acting twice. Returns {ok: true, ...} with what changed (a unit's new plot and moves left, a city's queue, a deal's answer), or {ok: false, err, choices / accepts, example}: the verb is not one of the target's (choices lists them), an argument is missing (accepts names the shape, example a complete call), or the game refuses it (err names the rule, e.g. the unit has no moves, the city is not mine, another client of my seat holds this turn's claim). Nothing is acted on when ok is false.

NameRequiredDescriptionDefault
idNowhich unit, city, civ, city-state or spy; empire and league take none
toYesthe target kind, something I own
argsNothe action's arguments by name, as the copied row has them; a refusal shows the shape with an example
actionYesthe verb, by target -- unit: move, mission, promote, upgrade, disband, trade_route, plunder; city: produce, purchase, dequeue, sell_building, buy_plot, specialist, work_plot, governor, status, strike, great_work; empire: research, policy, ideology, switch_ideology, pantheon, religion, enhance_religion, reformation, faith_purchase; civ: propose_deal, negotiate, peace, demand, friendship, declare_war, denounce, event; city_state: gift_gold, gift_unit, gift_improvement, or a city-state screen button by its name (pledge, revoke_pledge, bully_gold, bully_unit, declare_war, make_peace); league: propose, repeal, vote; spy: move, coup
action_idNoa token of my choosing: a retry with the same action_id replays the stored result instead of acting twice

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare `destructiveHint=true` and `readOnlyHint=false`; the description adds that most changes cannot be undone with concrete examples such as disbanding a unit or declaring war. It also discloses all-or-nothing execution, detailed failure returns, and `action_id` replay semantics, which is a useful idempotency-key nuance rather than a contradiction of `idempotentHint=false`.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is front-loaded and structured, placing purpose and alternatives before action details and return behavior. It is long and repeats the action enum already present in the schema, but the density is largely justified by the tool's breadth.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description's return-shape explanation is necessary and complete: it covers `{ok: true, ...}` changed state and `{ok: false, err, choices / accepts, example}` failures. It also explains atomicity and error cases, making the definition self-contained for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents and enumerates `to` and `action`. The description adds operational meaning beyond the schema: copy the read's returned rows for `id` and `args`, `action_id` replays stored replies, and empire/league targets take no `id`.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence defines an order as a mutation on something I own and names the core fields `to`, `id`, `action`, and `args`. The action lists map verbs to target kinds, and the description explicitly distinguishes this tool from read/query siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Not a read' and routes board reading to `state`, popup resolution to `question` / `answer`, and turn ending to `turn(action='finish')`. It also explains how to construct calls by copying rows returned by reads and that an order executes atomically.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

questionA
Read-onlyIdempotent

What the game is asking right now, so answer() can settle it. Read-only; takes nothing. Use it whenever a reply's gate is not null or turn(action='status') says discussion_pending; use state for the board and reference for the rules. It shows one of: a decision popup (a tech, a production item, a policy, a promotion, a belief, a ruins reward, a captured city's fate, a Great Person's use, a dig), the leader on screen with their words and the deal on the table, another human seat's proposal waiting on the trade table, or nothing pending. Returns the popup's own read -- the question in words plus answers rows, each a complete answer() call to copy (the item's name or button number, and the args the popup needs) -- with gate on the reply; a leader screen returns the leader, the speech, the buttons and the deal's items; when nothing is asked, {pending: false, decisions: [...]} lists the turn's open decisions instead. Several leaders can queue at a turn start: answering one returns the next under next.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint, so safety is covered; the description goes well beyond them by describing the idle return shape ({pending: false, decisions: [...]}), the leader-screen return contents, and the non-obvious queueing behavior at turn start where answering one leader surfaces the next under `next`. With no output schema present, this return-shape disclosure is exactly the burden the description should carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with the core purpose and the trigger condition before the return-shape detail, so an agent can stop reading early. The long parenthetical enumerating every popup type (tech, production item, policy, promotion, belief, ruins reward, captured city, Great Person, dig) is somewhat over-stuffed for the value it adds, keeping it below a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates fully by spelling out each return variant, including the empty case and the chained `next` case. Combined with the trigger conditions, an agent has everything needed to call it and interpret the reply correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4; the description reinforces this with 'takes nothing', removing any doubt that arguments are required. There is no parameter surface left to explain.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening clause states exactly what is returned — the pending question the game is asking — and enumerates the concrete forms it can take (decision popup, leader screen, human trade proposal, nothing). It actively distinguishes itself from siblings by telling the agent to use state for the board and reference for the rules. A specific verb is implied rather than stated ('What the game is asking ... Read-only; takes nothing'), which keeps it just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit trigger condition ('whenever a reply's `gate` is not null or turn(action='status') says discussion_pending') and explicit alternatives for the neighbouring concerns ('use state for the board and reference for the rules'). Nothing about when to reach for this tool versus answer/turn/state is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

referenceA
Read-onlyIdempotent

What things do, in two books. book="rules" (the default): the rule book of this very game, read once from its database (mods and DLC included) and cached -- every unit, building, wonder, project, process, promotion, social policy and ideology tenet, technology, belief, resource, terrain, feature, improvement, specialist and unit action, with its numbers. book="playbook": how to play through these tools (the turn loop, batches, blockers, diplomacy, the house rules, the action table). Read-only, usable while it is not my turn. Use it to learn what a choice means; use state for the live numbers (its chooser rows carry only the enum, the name and live numbers, never this text) and question for what a popup asks. section: one part per call. Rules sections: terrain, resources, improvements, units, buildings, projects, processes, promotions, policies, techs, beliefs, specialists, actions; left out, the whole book (tens of thousands of tokens: read it once at the start of a game if you can hold it, else the section a choice needs). Playbook topics: start, turn_loop, quiet_turns, batches, verify, blockers, diplomacy, rules, first_turn, orders (the action table), all; left out, the index of topics with the start section; city_state(s), deals, trade and league answer with diplomacy. Returns Markdown. An unknown rules section is refused as {ok: false, err, sections}; an unknown playbook topic answers with the topic list. Also served as the MCP resources civ5://reference and civ5://reference/{section}.

NameRequiredDescriptionDefault
bookNo'rules' (default): what everything in this game does; 'playbook': how to play through these toolsrules
findNorules: keep only the headings and the lines containing this word (a section too long for one reply: promotions, buildings)
sectionNoone section: a rule-book heading (terrain, units, buildings, ...) or a playbook topic; left out, the book's index

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond annotations: rules are read from the game database including mods and DLC and cached, full-book reads are tens of thousands of tokens, unknown sections are refused with an error structure, and results are Markdown. Annotations already cover read-only and idempotent behavior, but the description still adds useful operational details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Information is front-loaded with the two-book distinction followed by usage guidance and parameter behavior. It is dense and somewhat verbose with long parenthetical lists, so it is not maximally concise, but the complexity justifies most of its length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has no output schema, and the description compensates by explaining return format, section/topic behavior, fallback indexes, error handling for unknown sections, and MCP resource equivalents. It provides everything needed to invoke a complex reference tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description still adds value by listing concrete section names, explaining the default whole-book behavior and token cost, and clarifying how find narrows long sections such as promotions and buildings.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource: two reference books, rules and playbook, and enumerates what each covers. It clearly distinguishes this documentation lookup from sibling tools like state and question, which provide live data or popup prompts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to use reference to learn what a choice means, while directing live numbers to state and popup wording to question. It also notes the tool is usable when it is not the agent's turn, giving clear context for when to call it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sessionA
Destructive

Saves, loads and the seat of this game session: keep a state before a risky turn, open another save, leave a finished game, say which hotseat seat this server plays. It never plays a turn; use turn for that. Side effects: a load replaces the game on screen for everyone on it, and a hotseat game loads paused until turn(action='wait'); the notebook is per game and seat, so it follows a save of the same game and is not touched by a load. action -- save: a quick save of the game on screen into the one quick-save slot (each finished turn's autosave overwrites that slot, so copy a save you want kept); load {filename}: open that save (a name as the game lists it, without the single/ prefix; the refusal lists the legal ones), replacing the unsaved state, so save first; load_latest: open the newest save, whichever game it is; main_menu: leave the game for the main menu (the game_over gate's way out); seat {seat}: which human seat (0 or 1) this server plays in a hotseat game -- a server pinned with --seat refuses a change onto the other human seat, and never move onto the seat on screen. Returns {ok: true, saved / loaded, turn, seat, screen} or {ok: false, err} naming why (an unknown filename with the list, a seat that is someone else's, a game operation already running). In a game with other people ask the human before loading.

NameRequiredDescriptionDefault
argsNoload: {filename} (a save's name without the single/ prefix); seat: {seat} (0 or 1)
actionYessave | load | load_latest | main_menu | seat

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past destructiveHint=true: a load replaces the on-screen game for everyone, hotseat loads come up paused until turn(action='wait'), the quick-save slot is overwritten by every turn's autosave, and the notebook is per game-and-seat so it follows a save but survives a load. These are non-obvious side effects an agent could not infer from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence carries information — no filler — and the ordering is sensible (purpose, non-scope, side effects, per-action detail, returns). However it is delivered as one dense semicolon-chained block rather than separated per-action lines, which makes it harder to scan for the one action an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema, yet the return shape is documented ({ok: true, saved/loaded, turn, seat, screen} or {ok: false, err}) along with the three failure modes (unknown filename, someone else's seat, operation already running). Nothing needed to call any of the five actions correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so baseline is 3, but the description adds real meaning: filename is given without the single/ prefix, a refusal lists the legal names, seat is 0 or 1 with a --seat-pinned server refusing a move to the other human seat and a rule against moving onto the seat on screen.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource statement and then enumerates all five actions (save, load, load_latest, main_menu, seat) with a one-line definition each. It explicitly distinguishes itself from the sibling: "It never plays a turn; use turn for that."

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit routing: use turn to actually play, use main_menu as "the game_over gate's way out," use save before load because load discards unsaved state. It also adds a social precondition ("In a game with other people ask the human before loading") and distinguishes load from load_latest by scope.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stateA
Read-onlyIdempotent

Read the game as my seat sees it: the empire, units, cities, civs and city-states, the map, the league, spies, the screens, and the choices open to me (research, policies, beliefs, trade routes). Read-only, no side effect, usable while it is not my turn. Use it before an order (its rows ARE the orders) and after one to verify; use reference for what things do, question for what a popup asks, turn for the turn's own state. How to call: what names the object, view the part of it (left out: the default view), id the one object. Objects and their views: empire: default, demographics notifications: default screen: tech_tree, religion, culture, culture_works, great_people, domination, spaceship, wonders, intrigue, trade_routes, deals league: default spies: default units: default, actions unit: actions, targets, tactical, home cities: default city: screen, production, strikes map: window, grid, index, frontier civs: default civ: summary, war, trade_catalog city_state: summary, full options: research, policies, beliefs, trade_routes, spy_cities compare: default Selectors, by view: x, y, radius for map/window and map/grid; radius alone for unit/tactical (centred on the unit); id for map/frontier (the explorer) and options/trade_routes (the caravan); mission for unit/targets; kind for options/beliefs and compare; detail ('summary' / 'full') where a view has both; since and limit for lists; item and yield_type for city/production to price one item; args for the rest by the old call's name. Returns: the object as JSON (a list for units, cities, civs; one dict otherwise), with actions or call rows wherever something can be done: each row is a complete order() call to copy. A wrong what or view is refused with choices, and for an object that takes an id, a hint saying where the ids come from (unit ids from units, city-state ids from the minor: true rows of civs). Replies are the 1.x reads' replies unchanged.

NameRequiredDescriptionDefault
xNomap/window and map/grid: the centre plot, with y
yNowith x
idNothe one object's id (unit, city, civ, city-state or spy; the explorer's unit id for map/frontier and the caravan's for options/trade_routes); a list of unit ids for units/actions
argsNothe rest by the old call's name (compare's fields)
itemNocity/production: price this one item
kindNooptions/beliefs: the belief kind; compare: what to compare
viewNothe part of the object, from the list below; the default view when left out
whatYesthe object: empire, notifications, screen, league, spies, units, unit, cities, city, map, civs, civ, city_state, options, compare
limitNohow many rows a list returns
sinceNonotifications: only those after this turn number
detailNo'summary' or 'full' where a view offers both
radiusNomap/window and map/grid: tiles around x, y; unit/tactical: tiles around the unit
missionNounit/targets: the mission whose legal targets to list
yield_typeNocity/production with item: the yield to price it in

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint=false, but the description adds usable-while-not-my-turn behavior, JSON return shape, action/call rows as complete order() calls, and refusal behavior with choices and hint fields. These are substantial behavioral details beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with purpose and usage, then organized into how-to-call, object/view matrix, selectors, and returns sections, which suits a 14-parameter multiplexed tool. It is still lengthy and repeats some selector details already present in the schema, so it is not maximally concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although there is no output schema, the description explains the return type (list for units/cities/civs, dict otherwise), the presence of action/call rows, and error/refusal shape with choices and id hints. Given the complex view matrix, it supplies enough context for correct invocation and delegates deeper object semantics to the reference sibling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds high-value relational semantics that the schema cannot express: which views belong to each what, which selectors apply to which view, default-view behavior, and the args fallback. That directly helps an agent choose valid what/view/selector combinations.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource: 'Read the game as my seat sees it', then enumerates the game-state objects it covers. It also explicitly distinguishes itself from reference, question, and turn, so an agent can identify it as the read-state tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to use it before an order because its rows ARE the orders, and after an order to verify. It names three sibling alternatives and their roles: reference for what things do, question for popups, turn for turn state.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

turnA

The clock: my seat's turn loop, one action per call. Actions: status -- whose turn it is, the gate (answer it before anything else), what blocks the end. Read-only. briefing -- my turn in one read: decisions with their actions rows, changes, board, threats, notes. finish -- run actions as a batch, end my turn, wait until it is mine again, return the new turn. end -- end the turn only, no wait. wait -- block until it is my turn again. Arguments by action: since, limit and detail belong to briefing (since='turn' after a context reset; detail='digest' is the event digest alone); actions and notes to finish; timeout_seconds to finish and wait; args (skip_quiet_turns, wake_on, autosave, force, briefing) to finish and end. Side effects: finish and end hand the game to the other players, and nothing they do can be undone -- order and answer everything first; a session save is the way back. finish autosaves to the quick-save slot. A refused row in actions stops the batch and the turn is not ended. Safe to repeat: when it is not my turn, finish only waits. A second client of my seat is refused with turn_claim (args.force takes the turn over). Timeouts: past timeout_seconds (600 by default) the reply says my_turn false, timed_out true and next is the call that resumes the wait; progress notifications go out every 5 s meanwhile, so one long call beats several short ones. Not this tool: question / answer for what the game asks (nothing ends while gate is set); state for the board; batch for orders that leave the turn open; session for saves. Returns: turn, my_turn, gate, todo / decisions, digest (what happened meanwhile), notes; game_over with victory / defeat at the end. A refusal is {ok: false, err, end_turn: {todo, skip_actions}}: what blocks the turn and the rows that clear it.

NameRequiredDescriptionDefault
argsNofinish / end only, by name: skip_quiet_turns (a count: keep ending turns, up to N more, while nothing needs you), wake_on (words that stop a quiet run), autosave (default true), force (take the turn over from another client of my seat), briefing (finish: the new turn as a briefing)
limitNobriefing: rows per list of changes and notes (default 8)
notesNofinish: which notebook notes ride on the reply, 'new' (default) or 'all'
sinceNobriefing: 'previous' (default) compares with my last briefing, 'turn' with the last turn end (after a context reset)
actionYesstatus | briefing | finish | end | wait
detailNobriefing: 'compact' (default) or 'digest' (the event digest alone)
actionsNofinish only: order rows to run before the turn ends, [{tool, args}] as the reads hand them back
timeout_secondsNofinish / wait: seconds to wait for my turn before answering with the state so far (default 600)

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations: which actions are read-only ('status -- Read-only'), which are irreversible ('nothing they do can be undone -- order and answer everything first; a session save is the way back'), that finish autosaves, that a refused row aborts the batch, that the call is safely repeatable when it isn't my turn, and the timeout/notification cadence. None of that is inferable from destructiveHint=false or idempotentHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then organized into actions, arguments-by-action, side effects, timeouts, not-this-tool, and returns. It is long but tele squash-dense and mostly earns its length; a couple of parenthetical clauses could be tightened, which is why it's not a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still documents returns ('turn, my_turn, gate, todo / decisions, digest, notes; game_over with victory / defeat') and even the refusal shape ('{ok: false, err, end_turn: {todo, skip_actions}}'). Combined with the side-effect and timeout coverage, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline 3 applies, but the description adds per-action routing that is not in the schema: 'since, limit and detail belong to briefing; actions and notes to finish; timeout_seconds to finish and wait; args (...) to finish and end.' This meaningfully reduces misfires on which param pairs with which action.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('the clock: my seat's turn loop, one action per call') and then enumerates each of the five actions with a one-line purpose. This differentiates the tool from siblings like question, state, batch, and session without the agent having to open the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names alternatives in 'Not this tool: question / answer for what the game asks; state for the board; batch for orders that leave the turn open; session for saves,' plus the key exclusion that nothing ends while gate is set. This is exactly the when/when-not routing an agent needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 1 tool updatev2.10.0
    • Changedstate3 fields changed
      • changedInput schema / properties / id / description
        Previous value: -"the one object's id (unit, city, civ, city-state or spy); a list of unit ids for units/actions"New value: +"the one object's id (unit, city, civ, city-state or spy; the explorer's unit id for map/frontier and the caravan's for options/trade_routes); a list of unit ids for units/actions"
      • changedInput schema / properties / radius / description
        Previous value: -"map/window, unit/tactical: tiles around x, y"New value: +"map/window and map/grid: tiles around x, y; unit/tactical: tiles around the unit"
      • changedInput schema / properties / x / description
        Previous value: -"map/window centre or unit/tactical origin, with y"New value: +"map/window and map/grid: the centre plot, with y"
  2. 2 tool updatesv2.7.1
    • Changedbatch1 field changed
      • changedInput schema / properties / force / description
        Previous value: -"take over this turn's claim held by another client of my seat"New value: +"take over this turn's claim when another client of my seat holds it (default false: the first row is then refused with turn_claim)"
    • Changedturn1 field changed
      • changedInput schema / properties / args / description
        Previous value: -"other arguments of the old call by name: skip_quiet_turns (a count: keep ending turns, up to N more, while nothing needs you), wake_on, autosave, briefing"New value: +"finish / end only, by name: skip_quiet_turns (a count: keep ending turns, up to N more, while nothing needs you), wake_on (words that stop a quiet run), autosave (default true), force (take the turn over from another client of my seat), briefing (finish: the new turn as a briefing)"
  3. 4 tool updatesv2.7.0
    • Removedinspect
    • Changedreference1 field changed
      • addedInput schema / properties / find
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "rules: keep only the headings and the lines containing this word (a section too long for one reply: promotions, buildings)",
        +  "title": "Find"
        +}
    • Addedstate
    • Changedturn1 field changed
      • changedInput schema / properties / args / description
        Previous value: -"other arguments of the old call by name: skip_quiet_turns, wake_on, autosave, briefing"New value: +"other arguments of the old call by name: skip_quiet_turns (a count: keep ending turns, up to N more, while nothing needs you), wake_on, autosave, briefing"
  4. 152 tool updatesv2.1.0
    • Removedaccept_deal
    • Removedaccept_friendship
    • Removedadd_reformation_belief
    • Removedamend_assignment
    • Addedanswer
    • Removedanswer_popup
    • Removedarchaeology_options
    • Removedassign
    • Removedassignments
    • Removedavailable_beliefs
    • Removedavailable_city_strikes
    • Removedavailable_policies
    • Removedavailable_production
    • Removedavailable_research
    • Removedavailable_spy_cities
    • Removedavailable_trade_routes
    • Removedavailable_unit_actions
    • Addedbatch
    • Removedbriefing
    • Removedbuy_city_plot
    • Removedcancel_order
    • Removedchange_ideology
    • Removedchange_specialist
    • Removedchange_working_plot
    • Removedchoose_archaeology
    • Removedchoose_city_capture
    • Removedchoose_faith_great_person
    • Removedchoose_free_great_person
    • Removedchoose_goody_hut
    • Removedchoose_ideology
    • Removedchoose_maya_bonus
    • Removedchoose_policy
    • Removedchoose_promotion
    • Removedcities
    • Removedcity_capture_options
    • Removedcity_ranged_attack
    • Removedcity_screen
    • Removedcity_state_action
    • Removedcity_state_actions
    • Removedcity_state_bonuses
    • Removedcity_state_gifts
    • Removedcity_task
    • Removedclose_assignment
    • Removedcompare
    • Removedculture_overview
    • Removedculture_works
    • Removedcurrent_deals
    • Removeddeclare_war
    • Removeddemand
    • Removeddemographics
    • Removeddenounce
    • Removeddiplo_event
    • Removeddiplomacy
    • Removeddisband_unit
    • Removeddiscussion
    • Removeddismiss_discussion
    • Removeddo
    • Removeddomination_progress
    • Removedend_turn
    • Removedenhance_religion
    • Removedespionage_intrigue
    • Removedestablish_trade_route
    • Removedexit_to_main_menu
    • Removedexplore_frontier
    • Removedfaith_great_person_options
    • Removedfinish_turn
    • Removedforget
    • Removedfound_pantheon
    • Removedfound_religion
    • Removedfree_great_person_options
    • Removedgeneric_popup
    • Removedgift_tile_improvement
    • Removedgift_tile_improvement_options
    • Removedgift_unit
    • Removedgift_unit_options
    • Removedgive_order
    • Removedgoody_hut_options
    • Removedgreat_person_progress
    • Removedhow_to_play
    • Removedincoming_deal
    • Addedinspect
    • Removedknown_world
    • Removedleague_cast_votes
    • Removedleague_propose_enact
    • Removedleague_propose_repeal
    • Removedleague_status
    • Removedload_latest
    • Removedload_save
    • Removedmake_peace
    • Removedmap_index
    • Removedmap_window
    • Removedmaya_options
    • Removedminor_gold_gift
    • Removedmove_spy
    • Removedmove_unit
    • Removednegotiate_deal
    • Addednotebook
    • Removednotification_log
    • Addedorder
    • Removedorders
    • Removedoverview
    • Removedplayers
    • Removedplunder_trade_route
    • Removedpropose_deal
    • Removedpropose_friendship
    • Removedpurchase_cost
    • Removedpurchase_production
    • Addedquestion
    • Removedquick_save
    • Removedrecall
    • Changedreference2 fields changed
      • addedInput schema / properties / book
        Added value: +{
        +  "default": "rules",
        +  "description": "'rules' (default): what everything in this game does; 'playbook': how to play through these tools",
        +  "title": "Book",
        +  "type": "string"
        +}
      • addedInput schema / properties / section / description
        Added value: +"one section: a rule-book heading (terrain, units, buildings, ...) or a playbook topic; left out, the book's index"
    • Removedrefuse_deal
    • Removedrelationship
    • Removedreligion_overview
    • Removedremember
    • Removedremove_from_queue
    • Removedrespond_discussion
    • Removedresume_order
    • Removedrevealed_map
    • Removedsell_building
    • Addedsession
    • Removedset_auto_specialists
    • Removedset_avoid_growth
    • Removedset_city_focus
    • Removedset_faith_purchase
    • Removedset_production
    • Removedset_research
    • Removedset_seat
    • Removedset_swappable_great_work
    • Removedspaceship_status
    • Removedspies
    • Removedstage_coup
    • Removedsteal_tech
    • Removedsteal_tech_options
    • Removedswap_great_works
    • Removedtactical_view
    • Removedtech_tree
    • Removedtodo_actions
    • Removedtrade_catalog
    • Removedtrade_routes
    • Addedturn
    • Removedturn_digest
    • Removedturn_status
    • Removedunit_home_options
    • Removedunit_mission
    • Removedunit_mission_targets
    • Removedunits
    • Removedunlock_policy_branch
    • Removedupgrade_unit
    • Removedwait_for_my_turn
    • Removedwar_consequences
    • Removedwonder_overview
  5. 144 tool updatesv1.11.0
    • First observedaccept_deal
    • First observedaccept_friendship
    • First observedadd_reformation_belief
    • First observedamend_assignment
    • First observedanswer_popup
    • First observedarchaeology_options
    • First observedassign
    • First observedassignments
    • First observedavailable_beliefs
    • First observedavailable_city_strikes
    • First observedavailable_policies
    • First observedavailable_production
    • First observedavailable_research
    • First observedavailable_spy_cities
    • First observedavailable_trade_routes
    • First observedavailable_unit_actions
    • First observedbriefing
    • First observedbuy_city_plot
    • First observedcancel_order
    • First observedchange_ideology
    • First observedchange_specialist
    • First observedchange_working_plot
    • First observedchoose_archaeology
    • First observedchoose_city_capture
    • First observedchoose_faith_great_person
    • First observedchoose_free_great_person
    • First observedchoose_goody_hut
    • First observedchoose_ideology
    • First observedchoose_maya_bonus
    • First observedchoose_policy
    • First observedchoose_promotion
    • First observedcities
    • First observedcity_capture_options
    • First observedcity_ranged_attack
    • First observedcity_screen
    • First observedcity_state_action
    • First observedcity_state_actions
    • First observedcity_state_bonuses
    • First observedcity_state_gifts
    • First observedcity_task
    • First observedclose_assignment
    • First observedcompare
    • First observedculture_overview
    • First observedculture_works
    • First observedcurrent_deals
    • First observeddeclare_war
    • First observeddemand
    • First observeddemographics
    • First observeddenounce
    • First observeddiplo_event
    • First observeddiplomacy
    • First observeddisband_unit
    • First observeddiscussion
    • First observeddismiss_discussion
    • First observeddo
    • First observeddomination_progress
    • First observedend_turn
    • First observedenhance_religion
    • First observedespionage_intrigue
    • First observedestablish_trade_route
    • First observedexit_to_main_menu
    • First observedexplore_frontier
    • First observedfaith_great_person_options
    • First observedfinish_turn
    • First observedforget
    • First observedfound_pantheon
    • First observedfound_religion
    • First observedfree_great_person_options
    • First observedgeneric_popup
    • First observedgift_tile_improvement
    • First observedgift_tile_improvement_options
    • First observedgift_unit
    • First observedgift_unit_options
    • First observedgive_order
    • First observedgoody_hut_options
    • First observedgreat_person_progress
    • First observedhow_to_play
    • First observedincoming_deal
    • First observedknown_world
    • First observedleague_cast_votes
    • First observedleague_propose_enact
    • First observedleague_propose_repeal
    • First observedleague_status
    • First observedload_latest
    • First observedload_save
    • First observedmake_peace
    • First observedmap_index
    • First observedmap_window
    • First observedmaya_options
    • First observedminor_gold_gift
    • First observedmove_spy
    • First observedmove_unit
    • First observednegotiate_deal
    • First observednotification_log
    • First observedorders
    • First observedoverview
    • First observedplayers
    • First observedplunder_trade_route
    • First observedpropose_deal
    • First observedpropose_friendship
    • First observedpurchase_cost
    • First observedpurchase_production
    • First observedquick_save
    • First observedrecall
    • First observedreference
    • First observedrefuse_deal
    • First observedrelationship
    • First observedreligion_overview
    • First observedremember
    • First observedremove_from_queue
    • First observedrespond_discussion
    • First observedresume_order
    • First observedrevealed_map
    • First observedsell_building
    • First observedset_auto_specialists
    • First observedset_avoid_growth
    • First observedset_city_focus
    • First observedset_faith_purchase
    • First observedset_production
    • First observedset_research
    • First observedset_seat
    • First observedset_swappable_great_work
    • First observedspaceship_status
    • First observedspies
    • First observedstage_coup
    • First observedsteal_tech
    • First observedsteal_tech_options
    • First observedswap_great_works
    • First observedtactical_view
    • First observedtech_tree
    • First observedtodo_actions
    • First observedtrade_catalog
    • First observedtrade_routes
    • First observedturn_digest
    • First observedturn_status
    • First observedunit_home_options
    • First observedunit_mission
    • First observedunit_mission_targets
    • First observedunits
    • First observedunlock_policy_branch
    • First observedupgrade_unit
    • First observedwait_for_my_turn
    • First observedwar_consequences
    • First observedwonder_overview

TDQS

A4.6/5.0

Scored across 9 tools

Disambiguation5/5

Each tool owns a distinct slice of the loop: order (single mutation), answer (popup settlement), state/reference/question (three different reads), turn (clock), batch (multi-order), notebook (memory), session (saves/seat). The descriptions go further than most servers by including explicit "Not this tool" sections (e.g. order vs batch vs turn(finish), answer vs order) so the nearest-neighbour confusions are pre-empted.

Naming Consistency4/5

All nine names are single lowercase words with no prefixes, suffixes, casing or separator mixing (order, answer, batch, session...), which is highly predictable. The only weakness is that they are bare nouns rather than verb_noun, so a few (state, notebook, reference) don't self-describe their action as immediately as a verb would.

Tool Count5/5

Nine tools for a game harness spanning mutation, reads, popup resolution, turn management, batching, persistence and session control is tight and every tool has a clear distinct job. Complexity is pushed into per-tool `action`/`what` sub-selectors rather than into more top-level tools, which is the right trade-off here.

Completeness4/5

The lifecycle is essentially covered: read board/rules/prompts, issue orders singly or batched, settle every popup, advance/wait the turn, keep notes and standing orders, save/load/seat. The one plausible gap is that session only saves, loads and reassigns seats — there is no operation for starting a new game, which a full session lifecycle would normally include.

Maintenance

ActivityActive
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • 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
    230
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables any LLM to play Freeciv as a player through MCP tools and resources, with a graphical observer view.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables LLM agents to play full games of Civilization VI by connecting to running game instances via the FireTuner debug interface, with 76 tools for units, cities, diplomacy, research, and turn management, plus narration of game state through rule-enforcing APIs without requiring vision models.
    80
    MIT