DesyncedMCP
# DesyncedMCP
MCP server for [Desynced](https://store.steampowered.com/app/1450900/Desynced/) mod development. Gives an AI assistant (Claude Code or any MCP client) direct access to the game's Lua API reference, base-game source, live game logs and installed mods.
## Tools
### Static (filesystem)
| Tool | Purpose |
|------|---------|
| `search_lua_api` | Search the official Lua API reference (vendored in `docs/lua-api.txt`) |
| `search_game_source` | Regex search over base game (`main/`) + mods Lua/JSON in the workspace |
| `get_game_logs` | Tail a game log file if one exists (see `-abslog` note below) |
| `list_mods` | List mods the game will load vs. mods in the workspace |
| `read_game_file` | Read any workspace source file by relative path with line range |
### Live (lrdb debugger link, game running with `-moddev`)
| Tool | Purpose |
|------|---------|
| `game_status` | Live snapshot: tick, player faction, entity count, active mod settings |
| `game_logs` | Output captured live (print/errors/BOOT); survives crashes up to the moment of death |
| `game_eval` | Execute arbitrary Lua inside the running game and return the result |
| `game_reload` | `Debug.Reload()` — hot reload all mod Lua, exactly like pressing F7 |
The link speaks the satoren lrdb protocol (newline-delimited JSON-RPC, no
`init`) against `127.0.0.1:21110`. **The game's debug server takes commands
from a single client**: while this server is linked, the in-game log console
goes silent (output is redirected to the link) and VS Code cannot attach.
The VM answers eval only while executing Lua, so an idle menu can time out.
## Simulation bridge (companion mod)
`game_eval` runs in the game's UI Lua VM, where simulation mutations are
blocked. Controlling the game (move, deploy, mine, construct...) requires
the companion mod [Desynced MCP Bridge on the Steam Workshop](https://steamcommunity.com/sharedfiles/filedetails/?id=3789136847),
which exposes
`FactionAction.MCPSimCmd` into the simulation context. This server works
without it for read-only tools (logs, status, eval reads, hot reload).
## Setup
```sh
npm install
npm test # smoke test
```
Register in Claude Code (project scope):
```sh
claude mcp add desynced --scope project -- node <path-to>/DesyncedMCP/server.js
```
## Configuration (env vars)
| Var | Default |
|-----|---------|
| `DESYNCED_WORKSPACE` | current working directory — point it at the folder holding your mod sources |
| `DESYNCED_GAME_MODS` | `C:/Program Files (x86)/Steam/steamapps/common/Desynced/Desynced/Content/mods` — set it if Steam lives elsewhere (custom library folder) |
| `DESYNCED_SAVED` | `%LOCALAPPDATA%/Desynced/Saved` |
### Searching the base game (optional)
The game ships its entire base game as `main.zip` inside the mods folder
and always loads it zipped — it is never extracted in a normal install. To
let `search_game_source` and `read_game_file` see the base-game Lua, unzip
`main.zip` into a `main/` folder inside your workspace with any zip tool.
This is purely a development convenience; the game neither needs nor uses
the extracted copy.
## Game-side requirements
The server itself runs outside the game — nothing to install in the game. For logs to exist, launch Desynced with these Steam launch options:
```
-moddev -log
```
`-moddev` enables the mod developer mode (hot reload with F7, strict data checks, log console); `-log` writes the log file this server reads.
## Roadmap
- `deploy_mod`: copy a workspace mod into the game mods dir (replacing the manual copy step)
- Live bridge over the lrdb debug protocol (`localhost:21110` in `-moddev`): eval Lua in the running game, inspect entities/factions, trigger `Debug.Reload()`
- Workshop publishing via DesyncedModUploader
TDQS
Scored across 9 tools
Most tools are clearly distinct: game_status, game_reload, and game_eval each target different game actions, while search_lua_api and search_game_source have separate scopes. The only potential confusion is between game_logs (live debugger buffer) and get_game_logs (tail log file), but their descriptions clarify the difference. Overall, boundaries are well-defined with one minor overlap.
The naming pattern is largely verb_noun in snake_case (e.g., search_lua_api, list_mods, read_game_file), but there is a minor inconsistency: game_logs vs get_game_logs both refer to logs but use different prefixes. The game_ prefix for three tools and separate prefixes for others is slightly mixed but still predictable and readable.
With 9 tools, the set is well-scoped for a game modding/debugging server. Each tool serves a concrete function—checking status, reloading, evaluating, searching, reading files, listing mods, and retrieving logs—without unnecessary bloat. This falls comfortably within the ideal 3-15 range.
The tool surface covers the core workflows for mod development and debugging: connecting, inspecting state, executing code, searching reference and source, retrieving logs from two sources, and managing mods. Minor gaps include lack of write/update operations for game files and no direct tool to manage mod installation, but these are not essential for the stated purpose and can be worked around.