FlaxMCP-Live
# FlaxMCP-Live
[](https://github.com/meet-brad-ch/FlaxMCP-Live/actions/workflows/ci.yml)
[](LICENSE)
MCP (Model Context Protocol) server for **[Flax Engine](https://flaxengine.com)** projects, built with **.NET 10 / C#**
on the official [ModelContextProtocol C# SDK](https://www.nuget.org/packages/ModelContextProtocol).
An AI client uses it to work through the live editor without manual steps: check, compile, play, control the game,
read the result.
FlaxMCP-Live is an independent fork of [eXoz00rd/FlaxMCP](https://github.com/eXoz00rd/FlaxMCP) by Sebastian Rokicki (MIT).
It keeps all upstream tools and adds 16 tools. The code keeps the upstream names (`FlaxMcp` namespaces, the
`FlaxMcpBridge` plugin). Thus you can merge upstream changes. See [Staying in sync with upstream](#staying-in-sync-with-upstream).
**Why "Live":** the added tools work on the running editor and the running game, not on files:
- The bridge stays connected when the editor reloads the scripts.
- A client waits for the editor's events. It does not poll.
- A client calls commands in the game while the game plays.
The name tells you that this fork is about this live loop.
> **Status:** 1.1 (see [CHANGELOG](CHANGELOG.md)). You install from source. There is no
> NuGet package yet.
## What you get
| From upstream FlaxMCP | Added in FlaxMCP-Live |
|---|---|
| Offline project, content and scene inspection | A bridge host that survives script reloads |
| Headless script compilation, game builds, structured logs | Long operations as jobs with progress notifications |
| Live editor tools: actors, selection, transforms, colliders, static models, save, play mode, screenshots | Editor events and waiting: no polling, no sleeps |
| Material creation and material instance parameters | Game commands: your game registers named commands, the client calls them |
| An optional gated C# execution tool | Compile checks in under a second, also while the editor plays |
| Read-only mode and toolset selection | Read and write any member of an actor or script. Find actors by name, type or script |
| | An agent skill that teaches an AI agent to use the server ([`skills/flaxmcp-live`](skills/flaxmcp-live)) |
| | Large-world engine support (double-precision vectors), Flax 1.13 |
Use an IDE-integrated MCP, such as Rider, for C# navigation and refactoring. FlaxMCP-Live does the engine operations,
and it reads the editor state that a code model cannot see.
## An unattended loop
The main use: an AI client changes game code and checks the result in the running game. No step is manual.
```text
build_check_scripts {} # compile errors in under a second, as SARIF
editor_compile {} # reload scripts; returns when the editor has settled
editor_open_scene { "path": "Scenes/Main.scene" }
editor_play_mode { "action": "start" }
editor_wait_for { "kind": "play_begin", "timeoutSeconds": 60 }
game_command { "name": "spawn", "args": "wave=1" } # a command your game registered
editor_wait_for { "kind": "log", "textContains": "wave cleared", "timeoutSeconds": 300 }
editor_get_member { "actorId": "…", "member": "Score", "scriptType": "PlayerController" }
editor_play_mode { "action": "stop" }
logs_errors {} # anything that went wrong on the way
```
Each step returns when its work is done. A script reload between the steps does not stop the connection.
## Tools
The default configuration exposes 57 tools across ten toolsets. `server` is always enabled; every other toolset can be
selected with `FLAX_TOOLSETS`. Tools added in FlaxMCP-Live are in **bold**.
| Toolset | Tools |
|---|---|
| `server` | `server_info`, `flax_status` |
| `project` | `project_info`, `project_targets`, `project_settings` |
| `content` | `content_search`, `content_asset_info`, `content_resolve_guid`, `content_material_details`, `content_create_material`, `content_create_material_instance`, `content_set_material_instance_parameter`, **`content_create_material_transparent`** |
| `scene` | `scene_list`, `scene_outline`, `scene_find_actor` |
| `build` | **`build_check_scripts`**, `build_generate_projects`, `build_compile_scripts`, `build_clear_cache`, `build_game` |
| `logs` | `logs_tail`, `logs_errors` |
| `editor` | `editor_scene_graph`, `editor_get_selection`, `editor_set_selection`, `editor_actor_details`, `editor_modify_actor`, `editor_create_actor`, `editor_duplicate_actor`, `editor_rename_actor`, `editor_reparent_actor`, `editor_delete_actor`, `editor_static_model_details`, `editor_set_static_model`, `editor_set_static_model_material`, `editor_box_collider_details`, `editor_create_box_collider`, `editor_set_box_collider`, `editor_save`, `editor_play_mode`, `editor_screenshot`, **`editor_camera_screenshot`**, **`editor_compile`**, **`editor_open_scene`**, **`editor_host_status`**, **`editor_find_actors`**, **`editor_get_member`**, **`editor_set_member`**, **`editor_add_script`** |
| `events` | **`editor_events`**, **`editor_wait_for`** |
| `jobs` | **`editor_job_start`**, **`job_status`**, **`job_wait`** |
| `game` | **`game_commands`**, **`game_command`** |
`editor_execute_csharp` and **`editor_invoke_method`** are additional editor tools that are absent by default. They appear
only when `FLAX_ALLOW_CODE_EXECUTION=true` and read-only mode is disabled.
Upstream polls a build with `build_status` and `build_result`. FlaxMCP-Live replaces these two tools with the job tools.
The job tools also run compiles, play mode changes and scene loads.
### Offline inspection
`project_info` reads the `.flaxproj`; `project_targets` parses declarations from `*.Build.cs`; and `project_settings`
returns structured settings assets. The content tools maintain an in-memory index under `Content/`, including GUID and
type metadata read from binary asset headers (Storage format version 9, Flax 1.12 and 1.13). Unrecognized binary assets
remain searchable by path without guessed metadata.
The scene tools parse `.scene` and `.prefab` files without starting the editor. Actor trees use `ParentID` relationships,
attach scripts to their owners, and report when response limits truncate a result.
### Builds, checks and logs
`build_generate_projects`, `build_compile_scripts`, and `build_clear_cache` run the editor headlessly and wait for the
operation. Script compilation extracts structured diagnostics rather than returning a raw log.
**`build_check_scripts`** compiles the script modules outside the editor, with the compiler arguments Flax.Build last
wrote (`Cache/Intermediate/<EditorTarget>/<Platform>/<Arch>/<Config>/<Module>.CSharp.response`) and the modules' current
files. It uses the .NET SDK's compiler server and writes to a scratch folder. It returns the errors as SARIF, with
file, line, column and code, in less than a second. It also works while the editor is open or in play mode.
`editor_compile` runs this check first. Only a clean check continues to the editor.
Build tools refuse to start a second editor process while the same project has a live editor session. Close the GUI editor
before using them. `logs_tail` and `logs_errors` only read the newest project log and remain available while it is running.
The `diagnose_build_failure` prompt combines `build_compile_scripts` with `logs_errors` to distinguish compiler failures
from engine or project-configuration errors.
### Jobs
`build_game` can take minutes. Thus it starts a background job and returns the job's handle immediately:
1. Call `build_game` with a preset and target, for example `Development` and `Windows`.
2. Call **`job_wait`** with the job ID. It sends progress notifications. It returns the state when the job ends or when
the wait time ends. **`job_status`** reads the state and does not wait.
3. The `result` of an ended job is the build outcome. A failed job has an `error`.
**`editor_job_start`** runs long editor operations in the same way: `compile`, `play_start`, `play_stop`, `play_pause`,
`play_resume` or `open_scene`. It returns immediately. The editor runs one job at a time.
### Live editor bridge
The `editor` tools communicate with the companion plugin over a local named pipe. `flax_status` reports whether the
configured project has a reachable, protocol-compatible session. Live calls fail clearly when the editor or plugin is not
running, or when the editor process that opened the session has exited.
Live scene reads include unsaved state. Write tools change selection and transforms, save modified scenes and assets, and
control play mode with `start`, `pause`, `resume`, or `stop`. `editor_screenshot` writes a PNG of the visible scene viewport;
it requires a GUI editor with a rendered viewport and does not work headlessly. Its destination directory must exist.
`editor_camera_screenshot` renders a camera into its own render target instead: the given Camera actor, the main camera
in play mode, or the editor viewport's view. It does not read an editor window, so it works with the editor covered,
small or minimised, at any size from 16 to 8192 pixels per side. It shows the 3D scene with the game's post effects,
without editor or screen-space UI.
#### It survives script reloads
When a script changes, the editor reloads its plugins. A usual plugin loses its pipe at that time. In FlaxMCP-Live, a
bridge host (`src/FlaxMcpBridge/Host`) owns the pipe:
- The plugin compiles the host one time for each editor process, into the Default load context. Thus a reload does not
stop the host.
- Each reloaded plugin attaches to the host again.
- A request that arrives during a reload waits until the reload ends.
- When a reload interrupts a request, the host answers `interrupted_by_reload`. The server sends read-only requests
again.
- A changed host takes control of the pipe from the old host.
**`editor_host_status`** reports the host, the plugin generation, the editor's memory and how many old plugin load
contexts are still alive. Call it first when the memory increases over many reloads.
#### Events and waiting
The host records the editor's events in a ring buffer: managed log lines, compiles, reloads, play mode changes, scene
loads and saves. **`editor_events`** reads the events after a sequence number. **`editor_wait_for`** waits until an
event of a given kind arrives, for example `play_begin`, `reload_end` or `log`. It can also wait for an event with a
given text. Thus a client waits for the event that it needs and does not sleep or poll. **`editor_compile`** waits until
the editor has reloaded and is stable. The editor also compiles changed sources without a request.
#### Game commands
A game registers named commands. A client lists them with **`game_commands`** and calls them with **`game_command`**. The
registration needs the `FlaxMcpBridge` module as a dependency of the game module
(`options.PrivateDependencies.Add("FlaxMcpBridge")` in the `.Build.cs` file).
```csharp
using FlaxMcpBridge;
var registration = GameCommands.Register(
"spawn", "Spawns a wave. Argument: wave=<n>.", arg => SpawnWave(arg));
// Dispose the registration when the script is destroyed.
```
The handler gets the argument string and returns the result text. The tool shows the type that declares the handler
as the owner of the command.
#### Members, actors and snippets
**`editor_find_actors`** finds actors by name, type or script type. **`editor_get_member`** and **`editor_set_member`**
read and write a member path of an actor or of one of its scripts, for example `Settings.Speed`. **`editor_add_script`**
attaches a script. **`editor_open_scene`** opens a scene. The server checks each tool result against its output schema.
`editor_execute_csharp` compiles a snippet in the bridge host and runs it on the editor main thread. The compiler stays
loaded across reloads. **`editor_invoke_method`** calls one method by name. Both tools need `FLAX_ALLOW_CODE_EXECUTION`.
#### Large worlds and Flax 1.13
The bridge reads actor translations and vectors as double precision. It builds against engines with large worlds
enabled. The minimum engine version is 1.13.7012.
## Requirements
- .NET 10 SDK
- Flax Engine 1.13.7012 or newer installed locally
- a Flax project (`.flaxproj`)
- the companion plugin installed in that project for live editor tools
## Setup from source
### 1. Get and validate the server
```bash
git clone https://github.com/meet-brad-ch/FlaxMCP-Live.git
cd FlaxMCP-Live
dotnet build FlaxMcp.slnx
dotnet test FlaxMcp.slnx
dotnet format --verify-no-changes
```
### 2. Install the editor bridge
Add the bridge project to the consumer project's `References` array, using an absolute path or one relative to the
consumer `.flaxproj`:
```json
{
"References": [
{ "Name": "$(EnginePath)/Flax.flaxproj" },
{ "Name": "../FlaxMCP-Live/src/FlaxMcpBridge/FlaxMcpBridge.flaxproj" }
]
}
```
Keep existing references and adjust only the bridge path. Flax discovers the `EditorPlugin` from this reference; no
consumer-side `PrivateDependencies` or `Modules.Add` entry is required. Start or reload the GUI editor and call
`flax_status` to confirm `connected: true`.
### 3. Configure an MCP client
Publish the server with `tools/publish.sh` (it writes `.publish/FlaxMcp.exe`, which starts in under a second and does
not lock `bin/` while you build) and use the executable as the process target. `dotnet run --project src/FlaxMcp` works
too. This JSON shape works for clients that accept an `mcpServers` map, including Claude Code configuration files:
```json
{
"mcpServers": {
"flax": {
"command": "D:/Tools/FlaxMCP-Live/.publish/FlaxMcp.exe",
"env": {
"FLAX_PROJECT_PATH": "D:/Projects/YourFlaxProject"
}
}
}
}
```
In Rider's MCP server settings, create a stdio server with the same command and environment variables.
`tools/mcp_roundtrip.py` runs tool calls against a server build over stdio from the command line. Prefer absolute paths because GUI clients do not necessarily inherit the shell working directory.
Call `server_info`, `project_info`, and `flax_status` as a basic verification.
### 4. Give your AI agent the usage skill
The folder [`skills/flaxmcp-live`](skills/flaxmcp-live) is an agent skill. It tells an AI agent how to use the server:
the order of the calls, the two kinds of IDs, the traps of the live editor, worked workflows and all 59 tools with their
parameters. For Claude Code, copy the folder to `~/.claude/skills/` (for all your projects) or to `.claude/skills/` in
your Flax project. Other agents that read `SKILL.md` files can use the same folder.
After a server change, make the tool reference again:
```bash
python skills/flaxmcp-live/scripts/dump_tools.py --project "D:/Projects/YourFlaxProject"
```
## Configuration
| Variable | Required | Description |
|---|---|---|
| `FLAX_PROJECT_PATH` | yes | Path to a `.flaxproj`, or a directory containing exactly one top-level `.flaxproj` |
| `FLAX_ENGINE_PATH` | no | Flax Engine root. When omitted, uses the Flax Launcher's `%APPDATA%/Flax/Versions.txt` registrations |
| `FLAX_EDITOR_CONFIG` | no | Editor binary configuration: `Development` (default), `Debug`, or `Release` |
| `FLAX_TOOLSETS` | no | Comma-separated selection from `project`, `content`, `scene`, `build`, `logs`, `editor`, `events`, `jobs`, and `game`; `server` is always included. Omit for all toolsets |
| `FLAX_READ_ONLY` | no | `true`, `1`, or `yes` removes all tools that can alter files or editor state |
| `FLAX_BRIDGE` | no | Bridge mode placeholder; defaults to `auto`. It is parsed but does not currently change connection behavior |
| `FLAX_ALLOW_CODE_EXECUTION` | no | Enables `editor_execute_csharp` and `editor_invoke_method` only when true and `FLAX_READ_ONLY` is false |
| `FLAX_LOG_LEVEL` | no | Minimum server log level written to stderr; defaults to `Warning` |
Unknown toolset names fail at startup and list valid values. With `FLAX_READ_ONLY=true`, the remaining tools are
`server_info`, `flax_status`, the project and scene tools, `build_check_scripts`, `content_search`, `content_asset_info`,
`content_resolve_guid`, `content_material_details`, both log tools, `editor_scene_graph`, `editor_get_selection`,
`editor_actor_details`, `editor_static_model_details`, `editor_box_collider_details`, `editor_host_status`,
`editor_find_actors`, `editor_get_member`, `editor_events`, `editor_wait_for`, `job_status`, `job_wait`, and
`game_commands`.
## Security
- The bridge accepts local named-pipe connections and records discovery data under `%APPDATA%/FlaxMcp/sessions`; it does
not require network credentials.
- Build and editor write tools run with the current user's filesystem and process permissions. Use
`FLAX_READ_ONLY=true` for inspection-only clients.
- `editor_execute_csharp` compiles and runs arbitrary C# on the editor main thread with the Flax Editor process's full
machine permissions, including access to files, processes, credentials, and the network. Enable it only for trusted
clients and prompts.
## Troubleshooting
### `flax_status` reports `connected: false`
Confirm the configured project matches the project open in Flax, the bridge reference is present in its `.flaxproj`, and
the editor has finished compiling scripts. Reload scripts or restart the editor after adding the plugin. Check the latest
project log for `[FlaxMcpBridge] Pipe server started` or a plugin compilation error.
### Protocol mismatch
The server and editor plugin came from incompatible revisions. Update both from the same checkout, let Flax recompile the
plugin, and reload scripts. A mismatch is rejected explicitly rather than sent through an incompatible protocol.
### A build says the editor is already running
Headless build operations intentionally refuse to race a GUI editor using the same project and `Cache/` directory. Close
that editor session normally, then retry. Log-reading and live-editor tools do not require this step.
### Screenshot capture fails
Open a scene in the GUI editor and ensure its scene viewport is visible. Capture requires a rendered viewport, cannot run
headlessly, only accepts a `.png` path, and does not create the destination directory.
## Staying in sync with upstream
```bash
git fetch upstream --no-tags
git switch -c sync-upstream main
git merge upstream/main
```
The code of this fork is in files that upstream does not have. A few hook lines connect it to upstream code. A merge
has a conflict only where upstream changes one of these lines. See [MAINTAINING](MAINTAINING.md#staying-in-sync-with-upstream).
## Versions
FlaxMCP-Live uses [Semantic Versioning](https://semver.org). The [CHANGELOG](CHANGELOG.md) lists each release.
[MAINTAINING](MAINTAINING.md) gives the release steps.
The server and the bridge plugin must come from the same release.
## Contributing
- **[Contributing Guide](CONTRIBUTING.md)** — branch flow, commits, code style, CI
- **[Maintaining](MAINTAINING.md)** — versions, releases, upstream sync, seams
- **[Task Conventions](CONVENTIONS.md)** — writing issues and definitions of done
- **[Agent Instructions](AGENTS.md)** — single source of truth for AI tools working on this repository
## License
[MIT](LICENSE). Copyright (c) 2026 Sebastian Rokicki and Brad Chamberlain.
TDQS
Scored across 57 tools
Most tools have distinct purposes and the descriptions clarify live-editor versus file-based contexts. However, several pairs overlap in practice: editor_find_actors vs scene_find_actor, editor_scene_graph vs scene_outline, and editor_compile vs build_compile_scripts vs build_check_scripts. editor_job_start also duplicates blocking editor operations, so the large surface creates real selection ambiguity.
Names are consistently snake_case and grouped by clear functional prefixes such as editor_, content_, scene_, build_, logs_, project_, and job_. Within those prefixes some names are noun-first (editor_actor_details, editor_scene_graph, editor_play_mode) while others are verb-first (editor_find_actors, editor_create_actor), so it is not a pure verb_noun convention, but it remains predictable.
With 57 tools, the surface is far beyond the typical well-scoped range and well past the 25+ threshold for being heavy. Even though the tools are grouped into coherent domains, the sheer count makes reliable tool selection difficult for an agent.
Coverage is broad: project metadata, scene inspection, live actor manipulation, materials, builds, logs, screenshots, play mode, events, and jobs are all represented. Notable gaps remain around asset lifecycle operations (delete/rename/import), broader component creation beyond BoxCollider/StaticModel, script removal, and prefab creation, though generic member access and game commands provide workarounds.