faabandClaude Opus 5.5 1a5cc7426e Initial commit: Claude Co-Engineer
A Factorio 2.x mod plus MCP server that lets Claude answer questions about
a running game over Lua UDP, without RCON, so it works in singleplayer.

- Read-only tools: overview, problems, entities, production, power, trends,
  research, recipes, ratio calculator, belt tracer, screenshots, Lua queries
- In-game highlights with clickable [gps] links
- /ask chat command answered by a local helper running claude -p, with a
  per-player model setting and a systemd user service

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 21:28:44 +01:00
2026-10-29 21:28:44 +01:00
2026-10-29 21:28:44 +01:00
2026-10-29 21:28:44 +01:00

Claude Co-Engineer

Ask Claude questions about your live Factorio game — "what should I do next?", "why is my science slow?", "where's the nearest iron?" — from Claude Desktop or Claude Code, using your subscription instead of API tokens. Works in singleplayer; no RCON needed.

It's read-only by design: Claude looks, explains and suggests; you play.

Claude Desktop / Claude Code ──stdio(MCP)──▶ server/ (Python) ──UDP localhost──▶ mod/ (in-game Lua)

The mod uses Factorio 2.x's Lua UDP API (helpers.recv_udp / send_udp), which is enabled per game instance with --enable-lua-udp <port>.

Setup

1. Install the mod (symlinked, so edits apply on the next save load):

ln -s "$PWD/mod/claude-co-engineer" ~/.factorio/mods/claude-co-engineer

Then enable "Claude Co-Engineer" in the in-game Mods menu.

2. Launch Factorio with UDP enabled. In Steam: Factorio → Properties → Launch Options, add:

--enable-lua-udp 34200

The game only listens on 127.0.0.1.

3. Register the MCP server. Requires uv.

Claude Code:

claude mcp add factorio --scope user -e FACTORIO_UDP_PORT=34200 -- uv run --directory /home/faab/Documents/Code/Factorio/claude-co-engineer/server claude-co-engineer-mcp

Claude Desktop — add to claude_desktop_config.json (Settings → Developer → Edit Config), then restart it:

{
  "mcpServers": {
    "factorio": {
      "command": "uv",
      "args": ["run", "--directory", "/home/faab/Documents/Code/Factorio/claude-co-engineer/server", "claude-co-engineer-mcp"],
      "env": { "FACTORIO_UDP_PORT": "34200" }
    }
  }
}

Local (stdio) MCP servers only work in the desktop app and Claude Code, not claude.ai in a browser or the mobile apps.

Tools

Tool Answers
get_overview Where am I, what am I hovering, what's researching, what's broken — start here
get_player Inventory, cursor, hand-crafting queue, hovered/opened entity
inspect_entity Everything about the hovered entity (or one at x,y): status, recipe, contents, fuel, power
find_problems Machines not working, grouped by status (no_ingredients, full_output, low_power, …) with nearest examples
find_entities What's around a point; ore patches with total amounts
get_production Produced/consumed/net per minute per item and fluid
get_power kW consumption and production per electric network
trace_belt Follows a belt (the hovered one by default) through undergrounds, side-loads and splitters: fill and motion per section (backed up vs full and flowing), what inserters and drills put on or take off, and where it ends
get_trends How production, consumption and power changed over the last 10 min / hour / 10 hours; finds the biggest movers by itself
get_research Current/queued research, what's researchable now, the path to any technology
get_recipe How to make something, in which machines, whether it's unlocked, what uses it
calculate_ratios Machines, drills, belts and power for a target rate (or machine count), using your unlocked recipes and machines, research productivity, and what you've already built
screenshot An image of part of the map (Alt mode on, always daylight) for layout questions
highlight / clear_highlights Outline places in your game, with labels, guide lines from you, and clickable map links in chat
run_lua Read-only Lua query for anything else

"This" usually works: hover over a machine and ask "why isn't this working?".

When Claude points you at something, it outlines it in your world and posts a [gps] link in chat (click it to open the map there). Highlights are visible only to you, expire after a minute by default, and are purely visual.

run_lua is instructed to only read, but Lua can't be sandboxed read-only. To guarantee nothing in your world changes, turn off Allow Lua queries in Settings → Mod settings → Map. Every query is logged to factorio-current.log.

Asking from inside the game

Type /ask <question> in the game chat (e.g. /ask why is my green science slow?). The answer appears in chat a few seconds to a minute later, with clickable map links and item icons, and the places it mentions get highlighted. Follow-up questions continue the same conversation; /ask-new starts a fresh one.

/ask ──UDP──▶ claude-co-engineer-ask ──▶ claude -p (+ this MCP server) ──▶ answer ──UDP──▶ chat

This needs:

  • the claude CLI logged in with your subscription (claude auth login, once);

  • the helper running. Either start it by hand:

    ~/Documents/Code/Factorio/claude-co-engineer/server/.venv/bin/claude-co-engineer-ask
    

    or install it as a systemd user service that starts at login:

    cp server/claude-co-engineer-ask.service ~/.config/systemd/user/ && systemctl --user daemon-reload && systemctl --user enable --now claude-co-engineer-ask
    

    Its log shows each question and answer: journalctl --user -u claude-co-engineer-ask -f.

Pick the model under Settings → Mod settings → Per player → /ask model: Haiku, Sonnet (default), Opus or Fable. Bigger models give more thorough answers but are slower and use more of your plan's usage. It's per player, so in multiplayer everyone picks their own.

The dropdown entries are aliases, which the claude CLI resolves to the newest model of that name, so a new Sonnet or Opus is used automatically. To force any other model, uncomment FACTORIO_ASK_MODEL_OVERRIDE in server/claude-co-engineer-ask.service (an alias or a full model ID) and run systemctl --user daemon-reload && systemctl --user restart claude-co-engineer-ask. It wins over the in-game setting for everyone.

Claude only gets the Factorio tools in these sessions: no shell, files or web. If the helper isn't running, the game tells you after 3 seconds. The helper's port is a map setting (Ask helper port, default 34201). Helper environment variables: FACTORIO_ASK_PORT, FACTORIO_ASK_MODEL (model when the game doesn't send one, default sonnet), FACTORIO_ASK_MODEL_OVERRIDE (always use this model), FACTORIO_ASK_TIMEOUT (300 s), FACTORIO_ASK_CLAUDE (path to the CLI).

Ratio calculator

Ask things like "how many assemblers for 1 green science per second?" or "what does 10 red science assemblers need?". calculate_ratios works from your game, not a generic table:

  • Recipe: the unlocked one for each item (never recycling). Mineable items count as mined, so Space Age asteroid ore doesn't sneak in.
  • Machine: the type you already use for that recipe, otherwise the fastest one you've unlocked.
  • Productivity: research and machine bonuses are included. Modules and beacons aren't (yet).
  • Output: per step, how many machines you need, how many you've already built on that recipe, and how much you currently make. Ore becomes mining drill and belt counts.

Tell it what you already supply ("plates come from my main bus") to stop the breakdown there, or override the recipe or machine for any item. Byproducts are listed but not subtracted from demand.

Configuration

Environment variables for the server: FACTORIO_UDP_PORT (default 34200), FACTORIO_UDP_HOST (127.0.0.1), FACTORIO_TIMEOUT seconds (5), FACTORIO_SCRIPT_OUTPUT (~/.factorio/script-output).

Screenshots are rendered off-screen with game.take_screenshot (your camera doesn't move), written to script-output/claude-co-engineer/, and deleted once sent to Claude.

Troubleshooting

  • "No reply from Factorio": the game must be running a save, launched with --enable-lua-udp on the same port, with the mod enabled — and not paused. Singleplayer pauses while the Esc menu is open.
  • Headless servers pause with no players connected unless auto_pause is false in server settings. With nobody connected, queries use the player force and the first surface.
  • Screenshots need a game client that renders; a headless server can't take them.
  • Changes to control.lua take effect after reloading the save; changes to settings.lua need a full game restart.
S
Description
No description provided
Readme
169 KiB
0 Stars 1 Watchers 0 Forks
Languages
Lua 73.7%
Python 26.3%