MCP (Model Context Protocol) bridge for Unreal Engine 5 — lets AI assistants control the UE5 editor
Project description
UnrealMCP — AI Bridge for Unreal Engine 5
Control Unreal Engine 5 editor from AI coding assistants (Claude Code, Cursor, Windsurf, etc.). Create materials, blueprints, Niagara VFX, StateTrees, spawn actors, manage data tables, profile performance, and more — 280 commands across 13 categories, all without leaving your terminal.
Two ways to use it:
| CLI (new) | MCP Server | |
|---|---|---|
| Install | npm install -g unrealcli |
pip install unrealmcp |
| Dependencies | None (single binary) | Python 3.10+ |
| Works with | Claude Code (via Bash) | Claude Code, Cursor, Windsurf, VS Code, Gemini CLI, Rider, Zed, Amazon Q |
| Protocol | Direct TCP | MCP over stdio |
Both talk to the same C++ plugin inside the editor. Use whichever fits your workflow — or both.
Quick Start
Option A: CLI (Recommended for Claude Code)
# 1. Install
npm install -g unrealcli
# 2. Go to any UE5 project and install the plugin
cd YourProject/
ue-cli init
# 3. Open the editor, then verify
ue-cli health_check
That's it. No Python, no config files, no MCP setup.
Option B: MCP Server (For Cursor, Windsurf, etc.)
# 1. Clone the plugin into your project
git clone https://github.com/aadeshrao123/Unreal-MCP.git Plugins/UnrealMCP
# 2. Install the Python MCP server
pip install unrealmcp
# 3. Add to your AI tool's config (see MCP Setup section below)
How It Works
┌──────────────────────────────────────────┐
│ Unreal Engine 5 Editor │
│ │
│ C++ Plugin (UnrealMCPBridge) │
│ TCP server on localhost:55557 │
│ 280 commands: materials, blueprints, │
│ niagara, statetree, actors, data │
│ tables, profiling, and more │
└──────────────┬───────────────────────────┘
│ TCP/JSON
┌──────────────┴───────────────────────────┐
│ │
┌─────────┴─────────┐ ┌─────────┴──────────┐
│ CLI (ue-cli) │ │ MCP Server │
│ Go binary │ │ Python (unrealmcp)│
│ Direct TCP │ │ stdio → TCP │
│ │ │ │
│ Claude Code │ │ Cursor, Windsurf, │
│ (via Bash tool) │ │ VS Code, Rider... │
└───────────────────┘ └────────────────────┘
The C++ plugin runs inside the editor and exposes 280 commands over TCP. The CLI and MCP server are two different front doors to the same plugin.
CLI Reference
Installation
# From npm (recommended)
npm install -g unrealcli
# Or download binary directly from GitHub Releases
# https://github.com/aadeshrao123/Unreal-MCP/releases
Platforms: Windows (x64), macOS (Intel + Apple Silicon), Linux (x64 + ARM64)
Setup
# Navigate to your UE5 project
cd MyProject/
# Install the C++ plugin (one-time)
ue-cli init
# → Creates Plugins/UnrealMCP/ with C++ source
# → Patches .uproject to enable the plugin
# → Open editor to compile, then you're ready
# Verify everything works
ue-cli doctor
Usage
# Every command follows this pattern:
ue-cli <command> [--flag value]
# Examples:
ue-cli health_check
ue-cli find_assets --class-type material --path /Game
ue-cli spawn_actor --name MyCube --type StaticMeshActor --location "[0,0,100]"
ue-cli get_data_table_rows --data-table-path /Game/Data/DT_Items
ue-cli save_all
# For complex params, use --json:
ue-cli build_material_graph --json '{"material_path":"/Game/M_Test","nodes":[...],"connections":[...]}'
# Or pipe from stdin:
echo '{"material_path":"/Game/M_Test","nodes":[...]}' | ue-cli build_material_graph --json -
Help & Discovery
# See all commands grouped by category
ue-cli --help
# See flags for a specific command
ue-cli find_assets --help
# Dump all commands with descriptions, flags, and examples (for AI assistants)
ue-cli list_commands
Global Flags
| Flag | Description |
|---|---|
--port <int> |
TCP port override (default: auto-discover from port file) |
--timeout <int> |
Timeout in seconds (default: 30, large ops: 300) |
--json <string> |
Full params as JSON string (use - for stdin) |
--version |
Print version |
Key Commands
Assets
ue-cli find_assets --class-type material --path /Game/Materials
ue-cli list_assets --path /Game --class-filter blueprint
ue-cli get_asset_properties --asset-path /Game/Materials/M_Base
ue-cli import_asset --source-file "C:/Art/texture.png" --destination-path /Game/Textures
ue-cli save_asset --asset-path /Game/Materials/M_Base
ue-cli save_all
Blueprints
ue-cli create_blueprint --name BP_MyActor --parent-class Actor
ue-cli add_component_to_blueprint --blueprint-path /Game/BP_MyActor --component-class StaticMeshComponent
ue-cli add_event_node --blueprint-name BP_MyActor --event-name BeginPlay
ue-cli compile_blueprint --blueprint-name BP_MyActor
ue-cli read_blueprint_content --blueprint-path /Game/BP_MyActor
Materials
ue-cli create_material --name M_Red --path /Game/Materials
ue-cli build_material_graph --material-path /Game/Materials/M_Red \
--nodes '[{"type":"Constant3Vector","pos_x":-400,"properties":{"Constant":"(R=1,G=0,B=0)"}}]' \
--connections '[{"from_node":0,"to_node":"material","to_pin":"BaseColor"}]'
ue-cli create_material_instance --parent-path /Game/Materials/M_Base --name MI_Red
Data Tables
ue-cli get_data_table_schema --data-table-path /Game/Data/DT_Items
ue-cli get_data_table_rows --data-table-path /Game/Data/DT_Items
ue-cli add_data_table_row --data-table-path /Game/Data/DT_Items --row-name CopperOre \
--data '{"DisplayName":"Copper Ore","StackSize":100}'
ue-cli update_data_table_row --data-table-path /Game/Data/DT_Items --row-name CopperOre \
--data '{"StackSize":200}'
Actors & Level
ue-cli get_actors_in_level
ue-cli spawn_actor --name MyCube --type StaticMeshActor --location "[0,0,100]"
ue-cli spawn_blueprint_actor --blueprint-path /Game/BP_MyActor --location "[500,0,0]"
ue-cli find_actors_by_name --pattern "Light"
ue-cli get_world_info
ue-cli take_screenshot
Performance Profiling
# Record → Stop → Analyze
ue-cli performance_start_trace --channels "cpu,gpu,frame"
# ... play the game ...
ue-cli performance_stop_trace
ue-cli performance_analyze_insight --query diagnose
ue-cli performance_analyze_insight --query flame --count 20
ue-cli performance_analyze_insight --query search --filter "ConveyorProcessor"
Enhanced Input
ue-cli create_input_action --asset-path /Game/Input/IA_Jump --value-type Boolean
ue-cli create_input_mapping_context --asset-path /Game/Input/IMC_Default
ue-cli add_key_mapping --context-path /Game/Input/IMC_Default --action-path /Game/Input/IA_Jump --key SpaceBar
Niagara VFX
# Create a system from an emitter template, then tweak it
ue-cli create_niagara_system --asset-path /Game/VFX/NS_Sparks \
--template "/Niagara/DefaultAssets/FX_Sparks.FX_Sparks"
ue-cli get_niagara_system_info --asset-path /Game/VFX/NS_Sparks
ue-cli set_niagara_module_input --asset-path /Game/VFX/NS_Sparks \
--emitter-name Sparks --stack SpawnStack \
--module-name "Spawn Rate" --input-name SpawnRate --value 250
ue-cli compile_niagara_system --asset-path /Game/VFX/NS_Sparks
# Spawn it in the level
ue-cli spawn_niagara_effect --asset-path /Game/VFX/NS_Sparks --location "[0,0,200]"
StateTree
# Create a StateTree, add a state with a task, compile
ue-cli create_statetree --asset-path /Game/AI/ST_Enemy
ue-cli add_statetree_state --asset-path /Game/AI/ST_Enemy --state-name Patrol
ue-cli add_statetree_task --asset-path /Game/AI/ST_Enemy \
--state-name Patrol --task-type "MassEnemyNestPatrolTask"
ue-cli add_statetree_transition --asset-path /Game/AI/ST_Enemy \
--from-state Patrol --trigger OnEvent --event-tag "Enemy.SeePlayer"
ue-cli compile_statetree --asset-path /Game/AI/ST_Enemy
Mass Config Traits (Surgical Editing)
# Modify a single trait property without touching the rest of the trait array
ue-cli get_mass_config_traits --asset-path /Game/Mass/Enemy_Config
ue-cli set_mass_config_trait_property --asset-path /Game/Mass/Enemy_Config \
--trait-class MassMovementTrait --property-name MaxSpeed --property-value 600
Widgets (UMG)
ue-cli get_widget_tree --widget-blueprint-path /Game/UI/WBP_HUD
ue-cli add_widget --widget-blueprint-path /Game/UI/WBP_HUD --widget-class TextBlock \
--parent-widget-name RootCanvas --widget-name TitleText \
--widget-properties '{"Text":"Hello World"}'
Diagnostics
# Check entire setup
ue-cli doctor
# Output:
# [ok] Project MyProject/MyProject.uproject
# [ok] Plugin directory Plugins/UnrealMCP/ exists
# [ok] Plugin source Source/UnrealMCPBridge/ exists
# [ok] UProject entry UnrealMCP plugin listed and enabled
# [ok] Port file port 55557
# [ok] TCP connection Connected to 127.0.0.1:55557
# [ok] Health check Bridge is responsive
# All checks passed. ue-cli is ready to use.
MCP Server Setup
For AI tools that use the Model Context Protocol (Cursor, Windsurf, VS Code, etc.).
Requirements
- Unreal Engine 5.7 (tested on 5.7, may work on earlier 5.x versions)
- Python 3.10+
- UE5 Plugins (enabled automatically by the
.uplugin):PythonScriptPluginEditorScriptingUtilitiesEnhancedInput
Install
pip install unrealmcp
Setup Script (Alternative to Manual Config)
The setup script installs the unrealmcp pip package and creates the MCP config for your AI tool automatically.
Windows:
cd Plugins\UnrealMCP
install.bat
macOS / Linux:
cd Plugins/UnrealMCP
bash install.sh
The script asks where to create the MCP config:
| Scope | What it does | When to use |
|---|---|---|
| Project | Creates config next to your .uproject |
Only want UnrealMCP in this project |
| Global | Creates config in your user folder | Want UnrealMCP in all projects |
Configure Your AI Tool
Claude Code — .mcp.json (project root)
{
"mcpServers": {
"unreal": {
"type": "stdio",
"command": "unrealmcp"
}
}
}
Cursor — .cursor/mcp.json
{
"mcpServers": {
"unreal": {
"command": "unrealmcp"
}
}
}
VS Code / Copilot — .vscode/mcp.json
{
"servers": {
"unreal": {
"command": "unrealmcp"
}
}
}
Windsurf — ~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"unreal": {
"command": "unrealmcp"
}
}
}
Gemini CLI — .gemini/settings.json
{
"mcpServers": {
"unreal": {
"command": "unrealmcp"
}
}
}
JetBrains / Rider — .junie/mcp/mcp.json
{
"servers": [
{
"name": "unreal",
"command": "unrealmcp"
}
]
}
Zed — ~/.config/zed/settings.json
{
"context_servers": {
"unreal": {
"source": "custom",
"command": { "path": "unrealmcp" }
}
}
}
Amazon Q — .amazonq/mcp.json
{
"mcpServers": {
"unreal": {
"command": "unrealmcp"
}
}
}
All 280 Commands
| Category | Count | Highlights |
|---|---|---|
| Core | 2 | health_check, execute_python |
| Asset Management | 16 | find/list/import/duplicate/rename/delete/save |
| Blueprints | 22 | create, compile, variables, functions, graph nodes |
| Materials | 35 | create, build_material_graph, material functions, Substrate |
| Data Tables | 8 | full CRUD on rows + schema introspection |
| Data Assets | 12 | data assets + surgical Mass Config trait editing |
| Actors & Level | 19 | spawn, transform, properties, screenshot |
| Enhanced Input | 21 | actions, mapping contexts, triggers, modifiers |
| Widgets — UMG | 11 | widget tree, add/move/rename, slot props |
| Niagara VFX | 96 | systems, emitters, stack bindings (nested), scratch pad authoring, graph CRUD, DI member functions, source-menu discovery |
| StateTree | 33 | states, tasks, evaluators, transitions, conditions, bindings |
| Performance Profiling | 3 | record .utrace + smart analysis (diagnose/spikes/flame) |
| Debug | 2 | token tracking, debug toggle |
Core (2)
| Command | Description |
|---|---|
health_check |
Verify the bridge is running |
execute_python |
Run arbitrary Python in the editor |
Asset Management (16)
| Command | Description |
|---|---|
find_assets |
Search Asset Registry by class/path/name |
list_assets |
List assets in a directory |
get_asset_info |
Asset metadata |
get_asset_properties |
All editable properties |
set_asset_property |
Set a property |
find_references |
Find dependents/dependencies |
import_asset |
Import external file (PNG, FBX, etc.) |
import_assets_batch |
Batch import |
duplicate_asset |
Copy to new location |
rename_asset |
Rename/move (auto-fix references) |
delete_asset |
Delete (checks references) |
save_asset / save_all |
Save dirty assets |
open_asset |
Open in editor |
sync_browser |
Navigate Content Browser |
get_selected_assets |
Currently selected assets |
Blueprints (22)
| Command | Description |
|---|---|
search_parent_classes |
Find valid parent classes |
create_blueprint |
Create from any parent class |
compile_blueprint |
Compile |
read_blueprint_content |
Full structure readout |
analyze_blueprint_graph |
Graph analysis |
add_component_to_blueprint |
Add component |
create/get/set_blueprint_variable |
Variable management |
set_blueprint_variable_properties |
Modify variable settings |
create/delete/rename_blueprint_function |
Function management |
add_function_input/output |
Function parameters |
get_blueprint_function_details |
Function inspection |
get/set_blueprint_class_defaults |
CDO properties |
add_blueprint_node |
Add graph node (23+ types) |
add_event_node |
Add event (BeginPlay, Tick, etc.) |
connect_blueprint_nodes |
Wire nodes together |
delete_blueprint_node |
Remove node |
set_blueprint_node_property |
Edit node properties |
Materials (35)
| Command | Description |
|---|---|
create_material |
Create with blend/shading mode |
create_material_instance |
Create with parameter overrides |
build_material_graph |
Build complete node graph atomically |
get_material_info |
Inspect properties/params/textures |
set_material_properties |
Bulk-set material properties |
add/delete/move/duplicate_material_expression |
Manage nodes |
connect_material_expressions |
Wire nodes |
set_material_expression_property |
Set node property |
disconnect_material_expression |
Break connection |
layout_material_expressions |
Auto-layout |
recompile_material |
Force recompile |
get_material_errors |
Compilation errors |
get/set_material_instance_parameter |
MI parameter overrides |
list_material_expression_types |
Discover node types |
get_expression_type_info |
Node pins & properties |
search_material_functions |
Find Material Functions |
validate_material_graph |
Diagnose issues |
trace_material_connection |
Trace data flow |
cleanup_material_graph |
Remove orphaned nodes |
add_material_comments |
Comment boxes |
create/get_material_function |
Material Function management |
build_material_function_graph |
Build MF graph |
add/set_material_function_input/output |
MF pins |
validate/cleanup_material_function |
MF diagnostics |
apply_material_to_actor/blueprint |
Apply materials |
get_available_materials |
List materials |
get_actor/blueprint_material_info |
Material slot info |
Data Tables (8)
| Command | Description |
|---|---|
get_data_table_schema |
Column names and types |
get_data_table_rows / get_data_table_row |
Read rows |
add_data_table_row |
Add with initial data |
update_data_table_row |
Partial update |
delete_data_table_row |
Delete row |
duplicate_data_table_row |
Copy row |
rename_data_table_row |
Rename row |
Data Assets (12)
| Command | Description |
|---|---|
create_data_asset |
Create any UDataAsset subclass |
get/set_data_asset_property(ies) |
Read/write properties (single or batch) |
list_data_assets |
Browse by path/class |
list_data_asset_classes |
Discover all loaded UDataAsset subclasses |
get_property_valid_types |
Valid dropdown values for a property slot |
search_class_paths |
Find class paths |
get_mass_config_traits |
Inspect all traits on a Mass Entity Config asset |
add_mass_config_trait |
Append a new trait to a Mass Config (non-destructive) |
set_mass_config_trait_property |
Surgical in-place edit of a single trait property — never replaces the Traits array |
remove_mass_config_trait |
Remove a single trait by index or class without affecting siblings |
Actors & Level (19)
| Command | Description |
|---|---|
spawn_actor |
Spawn built-in actor types |
spawn_blueprint_actor |
Spawn BP actor |
spawn_actor_from_class |
Spawn from class name |
get_actors_in_level |
List all actors |
find_actors_by_name |
Search by name pattern |
get_actor_properties |
Read actor properties |
set_actor_transform |
Set location/rotation/scale |
delete_actor |
Remove from level |
get_selected_actors |
Viewport selection |
get_world_info |
Level info |
set_static_mesh_properties |
Mesh assignment |
set_physics_properties |
Physics config |
set_mesh_material_color |
Material color |
apply_material_to_actor/blueprint |
Apply material |
get_actor/blueprint_material_info |
Material slots |
get_available_materials |
List materials |
take_screenshot |
Capture viewport |
Enhanced Input (21)
| Command | Description |
|---|---|
create_input_action |
Create UInputAction |
get/set_input_action_properties |
Action properties |
add/remove_input_action_trigger |
Action triggers |
add/remove_input_action_modifier |
Action modifiers |
list_input_actions |
Browse actions |
create_input_mapping_context |
Create UInputMappingContext |
get_input_mapping_context |
Read mappings |
add/remove/set_key_mapping |
Key bindings |
add/remove_mapping_trigger/modifier |
Per-mapping overrides |
list_input_mapping_contexts |
Browse contexts |
list_trigger_types / list_modifier_types |
Discover types |
list_input_keys |
Valid key names |
Widgets — UMG (11)
| Command | Description |
|---|---|
get_widget_tree |
Widget hierarchy |
add_widget |
Add to parent |
remove/move/rename/duplicate_widget |
Widget operations |
get/set_widget_properties |
Widget properties |
get/set_slot_properties |
Layout slot properties |
list_widget_types |
Available widget classes |
Niagara VFX (96)
End-to-end Niagara authoring — read the full stack, mutate any binding (top-level or nested), author scratch-pad dynamic inputs from scratch, spawn arbitrary graph nodes including data-interface member functions, and discover every valid option the editor's dropdowns expose. Built on Niagara's exported ViewModel / Stack Graph APIs with safe replication of non-exported helpers.
Systems
| Command | Description |
|---|---|
create_niagara_system |
Create from emitter template or empty |
get_niagara_system_info |
System metadata, emitters, parameters |
list_niagara_systems |
Browse Niagara systems by path |
delete_niagara_system |
Delete a system |
compile_niagara_system |
Force recompile |
set_niagara_system_property |
Set top-level system property |
get_niagara_system_errors |
Compilation errors / warnings |
get_niagara_particle_stats |
Per-emitter particle stats |
get/set_niagara_playback_range |
Preview playback range |
Emitters
| Command | Description |
|---|---|
get_niagara_emitters |
List emitters in a system |
add_niagara_emitter |
Add from template |
remove_niagara_emitter |
Remove an emitter |
duplicate_niagara_emitter |
Copy emitter with new name |
reorder_niagara_emitter |
Change emitter index |
set_niagara_emitter_property |
Set emitter property |
get_niagara_emitter_attributes |
Particle attributes (Position, Velocity, etc.) |
Modules (Spawn / Update / Render stacks)
| Command | Description |
|---|---|
get_niagara_modules |
List modules in any stack |
add_niagara_module |
Add module from script asset |
remove_niagara_module |
Remove a module |
set_niagara_module_enabled |
Enable/disable a module |
reorder_niagara_module |
Reorder within stack |
get_niagara_module_inputs |
Inspect module inputs with current values |
set_niagara_module_input |
Set literal value (auto-routes Module.* inputs to rapid-iteration; supports nested dot-paths like "Spawn Count.int32001") |
set_niagara_dynamic_input |
Replace input with a dynamic input function (nested-path aware) |
set_niagara_curve |
Set curve points on a curve input |
get_niagara_module_versions |
List script versions |
Stack Input Binding Loop
| Command | Description |
|---|---|
get_niagara_module_input_binding |
Resolve mode (Default/Local/Linked/Dynamic/Data/Expression) + target + recursive children for every input in one call |
clear_niagara_module_input |
Reset an input (or nested path) to default — equivalent to "Reset to Default" in the stack UI |
list_niagara_input_source_menu |
Reproduces the editor's source dropdown — engine dynamic-input assets + scratch-pad DIs + link parameters grouped by namespace |
Parameters & Bindings
| Command | Description |
|---|---|
get_niagara_user_parameters |
List User-namespace parameters |
add_niagara_user_parameter |
Add a User parameter |
set_niagara_user_parameter |
Set a User parameter value |
remove_niagara_user_parameter |
Remove a User parameter |
link_niagara_parameter |
Bind module input to a parameter (supports nested dot-paths) |
get_niagara_rapid_iteration_parameters |
RI param introspection |
set_niagara_rapid_iteration_parameter |
Set RI param value |
list_niagara_available_parameters |
Enumerate well-known + user + scratch-pad-scoped parameters |
Renderers
| Command | Description |
|---|---|
add_niagara_renderer |
Add Sprite/Mesh/Ribbon/Light renderer |
remove_niagara_renderer |
Remove a renderer |
get_niagara_renderer_info |
Renderer summary with per-binding detail (binding_name + bound_variable + type + dataset_variable) |
get_niagara_renderer_properties |
Full renderer property dump |
set_niagara_renderer_property |
Set renderer property |
set_niagara_renderer_binding |
Bind renderer attribute to particle data |
Scratch Pad — CRUD & Apply
| Command | Description |
|---|---|
create_niagara_scratch_pad_module |
Create per-emitter scratch module (module / dynamic_input / function) |
list_niagara_scratch_pad_modules |
List scratch pads on a system |
duplicate_niagara_scratch_pad_module |
Duplicate with new name |
rename_niagara_scratch_pad_module |
Rename in-place |
delete_niagara_scratch_pad_module |
Remove from system |
apply_niagara_scratch_pad |
Commit edit-copy → asset (Apply button) |
apply_and_save_niagara_scratch_pad |
Apply + save asset (Apply & Save button) |
create_niagara_module_asset |
Create reusable standalone Niagara Module Script asset |
Script Properties (Details Panel)
| Command | Description |
|---|---|
get_niagara_script_properties |
Read Category, Description, Keywords, ModuleUsageBitmask, ProvidedDependencies, RequiredDependencies, LibraryVisibility, bDeprecated, bExperimental, NumericOutputTypeSelectionMode, ScriptMetaData, ConversionUtility |
set_niagara_script_properties |
Batch-set any subset (supports TArray<FName> like ProvidedDependencies and TArray<FNiagaraModuleDependency>) |
Script Parameters (Input / Output)
| Command | Description |
|---|---|
list_niagara_script_parameters |
Inputs + outputs on a scratch pad / standalone script |
add_niagara_script_parameter |
Add input or output parameter with any registered type (incl. data interfaces) |
remove_niagara_script_parameter |
Remove — cascades to Map Get / Map Set pin cleanup automatically |
rename_niagara_script_parameter |
Rename across asset + edit-copy graphs |
Graph Introspection
| Command | Description |
|---|---|
get_niagara_graph_nodes |
List every node with verbosity (summary/connections/full) + type_filter + name_filter. Three resolver modes: scratch pad, emitter stack graph, standalone script |
get_niagara_node_info |
Deep single-node inspect by node_index / node_class / node_id with pin layout, links, and type-specific fields (op_name, function_script, hlsl_preview, input_name/type) |
trace_niagara_connection |
BFS upstream/downstream with pin_name filter — see the dependency chain without dumping the whole graph |
validate_niagara_graph |
Classify orphaned / dead-end / missing-input nodes (skips +Add placeholders) |
Graph Node CRUD
| Command | Description |
|---|---|
add_niagara_graph_node |
Spawn Op / FunctionCall / DataInterfaceFunction / ParameterMapGet / ParameterMapSet / Reroute / Input node. DI member functions (e.g. Array.Length) use UNiagaraDataInterface::GetFunctionSignatures — same path as the right-click "Functions" submenu |
delete_niagara_graph_node |
Delete by index or GUID, mirrors on asset + edit-copy |
Pin Management
| Command | Description |
|---|---|
add_niagara_map_get_pin |
Add a typed output pin to a Map Get (e.g. Module.MyParam as Vector) |
add_niagara_map_set_pin |
Add a typed input pin to a Map Set (e.g. Particles.Velocity) |
add_niagara_node_pin |
Add a pin to any UNiagaraNodeWithDynamicPins-derived node |
rename_niagara_node_pin |
Rename a pin on a dynamic-pin node |
remove_niagara_node_pin |
Remove a dynamic pin |
connect_niagara_pins |
Wire two pins with UEdGraphSchema_Niagara::TryCreateConnection validation |
disconnect_niagara_pins |
Break a pin connection |
Custom HLSL
| Command | Description |
|---|---|
set_niagara_scratch_pad_hlsl |
Write HLSL source into the scratch pad's Custom HLSL node (creates pins as needed) |
add_niagara_custom_hlsl_input |
Add an input pin to a Custom HLSL node |
add_niagara_custom_hlsl_output |
Add an output pin to a Custom HLSL node |
rename_niagara_custom_hlsl_pin |
Rename a pin (also rewrites {PinName} references in the HLSL body) |
remove_niagara_custom_hlsl_pin |
Remove a pin |
Events & Simulation Stages
| Command | Description |
|---|---|
add_niagara_event_handler |
Add event handler stage |
add_niagara_simulation_stage |
Add simulation stage |
get_niagara_event_handlers |
Inspect handlers on emitter |
Level Spawning
| Command | Description |
|---|---|
spawn_niagara_effect |
Spawn at world location |
control_niagara_effect |
Activate / deactivate / restart |
add_niagara_component |
Add NiagaraComponent to a Blueprint |
get_niagara_actors |
Find spawned Niagara actors |
Discovery (zero-guess authoring)
| Command | Description |
|---|---|
list_niagara_modules |
All available Niagara module scripts |
list_niagara_emitter_templates |
Emitter templates |
list_niagara_data_interfaces |
Available data interfaces (DI_*) |
list_niagara_data_interface_functions |
Member functions on a DI class (Array.Length, Array.Get, etc.) — pass result to add_niagara_graph_node(node_type="DataInterfaceFunction") |
list_niagara_parameter_types |
Parameter type registry |
list_niagara_node_types |
Spawnable node classes with pin schema |
get_niagara_node_type_info |
Pin schema for a node class or script asset |
search_niagara_functions |
Find Niagara script assets by usage + name |
get_niagara_schema_actions |
Full graph right-click menu — same source the editor uses. Returns op_name / function_script / input_name for direct use with add_niagara_graph_node |
describe_niagara_type |
Type query — FNiagaraTypeRegistry types + UEnum / UScriptStruct reflection fallback for script-property enums and custom types |
get_niagara_data_interface_schema |
Walk a DI class's editable property schema |
find_niagara_scratch_pad_usage |
Reverse lookup — where is this scratch pad referenced? |
resolve_niagara_built_in_dynamic_input |
AssetRegistry scan for engine-shipped DI scripts (no more hardcoded paths) |
StateTree (33, NEW)
Read and author StateTree assets — states, tasks, evaluators, transitions, conditions, parameters, and bindings. Schema-aware: works with both StateTreeSchemaBase and Mass schema variants.
Reading
| Command | Description |
|---|---|
get_statetree_info |
Asset summary (schema, states, evaluators) |
get_statetree_full_info |
Full recursive dump (states + tasks + transitions + bindings) |
get_statetree_states |
List all states (flat) |
get_statetree_state |
Single state details by ID/name |
get_statetree_node |
Inspect any node (task/evaluator/condition) |
get_statetree_evaluators |
Global evaluators |
get_statetree_global_tasks |
Global tasks |
get_statetree_parameters |
Tree parameters |
get_statetree_bindings |
All property bindings |
get_statetree_transition_targets |
Valid transition targets for a state |
search_statetree_nodes |
Search nodes by name / type |
Authoring
| Command | Description |
|---|---|
create_statetree |
Create new StateTree asset |
set_statetree_schema |
Set schema (e.g. Mass schema) |
add_statetree_state |
Add a state (parent or root) |
add_statetree_task |
Add task to a state |
add_statetree_evaluator |
Add global evaluator |
add_statetree_global_task |
Add global task |
add_statetree_condition |
Add enter / transition condition |
add_statetree_transition |
Add transition (event / completed / delegate) |
add_statetree_parameter |
Add tree parameter |
add_statetree_binding |
Bind property between nodes |
compile_statetree |
Compile after edits |
Modification
| Command | Description |
|---|---|
set_statetree_state_property |
Edit state property |
set_statetree_node_property |
Edit task / evaluator / condition property |
set_statetree_transition_property |
Edit transition property |
set_statetree_color |
Set state color |
Removal
| Command | Description |
|---|---|
remove_statetree_state |
Remove a state |
remove_statetree_node |
Remove a task / evaluator / condition |
remove_statetree_transition |
Remove a transition |
remove_statetree_binding |
Remove a binding |
remove_statetree_parameter |
Remove a parameter |
Discovery
| Command | Description |
|---|---|
list_statetree_node_types |
All available task / evaluator / condition types |
list_statetree_enum_values |
Enum values for property dropdowns |
Performance Profiling (3)
| Command | Description |
|---|---|
performance_start_trace |
Start recording .utrace |
performance_stop_trace |
Stop and auto-load |
performance_analyze_insight |
Smart analysis (diagnose, spikes, flame, hotpath, search, histogram, etc.) |
Debug (2)
| Command | Description |
|---|---|
set_mcp_debug |
Enable token tracking |
get_mcp_token_stats |
Token usage stats |
Usage Examples
These work with both the CLI and MCP server. With the CLI, the AI calls ue-cli via Bash. With MCP, the AI calls tools directly.
Create a Material
Create a red metallic material at /Game/Materials/M_RedMetal
with roughness 0.3 and metallic 1.0
The AI will call create_material, then build_material_graph to wire up constant nodes to Base Color, Metallic, and Roughness pins.
Spawn Actors
Spawn 5 point lights in a circle around the origin at height 300
The AI will call spawn_actor with actor_type: "PointLight" five times with calculated positions.
Blueprint Creation
Create a Blueprint actor called BP_HealthPickup based on Actor,
add a Sphere Collision component and a Static Mesh component,
set it up so on BeginOverlap it prints "Health Picked Up"
The AI will use create_blueprint, add_component_to_blueprint, add_event_node, add_blueprint_node, and connect_blueprint_nodes.
Profile Performance
Start a performance trace, play for 10 seconds, stop it,
then diagnose the bottlenecks
The AI will call performance_start_trace, wait, performance_stop_trace, then performance_analyze_insight with query: "diagnose".
Data Table Management
Show me the schema of DT_Items, then add a new row called
"IronIngot" with StackSize 100
The AI will call get_data_table_schema, then add_data_table_row with the appropriate data.
Configuration
Custom Port
Add to Config/DefaultEngine.ini:
[UnrealMCP]
Port=55557
Environment Variable
# Force a specific port (overrides port file)
set UNREAL_MCP_PORT=55560
Multiple Editor Instances
Each editor picks a unique port automatically. The CLI and MCP server read the port from Saved/UnrealMCP/port.txt. Use --port flag or UNREAL_MCP_PORT env var to target a specific instance.
Architecture
Plugin Structure
Plugins/UnrealMCP/
├── UnrealMCP.uplugin # Plugin manifest
├── cli/ # Go CLI source (ue-cli)
│ ├── cmd/ # Command definitions (280 commands)
│ ├── internal/bridge/ # TCP client
│ ├── internal/project/ # Plugin embedding & project detection
│ └── npm/ # npm package wrapper
├── unrealmcp/ # Python MCP server
│ ├── _tcp_bridge.py # TCP communication
│ └── tools/ # Tool modules (one per category)
├── Source/UnrealMCPBridge/ # C++ editor plugin
│ ├── Public/ # Headers
│ └── Private/ # Implementation + command handlers
└── .github/workflows/release.yml # CI: builds + GitHub Release + npm publish
Communication Protocol
TCP with length-prefix framing:
[4 bytes: big-endian payload length] [N bytes: UTF-8 JSON]
Request: {"type": "command_name", "params": {...}}
Response: {"status": "success", "result": {...}}
Adding Custom Commands
CLI Side (Go)
Add a CommandSpec to the appropriate cmd/*.go file:
{
Name: "my_command",
Group: "mygroup",
Short: "What it does",
Long: "Detailed description.",
Example: "ue-cli my_command --param value",
Params: []ParamSpec{
{Name: "param", Type: "string", Required: true, Help: "Description"},
},
},
MCP Side (Python)
Create a new file in unrealmcp/tools/:
# unrealmcp/tools/my_tools.py
from unrealmcp._bridge import mcp
from unrealmcp._tcp_bridge import _call
@mcp.tool()
def my_command(param: str) -> str:
"""Description shown to the AI assistant."""
return _call("my_command", {"param": param})
Register it in unrealmcp/tools/__init__.py:
from unrealmcp.tools import my_tools # noqa: F401
C++ Side
Add a command handler in Source/UnrealMCPBridge/Private/Commands/ and register it in ExecuteCommand().
Supported AI Tools
| Tool | Interface | Config File | Status |
|---|---|---|---|
| Claude Code | CLI or MCP | Bash (CLI) / .mcp.json (MCP) |
Tested |
| Cursor | MCP | .cursor/mcp.json |
Tested |
| VS Code / Copilot | MCP | .vscode/mcp.json |
Supported |
| Windsurf | MCP | ~/.codeium/windsurf/mcp_config.json |
Supported |
| Gemini CLI | MCP | .gemini/settings.json |
Supported |
| JetBrains / Rider | MCP | .junie/mcp/mcp.json |
Supported |
| Zed | MCP | ~/.config/zed/settings.json |
Supported |
| Amazon Q | MCP | .amazonq/mcp.json |
Supported |
Troubleshooting
| Problem | Solution |
|---|---|
| "Connection refused" | Is the UE5 editor running? Check Output Log for MCP Bridge initialized on port XXXXX |
ue-cli doctor shows port file missing |
Editor hasn't started yet, or check Saved/UnrealMCP/port.txt |
| Commands timeout | Large operations (profiling, complex graphs) have 300s timeout. Use --timeout 600 to increase |
| Multiple editors | Use --port <num> or UNREAL_MCP_PORT env var to target a specific instance |
| Plugin not compiling | Ensure PythonScriptPlugin, EditorScriptingUtilities, EnhancedInput are enabled |
| Python import errors | Run pip install fastmcp requests — make sure the Python on your PATH matches your AI tool's |
| Plugin not loading | Verify UnrealMCP.uplugin has "Type": "Editor" and required plugins are available in your engine build |
Releases & Distribution
| Channel | Command |
|---|---|
| npm | npm install -g unrealcli |
| GitHub Releases | Download binaries |
| pip (MCP only) | pip install unrealmcp |
Releases are automated via GitHub Actions. Push a tag to trigger:
git tag v1.2.2 && git push origin v1.2.2
# → Builds 5 platform binaries
# → Creates GitHub Release
# → Publishes to npm + PyPI
Contributing
- Bug? Open an issue
- Feature idea? Open an issue
- Code? Fork, make changes, open a PR
See CONTRIBUTING.md for guidelines.
Enterprise & Studio Integration
Need Unreal MCP integrated into your studio's production pipeline? I work directly with game studios to build custom AI-assisted workflows on top of this tool.
What I offer:
- Pipeline Integration — Set up Unreal MCP within your existing build system, CI/CD, and team workflow so every artist and developer can use AI assistants with your Unreal project out of the box
- Custom Tool Development — Build MCP commands tailored to your studio's proprietary formats, internal tools, and specific production needs that the open-source version doesn't cover
- AI Workflow Design — Design and implement how your team uses AI assistants (Claude, Cursor, Copilot) with Unreal Engine — from material creation to level design to asset pipelines
- Advanced Material & Substrate Systems — Procedural material generation, Substrate workflows, complex shader pipelines — fully automated through MCP
Get in touch:
- Email: aadeshrao80@gmail.com
- LinkedIn: linkedin.com/in/aadeshyadav
- Discord:
destroyerpal - Portfolio: aadeshyadav.vercel.app
Custom Development & Support
Need help with your Unreal project? I'm available for contract work across the full UE5 C++ stack, from gameplay and multiplayer to editor tooling and Mass Entity systems. See SUPPORT.md for details.
aadeshrao80@gmail.com · LinkedIn · Portfolio · Discord: destroyerpal
License
MPL-2.0 — see LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file unrealmcp-1.2.3.tar.gz.
File metadata
- Download URL: unrealmcp-1.2.3.tar.gz
- Upload date:
- Size: 97.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe3306b12b7412d4be6466f41d6f99d429b294f96d66754b791837b5e0d8394e
|
|
| MD5 |
e7e0b1809fa71d1eb4b0e7aa03a40e02
|
|
| BLAKE2b-256 |
a008330af56916f3834c47c1c6038d4eca16a8fd25b648ad5bb61d5928ae65d5
|
File details
Details for the file unrealmcp-1.2.3-py3-none-any.whl.
File metadata
- Download URL: unrealmcp-1.2.3-py3-none-any.whl
- Upload date:
- Size: 80.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dfbd115443fb5a21274964d9ffec5272632edba0129ed4c5309c18ef202928df
|
|
| MD5 |
501da07e841621148dcd695e89c4cc8f
|
|
| BLAKE2b-256 |
1119a5ff202de13ca882a6604866f035ce02dc6297a92d810227a2936c7cc35d
|