Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,41 @@ TSharedPtr<FJsonObject> FUnrealMCPEditorCommands::HandleSpawnActor(const TShared
if (ActorType == TEXT("StaticMeshActor"))
{
NewActor = World->SpawnActor<AStaticMeshActor>(AStaticMeshActor::StaticClass(), Location, Rotation, SpawnParams);

// FIX: Set the static mesh on StaticMeshActor after creation
// Previously, StaticMeshActors were created without any mesh assigned, making them invisible
// This fix adds support for the "static_mesh" parameter and defaults to cube if not specified
if (NewActor)
{
AStaticMeshActor* MeshActor = Cast<AStaticMeshActor>(NewActor);
if (MeshActor && MeshActor->GetStaticMeshComponent())
{
// Check if a static_mesh parameter was provided (e.g., "/Engine/BasicShapes/Cube.Cube")
FString MeshPath;
if (Params->TryGetStringField(TEXT("static_mesh"), MeshPath))
{
// Load the specified mesh from the provided path
UStaticMesh* Mesh = LoadObject<UStaticMesh>(nullptr, *MeshPath);
if (Mesh)
{
MeshActor->GetStaticMeshComponent()->SetStaticMesh(Mesh);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Failed to load mesh: %s"), *MeshPath);
}
}
else
{
// Default to cube mesh if no mesh specified - ensures actors are always visible
UStaticMesh* CubeMesh = LoadObject<UStaticMesh>(nullptr, TEXT("/Engine/BasicShapes/Cube.Cube"));
if (CubeMesh)
{
MeshActor->GetStaticMeshComponent()->SetStaticMesh(CubeMesh);
}
}
}
}
}
else if (ActorType == TEXT("PointLight"))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@
#include "Commands/UnrealMCPUMGCommands.h"

// Default settings
#define MCP_SERVER_HOST "127.0.0.1"
// FIX: Changed from "127.0.0.1" to "0.0.0.0" to allow connections from all network interfaces
// This enables WSL2 and remote connections to connect to the Unreal MCP server
// Previously only localhost connections were possible
#define MCP_SERVER_HOST "0.0.0.0" // Bind to all interfaces (was "127.0.0.1")
#define MCP_SERVER_PORT 55557

UUnrealMCPBridge::UUnrealMCPBridge()
Expand Down
18 changes: 18 additions & 0 deletions Python/start_mcp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash
# Start the Unreal MCP server with proper environment settings

# Get the directory where this script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"

# Use environment variables if set, otherwise use defaults
# For WSL2 users: Set UNREAL_HOST to your Windows IP address
UNREAL_HOST="${UNREAL_HOST:-127.0.0.1}"
UNREAL_PORT="${UNREAL_PORT:-55557}"

export UNREAL_HOST
export UNREAL_PORT

echo "Starting Unreal MCP Server..."
echo "Connecting to Unreal at $UNREAL_HOST:$UNREAL_PORT"
exec uv run unreal_mcp_server.py
57 changes: 56 additions & 1 deletion Python/tools/editor_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ def spawn_actor(
name: str,
type: str,
location: List[float] = [0.0, 0.0, 0.0],
rotation: List[float] = [0.0, 0.0, 0.0]
rotation: List[float] = [0.0, 0.0, 0.0],
static_mesh: str = None
) -> Dict[str, Any]:
"""Create a new actor in the current level.

Expand All @@ -91,6 +92,7 @@ def spawn_actor(
type: The type of actor to create (e.g. StaticMeshActor, PointLight)
location: The [x, y, z] world location to spawn at
rotation: The [pitch, yaw, roll] rotation in degrees
static_mesh: Optional path to static mesh for StaticMeshActor (e.g. /Engine/BasicShapes/Cube.Cube)

Returns:
Dict containing the created actor's properties
Expand All @@ -111,6 +113,10 @@ def spawn_actor(
"rotation": rotation
}

# Add static_mesh parameter if provided
if static_mesh:
params["static_mesh"] = static_mesh

# Validate location and rotation formats
for param_name in ["location", "rotation"]:
param_value = params[param_name]
Expand Down Expand Up @@ -366,4 +372,53 @@ def spawn_blueprint_actor(
logger.error(error_msg)
return {"success": False, "message": error_msg}

@mcp.tool()
def take_screenshot(
ctx: Context,
filename: str,
show_ui: bool = False,
resolution: List[int] = None
) -> Dict[str, Any]:
"""Take a screenshot of the current viewport.

Args:
ctx: The MCP context
filename: Name for the screenshot file (without extension)
show_ui: Whether to include UI in the screenshot
resolution: Optional [width, height] for the screenshot

Returns:
Dict containing screenshot information
"""
from unreal_mcp_server import get_unreal_connection

try:
unreal = get_unreal_connection()
if not unreal:
logger.error("Failed to connect to Unreal Engine")
return {"success": False, "message": "Failed to connect to Unreal Engine"}

params = {
"filename": filename,
"show_ui": show_ui
}

if resolution:
if isinstance(resolution, list) and len(resolution) == 2:
params["resolution"] = resolution

logger.info(f"Taking screenshot: {filename}")
response = unreal.send_command("take_screenshot", params)

if not response:
logger.error("No response from Unreal Engine")
return {"success": False, "message": "No response from Unreal Engine"}

return response

except Exception as e:
error_msg = f"Error taking screenshot: {e}"
logger.error(error_msg)
return {"success": False, "message": error_msg}

logger.info("Editor tools registered successfully")
5 changes: 3 additions & 2 deletions Python/unreal_mcp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@
logger = logging.getLogger("UnrealMCP")

# Configuration
UNREAL_HOST = "127.0.0.1"
UNREAL_PORT = 55557
import os
UNREAL_HOST = os.environ.get("UNREAL_HOST", "127.0.0.1") # Default to localhost, override with env var for WSL2
UNREAL_PORT = int(os.environ.get("UNREAL_PORT", "55557"))

class UnrealConnection:
"""Connection to an Unreal Engine instance."""
Expand Down
104 changes: 102 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The Unreal MCP integration provides comprehensive tools for controlling Unreal E
| **Actor Management** | • Create and delete actors (cubes, spheres, lights, cameras, etc.)<br>• Set actor transforms (position, rotation, scale)<br>• Query actor properties and find actors by name<br>• List all actors in the current level |
| **Blueprint Development** | • Create new Blueprint classes with custom components<br>• Add and configure components (mesh, camera, light, etc.)<br>• Set component properties and physics settings<br>• Compile Blueprints and spawn Blueprint actors<br>• Create input mappings for player controls |
| **Blueprint Node Graph** | • Add event nodes (BeginPlay, Tick, etc.)<br>• Create function call nodes and connect them<br>• Add variables with custom types and default values<br>• Create component and self references<br>• Find and manage nodes in the graph |
| **Editor Control** | • Focus viewport on specific actors or locations<br>• Control viewport camera orientation and distance |
| **Editor Control** | • Focus viewport on specific actors or locations<br>• Control viewport camera orientation and distance<br>• Take screenshots of the viewport with configurable resolution |

All these capabilities are accessible through natural language commands via AI assistants, making it easy to automate and control Unreal Engine workflows.

Expand Down Expand Up @@ -86,6 +86,35 @@ For getting started quickly, feel free to use the starter project in `MCPGamePro
- Choose `Development Editor` as your target.
- Build

### Starting Unreal Editor

#### Normal Start (Local connections only)
Simply open the project normally through Epic Games Launcher or by double-clicking the .uproject file.

#### For WSL2 or Remote Connections
You MUST start Unreal with special command-line arguments to allow external connections:

**PowerShell:**
```powershell
# Define paths (adjust to your installation)
$ue = "C:\Program Files\Epic Games\UE_5.6\Engine\Binaries\Win64\UnrealEditor.exe"
$proj = "C:\Dev\UEFN\temp\unreal-mcp\MCPGameProject\MCPGameProject.uproject"

# Start with network binding to all interfaces
& "$ue" "$proj" -UnrealMCPBind="0.0.0.0" -UnrealMCPPort=55557
```

**Command Prompt:**
```cmd
"C:\Program Files\Epic Games\UE_5.6\Engine\Binaries\Win64\UnrealEditor.exe" "C:\Dev\UEFN\temp\unreal-mcp\MCPGameProject\MCPGameProject.uproject" -UnrealMCPBind=0.0.0.0 -UnrealMCPPort=55557
```

**Important Notes:**
- `-UnrealMCPBind=0.0.0.0` makes Unreal listen on all network interfaces (not just localhost)
- This is REQUIRED for WSL2 connections (WSL2 cannot access Windows localhost)
- Only use these flags if connecting from WSL2 or another machine
- Default port is 55557 (can be changed with `-UnrealMCPPort`)

### Plugin
Otherwise, if you want to use the plugin in your existing project:

Expand Down Expand Up @@ -113,7 +142,8 @@ See [Python/README.md](Python/README.md) for detailed Python setup instructions,

### Configuring your MCP Client

Use the following JSON for your mcp configuration based on your MCP client.
#### Standard Configuration (Windows/Mac/Linux)
Use the following JSON for your mcp configuration:

```json
{
Expand All @@ -131,6 +161,49 @@ Use the following JSON for your mcp configuration based on your MCP client.
}
```

#### WSL2 Configuration
If running the MCP server in WSL2 while Unreal runs on Windows, you need to specify the Windows host IP:

```json
{
"mcpServers": {
"unrealMCP": {
"command": "bash",
"args": ["/path/to/unreal-mcp/Python/start_mcp.sh"],
"env": {
"UNREAL_HOST": "192.168.1.106", // Replace with YOUR Windows IP
"UNREAL_PORT": "55557"
}
}
}
}
```

**To find your Windows IP for WSL2:**
1. From WSL2, run: `cat /etc/resolv.conf | grep nameserver`
2. Or use your Windows LAN IP: `ipconfig` (from Windows) and look for your IPv4 address

**Alternative WSL2 configuration using direct command:**
```json
{
"mcpServers": {
"unrealMCP": {
"command": "uv",
"args": [
"--directory",
"/mnt/c/Dev/unreal-mcp/Python", // WSL path format
"run",
"unreal_mcp_server.py"
],
"env": {
"UNREAL_HOST": "192.168.1.106", // Your Windows IP
"UNREAL_PORT": "55557"
}
}
}
}
```

An example is found in `mcp.json`

### MCP Configuration Locations
Expand All @@ -147,6 +220,33 @@ Each client uses the same JSON format as shown in the example above.
Simply place the configuration in the appropriate location for your MCP client.


## Example MCP Usage

Once configured, you can use natural language commands in your MCP client:

### Creating Actors with Meshes
```
"Create a cube at position 0,0,100"
"Spawn a sphere at 200,0,100"
"Add a cylinder mesh actor"
```
The actors will now appear with proper meshes (previously they were invisible).

### Taking Screenshots
```
"Take a screenshot of the viewport"
"Capture the current scene"
"Take a high-res screenshot at 4K resolution"
```
Screenshots are saved to the Unreal project's Screenshots folder.

### Blueprint Creation
```
"Create a new Blueprint called MyCharacter"
"Add a static mesh component to the Blueprint"
"Set the mesh to a cube"
```

## License
MIT

Expand Down
49 changes: 49 additions & 0 deletions StartUnrealWithMCP.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@echo off
REM StartUnrealWithMCP.bat - Start Unreal Editor with MCP network binding
REM This is required for WSL2 or remote connections

echo ========================================
echo Starting Unreal Editor with MCP Support
echo ========================================
echo.
echo This will start Unreal Engine with network binding enabled
echo to allow connections from WSL2 or remote machines.
echo.

REM Define paths - adjust these if your installation is different
set UE_PATH=C:\Program Files\Epic Games\UE_5.6\Engine\Binaries\Win64\UnrealEditor.exe
set PROJECT_PATH=C:\Dev\UEFN\temp\unreal-mcp\MCPGameProject\MCPGameProject.uproject

REM Check if Unreal Editor exists
if not exist "%UE_PATH%" (
echo ERROR: Unreal Editor not found at: %UE_PATH%
echo Please edit this batch file and update UE_PATH
pause
exit /b 1
)

REM Check if project exists
if not exist "%PROJECT_PATH%" (
echo ERROR: Project not found at: %PROJECT_PATH%
echo Please edit this batch file and update PROJECT_PATH
pause
exit /b 1
)

echo Starting Unreal Editor...
echo Path: %UE_PATH%
echo Project: %PROJECT_PATH%
echo.
echo Network Settings:
echo - Binding to: 0.0.0.0 (all interfaces)
echo - Port: 55557
echo.
echo Press Ctrl+C to cancel, or any key to continue...
pause > nul

REM Start Unreal with MCP network binding
"%UE_PATH%" "%PROJECT_PATH%" -UnrealMCPBind=0.0.0.0 -UnrealMCPPort=55557

echo.
echo Unreal Editor has closed.
pause
22 changes: 22 additions & 0 deletions mcp-wsl2-example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"mcpServers": {
"unrealMCP": {
"command": "bash",
"args": ["/mnt/c/Dev/unreal-mcp/Python/start_mcp.sh"],
"env": {
"UNREAL_HOST": "YOUR_WINDOWS_IP_HERE",
"UNREAL_PORT": "55557"
}
}
},
"_comment": "WSL2 Configuration Example",
"_instructions": [
"1. Replace YOUR_WINDOWS_IP_HERE with your actual Windows IP",
"2. To find your Windows IP:",
" - From WSL2: cat /etc/resolv.conf | grep nameserver",
" - Or from Windows: ipconfig (use your LAN IPv4 address)",
"3. Make sure Unreal is started with: -UnrealMCPBind=0.0.0.0",
"4. Ensure Windows Firewall allows port 55557",
"5. Update the path in 'args' to match your installation"
]
}