Skip to main content

MCP (Model Context Protocol) bridge for Unreal Engine 5 — lets AI assistants control the UE5 editor

Project description

UnrealMCP — Model Context Protocol Bridge for Unreal Engine 5

UnrealMCP exposes the Unreal Engine 5 editor to AI coding assistants (Claude Code, Cursor, Windsurf, etc.) through the Model Context Protocol. Drop it into any UE5 project's Plugins/ folder and let your AI assistant create materials, blueprints, spawn actors, manage data tables, profile performance, and more — all without leaving your terminal.

How It Works

UnrealMCP has two halves:

  1. C++ Editor Plugin (UnrealMCPBridge module) — runs inside the UE5 editor as a TCP server. It receives JSON commands and executes them in-editor using Unreal's C++ API.
  2. Python MCP Server (pip install unrealmcp) — runs as a stdio process spawned by your AI tool. It translates MCP tool calls into TCP commands sent to the C++ bridge.
┌─────────────┐   stdio    ┌──────────────────┐   TCP/JSON    ┌──────────────────┐
│ Claude Code  │ ────────► │  Python MCP       │ ────────────► │  C++ Bridge      │
│ / Cursor     │ ◄──────── │  Server           │ ◄──────────── │  (in UE5 Editor) │
└─────────────┘            └──────────────────┘                └──────────────────┘

The C++ bridge writes its TCP port to Saved/UnrealMCP/port.txt on startup. The Python server reads that file automatically — no manual port configuration needed.


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):
    • PythonScriptPlugin
    • EditorScriptingUtilities
    • EnhancedInput

Setup

There are two parts to UnrealMCP:

  1. C++ Plugin — lives inside your project or engine Plugins/ folder. You get this by cloning the repo.
  2. Python MCP Server — a global pip package. Install once, works everywhere.

Step 1: Clone the Plugin

# Into your project
git clone https://github.com/aadeshrao123/Unreal-MCP.git Plugins/UnrealMCP

# OR into your engine (shared across all projects using this engine version)
git clone https://github.com/aadeshrao123/Unreal-MCP.git "C:/Program Files/Epic Games/UE_5.5/Engine/Plugins/Marketplace/UnrealMCP"

Step 2: Run the Setup Script

The setup script installs the unrealmcp pip package and creates the MCP config for your AI tool.

Windows:

cd Plugins\UnrealMCP
install.bat

macOS / Linux:

cd Plugins/UnrealMCP
bash install.sh

You can run the script from anywhere inside your project — it automatically detects the project root by searching upward for the .uproject file.

How Scope Works

The setup script asks where to create the MCP config:

Scope What it does When to use
Project Creates config in your project root (e.g., .mcp.json next to your .uproject) You only want UnrealMCP in this one project
Global Creates config in your user folder (e.g., ~/.claude.json) You want UnrealMCP available in all projects

If you run the script from inside an engine folder (e.g., Engine/Plugins/...), it only offers global scope — because engine-level plugins are shared across projects, so project-scope config doesn't make sense there.

If you run it from inside a project (anywhere under a folder with a .uproject), you get to choose between project scope and global scope.

Manual Setup (Without the Script)

If you prefer to set things up yourself:

# Install the MCP server globally
pip install unrealmcp

# Add to your AI tool's config (example for Claude Code .mcp.json):
# { "mcpServers": { "unreal": { "type": "stdio", "command": "unrealmcp" } } }

See Step 5: Configure Your AI Tool for the exact config format for each AI tool.


Manual Installation

Step 1: Copy the Plugin

Copy the UnrealMCP/ folder into your project's Plugins/ directory:

YourProject/
├── Content/
├── Source/
├── Plugins/
│   └── UnrealMCP/          ← put it here
│       ├── UnrealMCP.uplugin
│       ├── unrealmcp/           # Python MCP server (pip package)
│       └── Source/              # C++ bridge
└── YourProject.uproject

Step 2: Install Python Dependencies

pip install unrealmcp

Step 3: Regenerate Project Files

If you use Visual Studio or Rider, regenerate your project files so the new module is picked up:

# Windows (adjust path to your engine)
"<EnginePath>/Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.exe" \
    -projectfiles \
    -project="<YourProject>/YourProject.uproject" \
    -game -engine

Step 4: Build and Launch the Editor

Build your project and open the editor. You should see this in the Output Log:

LogUnrealMCPBridge: MCP Bridge initialized on port 55557

This confirms the C++ bridge is running and ready for connections.

Step 5: Configure Your AI Tool

Each AI tool uses a slightly different config file and format. After installing via pip install unrealmcp, pick your tool below.

Tip: Since unrealmcp is a global pip command, the same config works on Windows, macOS, and Linux — no platform-specific paths needed.

Claude Code.mcp.json (project root)
{
  "mcpServers": {
    "unreal": {
      "type": "stdio",
      "command": "unrealmcp",
      "args": [],
      "env": {}
    }
  }
}

Claude Code is the only tool that requires "type": "stdio" explicitly.

Cursor.cursor/mcp.json (project root)
{
  "mcpServers": {
    "unreal": {
      "command": "unrealmcp",
      "args": [],
      "env": {}
    }
  }
}
VS Code / Copilot.vscode/mcp.json (project root)
{
  "servers": {
    "unreal": {
      "command": "unrealmcp",
      "args": [],
      "env": {}
    }
  }
}

Note: VS Code uses "servers", not "mcpServers".

Windsurf~/.codeium/windsurf/mcp_config.json (user-level)
{
  "mcpServers": {
    "unreal": {
      "command": "unrealmcp",
      "args": [],
      "env": {}
    }
  }
}
Gemini CLI.gemini/settings.json (project root)
{
  "mcpServers": {
    "unreal": {
      "command": "unrealmcp",
      "args": [],
      "env": {}
    }
  }
}
JetBrains / Rider.junie/mcp/mcp.json (project root)
{
  "servers": [
    {
      "name": "unreal",
      "command": "unrealmcp",
      "args": [],
      "env": {}
    }
  ]
}

Note: JetBrains uses "servers" as an array with a "name" field. Requires IDE 2025.1+ with AI Assistant.

Zed~/.config/zed/settings.json

Add to your Zed settings.json:

{
  "context_servers": {
    "unreal": {
      "source": "custom",
      "command": {
        "path": "unrealmcp",
        "args": [],
        "env": {}
      }
    }
  }
}

Note: Zed uses "context_servers" with a nested "command" object.

Amazon Q.amazonq/mcp.json (project root)
{
  "mcpServers": {
    "unreal": {
      "command": "unrealmcp",
      "args": [],
      "env": {}
    }
  }
}

Step 6: Verify

Open your AI tool (e.g., Claude Code) in the project directory. The MCP server will auto-connect to the editor. You can verify with:

> Use the health_check tool

If it returns successfully, you're connected.


Configuration (Optional)

Custom Port

Add to Config/DefaultEngine.ini:

[UnrealMCP]
Port=55557

The bridge scans up to 100 ports from this base if the default is taken (useful when running multiple editor instances).

Environment Variable Override

set UNREAL_MCP_PORT=55560

Forces the Python server to connect to a specific port instead of reading from port.txt.

Token Debug Mode

Enable to see estimated token usage per command (useful for optimizing MCP calls):

> Use set_mcp_debug with enabled=true
> Use get_mcp_token_stats to see per-command statistics

Available Tools

UnrealMCP provides 100+ tools organized by category. Here's a summary of what you can do:

Core

Tool Description
health_check Verify the bridge is running and responsive
execute_python Run arbitrary Python in the editor (set result to return data)

Asset Management

Tool Description
find_assets Search the Asset Registry by class, path, or name pattern
list_assets List assets in a Content Browser directory
get_asset_info Get asset metadata (class, package, disk path)
get_asset_properties Read all editable properties of any asset
set_asset_property Set a single property on any asset
find_references Find dependents or dependencies of an asset
import_asset Import an external file (FBX, PNG, WAV, etc.)
import_assets_batch Batch import from a file list or directory scan
duplicate_asset Copy an asset to a new location
rename_asset Rename/move an asset (auto-fixes references)
delete_asset Delete an asset (checks for references first)
save_asset / save_all Save one or all dirty assets
open_asset Open an asset in the editor
sync_browser Navigate Content Browser to an asset
get_selected_assets Get currently selected Content Browser assets

Blueprints

Tool Description
search_parent_classes Find valid parent classes for Blueprint creation
create_blueprint Create a Blueprint from any C++ or BP parent class
compile_blueprint Compile a Blueprint
read_blueprint_content Read full BP structure: graphs, variables, components
add_component_to_blueprint Add a component (StaticMesh, Box Collision, etc.)
create_blueprint_variable Create a variable in a Blueprint
get/set_blueprint_class_defaults Read/write Class Default Object (CDO) properties
get/set_blueprint_variable_properties Inspect/modify variable settings
create/delete/rename_blueprint_function Manage Blueprint functions
add_function_input / add_function_output Add parameters to functions
get_blueprint_function_details Inspect function signatures and graphs

Blueprint Graph

Tool Description
add_blueprint_node Add a node (Branch, ForLoop, CallFunction, Print, etc.)
add_event_node Add an event (BeginPlay, Tick, ActorBeginOverlap, etc.)
connect_blueprint_nodes Wire two nodes together (execution or data pins)
delete_blueprint_node Remove a node by ID
set_blueprint_node_property Edit node properties (add pins, set enum, etc.)
analyze_blueprint_graph Get structural analysis of a graph

Materials

Tool Description
create_material Create a new material with blend/shading mode
create_material_instance Create a Material Instance with parameter overrides
build_material_graph Build a complete node graph atomically (nodes + connections)
get_material_info Inspect material properties, parameters, textures
set_material_properties Set blend mode, shading model, two-sided, etc.
add/delete/move/duplicate_material_expression Manage expression nodes
connect_material_expressions Wire expression outputs to inputs
set_material_expression_property Set properties on expression nodes
layout_material_expressions Auto-layout expression nodes
recompile_material Force recompile and save
get/set_material_instance_parameter Read/write MI parameter overrides
list_material_expression_types Discover available expression types
add_material_comments Add comment boxes to the material graph
apply_material_to_actor / apply_material_to_blueprint Apply materials
get_available_materials List materials in project or engine

Data Tables

Tool Description
get_data_table_schema Get column names and types from the row struct
get_data_table_rows / get_data_table_row Read all or one row
add_data_table_row Add a row with optional initial data
update_data_table_row Partial update of row fields
delete_data_table_row Delete a row
duplicate_data_table_row Copy a row under a new name
rename_data_table_row Rename a row in-place

Data Assets

Tool Description
create_data_asset Create any UDataAsset subclass with initial properties
get_data_asset_properties Read all properties (with optional filter)
set_data_asset_property / set_data_asset_properties Set one or many properties
list_data_assets Browse by path or class
list_data_asset_classes List all loaded UDataAsset subclasses
get_property_valid_types Query valid dropdown/enum values for a property

Actors & Level

Tool Description
spawn_actor Spawn an actor (StaticMeshActor, PointLight, etc.)
spawn_blueprint_actor Spawn a Blueprint actor instance in the level
get_actors_in_level List all actors in the current level
find_actors_by_name Find actors by name pattern
get_actor_properties Read all properties from a placed actor
set_actor_transform Set location, rotation, and/or scale
delete_actor Delete an actor from the level
get_selected_actors Get currently selected viewport actors
get_world_info Get level name, actor count, etc.
set_static_mesh_properties Set mesh on a component
set_physics_properties Configure physics simulation
set_mesh_material_color Set material color on a mesh component
take_screenshot Capture viewport or editor window to PNG

Enhanced Input

Tool Description
create_input_action Create a UInputAction (Boolean/Axis1D/2D/3D)
get/set_input_action_properties Read/write action properties
add/remove_input_action_trigger Manage triggers (Hold, Pressed, Tap, etc.)
add/remove_input_action_modifier Manage modifiers (DeadZone, Negate, Scalar, etc.)
create_input_mapping_context Create a UInputMappingContext
get_input_mapping_context Read all key mappings
add/remove/set_key_mapping Manage key-to-action mappings
add/remove_mapping_trigger / add/remove_mapping_modifier Per-mapping overrides
list_input_actions / list_input_mapping_contexts Browse input assets
list_trigger_types / list_modifier_types / list_input_keys Discover available types

Widgets (UMG)

Tool Description
get_widget_tree Read full widget hierarchy as JSON
add_widget Add a widget to a parent slot
remove_widget / move_widget / rename_widget / duplicate_widget Manage widgets
get/set_widget_properties Read/write widget properties
get/set_slot_properties Read/write layout slot properties
list_widget_types Discover available UWidget classes

Performance Profiling

Tool Description
performance_start_trace Start recording a live .utrace (CPU, GPU, frame, etc.)
performance_stop_trace Stop recording and auto-load for analysis
performance_analyze_insight Query loaded traces with smart analysis

Smart analysis queries:

  • diagnose — full automated report with severity findings
  • spikes — worst frames with category breakdown
  • flame — top timers by exclusive (self) time
  • bottlenecks — auto-categorize frame into Animation/Slate/Network/etc.
  • hotpath — drill into a category's children by time
  • compare — compare a frame vs trace median
  • search — find a timer across all frames (min/avg/max/p95/p99)
  • histogram — frame time distribution

Standard queries: summary, worst_frames, frame_details, timer_stats, butterfly, threads, counters

Provider queries (require specific trace channels): net_stats, loading, logs, memory, regions, bookmarks, session, modules, file_io, tasks, allocations, context_switches, screenshots, stack_samples

Debug

Tool Description
set_mcp_debug Enable/disable token estimation debug headers
get_mcp_token_stats Per-command token usage statistics

Usage Examples

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.


Architecture

Plugin Structure

Plugins/UnrealMCP/
├── UnrealMCP.uplugin                  # Plugin manifest
├── pyproject.toml                     # pip package config
├── unrealmcp/                         # Python MCP server (pip install unrealmcp)
│   ├── __init__.py                    # Entry point (unrealmcp command)
│   ├── _bridge.py                     # Shared FastMCP instance
│   ├── _tcp_bridge.py                 # TCP communication layer
│   └── tools/                         # Tool modules (one per category)
│       ├── __init__.py
│       ├── core.py                    # health_check, execute_python
│       ├── assets.py                  # Asset management
│       ├── blueprints.py              # Blueprint creation & components
│       ├── blueprint_graph.py         # Graph node manipulation
│       ├── materials.py               # Material creation & graphs
│       ├── editor_commands.py         # Actors, physics, screenshots
│       ├── data_tables.py             # Data Table CRUD
│       ├── data_assets.py             # Data Asset CRUD
│       ├── widgets.py                 # Widget tree manipulation
│       ├── enhanced_input.py          # Input Actions & Mapping Contexts
│       ├── level.py                   # Level info & actor selection
│       ├── profiling.py               # Performance tracing & analysis
│       └── debug.py                   # Token stats & debug mode
└── Source/UnrealMCPBridge/
    ├── Public/
    │   ├── EpicUnrealMCPBridge.h      # Main subsystem (UEditorSubsystem)
    │   ├── MCPServerRunnable.h        # TCP server thread
    │   └── Commands/                  # Command handler headers
    └── Private/
        ├── EpicUnrealMCPBridge.cpp    # Subsystem implementation
        ├── EpicUnrealMCPModule.cpp    # Module startup
        ├── MCPServerRunnable.cpp      # Server thread implementation
        └── Commands/                  # Command handler implementations

Communication Protocol

The C++ bridge and Python server communicate over TCP using length-prefix framing:

[4 bytes: big-endian payload length] [N bytes: UTF-8 JSON]

Request format:

{
  "type": "create_material",
  "params": {
    "name": "M_Example",
    "path": "/Game/Materials"
  }
}

Response format:

{
  "status": "success",
  "result": { ... }
}

Port Discovery

  1. C++ bridge starts TCP listener on configured port (default 55557)
  2. Writes the actual port number to <ProjectDir>/Saved/UnrealMCP/port.txt
  3. Python server reads that file on connection
  4. If the default port is taken, the bridge scans up to 100 ports

This means multiple editor instances can run simultaneously without conflicts.


Adding Custom Tools

Python Side

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_custom_tool(param1: str, param2: int = 10) -> str:
    """Description shown to the AI assistant."""
    return _call("my_custom_command", {
        "param1": param1,
        "param2": param2,
    })

Register it in unrealmcp/tools/__init__.py:

from unrealmcp.tools import my_tools  # noqa: F401

C++ Side

  1. Create a command handler class in Source/UnrealMCPBridge/Private/Commands/
  2. Implement the command routing logic
  3. Register the handler in UEpicUnrealMCPBridge::ExecuteCommand()

The C++ handler receives the params JSON object and returns a JSON result. All editor operations should be executed on the game thread (use AsyncTask(ENamedThreads::GameThread, ...) if called from the TCP thread).


Troubleshooting

"Connection refused" or tools not working

  1. Make sure the UE5 editor is running
  2. Check the Output Log for LogUnrealMCPBridge: MCP Bridge initialized on port XXXXX
  3. Verify Saved/UnrealMCP/port.txt exists and contains a port number
  4. Check that PythonScriptPlugin is enabled in your .uproject

Python import errors

pip install fastmcp requests

Make sure the Python on your PATH is the same one your AI tool will invoke.

Multiple editor instances

Each editor instance picks a unique port automatically. The .mcp.json config connects to whichever editor wrote port.txt most recently. If you need to target a specific instance, set the UNREAL_MCP_PORT environment variable.

Plugin not loading

  • Verify UnrealMCP.uplugin has "Type": "Editor" in its module definition
  • Check that PythonScriptPlugin and EditorScriptingUtilities are available in your engine build
  • Look for errors in the Output Log at editor startup

Commands timing out

Large operations (profiling analysis, complex Blueprint graphs) have a 300-second timeout. If you hit it, break the operation into smaller steps.


Supported AI Tools

UnrealMCP works with any tool that supports the Model Context Protocol:

Tool Config File Status
Claude Code .mcp.json Tested
Cursor .cursor/mcp.json Tested
VS Code / Copilot .vscode/mcp.json Supported
Windsurf ~/.codeium/windsurf/mcp_config.json Supported
Gemini CLI .gemini/settings.json Supported
JetBrains / Rider .junie/mcp/mcp.json Supported
Zed ~/.config/zed/settings.json Supported
Amazon Q .amazonq/mcp.json Supported

See Step 5: Configure Your AI Tool for the exact config format for each tool.


Contributing

Contributions are welcome! Whether it's bug fixes, new tools, documentation, or feature ideas — feel free to get involved.

See CONTRIBUTING.md for detailed guidelines on submitting PRs and adding new tools.


License

MIT — 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

unrealmcp-1.1.0.tar.gz (44.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unrealmcp-1.1.0-py3-none-any.whl (42.2 kB view details)

Uploaded Python 3

File details

Details for the file unrealmcp-1.1.0.tar.gz.

File metadata

  • Download URL: unrealmcp-1.1.0.tar.gz
  • Upload date:
  • Size: 44.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for unrealmcp-1.1.0.tar.gz
Algorithm Hash digest
SHA256 24e9e81ff8c47c2de602f60a9e5891efb9af351c0b92942858c548c367ed25d5
MD5 6ac9294c537cd5bccd5ac91fe558c903
BLAKE2b-256 980d612777b970cf97b9c8379526d454f1e41aa624c54607da5b9e52c0e0e56e

See more details on using hashes here.

File details

Details for the file unrealmcp-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: unrealmcp-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 42.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for unrealmcp-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3108e85985b24026df9349be7699b6ceaac01505fcc277207e5db0f547248195
MD5 93938dcc94a6bbd970661381296b10bf
BLAKE2b-256 4acf98ccb901cb45afae811aaf25bb2f21d7483045d3b1983e3685796447d479

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page