CitiesSkylinesModding

🕹️ Agents Plugins

Updated

🤖 Drive your Coherent Gameface game's UI with a Claude/Codex plugin with an MCP server and skills

🕹️ Agents Plugins

The CS Modding marketplace (csmodding) of agent plugins for Claude Code and OpenAI CodexCLI.

Give your agent eyes and hands inside a runningCoherent Gameface game UI.Generic tooling: works with any game or application embedding Gameface, not justCities: Skylines II.

CInpmnodelicense

Install · See it in action ·MCP Tool reference ·Gameface MCP npm package

The marketplace hosts one plugin, coherent-gameface: a generic toolkit for driving arunning Coherent Gameface UI, whatever the game or application embedding it.

Coherent Gameface (Cohtml) is theHTML/CSS/JS UI engine many games embed.The plugin ships gameface-devtools-mcp, an MCPserver that lets your agent drive any Gameface UI over a direct Chrome DevTools Protocol (CDP)connection: evaluate JavaScript, take screenshots, inspect and drive the DOM, capture the console,and even set JS breakpoints.

It also ships two skills.

  • The gameface skill teaches the agent the engine itself: how Gameface is, and is not, abrowser; version-gating features against the changelog; data binding; and how to probe therunning game for what the docs cannot promise.
  • The gameface-driving skill is the operating manual for the game_* tools: field-verifiedprocedures for finding elements, acting then verifying, surviving reloads, and debugging withoutfreezing the game; the traps the tool schemas cannot tell.

[!NOTE]Generic, but developed against Cities: Skylines II. The server makes no assumptions about aspecific application; it works against any Gameface CDP endpoint. It is developed and verifiedagainst Cities: Skylines II's Gameface UI, which is the reference target.

[!TIP]Not using Claude Code or Codex CLI? The MCP server is also published on npm as@csmodding/gameface-devtools-mcpand works with any MCP client (Cursor, Gemini CLI, VS Code, …).See mcp/README.md for the tool reference andper-client install snippets.

Table of contents

  • What it looks like in practice
  • Requirements
  • Install
    • Claude Code
    • Codex CLI
  • Configuration
  • Development
  • Troubleshooting

What it looks like in practice

Short, abridged transcripts. The skill supplies the engine knowledge; the server supplies thehands.

"My panel looks right in Chrome but wrong in-game"

You: My settings panel is a two-column grid in Chrome, but in the game everything stacksinto one column. Why?

Agent: Gameface has no CSS Grid in any version, and unsupported CSS is silently ignored:your display: grid just falls back to the default, and in Gameface every element defaults todisplay: flex in column direction, hence the single column. I rewrote the layout with nestedflex rows, and a game_screenshot of .settings-panel confirms the two columns now renderin-game.

"The UI stops updating after the first refresh"

You: My mod pushes stats to the UI every second, but the panel freezes on the first value.No errors anywhere.

Agent: game_console shows no exceptions, and game_eval on the bound nodes shows theyare stuck on the first payload. This is a known engine gotcha: Cohtml caches a model's shape byits type name, and two payloads sharing a type name must expose the same set of PRESENTproperties. Your second update omits delta when nothing changed; an omitted property is adifferent shape than a null one, and the cached binding breaks silently. Send delta: nullinstead. Verified in-game across two refresh cycles.

"Test the new toolbar button end to end"

You: I just built the milestones toolbar button. Can you verify the whole flow in therunning game?

Agent: game_click on [data-tooltip="Milestones"]: Gameface accepts CDP input commandsbut never delivers them to the UI, so the click is dispatched as real bubbling DOM events,which your React handlers receive. game_wait until .milestones-panel is visible,game_screenshot to check the render, game_console shows no new errors. The flow works;screenshot attached.

"Something throws when the trade panel opens, no idea where"

You: Opening the trade panel logs TypeError: cannot read 'income' of undefined and Icannot reproduce it outside the game.

Agent: game_console captures the stack, pointing at trade-panel.js:412.game_debug_set_breakpoint there with the condition district == null, then game_click onthe trade button. It pauses; the UI thread is frozen while paused, so I inspect quickly:game_debug_pause_state shows district is undefined exactly when the row is an outsideconnection, then game_debug_step resume. Fix: guard the outside-connection case, which has nodistrict.

Requirements

  • A Gameface application running with its CDP debug endpoint reachable (defaulthttp://localhost:9444). Verify with:
    curl http://localhost:9444/json/list
    
    You should get back a JSON array containing a "type": "page" target. Set the host/port to matchyour application if it differs (see Configuration).
  • Node 22.4+ to launch the server.No npm install is needed: the plugin launches the server from a committed, self-containedbundle, so it works offline and stays version-locked to the plugin.

Install

Both harnesses add this repository as a marketplace, install the plugin from it, and launch thesame committed server bundle. The full tool reference (UI tools and JS debugger tools) lives inmcp/README.md.

Claude Code

In Claude Code, add this repository as a marketplace, then install the plugin from it:

/plugin marketplace add CitiesSkylinesModding/agents-plugins
/plugin install coherent-gameface@csmodding

Or from your terminal:

claude plugin marketplace add CitiesSkylinesModding/agents-plugins
claude plugin install coherent-gameface@csmodding

Once enabled, Claude Code autoloads the gameface MCP server from the plugin's.mcp.json.Run /mcp to confirm it connected, then Claude will use this MCP when it needs it.You can ask it to call game_status to check the MCP is working properly.

Codex CLI

Add this repository as a marketplace, then install the plugin from it:

codex plugin marketplace add CitiesSkylinesModding/agents-plugins
codex plugin add coherent-gameface@csmodding

Once enabled, Codex autoloads the gameface MCP server from.codex-plugin/mcp.json.Run /mcp to confirm it connected, then Codex will use this MCP when it needs it.You can ask it to call game_status to check the MCP is working properly.

Configuration

The server reads these environment variables (all optional):

Variable Default Purpose
GAMEFACE_HOST localhost Host of the Gameface CDP endpoint.
GAMEFACE_PORT 9444 Port of the Gameface CDP endpoint.
GAMEFACE_CONNECT_TIMEOUT_MS 5000 HTTP discovery / WebSocket open timeout.
GAMEFACE_CALL_TIMEOUT_MS 15000 Per-command reply timeout.

On Claude Code, the plugin's .mcp.json forwards themfrom your environment(${VAR:-default}), and an extra GAMEFACE_MCP_RUNTIME variable (default node) overrides theruntime used to launch the server.

On Codex CLI, the plugin config passes no environment block (Codex does not interpolate${VAR} placeholders, and ~/.codex/config.toml cannot override a plugin-provided server), so theserver always starts with the defaults above. If you need non-default settings, register thenpm-published server manually with codex mcp add and the environment you want; it replaces theplugin's copy under the same name (see mcp/README.md).

Development

Uses mise + bun (never npx). The repository is a marketplace hosting the plugin(s) underplugins/, and a bun workspace: the root package.json carries the lint/format tooling (oxlint,oxfmt) and the lefthook git hooks, while the MCP server lives in theplugins/coherent-gameface/mcp/ workspace package (published on npm as@csmodding/gameface-devtools-mcp).

bun install   # install all workspace deps (also installs the git hooks)
mise check    # type-check, lint (with safe auto-fixes), and format
mise build    # rebuild the server bundle (commit the result)

Run mise tasks for the full list.

After changing anything under plugins/coherent-gameface/mcp/src/, run mise check, rebuild, andcommit the updated dist/server.mjs.

Troubleshooting

  • /mcp shows the server failed / tools error with "Cannot reach …": the Gameface applicationis not running or the debug port is not reachable. Check curl http://localhost:9444/json/list.Use game_status for a structured diagnosis.
  • Runtime not found: ensure node (22.4+) is on your PATH.
  • Read the MCP server logs: Claude Code records each server's connection attempts and capturedstderr to per-project .jsonl files, the fastest way to see why a launch failed (e.g., a-32000 Connection closed from a bad command/path before any game_* tool runs). They live underthe Claude CLI cache, in an mcp-logs-gameface/ folder keyed by the project path (separatorsreplaced with -); newest .jsonl first, and each Server stderr: ... line is what the serverprinted:
    • Windows: %LocalAppData%\claude-cli-nodejs\Cache\<project-path>\mcp-logs-gameface\
    • macOS / Linux: ~/.cache/claude-cli-nodejs/Cache/<project-path>/mcp-logs-gameface/

MCP Server · Populars

MCP Server · New