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>
This commit is contained in:
13 files changed
+3578
No files matched your search
@@ -0,0 +1,164 @@
|
||||
# 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):
|
||||
|
||||
```bash
|
||||
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](https://docs.astral.sh/uv/).
|
||||
|
||||
Claude Code:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```json
|
||||
{
|
||||
"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:
|
||||
|
||||
```bash
|
||||
~/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:
|
||||
|
||||
```bash
|
||||
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.
|
||||
Reference in new issue
Block a user