{"id":50837634,"url":"https://github.com/wellingfeng/ue-mcp-for-all-versions","last_synced_at":"2026-06-14T05:01:38.097Z","repository":{"id":363652435,"uuid":"1264256400","full_name":"wellingfeng/ue-mcp-for-all-versions","owner":"wellingfeng","description":"A single version-agnostic C++ MCP server that drives any Unreal Engine version (4.25 to 5.8) via the built-in RemoteControl HTTP API. One binary, no engine headers, runtime capability degradation.","archived":false,"fork":false,"pushed_at":"2026-06-09T19:05:12.000Z","size":243,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-09T21:07:36.437Z","etag":null,"topics":["cpp","mcp","model-context-protocol","remote-control","unreal","unreal-engine"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wellingfeng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-09T18:00:33.000Z","updated_at":"2026-06-09T19:07:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/wellingfeng/ue-mcp-for-all-versions","commit_stats":null,"previous_names":["wellingfeng/ue-mcp-for-all-versions"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/wellingfeng/ue-mcp-for-all-versions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wellingfeng%2Fue-mcp-for-all-versions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wellingfeng%2Fue-mcp-for-all-versions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wellingfeng%2Fue-mcp-for-all-versions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wellingfeng%2Fue-mcp-for-all-versions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wellingfeng","download_url":"https://codeload.github.com/wellingfeng/ue-mcp-for-all-versions/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wellingfeng%2Fue-mcp-for-all-versions/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34309655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","mcp","model-context-protocol","remote-control","unreal","unreal-engine"],"created_at":"2026-06-14T05:01:32.212Z","updated_at":"2026-06-14T05:01:38.087Z","avatar_url":"https://github.com/wellingfeng.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ue-mcp-for-all-versions\n\nA single, version-agnostic **C++ MCP server** that drives **any Unreal Engine\nversion (4.25 → 5.8)** through the engine's built-in **RemoteControl** HTTP API.\n\nThe server links **no Unreal headers**. It is an ordinary native executable that\nspeaks the [Model Context Protocol](https://modelcontextprotocol.io) over stdio\nto an MCP client (Claude Desktop / Claude Code / Cursor / …) and talks plain\nHTTP/JSON to the editor. Because it has no engine ABI or `.modules` BuildId\ndependency, **one binary works across every engine version**, and APIs that a\ngiven version lacks are reported as a structured `\"unsupported\"` result at\nruntime instead of failing.\n\n## Why this design\n\nA native in-engine C++ plugin **cannot** be a single drop-in binary across\nversions: UE enforces an exact-match `.modules` BuildId at load and guarantees\nno C++ ABI stability between versions (even 5.x → 5.x). Forcing a mismatched\nDLL to load corrupts memory rather than failing gracefully — so \"auto-degrade\nwhen an API is missing\" is impossible *inside* a compiled engine module.\n\nThis project sidesteps the problem entirely: the binary lives **outside** the\nengine and uses RemoteControl's HTTP wire protocol, which is far more stable\nacross versions than the engine's C++ classes. Capability differences are\ndiscovered **at runtime**.\n\n```\n[ MCP Client ] \u003c--stdio JSON-RPC--\u003e [ ue-mcp-for-all-versions.exe ] \u003c--HTTP--\u003e [ UE (any version) ]\n                                          (one binary)                 :30010 / :8080   RemoteControl\n```\n\n## Requirements on the UE side (zero code intrusion)\n\nUse the one-click setup command below for the normal path. It enables the\nengine's stock plugins and writes the version-specific RemoteControl settings\nneeded by this server (no source mod, no custom plugin).\n\nManual requirements, if you do not use setup:\n\n- **UE 4.26+** auto-starts it on `:30010` by default.\n- **UE 4.25** uses `:8080` and does **not** auto-start — run `WebControl.StartServer`\n  in the editor console (or launch with\n  `-ExecCmds=\"WebControl.EnableServerOnStartup 1; WebControl.StartServer\"`).\n\nThe server probes `:30010` then `:8080` automatically.\n\n## Build\n\nRequirements: CMake ≥ 3.20 and a C++17 compiler (MSVC 2022 on Windows).\nDependencies (`nlohmann/json`, `cpp-httplib`) are vendored under `third_party/`\n— nothing to fetch.\n\n```bash\ncmake -S . -B build -G \"Visual Studio 17 2022\" -A x64\ncmake --build build --config Release\n```\n\nOutput: `build/Release/ue-mcp-for-all-versions.exe`. On MSVC it links the static\nruntime, so it is genuinely copy-and-run — distribute the single `.exe`.\n\n## Usage\n\n```\nue-mcp-for-all-versions [--host H] [--port P] [--probe]\n  --host H   RemoteControl host (default 127.0.0.1)\n  --port P   force a single RC port (default: probe 30010 then 8080)\n  --probe    connect, print detected engine + capabilities as JSON, then exit\n```\n\n### One-click project setup\n\nPoint the binary at either a `.uproject` file or the project directory:\n\n```bash\nue-mcp-for-all-versions --setup-project C:/path/to/MyGame\n```\n\nThe setup command is designed for host apps such as FreeUltraCode to call from\na single \"Enable Unreal MCP\" button. It:\n\n- detects the `.uproject` and `EngineAssociation`\n- enables `RemoteControl`, `EditorScriptingUtilities`, and `PythonScriptPlugin`\n- writes the correct RemoteControl config file for the engine line:\n  - UE 4.25: `Config/DefaultEngine.ini` startup CVar fallback\n  - UE 4.26: `Config/DefaultWebRemoteControl.ini`\n  - UE 5.x: `Config/DefaultRemoteControl.ini`\n- on UE 5.x, writes the **full-access profile** by default so the MCP server\n  can drive every editor operation without interactive prompts:\n  `bEnableRemotePythonExecution`, `bIgnoreProtectedCheck`, and\n  `bIgnoreGetterSetterCheck` are all set to `True`. This avoids the deadlock\n  where protected-property edits (e.g. `WidgetTree.ConstructWidget`) require a\n  confirmation that cannot be answered over a remote connection. Pass\n  `--no-python` to keep the conservative defaults instead.\n- writes/merges project `.mcp.json` with this server command\n- prints a machine-readable JSON report listing changed files, notes and warnings\n\n\u003e These settings are read only when the editor boots. After setup, **restart the\n\u003e Unreal Editor** so the new plugins and RemoteControl flags take effect — a\n\u003e running editor will not hot-reload them. The JSON report surfaces this as a\n\u003e `RESTART REQUIRED` warning whenever files actually changed.\n\nUseful setup flags:\n\n```bash\nue-mcp-for-all-versions --setup-project C:/path/to/MyGame --dry-run\nue-mcp-for-all-versions --setup-project C:/path/to/MyGame --server-command C:/tools/ue-mcp-for-all-versions.exe\nue-mcp-for-all-versions --setup-project C:/path/to/MyGame --no-python\nue-mcp-for-all-versions --setup-project C:/path/to/MyGame --no-mcp-config\n```\n\nAfter setup, restart the Unreal Editor if plugins or RemoteControl settings\nchanged. The MCP server itself can be started before the editor; it connects\nlazily and auto-reconnects.\n\nManual MCP client config, if you do not use setup (example `.mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"ue-mcp-for-all-versions\": {\n      \"command\": \"C:/path/to/ue-mcp-for-all-versions.exe\"\n    }\n  }\n}\n```\n\n### Registering with CLI clients\n\nBecause the server speaks the standard MCP stdio transport, any MCP-capable CLI\ncan use it. The binary is the same for every UE version.\n\n**Claude Code:**\n```bash\nclaude mcp add ue-mcp-for-all-versions -- C:/path/to/ue-mcp-for-all-versions.exe\n```\n(or drop the `examples/mcp.json` content into your project's `.mcp.json`.)\n\n**Codex CLI** — in `~/.codex/config.toml`:\n```toml\n[mcp_servers.ue-mcp-for-all-versions]\ncommand = \"C:/path/to/ue-mcp-for-all-versions.exe\"\nargs = []\n```\n\n**Gemini CLI** — in `~/.gemini/settings.json`:\n```json\n{ \"mcpServers\": { \"ue-mcp-for-all-versions\": {\n    \"command\": \"C:/path/to/ue-mcp-for-all-versions.exe\" } } }\n```\n\nYou can start the CLI before the editor — the server connects lazily (see\n*Connection lifecycle* below).\n\n## Tools\n\n110 tools, grouped below. Every tool is **capability-gated**: if the connected\nengine lacks the required capability it returns\n`{\"status\":\"unsupported\", \"reason\": ..., \"missingCapability\": ...}` instead of\nfailing. Tools marked *modern→legacy* call the UE5 editor subsystem first and\nfall back to the UE4 library automatically, so one tool spans 4.25 → 5.8.\n\n### Core RemoteControl\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_get_engine_version` | — | Engine version + detected capabilities |\n| `ue_call_function` | object.call | Call any UFunction (`/remote/object/call`) |\n| `ue_get_property` / `ue_set_property` | object.property | Read / write a property |\n| `ue_remote_info` | info (4.26+) | RemoteControl server info / routes |\n| `ue_describe_object` | object.describe (4.26+) | Object properties \u0026 functions |\n| `ue_search_assets` | search.assets (4.26+) | Search project assets |\n| `ue_batch` | batch (4.26+) | Multiple RC requests in one round-trip |\n\n### Scripting \u0026 editor context\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_python_exec` | python (probed) | Run Python and capture result + log (`ExecutePythonCommandEx`). 4.25→5.8 when the PythonScriptPlugin is enabled |\n| `ue_exec_console_command` | object.call | Run an editor/console command (auto-resolves world context on UE4) |\n| `ue_get_editor_world` | object.call | Editor UWorld path (*modern→legacy*) |\n| `ue_get_project_info` | object.call | Aggregated engine/project metadata |\n\n### Actors\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_list_actors` | object.call | List level actors (*modern→legacy*) |\n| `ue_spawn_actor` / `ue_destroy_actor` | object.call | Spawn / destroy an actor (*modern→legacy*) |\n| `ue_get_actor_transform` | object.call | Read an actor's transform |\n| `ue_set_actor_location` / `_rotation` / `_scale` | object.call | Set actor location / rotation / scale |\n| `ue_get_actor_label` / `ue_set_actor_label` | object.call | Read / set the World Outliner label |\n| `ue_get_selected_actors` / `ue_select_actors` / `ue_clear_selection` | object.call | Editor selection (*modern→legacy*) |\n\n### Assets\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_list_assets` / `ue_does_asset_exist` | object.call | List / check assets (*modern→legacy*) |\n| `ue_find_asset_data` | object.call | Asset registry metadata |\n| `ue_save_asset` / `ue_save_directory` | object.call | Save an asset / a directory |\n| `ue_duplicate_asset` / `ue_rename_asset` | object.call | Duplicate / rename an asset |\n| `ue_delete_asset` | object.call | **Delete** an asset (destructive) |\n\n### Level, viewport \u0026 play\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_save_current_level` / `ue_load_level` / `ue_new_level` | object.call | Level open / save / new (*modern→legacy*) |\n| `ue_get_viewport_camera` / `ue_set_viewport_camera` | object.call | Read / move the editor viewport camera |\n| `ue_take_screenshot` | object.call | High-res editor screenshot |\n| `ue_is_pie` / `ue_stop_pie` | pie.control (5.x) | Query / end Play-In-Editor |\n\n### Property array ops \u0026 presets\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_property_array_append` / `_insert` / `_remove` | object.property.arrayops (5.0+) | In-place array property edits |\n| `ue_list_presets` / `ue_get_preset` | presets (4.26+) | List / inspect RemoteControl presets |\n| `ue_preset_call_function` | presets (4.26+) | Invoke a function exposed on a preset |\n| `ue_preset_get_property` / `ue_preset_set_property` | presets (4.26+) | Read / write an exposed preset property |\n\n### Scene introspection\n\nQuery the scene directly instead of guessing it from screenshots. These turn\n\"which actor is the terrain and what controls its color\" into a single lookup\nrather than a show/hide-and-screenshot search.\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_find_actors_by_class` | object.call | All actors matching a class path (composes `GetAllLevelActors` + `EditorFilterLibrary.ByClass`) |\n| `ue_find_actors_by_label` | object.call | Actors whose Outliner label matches (Contains / Wildcard / Exact) |\n| `ue_get_actor_components` | object.call | An actor's components, optionally filtered by class (`K2_GetComponentsByClass`) |\n| `ue_get_actor_bounds` | object.call | World-space bounding box (origin + extent) |\n| `ue_get_actor_reference` | object.call | Resolve an actor path/name to a concrete reference (UE5) |\n\n### Component transforms, bounds \u0026 character scale\n\nComponent-level tools for adjusting Pawn internals such as a `HeroineMesh`,\ncamera, or spring arm without moving the whole actor. Python-backed read helpers\nreturn normalized JSON instead of raw UE structs.\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_set_component_relative_transform` | object.call | Set a child SceneComponent's relative location / rotation / scale (`K2_SetRelativeLocation`, `K2_SetRelativeRotation`, `SetRelativeScale3D`) |\n| `ue_get_component_transform` | python | Read component world transform, relative transform, attach parent, owner, class, and world scale |\n| `ue_get_component_bounds` | python | Read local/world component bounds, or aggregate filtered actor bounds; defaults `includeEditorVisualization=false` to exclude camera frustums, billboards, arrows, sprites, and editor-only components |\n| `ue_fit_mesh_component_to_height` | python | Read StaticMesh/SkeletalMesh local bounds, compute uniform scale for a target height such as 180, and optionally apply it |\n| `ue_normalize_imported_character_mesh` | python | Suggest rotation and optional scale for common imported character axis conventions, defaulting to Unreal `targetUp=Z`, `targetForward=X`; can optionally apply to a component |\n| `ue_get_blueprint_components` | python | List a Blueprint generated CDO's component tree: name, class, parent, relative transform, and common resource references |\n| `ue_set_blueprint_component_template_transform` | python | Persistently edit a Blueprint component template on the generated CDO and exposed SCS template, for defaults such as `BP_HeroineThirdPersonPawn.HeroineMesh` |\n\n### Materials \u0026 visuals\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_set_material_param` | object.call | Create a dynamic material instance on a component element and set a scalar / vector (color) / texture parameter — the precise way to recolor a mesh or landscape |\n| `ue_set_material_instance_param` | object.call | Set a scalar / vector parameter on a Material Instance Constant **asset** (`MaterialEditingLibrary`) |\n| `ue_get_object_thumbnail` | object.thumbnail (4.26+) | Render an object's thumbnail and return it as an **image** content block (PNG/JPEG per the engine) a vision client can see |\n\n### Editor workflow\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_load_asset` | object.call | Load an asset and return its object path (*modern→legacy*) |\n| `ue_spawn_actor_from_asset` | object.call | Spawn an actor from an asset (mesh / Blueprint / …) (*modern→legacy*) |\n| `ue_set_actor_transform` | object.call | Set location + rotation + scale together (decomposed setters) |\n| `ue_focus_viewport_on_actor` | object.call | Frame the viewport camera on an actor using its bounds |\n| `ue_set_game_view` | object.call | Toggle viewport Game View (*modern→legacy*) |\n| `ue_get_console_variable` | object.call | Read a CVar value (float / int / bool / string) |\n\n### Scene authoring (Layer 1)\n\nBuild and organize scenes faster — batch spawning avoids the per-actor latency\nthat makes \"build a town\" painful.\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_batch_spawn_actors` | batch (4.26+) | Spawn many actors in one `/remote/batch` round-trip |\n| `ue_duplicate_actor` | object.call | Duplicate a level actor with an optional offset (*modern→legacy*) |\n| `ue_attach_actor` / `ue_detach_actor` | object.call | Parent / unparent actors (`K2_AttachToActor` / `K2_DetachFromActor`) |\n| `ue_set_actor_folder` | object.property | Set an actor's World Outliner folder path |\n\n### Mesh \u0026 lighting (Layer 1)\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_set_static_mesh` | object.call | Swap a StaticMeshComponent's mesh asset |\n| `ue_set_actor_material` | object.call | Assign a material **asset** to a component's slot (`SetMaterial`) |\n| `ue_set_light_property` | object.call | Set a LightComponent's intensity and/or color |\n\n### Asset \u0026 material creation (Layer 1)\n\nPython recipes — each runs as one `ExecutePythonCommandEx` round-trip, not a\nsequence of REPL calls. Require the PythonScriptPlugin.\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_create_material` | python | Create a Material asset (optional constant base color) |\n| `ue_create_material_instance` | python | Create a Material Instance Constant parented to a material |\n| `ue_import_asset` | python | Import a source file (FBX/OBJ/PNG/…) via `AssetImportTask` |\n| `ue_import_asset_with_transform_policy` | python | Import FBX/GLB/glTF with explicit convertScene, forceFrontXAxis, convertSceneUnit, importUniformScale, skeletal/static mesh import-data overrides, and material/texture flags where exposed by the engine |\n| `ue_create_folder` | python | Create a content-browser folder |\n\n### Data \u0026 debug (Layer 1)\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_data_table_get_rows` | python | Read a DataTable's rows + names as JSON |\n| `ue_set_cvar` | object.call | **Write** a console variable (counterpart to `ue_get_console_variable`) |\n| `ue_start_pie` | pie.control (5.5+) | Start a Play-In-Editor session (`EditorRequestBeginPlay`) |\n| `ue_simulate_player_input` | python + pie.control | Inject key/axis input into the PIE PlayerController and report pawn movement delta, with an explicit AddMovementInput fallback when Python does not expose low-level input calls |\n\n### Blueprint, gameplay \u0026 UMG authoring (Layer 2)\n\nCreation tasks pure RemoteControl can't express — building an asset's internal\nstructure. Python recipes; require the PythonScriptPlugin (and\n`BlueprintEditorLibrary`, UE5, for the blueprint tools).\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_create_blueprint` | python | Create a Blueprint class asset with a chosen parent |\n| `ue_add_blueprint_variable` | python | Add a member variable (UE5 `BlueprintEditorLibrary`) |\n| `ue_compile_blueprint` | python | Compile and save a Blueprint |\n| `ue_create_character_blueprint` | python | Create a `Character` Blueprint, configure capsule / mesh / `CharacterMovement`, and try to add a SpringArm + Camera |\n| `ue_configure_character_movement` | python | Configure an existing Character Blueprint for grounded walking, gravity, jump, step height, floor angle, capsule size, mesh transform, and optional Anim Blueprint |\n| `ue_calibrate_character_collision` | python | Calibrate capsule radius / half-height and mesh offset for a target character height, with Pawn / CharacterMesh collision profiles |\n| `ue_configure_third_person_camera` | python | Add or update a SpringArm + Camera for third-person follow, shoulder offset, collision testing, and camera lag |\n| `ue_create_enhanced_input_assets` | python | Create IA_Move / IA_Look / IA_Jump and an Input Mapping Context with WASD, mouse, SpaceBar, and common modifiers |\n| `ue_create_locomotion_animation_assets` | python | Create an Animation Blueprint and 1D speed BlendSpace scaffold for a skeleton, with optional idle/walk/run samples where Python exposes sample editing |\n| `ue_set_game_defaults` | python | Persist GameMapsSettings: game default map, editor startup map, and default GameMode |\n| `ue_validate_third_person_pie` | python + pie.control | PIE smoke test for Player0 pawn class, possession, CharacterMovement, camera, and movement-input displacement |\n| `ue_create_widget_blueprint` | python | Create a UMG Widget Blueprint **with a root panel** — tries several strategies and reports `strategiesTried`; returns `unsupported` (pointing at the Layer-3 plugin) on stripped builds where the root can't be set, rather than looping |\n| `ue_add_widget_to_blueprint` | python | Add a child widget (Button / TextBlock / EditableTextBox / …) to a Widget Blueprint's root |\n| `ue_inspect_widget_blueprint` | python | Inspect a Widget Blueprint tree: root, descendants, parent/child names, slot types, and common text/value properties |\n| `ue_add_widget_to_panel` | python | Add a widget to a named panel/content widget with optional text, properties, and layout in one call |\n| `ue_set_widget_properties` | python | Set common UMG properties such as text, tooltip, visibility, enabled state, opacity, font size, color, brush color, and image |\n| `ue_configure_widget_layout` | python | Configure CanvasPanelSlot position / size / anchors / alignment / z-order and common panel-slot padding/alignment |\n| `ue_create_widget_component_blueprint` | python | Create an Actor Blueprint with a WidgetComponent assigned to a UMG Widget Blueprint for world-space or screen-space UI |\n\n\u003e **UMG note (empirically confirmed on UE 5.5):** setting a Widget Blueprint's\n\u003e *root* widget is the one creation task that can't be done from outside the\n\u003e engine. `UWidgetTree` has no Python type binding (even after\n\u003e `load_module(\"UMG\"/\"UMGEditor\")`), and `WidgetTree.RootWidget` carries the\n\u003e `EditConst` flag — so Python's `set_editor_property` AND the RemoteControl\n\u003e write path (even with `bIgnoreProtectedCheck`) both refuse it. RC *can* read\n\u003e the protected WidgetTree and `new_object(CanvasPanel, tree)` *can* create a\n\u003e panel, but the final assignment is blocked. `ue_create_widget_blueprint` is\n\u003e honest about this: it creates the asset, tries each path, reports\n\u003e `strategiesTried`, and returns `unsupported` — it does NOT loop (the failure\n\u003e mode that cost 27 minutes). Authoring the root needs the optional Layer-3\n\u003e in-engine plugin (see `.omc/plans/layer3-inengine-plugin-design.md`).\n\nThe one-click setup command enables the stock engine plugins needed by these\nhelpers. If configuring manually, enable `RemoteControl`,\n`EditorScriptingUtilities`, and `PythonScriptPlugin`. For Python tools on\nUE 5.x, setup also enables RemoteControl's remote Python execution project\nsetting by default.\n\n### Pencil → UMG conversion (Layer 3 plugin)\n\nWhen the user wants to turn a Pencil design (`.pen`) into a UMG widget, these\nthree tools wrap the external\n[Pencil2UMG](https://github.com/wellingfeng/pencil2umg) editor plugin. The\nplugin ships as a prebuilt editor module in GitHub Releases and exposes\n`UPencil2UMGImporterLibrary::ImportPenFile`, which these tools drive from a UE\nPython recipe (the GitHub query, download, unzip, and import all run inside the\neditor, which has TLS + filesystem access). The install is **confirm-gated and\nself-updating**: the user confirms once for the first install and again for any\nlater release, and \"latest\" always means the newest GitHub release at call time.\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_pencil2umg_status` | python | Report installed version, the latest GitHub release, whether an update is available, and whether the importer is loaded |\n| `ue_pencil2umg_install` | python | Confirm-gated download/install of the latest release into `Plugins/Pencil2UMG` and enable it in the `.uproject`. `confirm=false` returns a `needsConfirmation` preview (fresh install vs. from→to update); `confirm=true` performs it; restart the editor afterward |\n| `ue_pencil_to_umg` | python | Convert a `.pen` file to a UMG Widget Blueprint via the installed importer; returns `needsInstall` / `needsRestart` when the plugin isn't ready |\n\nTypical flow: `ue_pencil2umg_status` → if not installed or an update exists, ask\nthe user, then `ue_pencil2umg_install(confirm=true)` → restart the editor →\n`ue_pencil_to_umg(penFilePath=..., packagePath=\"/Game/UI\")`. The install never\nwrites anything without an explicit `confirm=true`, so the agent can safely\npreview the action first.\n\n### Figma → UMG conversion (Layer 3 plugin)\n\nWhen the user wants to import a Figma design into UMG, these three tools wrap\nthe external [Figma2UMG](https://github.com/wellingfeng/figma2umg) editor plugin\n(Buvi Games, MIT). It differs from Pencil2UMG in important ways, and the tools\nare honest about them:\n\n- **No tagged releases.** Figma2UMG is a C++ *source* plugin with no prebuilt\n  binaries, so \"latest\" is tracked by the main-branch HEAD commit SHA (recorded\n  in a `.figma2umg_version` marker), and install pulls the source zipball.\n- **Compile step.** After install/update the editor must restart and *compile*\n  the module (a C++ toolchain is required) before the importer is usable.\n- **No scriptable import.** Its importer subsystem has no BlueprintCallable\n  entry point, so the conversion can't be triggered from Python. `ue_figma_to_umg`\n  instead pre-fills the Figma token / file key / import path settings and\n  returns a `manualStep` payload telling the user to launch the import from the\n  Content Browser context menu — the only supported trigger.\n\n| Tool | Requires | Description |\n|------|----------|-------------|\n| `ue_figma2umg_status` | python | Report installed version + source commit, the latest main-branch commit, whether an update is available, and whether the module is compiled/loaded |\n| `ue_figma2umg_install` | python | Confirm-gated download/install of the latest source commit into `Plugins/Figma2UMG` and enable it in the `.uproject`. `confirm=false` previews (fresh install vs. from→to commit update); `confirm=true` performs it; restart + recompile the editor afterward |\n| `ue_figma_to_umg` | python | Pre-fill the Figma access token / file key / content path in the project settings, then return a `manualStep` payload guiding the Content-Browser import; returns `needsInstall` / `needsCompile` when the plugin isn't ready |\n\nTypical flow: `ue_figma2umg_status` → if not installed or an update exists, ask\nthe user, then `ue_figma2umg_install(confirm=true)` → restart the editor and let\nit compile → `ue_figma_to_umg(accessToken=..., fileKey=..., contentRootFolder=\"/Game/Figma\")`\n→ launch the import from the Content Browser as instructed. As with Pencil2UMG,\nthe install never writes anything without an explicit `confirm=true`.\n\nA tool whose capability is absent on the connected engine returns\n`{\"status\":\"unsupported\", \"reason\": ..., \"missingCapability\": ...}` — never a\nhard failure.\n\n## Connection lifecycle (works with long-lived CLI clients)\n\nMCP CLIs (Claude Code, Codex, Gemini, Cursor, Cline) start the server once and\nkeep it alive for the whole session. The server is built for that:\n\n- **Lazy connect.** It does not require the engine to be running at launch. It\n  connects on first use, so you can start the CLI first and the editor later.\n- **Auto-reconnect.** If the editor is closed and reopened (or restarted) mid\n  session, the next tool call transparently re-probes ports, reconnects, and\n  refreshes capabilities — no need to restart the CLI.\n- **Throttled.** While the engine is down, reconnect attempts are rate-limited\n  so a tool call fails fast instead of stalling on a full port-probe timeout.\n\nWhile disconnected, capability-gated tools return a connection *error* (the\nengine isn't there to tell us what it supports); once connected they behave per\nthe capability table above.\n\n\n## Verified versions\n\nThe **same single binary** was integration-tested against four installed engine\nversions (one process, no recompilation). Per-version capability detection and\nruntime degradation behave as designed:\n\n| Engine | Port | `/remote/info` | Capabilities | `ue_list_actors` | 4.26+ tools |\n|--------|------|----------------|--------------|------------------|-------------|\n| 4.25.4 | 8080 | absent | 2 (call, property) | ✓ (legacy lib) | `unsupported` |\n| 4.26.2 | 30010 | 14 routes | 7 (no array-ops) | ✓ (legacy lib) | ✓ |\n| 5.3.2  | 30010 | 31 routes | 8 | ✓ (subsystem) | ✓ |\n| 5.5.1  | 30010 | 31 routes | 8 | ✓ (subsystem) | ✓ |\n\n`ue_list_actors`/`ue_spawn_actor`/`ue_destroy_actor` prefer the UE5\n`EditorActorSubsystem` and fall back to the UE4 `EditorLevelLibrary`\nautomatically, so one tool works across the 4.x ↔ 5.x boundary.\n\nThe expanded tool set (Python, actor transform/label/selection, asset\nsave/duplicate/rename/delete, level/viewport, PIE, property array ops, presets)\nwas re-verified live against UE 5.5.1: spawning an actor, setting its\nlocation/rotation/scale, reading the transform back, setting/reading its label,\nselecting it, and saving — all confirmed end-to-end. Capability degradation was\nconfirmed too (e.g. `ue_python_exec` returns `unsupported` when the\nPythonScriptPlugin is disabled rather than erroring).\n\nUE 5.8 (which also ships Epic's own experimental `ModelContextProtocol` plugin)\nis not yet hardware-tested here; the design adapts at runtime via `/remote/info`\nroute discovery and engine-version inference.\n\n## Tests\n\n```bash\n# unit tests (no engine required)\nctest --test-dir build -C Release --output-on-failure\n\n# cross-version integration (launches a real editor on a minimal project)\nbash scripts/integration_test.sh 55  5.5  UnrealEditor 30010\nbash scripts/integration_test.sh 425 4.25 UE4Editor    8080\n\n# long-lived server / late-start / auto-reconnect (CLI usage pattern)\npython scripts/drive_server.py 30010 full\n```\n\n## Layout\n\n```\ninclude/ue_mcp_for_all_versions/   public headers (namespace ue_mcp_for_all_versions)\nsrc/                               rc_client / capability_registry / tool_registry / mcp_server / main\nthird_party/                       vendored nlohmann/json + cpp-httplib (header-only)\ntests/                             dependency-free unit tests\nscripts/                           cross-version integration harness\n```\n\n## License\n\nMIT. See `LICENSE`. Vendored third-party headers keep their own licenses\n(`nlohmann/json` — MIT; `cpp-httplib` — MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwellingfeng%2Fue-mcp-for-all-versions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwellingfeng%2Fue-mcp-for-all-versions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwellingfeng%2Fue-mcp-for-all-versions/lists"}