unreal-mcp
Skill2 starsChanged 6 days agoMITView on GitHub
Core rules for driving Unreal Editor (UE 5.8) from Claude — Epic's built-in Unreal MCP plugin (ModelContextProtocol + EditorToolset, tool-search mode with list_toolsets/describe_toolset/call_tool) plus Python remote execution for everything the toolsets don't cover (Sequencer, Movie Render Queue, bulk edits). Covers enabling and auto-starting the MCP server, registering it in Claude Code, the remote-execution helper script, viewport captures you can actually look at, editor crash traps, where the logs are, and an index of the Unreal sub-skills. Use EVERY time a task touches Unreal Engine / Unreal Editor / a .uproject.
4 other projects use a version of this.
Adopted by
Most recently taken up by
- PeterTXPan/dsh-unreal-mcptheir own version, first seen Oct 11, 2026
- soatori/unreal-mcp-skillstheir own version, first seen Sep 15, 2026
- 44-99/unreal-agent-benchmarktheir own version, first seen Jul 22, 2026
- EpicGames/unreal-engine-skills-for-claude-code-plugintheir own version, first seen Jun 7, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- EpicGames/unreal-engine-skills-for-claude-code-plugin★ 1.8ksame name
- PeterTXPan/dsh-unreal-mcp★ 16same name
- soatori/unreal-mcp-skills★ 8same name
- 44-99/unreal-agent-benchmark★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository26 other files it gives its agents.
- aftereffects-bridgeSkill
- aftereffects-scriptingSkill
- cinema4d-alembicSkill
- cinema4d-mcpSkill
- cinema4d-motion-trackerSkill
- cinema4d-particlesSkill
- cinema4d-redshiftSkill
- cinema4d-render-previewSkill
- cinema4d-riggingSkill
- cinema4d-takesSkill
- houdini-flipbookSkill
- houdini-mcpSkill
- houdini-network-layoutSkill
- houdini-pop-particlesSkill
- houdini-pyro-smokeSkill
- houdini-to-cinema4dSkill
- houdini-vdb-surfacingSkill
- premiere-bridgeSkill
- project-notesSkill
- unreal-content-managementSkill
- unreal-editor-toolsSkill
- unreal-led-volume-rigSkill
- unreal-materials-pythonSkill
- unreal-sequencer-pythonSkill
- unreal-ultra-dynamic-skySkill
- vo-timingSkill
The file
We split this skill into the rules it gives an agent
4 rules. 0 are common, 1 is distinctive, and 3 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 9
Prefer these notes over memory.
- Very specific: line 38
Add to the .uproject Plugins array (or Edit → Plugins, search "Unreal MCP"): {"Name": "ModelContextProtocol", "Enabled": true} and {"Name": …
- Very specific: line 86
Call it as call_tool(toolset_name="EditorToolset.EditorAppToolset", tool_name="CaptureViewport") — the full dotted name as tool_name gives …
- Very specific: line 144
After a crash a *CrashReportClientEditor* window stays open.
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Unreal Editor via MCP + Python — core
Verified on Unreal Engine 5.8.4 (launcher build), Windows 11, Claude Code desktop app, Oct 2026. Prefer these notes over memory. Anything not tested is marked (unverified).
Sub-skills — load the one that matches the task
unreal-materials-python— building materials, material functions and parameter collections from Python (MaterialEditingLibrary), Custom HLSL nodes, injecting a function into existing materials, reading compile errors, a flat unshaded colour look.unreal-sequencer-python— Level Sequences from Python: camera transform, camera on a movable rail, camera cut, animating a parameter collection, auto-play on Play, checking it in PIE.unreal-ultra-dynamic-sky— adding Ultra Dynamic Sky, setting its Blueprint variables via ObjectTools, locking exposure for renders.unreal-content-management— moving assets and maps, redirectors, World Partition / one-file-per-actor levels, what imported samples do to project config, backups, folder colours, tidying the Outliner.unreal-led-volume-rig— multi-screen LED box / CAVE rigs: off-axis cameras from a C4D rig, one video per screen through Movie Render Queue.unreal-editor-tools— one-click tools for the user: a custom main-menu entry (ToolMenus) registered at every start, undoable actions, piloting / viewport camera, Game View.project-notes— per-production notes; read them at the start of any task on a named production.
Two channels, use both
| Unreal MCP (Epic plugin) | Python remote execution | |
| What | mcp__unreal__list_toolsets / describe_toolset / call_tool | scripts/ue_exec.py runs any Python in the editor |
| Good for | viewport/asset captures, inspecting objects and Blueprint properties, material graph queries, actor/asset tools, logs | bulk spawning, Sequencer, Movie Render Queue, anything the toolsets lack, long scripts kept in files |
| Limits | no raw Python or console tool (execute_tool_script is a sandbox that only chains toolset tools; imports limited to json/math/re/...) | no images back; output = what the script prints |
The UE 5.8 Film/Video template also enables the Remote Control web API on :30010, but it refuses
PythonScriptLibrary ("cannot be accessed remotely") — don't use it as a Python channel.
Enabling the Unreal MCP plugin (per project)
- Add to the
.uprojectPluginsarray (or Edit → Plugins, search "Unreal MCP"):{"Name": "ModelContextProtocol", "Enabled": true}and{"Name": "EditorToolset", "Enabled": true}. Both are Experimental. Other toolsets live inEngine/Plugins/Experimental/Toolsets/(PCGToolset, NiagaraToolsets, ConfigSettingsToolset, AllToolsets ...). - Auto-start the server: create
Config/DefaultEditorPerProjectUserSettings.iniwith
(The settings class is[/Script/ModelContextProtocolEngine.ModelContextProtocolSettings] bAutoStartServer=True ServerPortNumber=8000 ServerUrlPath=/mcpconfig=EditorPerProjectUserSettings; putting it in the project's Default layer avoids the editor overwritingSaved/Config/...while it is open.) Alternatives: consoleModelContextProtocol.StartServer [port], or launch with-ModelContextProtocolStartServer.ModelContextProtocol.GenerateClientConfig ClaudeCodewrites a.mcp.jsonin the project dir. - Restart the editor (plugins only load at startup). Server:
http://127.0.0.1:8000/mcp(binds localhost only; rejects non-localhostOriginheaders). - Register in Claude Code from the folder the sessions run in:
claude mcp add --transport http --scope local unreal http://localhost:8000/mcp - The tools appear only in a Claude session started AFTER registering; restarting Unreal makes the server briefly "still connecting" in the session, then it reconnects by itself.
- Quick health check without the tools: POST a JSON-RPC
initializeto the URL withAccept: application/json, text/event-stream; a 200 with anMcp-Session-Idheader = alive.
Using the toolsets
bEnableToolSearchis on by default: only 3 native tools. Calllist_toolsets, thendescribe_toolset(full JSON schemas), thencall_tool(toolset_name, tool_name, arguments).- Toolset names are mixed style:
EditorToolset.EditorAppToolset,editor_toolset.toolsets.material.MaterialTools,editor_toolset.toolsets.object.ObjectTools, ... - Object refs are
{"refPath": "/Game/Map.Map:PersistentLevel.Actor_C_0"}. - Every struct parameter in a schema must be passed, even "optional" ones — omitting
annotationsorcaptureTransformfails with "needs a default value". ObjectTools.list_propertieson a Blueprint actor returns a JSON schema of ALL variables (Ultra Dynamic Sky: ~1000 keys, 330 KB) — it lands in a tool-results file; parse it with Python, don't read it raw. Keys are the display names with a lower-case first letter ("time of Day","cloud Coverage").
Looking at the viewport
EditorToolset.EditorAppToolset.CaptureViewport returns a base64 PNG inside JSON (~3 MB) — always
too big for the context, so it is saved to a tool-results file. Decode and downscale it, then Read
the image:
python -I scripts/decode_capture.py <tool-result.txt> <out.png> 1400Pass a captureTransform (location cm, rotation pitch/yaw/roll deg) to shoot from a fixed pose,
and annotations with zeros (gridSpacing 0, maxLabelDistance 0, maxLabels 0, classFilter
{"refPath": ""}) for a clean image. The image has the viewport's aspect ratio (a wide editor
viewport gives e.g. 1400x444).
- Call it as
call_tool(toolset_name="EditorToolset.EditorAppToolset", tool_name="CaptureViewport")— the full dotted name astool_namegives "Unknown tool". - While Sequencer locks the viewport to a shot camera, the capture uses that camera's FOV (e.g. 52.7°
for 24 mm on a 23.76 mm filmback) even with a
captureTransform; the aspect stays the viewport's, and changes when the user resizes panels. - Editor sprites / volume outlines / selected splines appear in captures: switch on Game View
(
LevelEditorSubsystem.editor_set_game_view(True), = G) for render-like images. - A capture pose far from the previous frame shows motion blur (temporal); capture again at the same
pose for a sharp image. If it stays smeared, the viewport itself keeps moving (piloting an actor, or
the user scrubbing Sequencer): eject the pilot, park the viewport at the pose
(
UnrealEditorSubsystem.set_level_viewport_camera_info(loc, rot)), and for that capture only setr.MotionBlurQuality 0(read the old value withSystemLibrary.get_console_variable_int_value, restore it). - An open Level Sequence drives its actors at the playhead: setting a rail/actor property from Python
only lasts until Sequencer re-evaluates. Read positions after
LevelSequenceEditorBlueprintLibrary .set_current_time(frame)in a later call, and put the user's playhead back when done.
Python remote execution
- Enable: Project Settings → Plugins → Python → Enable Remote Execution? or in
DefaultEngine.ini:
(multicast group 239.0.0.1:6766, bound to localhost by default). Toggling it in the UI takes effect immediately; the ini route needs a restart.[/Script/PythonScriptPlugin.PythonScriptPluginSettings] bRemoteExecution=True RemoteExecutionMulticastBindAddress=127.0.0.1 - Client:
scripts/ue_exec.pywraps Epic'sEngine/Plugins/Experimental/PythonScriptPlugin/Content/Python/remote_execution.py. Run it with the engine's own Python and-I:
Set"<UE>/Engine/Binaries/ThirdParty/Python3/Win64/python.exe" -I ue_exec.py script.py "<UE>/Engine/Binaries/ThirdParty/Python3/Win64/python.exe" -I ue_exec.py -c "import unreal; print(1)"UE_ROOTif the engine is not inC:\Program Files\Epic Games\UE_5.8. - Code runs as a file (
MODE_EXEC_FILE), so multi-line scripts work;__file__is not set —sys.path.insert(0, r"<scripts dir>")thenimport+importlib.reload()your own modules. - The editor's Python is 3.11 with numpy available (UE 5.8); PIL is not guaranteed.
- A Python exception comes back as
COMMAND_FAILEDwith the traceback. - UE Python structs often take no constructor kwargs (
unreal.CustomInput(input_name=...)→ TypeError). Create empty, thenset_editor_property. Some (e.g.Vector4f) expose no fields at all: use.import_text("(X=1,Y=0,Z=0,W=0)"). SubobjectDataSubsystem.add_new_subobjectreturns(handle, fail_text); an empty fail text is truthy-looking — checkSubobjectDataBlueprintFunctionLibrary.is_handle_valid(handle)instead. Adding an InstancedStaticMeshComponent to a plainunreal.Actorthis way works.- Editor-world parameter-collection values (what the viewport shows):
unreal.MaterialLibrary.set_scalar_parameter_value(editor_world, mpc, "Name", v). - Console commands:
unreal.SystemLibrary.execute_console_command(editor_world, "r.Foo 1"). - Stop Play-In-Editor before editing assets: while PIE runs,
EditorAssetLibrary.load_assetreturns None (asset scripting is blocked during play) → confusing'NoneType'errors.EditorAppToolset.StopPIE/IsPIERunningvia MCP.
Crash traps (each one killed the editor)
- Never load a map package as an ordinary asset and then
load_level()it in the same session → fatal "World Memory Leaks" (EditorServer.cpp). Hit twice:duplicate_asset()of a map, andload_asset()of a map (forAssetRenameData) followed byload_level(). The world stays in memory as standalone. Create levels withLevelEditorSubsystem.new_level_from_template(new, template); checkfind_asset_data(path).is_asset_loaded()before opening a map you touched. - Moving, renaming or reorganising content (maps, World Partition, redirectors, imported samples):
load
unreal-content-managementfirst. - After a crash a CrashReportClientEditor window stays open; the editor can be relaunched with
UnrealEditor.exe "<path>.uproject"(launching without the Epic launcher skips its login — fine for editing; Fab needs the launcher). If an imported sample replacedDefaultEngine.ini, remote execution may be off after a restart: re-enable it via ObjectToolsset_propertieson/Script/PythonScriptPlugin.Default__PythonScriptPluginSettings{"bRemoteExecution": true}.
Logs and errors
<Project>/Saved/Logs/<Project>.log. SearchCritical error,Fatal errorfor crashes,Failed to compile Material(the error lines follow it) for shaders,LogPython: Error.- Tip: note
wc -lof the log before a script, then grep only the new lines. - Saving a level may log "Unable to Check Out From Revision Control" with an auto-closed dialog even without source control; the package still saves.
Helper scripts
scripts/ue_exec.py— remote Python runner (file or-c).scripts/decode_capture.py— CaptureViewport / CaptureEditorImage result → PNG/JPG (needs PIL in the Python that runs it, e.g. the system Python).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

