Merge of the two project copies into one self-contained plugin (the superset: variable_op + variables.py, full pcg_op runtime/declarative/preset ops, the CreateWidgetFloatAnimation widget tool, and full Voxel graph authoring). Made fully project- and machine-agnostic — no hardcoded paths: - New src/projectPaths.js auto-detects the host .uproject (walk-up), project name, Editor build target, log file, and engine install (EngineAssociation via launcher manifest/registry, else installed-engine scan). All overridable via UE_* env vars. - Rewired buildOrchestrator/insights/launcher/insightsExporter/server.js and the Python workers (cpp_scaffold, live_coding, apply_graph, console) off the old C:/Github/ihy, IHY*, E:/UE_Versions and UE_5.7 literals onto the resolver. - Voxel made optional: Build.cs auto-detects the Voxel plugin (env UE_MCP_WITH_VOXEL override) and the C++ compiles to stubs under WITH_MCP_VOXEL, so the module builds in projects without Voxel; .uplugin marks Voxel optional. - De-branded the agent-gateway and docs; scrubbed a leaked API key; excluded node_modules/Binaries/Intermediate/__pycache__/secrets from the repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.8 KiB
UEBlueprintMCP — TODO / Future Tool Coverage
Domains still missing from the MCP surface. Ordered by likely value.
High value (likely soon)
pcg_op — mesh-entry & volume helpers (gap found building a PCG graph)
set_mesh_entries{asset_path, node, entries:[{mesh, weight?}]}— populate a PCGStaticMeshSpawner's weighted selector. Today this needs raw py: themesh_selector_parametersinstance is READ-ONLY (can't reassign), so you must mutate it in place —msp.set_editor_property("mesh_entries", [...])where each entry is aPCGMeshSelectorWeightedEntryand the mesh goes onentry.descriptor.static_mesh(struct is value-copy → set descriptor back).set_node_propertystruct coercion already handles Vector vs Rotator (3-num list, Vector tried then Rotator(roll,pitch,yaw)) — extend to Vector2D/Color/ Transform as needed.spawn_pcg_volume{graph, location, scale, name?}+generate{actor}— wrap PCGVolume spawn +PCGComponent.set_graph+generate(True). Note: partitioned worlds route instances to PCGPartitionActors async; count there, not on the volume.
Sequencer / Cinematics
- create_level_sequence{path}
- add_binding{seq, actor_name}, remove_binding{seq, guid}
- add_track{seq, binding_guid, track_class} (Transform, Float, Visibility, ...)
- add_key{seq, track, time, value}
- set_playback_range{seq, start, end}
- bake_to_anim_sequence{seq, binding}
- spawn_camera_actor{location, rotation, fov?}
- export_video / export_image_sequence (MovieRenderQueue)
GAS — Gameplay Ability System
- create_gameplay_ability_bp{path, parent?}
- create_attribute_set_bp{path}
- create_gameplay_effect_bp{path}
- add_gameplay_tag{tag}, remove_gameplay_tag{tag}, list_gameplay_tags{prefix?}
- gameplay_cue_create{path}
Data-driven assets
- create_gameplay_tags_table{path}
- data_table_add_row{path, row_name, fields}
- data_table_set_cell{path, row, column, value}
- data_table_read{path, row?}
- curve_table_create / add_curve
- data_asset_set_property{path, property, value}
- enum_add_value, struct_add_field
Physics / Chaos
- create_physics_asset{path, skeletal_mesh}
- create_physical_material{path, friction?, restitution?, density?}
- physics_constraint_set{component, properties}
- chaos_destruction_field_spawn
Landscape / Foliage / World Partition
- landscape_create{section_size, components_per_section, ...}
- landscape_apply_material{path}
- landscape_paint_layer{layer_name, brush_op:'add|remove', position, radius}
- foliage_add_type{static_mesh, density?, ...}
- foliage_paint{location, radius}
- world_partition_set_loading_range{actor, range}
- hlod_build{level_path}
Lighting
- build_lighting{quality:'preview|medium|high|production'}
- set_lumen{enabled, software_raytracing?, hardware_raytracing?}
- set_vsm{enabled, resolution?}
- light_set_property{actor_name, property, value}
PIE (Play-In-Editor) control
- pie_play{mode:'selected|standalone|spawn_player', num_players?}
- pie_stop{}
- pie_pause / pie_resume
- pie_eject
- pie_screenshot{path}
- pie_console_command_in_session{command}
- pie_get_log{tail?, errors_only?}
Editor / Project settings
- ini_get{config:'Engine|Game|Editor|Input', section, key}
- ini_set{config, section, key, value}
- plugin_enable{name} / plugin_disable{name} / plugin_list{}
- platform_target_settings{platform, key, value}
Source Control (Perforce/Git/Plastic)
- sc_status{paths}
- sc_checkout{paths}
- sc_revert{paths}
- sc_submit{paths, description}
- sc_get_user_settings
Cook / Package / Build
- cook_project{platform, maps?, options?}
- package_project{platform, build_config:'Development|Shipping', output_dir}
- build_lighting_then_save{level}
- check_cook_errors{platform}
Medium value
Niagara — extending the existing niagara_op
- set_module_input (currently stubbed) — write parameters into a module
- promote_to_user_parameter
- niagara_simulation_cache_record / play
UMG — extending widget_op
- bind_property{widget, property, function_path}
- create_animation{widget, name, duration}
- add_animation_track{...}
- compile_and_preview
Materials — extending material_op
- material_function_create
- material_layer_create / material_layer_blend_create
- substrate_topology helpers (if Substrate enabled)
- material_parameter_collection_create
Localization
- loc_target_create / loc_gather / loc_compile
- text_add_to_target{namespace, key, source}
Replication / Networking helpers
- bp_set_replication{bp_path, replicates?, replicates_movement?}
- bp_variable_set_replication{bp_path, name, replication:'None|Replicated|RepNotify'}
Online subsystem / OSS / EOS
- launch_dedicated_pie_server
- set_steam_appid / set_eos_credentials
Editor utility / Pipeline
- editor_utility_widget_run{path}
- editor_utility_blueprint_run{path, function}
- exec_python_file{path}
- exec_python_inline{code} — gated, dev-only
Test / Automation
- automation_run{tests:'filter'}
- gauntlet_run{config}
- unit_test_blueprint{bp_path}
Low priority / nice-to-have
- Composure (in-camera VFX)
- USD import/export
- Datasmith
- Pixel Streaming setup
- nDisplay
- VR/AR specific (OpenXR session, head tracking)
- Web Browser widget
- Movie Render Queue presets
- AI behavior debugging (LogVisualizer)
- Replay / DemoNetDriver
Architecture improvements
- Common helpers module (
_common.py) for_tee,_load,_split_pkg,_vec,_rot— every module currently duplicates these. - Versioned envelope — include schema_version in every result for client compatibility.
- Streaming results — for long-running ops (cook, lighting build), stream progress via a separate channel instead of one blocking call.
- Auto-discovery of ops — generate the JSON schemas in server.js from python module introspection, so adding an op in python automatically exposes it.
- Per-op permissions — read-only vs mutating tag in schema so a client policy can block destructive ops.
- Undo grouping — wrap each entrypoint in
unreal.ScopedEditorTransactionso every mutation is one undo step.
BUG: apply_graph spawn_actor kind hard-crashes the editor (2026-06-22)
apply_graph node kind spawn_actor → UMCPGraphLibrary::SpawnSpawnActorFromClassNode()
(MCPGraphLibrary.cpp:716) calls PlaceNode<UK2Node_SpawnActorFromClass>, whose blind
AllocateDefaultPins() trips check(Result) in EdGraphNode.h:586 and takes the whole
editor down (assertion → StaticShutdownAfterError). Reproduced 3x.
Workaround used: spawn from C++ instead (UWorld::SpawnActor) exposed via a
UBlueprintFunctionLibrary, or build the deferred-spawn pair manually with call_function
nodes (GameplayStatics.BeginDeferredActorSpawnFromClass + FinishSpawningActor).
Proper fix: construct UK2Node_SpawnActorFromClass via FGraphNodeCreator<> /
set the Class pin before AllocateDefaultPins, or guard the assert. Until fixed, do not
use the spawn_actor kind.