# Unreal Ai Connection

> Drive Unreal Engine 5.7 from any MCP client — 143 editor-automation tools (inspect, author, render) over a local TCP socket.

- **Type:** MCP server
- **Install:** `agentstack add mcp-najemwehbe-unreal-ai-connection`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [NAJEMWEHBE](https://agentstack.voostack.com/s/najemwehbe)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [NAJEMWEHBE](https://github.com/NAJEMWEHBE)
- **Source:** https://github.com/NAJEMWEHBE/unreal-ai-connection

## Install

```sh
agentstack add mcp-najemwehbe-unreal-ai-connection
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Unreal AI Connection

**Drive Unreal Engine 5.7 from any MCP-compliant client over a local TCP socket.**

151 tools total. Zero pixel-clicking. ~50ms round-trip.

[](https://github.com/NAJEMWEHBE/unreal-ai-connection/actions/workflows/tests.yml)
[](LICENSE)
[-313131?logo=unrealengine)](docs/PHASE-H-COMPAT.md)
[](https://www.python.org/)
[](https://modelcontextprotocol.io/)
[](tests/)
[](docs/TOOLS.md)
[](CHANGELOG.md)
[](#contributing)

*Live capture — an MCP client builds the scene, places **Niagara FX** (`spawn_niagara_at_location`), and orbits a camera, entirely over the local TCP socket. Reproduce with [`scripts/capture_demo_gif.py`](scripts/capture_demo_gif.py).*

**Native C++ handlers — not Python Remote Execution.** ~50 ms round-trips across 149 tools · 637 tests · MIT · works with any MCP-compliant client (Claude Code, Cursor, Cline, Codex, Gemini, Continue, Windsurf, Zed, …).

The suite now spans **inspection and authoring** — read existing assets and *create* them: actors, levels, data tables/assets, Blueprints (incl. K2 graph nodes), material graphs, **Niagara FX, Level Sequence cinematics (camera cuts, audio, visibility), and Movie Render Queue renders** — all over the same socket.

⭐ **If this saves you time, a star helps other devs find it.**

Authoring high-quality assets: see [docs/ASSET-PIPELINE-BLENDER.md](docs/ASSET-PIPELINE-BLENDER.md).

---

## Install (one paste, any client)

> **Every route below only wires the stdio bridge.** You must separately install the UE 5.7 plugin into your project's `Plugins/` folder and launch the editor (it binds `127.0.0.1:18888`). See [`docs/setup/README.md`](docs/setup/README.md) for the prerequisite, and [`docs/DISTRIBUTION.md`](docs/DISTRIBUTION.md) for how this is published.

**Claude Code** — paste the owner/repo, no clone needed:

```text
/plugin marketplace add NAJEMWEHBE/unreal-ai-connection
/plugin install unreal-ai-connection@unreal-ai-connection
```

**Cursor** — one-click deeplink. Base64-encode your machine's bridge path into this template:

```text
cursor://anysphere.cursor-deeplink/mcp/install?name=unreal-ai-connection&config=
```

where `` is base64 of `{"command":"python3","args":["/ABSOLUTE/PATH/TO/bridge/unreal_ai_connection_bridge.py"]}` (on Windows use `"command":"py"` if `python3` is not on PATH). Manual fallback — `.cursor/mcp.json`:

```json
{ "mcpServers": { "unreal-ai-connection": { "command": "python3", "args": ["/ABSOLUTE/PATH/TO/bridge/unreal_ai_connection_bridge.py"] } } }
```

**VS Code** — install deeplink (URL-encode the JSON for your path):

```text
vscode:mcp/install?
```

> **Windows:** all snippets use `python3`; if that's not on PATH use the `py` launcher instead (`"command": "py"`). The `.claude-plugin/mcp-config.json` marketplace path uses `python3` for cross-platform consistency — Windows users without `python3` should use the manual per-client recipe in `docs/setup/` with `py`.

**Every other client** — copy-paste recipe per client:

| Client | Route | Recipe |
|---|---|---|
| Claude Code | `/plugin marketplace add NAJEMWEHBE/unreal-ai-connection` | [docs/setup/claude-code.md](docs/setup/claude-code.md) |
| Claude Desktop | edit `claude_desktop_config.json` | [docs/setup/claude-desktop.md](docs/setup/claude-desktop.md) |
| Cursor | deeplink / `.cursor/mcp.json` | [docs/setup/cursor.md](docs/setup/cursor.md) |
| Codex CLI | `codex mcp add unreal-ai-connection -- …` | [docs/setup/codex-cli.md](docs/setup/codex-cli.md) |
| Windsurf | `mcp_config.json` | [docs/setup/windsurf.md](docs/setup/windsurf.md) |
| Continue | `~/.continue/config.yaml` | [docs/setup/continue.md](docs/setup/continue.md) |
| Cline | MCP Marketplace tab / settings | [docs/setup/cline.md](docs/setup/cline.md) |
| Zed | `~/.config/zed/settings.json` | [docs/setup/zed.md](docs/setup/zed.md) |
| Gemini CLI | `~/.gemini/settings.json` | [docs/setup/gemini-cli.md](docs/setup/gemini-cli.md) |
| VS Code Copilot | `.vscode/mcp.json` | [docs/setup/vscode-copilot.md](docs/setup/vscode-copilot.md) |

Also discoverable in the [official MCP Registry](https://github.com/modelcontextprotocol/registry) as `io.github.najemwehbe/unreal-ai-connection` (feeds the VS Code MCP gallery, mcp.so, PulseMCP) and submittable to the Cline marketplace via [`llms-install.md`](llms-install.md).

---

## Jump to

- [How it fits together](#how-it-fits-together) — architecture diagram + per-call sequence
- [Why it exists](#why-it-exists) — the UE 5.7 Python dead-ends this plugin sidesteps
- [Why MCP specifically](#why-mcp-specifically) — one protocol, every conforming client
- [Tools](#tools) — 147 tools grouped into 15 expandable categories
- [Quick start](#quick-start) — copy-paste path to a running editor with the plugin live
- [What's in the box](#whats-in-the-box) — directory tree
- [Status](#status) — release / test / build state
- [Contributing](#contributing) — house rules + how to add a tool
- [License](#license)

---

## How it fits together

```mermaid
graph LR
    A[Any MCP client] -->|stdio MCP| B[Python Bridge]
    B -->|TCP 127.0.0.1:18888| C[UnrealAIConnection pluginUE editor module]
    C -->|native C++ API| D[Unreal Editor 5.7]
```

Per-call sequence — click to see exactly what fires on a single tool call

```mermaid
sequenceDiagram
    participant User
    participant Client as MCP client(e.g. Claude Code)
    participant Bridge as Python bridge
    participant Plugin as UE plugin module
    participant Editor as Unreal Editor 5.7

    User->>Client: "Spawn a Cube at origin"
    Client->>Bridge: stdio MCP — tools/call spawn_actor
    Bridge->>Plugin: TCP 127.0.0.1:18888JSON-RPC framed
    Plugin->>Editor: GEditor->SpawnActor()
    Editor-->>Plugin: success + actor ref
    Plugin-->>Bridge: JSON-RPC result
    Bridge-->>Client: MCP envelope
    Client-->>User: rendered confirmation(~50ms total)
```

You ask Claude Code: *"Take a screenshot of my level and tell me what's there."* — Claude resolves the request to a tool call, the bridge forwards it as JSON-RPC to the running editor, the plugin captures the viewport, and Claude renders the image inline. Same flow works for spawning actors, inspecting Blueprints, mutating Widget Trees, executing arbitrary `unreal.*` Python, listing actors, focusing the viewport, loading levels, taking high-res screenshots.

The plugin binds to **`127.0.0.1` only** — your running editor is never reachable across the network.

---

## Why it exists

UE 5.7's Python reflection has known dead-ends. Most painfully: `EditorUtilityWidgetBlueprint.WidgetTree` is a `UPROPERTY()` without `EditAnywhere`, so neither `get_editor_property` nor direct attribute access can reach it. This blocks "let an LLM build me an editor utility panel" workflows entirely.

The plugin sidesteps these limits by calling UE's native C++ APIs directly inside the editor process. It's also dramatically faster than driving UE's GUI with screenshot pixel-clicks — **~50ms round-trip vs. minutes of GUI fiddling**.

---

## Why MCP specifically

MCP (Model Context Protocol) is a vendor-neutral I/O protocol designed for LLM tool-use. Because this plugin speaks MCP rather than baking in any one client, **every conforming client gets all 151 tools for free**: Claude Code, Codex CLI, Cursor, Gemini CLI, Continue, Zed, Cline, and any future entrant. Switch clients without changing the plugin or the bridge.

The wire format is `stdio MCP` between client and bridge, then a tight `length-prefixed JSON-RPC over TCP 127.0.0.1:18888` between bridge and the running UE editor. Either side can be reimplemented in another language; the contract is the JSON.

---

## Tools

**151 tools total.** 114 are native C++ handlers registered by the plugin at editor startup; 37 are bridge-side synthetic tools (`wait_for_events`, `get_camera_transform`, `set_camera_transform`, `screenshot_actor`, `compile_mod_pak`, `compile_mod_pak_direct`, `bulk_delete_assets`, `bulk_move_assets`, `bulk_rename_assets`, `bulk_duplicate_assets`, `bulk_inspect_assets`, `inspect_data_asset`, `inspect_sound_class`, `inspect_sound_submix`, `inspect_audio_bus`, `inspect_material_function`, `inspect_metasound`, `find_unused_assets`, `get_reference_chain`, `bulk_compile_blueprints`, `audit_blueprint_compile_status`, `find_actors_by_class`, `bulk_focus_actors`, `bulk_screenshot_actors`, `bulk_set_actor_property`, `compare_assets`, `bulk_set_console_variables`, `inspect_dependency_graph`, `bulk_fix_redirectors`, `marketplace_search`, `marketplace_import`, `convert_hdri_to_cubemap`, `sequencer_add_transform_keyframe`, `import_mesh`, `material_auto_remap`, `batch_capture_cameras`, `batch_spawn_from_csv`) that compose existing handlers without a dedicated UE round-trip (or, for `compile_mod_pak` and `compile_mod_pak_direct`, shell out to RunUAT or UnrealPak entirely outside the UE process) — see `bridge/unreal_ai_connection_bridge.py`'s `SYNTHETIC_TOOLS`. Per-tool JSON schemas and examples live in [`docs/TOOLS.md`](docs/TOOLS.md). Grouped overview:

> **Progressive tool disclosure (opt-in).** Advertising all 147 schemas up front is a lot of context — past ~30–50 tools, model tool-selection accuracy and token cost both degrade ([Anthropic Tool Search Tool](https://www.anthropic.com/engineering/advanced-tool-use), [MCP discussion #532](https://github.com/orgs/modelcontextprotocol/discussions/532)). Set the environment variable `UCMCP_TOOL_MODE=progressive` on the bridge and `tools/list` returns only a small **core** set (`get_project_summary`, `list_tools`, `get_actors_in_level`, `execute_unreal_python`, `take_high_res_screenshot`, `get_viewport_screenshot`, `poll_events`) plus a single **`search_tools`** discovery tool. The model calls `search_tools(query="add a camera keyframe", category="sequencer")` to pull the schemas of just the tools it needs, on demand. **Every one of the 147 tools stays directly callable via `tools/call` in both modes** — progressive mode changes only what is *advertised*, never what is *dispatchable*, so existing clients keep working. Default (unset / `all`) is the legacy expose-everything behaviour. `search_tools` runs entirely bridge-side (no UE round-trip), validates its input, and fails closed.

### Python execution (5 tools)

Python execution — click to expand the tool table

| Tool | Purpose |
|---|---|
| `execute_unreal_python` | Universal escape hatch — run arbitrary `unreal.*` Python in the editor's interpreter. Multi-line scripts work. |
| `run_python_file` | Execute a `.py` file from disk in the editor's Python interpreter. |
| `apply_python_to_selection` | Run a Python snippet with the editor's current selection bound as `actors` / `assets`. |
| `exec_python_persistent` | Persistent Python session — variables defined in one call survive into the next. |
| `reset_python_state` | Wipe the persistent session's globals. |

### Project / asset registry (10 tools)

Project / asset registry — click to expand the tool table

| Tool | Purpose |
|---|---|
| `get_project_summary` | Project name, engine version, enabled plugins, asset count. |
| `find_assets` | Query the asset registry by class + path + name. |
| `inspect_asset` | Class, tags, dependencies, referencers, on-disk size. |
| `move_asset` | Move an asset to a different folder; UE creates a redirector at the source path. |
| `rename_asset` | Change an asset's leaf name in place; UE creates a redirector at the old name. |
| `duplicate_asset` | Copy an asset to a new path. |
| `delete_asset` | Delete an asset; refuses if referenced by other packages unless `force=true`. |
| `fix_up_redirectors` | Resolve all object redirectors under a folder. |
| `create_data_table` | Create a new `UDataTable` asset whose rows conform to a given row `UScriptStruct`. |
| `create_data_asset` | Create a new `UDataAsset` (or subclass) asset from a `UDataAsset` subclass path. |

### Blueprint / widget / animation — introspection + authoring (20 tools)

Blueprint / widget / animation — introspection + authoring — click to expand the tool table

| Tool | Purpose |
|---|---|
| `inspect_blueprint` | Variables, function/event graphs, parent class of any Blueprint asset. |
| `compile_blueprint` | Recompile a Blueprint asset and report errors. |
| `inspect_widget_tree` | Read the widget hierarchy of a `UWidgetBlueprint` or EUW (the thing UE Python can't do). |
| `inspect_widget_blueprint` | Widget-BP-specific surface: animations, delegate bindings, palette category, inherited named slots, property-binding count, blueprint compile status. Pairs with `inspect_blueprint` + `inspect_widget_tree`. |
| `edit_widget_tree` | Mutate the tree: `set_root` / `add_child` / `set_property`. Solves the EUW WidgetTree blocker. |
| `inspect_anim_blueprint` | Read variables and state machines of an Animation Blueprint. |
| `inspect_anim_montage` | Read sections, slots, and notify tracks of an `UAnimMontage`. |
| `inspect_static_mesh` | LODs, materials, collision, bounds for a `UStaticMesh`. |
| `inspect_skeletal_mesh` | LODs, materials, sockets, skeleton info for a `USkeletalMesh`. |
| `inspect_physics_asset` | Body setups (one per simulated bone), constraint setups (joints between bodies), bounds-bodies subset, named physical-animation + constraint profiles. Cross-links to `inspect_skeletal_mesh` via `preview_skeletal_mesh`. |
| `inspect_niagara_system` | Emitters and exposed user parameters of a Niagara system. |
| `inspect_landscape` | Components, layers, and material info for a landscape actor. |
| `inspect_data_table` | RowStruct identity, sorted row names, per-property name+type for every `FProperty` on the row struct, plus client-strip / ignore-extra/missing-fields flags. |
| `inspect_curve` | UCurveBase channel layout (1ch UCurveFloat / 4ch UCurveLinearColor / 3ch UCurveVector), per-channel name + key count + per-channel + global time/value range. |
| `create_blueprint` | Create a new `UBlueprint` asset under `/Game/` from a parent class (default `/Script/Engine.Actor`). |
| `add_blueprint_variable` | Add a typed member variable (bool/int/float/string/name/vector/rotator/transform/object) to an existing `UBlueprint`. |
| `add_blueprint_function` | Add a new empty function graph to an existing `UBlueprint`. |
| `add_blueprint_node` | Add a K2 node (`call_function` / `variable_get` / `variable_set` / `branch`) to a Blueprint event or function graph; returns the new node's GUID + pins. |
| `connect_blueprint_pins` | Wire two pins (exec or data) between nodes by GUID + pin name, via the schema-validated `UEdGraphSchema_K2::TryCreateConnection`. |
| `set_blueprint_node_pin_default` | Set a literal or object default on an input pin (verified by read-back). |

### Materials (6 tools)

Materials — click to expand the tool table

| Tool | Purpose |
|---|---|
| `create_material_instance` | Create a `UMaterialInstanceConstant` asset with a parent material set. |
| `set_mi_parameter` | Override a scalar/vector/texture parameter on a material instance. Type discriminator picks value shape. |
| `inspect_material` | List parameter names declared by a `UMaterial` or `UMaterialInstance` (scalar/vector/texture/static-switch). |
| `inspect_material_instance` | Read a material instance's parent + currently-overridden parameter values. |
| `add_material_expression` | Create a `UMaterialExpression` node inside an existing `UMaterial`'s graph, then recompile the material. |
| `connect_material_expression` | Wire an expression's output to a material property input (`property:BaseColor`) or another expression's input (`node::`), then recompile. |

### Textures (3 tools)

Textures — click to expand the tool table

| Tool | Purpose |
|---|---|
| `import_texture` | Bring an image file (PNG / JPG / EXR / TGA / BMP / HDR) from disk into the project as a `UTexture2D` asset via UE's canonical import path. |
| `configure_texture` | Adjust SRGB / compression / LOD group / filter on an existing texture asset. |
| `inspect_texture` | Texture class, surface dimensions, sRGB, compression, filter, LOD group,

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [NAJEMWEHBE](https://github.com/NAJEMWEHBE)
- **Source:** [NAJEMWEHBE/unreal-ai-connection](https://github.com/NAJEMWEHBE/unreal-ai-connection)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-najemwehbe-unreal-ai-connection
- Seller: https://agentstack.voostack.com/s/najemwehbe
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
