Skip to content

Releases

Release v0.6.1-beta-b

Release v0.6.1-beta-b Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 08 Nov 10:37

Note

Beta. Published as a semver prerelease (0.6.1-beta-b) under the npm beta dist-tag, so npm install keeps serving the newest stable release, 0.6.0. This section is everything on dev since the v0.6.1-beta-a tag, written from the code diff.

🔄 Changed
  • Inputs are held to their contract: execute refuses a string or object key past its maxLength, or past the 1023 characters an FName holds where none is set (code, scripts and prose parameters take more); a vector or color sent as an array must hold exactly the type's numbers; add_keyframe requires property.
🔧 Fixed
  • Builds: the plugin builds on macOS again and on UE 5.0 and 5.1, and a source check in CI keeps those compiler traps out.
  • Crashes: an overlong tag, name or key and an add_keyframe with no property no longer close the editor.
  • Vectors and colors: Niagara parameters, effect and skeleton scale, light, debug shape and texture colors, material vector defaults, blackboard vector and rotator keys and actor location, rotation and scale no longer pad, cut or zero an array that is not exactly their numbers and answer success.
  • Sequence keys: an add_keyframe Transform whose value keys nothing is refused INVALID_ARGUMENT naming the value instead of reading as an unsupported property, a value that wraps property or value is refused, and every refusal shows a key's whole params (the old example put property inside value).
⚠️ Migration
  • Long text: a string over 1023 characters, or over a parameter's own maxLength, is refused OUT_OF_RANGE; send long text only in the parameters that take it (code, scripts, descriptions, comments, subtitles, widget text).
  • Vector and color arrays: send exactly the type's numbers (three for a vector, three or four for a color), or the object form.
  • Sequence keys: send property beside value in add_keyframe; a Transform whose value keys nothing answers INVALID_ARGUMENT, not UNSUPPORTED_PROPERTY.
🔄 Dependencies
  • GitHub Actions: github/codeql-action (init, autobuild, analyze) 4.39.0 → 4.39.2. No npm package changed, and the package still has no runtime dependencies.
📊 Change Statistics
Metric Count
Diff range v0.6.1-beta-a..v0.6.1-beta-b
Commits 12, the version bump and the release cut included
Files changed 80 (65 hand-written, not counting generated files or line-ending-only changes)
Insertions / deletions 2,035 / 540 (hand-written: 889 / 101)
Capability records 489
Callable {tool, action} pairs 1,658
C++ domain directories 58

Release v0.6.1-beta-a

Release v0.6.1-beta-a Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Nov 14:08

Note

Beta. Published as a semver prerelease (0.6.1-beta-a) under the npm beta dist-tag, so npm install keeps serving the newest stable release, 0.6.0. This section is everything on dev since the v0.6.0 tag, written from the code diff.

✨ Added
  • Engine versions: a capability an older engine cannot run reads unavailable and is refused ENGINE_VERSION_UNSUPPORTED (Geometry Script 5.1, MetaSound graph reads and skinning 5.5, retargeting 5.8).
  • Search and execute: a typo is read as the word meant (corrected), options.aggregate counts a long list by group, and an alias sent as tool + action resolves.
  • Blueprints: lint_blueprint follows values (a divisor that can be 0, an index past the end, a Set outside a Value Range, == on computed floats, a decided Branch, an endless While); fuzz_blueprint calls a Blueprint's functions in Play with edge-case inputs and names each error's node; MVVM viewmodels (UE 5.4+); add_variable exposeToCinematics.
  • Graph as code: read_graph_as_code entry and codeOnly; write_graph_from_code reads back only what it wrote.
  • Views and cameras: camera looks through a camera actor (screenshot, describe_view, analyze_view, audit_materials); pause and list_track_keys name each cut's camera; screenshot renderSize and pathTraced (a denoised path-traced image); fov on every view read.
  • Plugins and project: get_plugin_info, create_plugin / remove_plugin, game features (UE 5.1+), data registries, an unused-asset report, set_project_thumbnail, get_console_variables, remove_cpp_class.
  • Editor: read_editor_ui, configure_editor close_tab, set_selected_actors, viewport show_flags, reimport without a dialog, set_current_level, console_command filter.
  • Actors: snap to grid, distribute, align, lock, group, randomize, replace, convert to a Blueprint, move to a level, numbered rename, copies along a spline, place_decals; list bounds and find locations; sample_motion feel (jump, run, key latency, camera jerk).
  • Sequences: add_actors rebind points a sequence copied with its level at the new level's actors; add_behaviour sequence_trigger plays one when the player walks in.
  • Geometry: append_tubes, append_polygons repeat and bake_vertex_colors coarseShare.
  • Look and sound: material color / glow, light flicker, a first-person view, sound_trigger, subtitles, sound volume and looping, footsteps, animation play rate, massKg.
  • Scripts and sheets: run_script takes (if cond a b) as a value and waits within deadlineMs for a call that answers later; contact and thumbnail sheets take keepFile: false.
  • Frame budget: fit_frame_budget finds which lights' shadows and far small meshes to turn down to meet a GPU frame time at the least change to the picture, and keeps them as one undo step.
  • Proxy CLI: init <client> writes a client's MCP config; doctor checks the setup (the token is never shown).
🔄 Changed
  • Movie Render Queue, Takes and MetaSound are required plugins: EngineWire links their modules, so enabling it turns them on (left off in a Blueprint-only project, EngineWire did not load on Windows and the editor crashed at startup on macOS).
  • Write replies pass on only lint errors: the warnings (unreachable nodes, heavy Tick work) stay in Validate Assets, saves and validate_assets, so a graph built one node at a time is not told its newest node never runs.
  • No-op and mid-compile edits are refused: an edit that changes nothing is refused instead of answered done, and so is any edit while a Live Coding compile runs.
  • Scopes follow what a call writes: export_level needs write, and export_mesh outputPath, screenshot path and get_transform (sample_motion) inputs raise a call to write.
🛡️ Security
  • Native /mcp binds to loopback only, whatever Allow Non Loopback says: it has no TLS, so a token would cross the network in clear text. A WebSocket listener on a LAN address needs the capability token and TLS.
  • The stdio proxy sends its token only to a loopback upstream unless UNREAL_MCP_ALLOW_REMOTE_TOKEN=1, and doctor follows the same rule.
  • A path-restricted token's prefixes hold everywhere: saves, deletes, reflection reads, searches and listings run as the request's principal, and a file the caller places is written through a handle checked inside the project.
  • Inputs and consent: script, search and list inputs are bounded, and a consent grant comes back only when no handler ran.
🔧 Fixed
  • Plugin loading: geometry and skinning actions refuse with GEOMETRYSCRIPTING_PLUGIN_NOT_ENABLED while GeometryScripting is off instead of crashing, and the game features module compiles on UE 5.6 and 5.7.
  • Crashes: a glTF or GLB export and a key tapped with no Play session no longer take the editor down.
  • Input: simulated game keys stay out of the editor's panels.
  • Search: about 250 more plain requests find their capability, and an alias a family member declared runs that member.
  • Replies: long lists page and aggregate from the reply's data; console replies stay short; a script step still running at the deadline says so; logpoints read an unwired input's own value; the tool says how to get a fresh consent grant.
  • Undo: asset edits are one step each (notifies, sockets, physics bodies, blackboard keys, Behavior Trees and more), enum undo no longer crashes UE 5.7+, and a script's rollback undoes only its own steps.
  • Graph as code: %, == on text, calls used as values, ids with underscores, custom event calls, other classes' variables, expose-on-spawn inputs, calls on the Blueprint itself and events bound to a delegate write as read_graph_as_code prints them.
  • Placement: props in a room built as one mesh read as they are; a support with no collision is named; fix_coplanar checks each move against the others.
  • Views: frame readers warn while shaders, meshes or textures still build; contact_sheet draws beside water and titles small sheets in full.
  • Geometry: bevel and chamfer cut whole parts, and material and PolyGroup edits are their own undo steps.
  • Assets: check_mesh finds parts wound inside out, on skeletal meshes too; FBX imports open no Message Log window and convert units with options; material instances draw their parent; morph targets and skin weight profiles survive rebuilds; output files reach captures, exports and thumbnails.
  • Editor state: save_all saves streaming sublevels; dry runs no longer compile or save; Blueprint compiles leave placed skeletal meshes posed; Behavior Trees build from their Root.
  • Niagara: a created emitter keeps the name it was asked for.
  • Game framework and materials: default_pawn_class takes None, and material pins connect by the short names the material editor shows.
  • Sequence sections: a sound section plays in the editor and the game, and adding one is one undo step.
⚠️ Migration
  • A client on another machine: the native server no longer binds to a LAN address. Tunnel to it (ssh -L 3000:127.0.0.1:3000 <user>@<editor machine>) and keep UNREAL_MCP_URL at http://127.0.0.1:3000/mcp; a stdio proxy pointed at another machine sends no token unless UNREAL_MCP_ALLOW_REMOTE_TOKEN=1. A WebSocket listener on a LAN address also needs Enable Tls.
  • Scoped tokens: a token without write no longer runs export_level, nor export_mesh with outputPath, screenshot with path or get_transform with inputs.
  • Projects that turned off Movie Render Queue, Takes or MetaSound: enabling EngineWire turns them on again.
  • Lint warnings after a write: read them with lint_blueprint or validate_assets; write replies carry only lint errors.
🔄 Dependencies
  • None: no npm package and no GitHub Action changed, and the package still has no runtime dependencies.
👥 Contributors
  • @SoloGorilla for keeping a created Niagara emitter's requested name (#669), and for reporting the crash when a key was tapped with no play session (#685) and simulated keys reaching editor panels, sample_motion inputs included (#686).
  • @claudemlandry for reporting the macOS startup crash on UE 5.7.4 (#705).
📊 Change Statistics
Metric Count
Diff range v0.6.0..v0.6.1-beta-a
Commits 164, the version bump and the release cut included
Files changed 767 (741 hand-written, not counting generated files or line-ending-only changes)
Insertions / deletions 43,428 / 5,766 (hand-written: 29,413 / 3,729)
Capability records 489
Callable {tool, action} pairs 1,658
C++ domain directories 58

Release v0.6.0

Choose a tag to compare

@github-actions github-actions released this 27 Oct 17:11
e068573

Note

Stable. The 0.6 line's stable release, published under the npm latest dist-tag. This section is everything since the v0.6.0-beta-f tag, written from the code diff.

✨ Added
  • Blueprint runtime errors name their node and an Accessed None its cause; lint_blueprint finds such mistakes before Play, and Validate Assets and saves report them too; logpoints record a node's pin values each time it runs in Play, without pausing; read_graph_as_code and write_graph_from_code read and write graphs as Epic's 5.8 Blueprint DSL text, on every 5.x (a rewrite keeps the nodes its ids name); create_node menuId, arrange_nodes layout: 'layered'.
  • MCP 2026-07-28: sessionless requests, client consent and tasks; older clients unchanged.
  • Reads: get_editor_state focus; describe_view points, labels, coveredBy, compareWith (what changed since saveAs); analyze_view (saliency, palette, light, shader cost); contact_sheet (an actor from every side); audit_materials (base colours, metallic and roughness off physically based ranges, stretched or crammed textures, meshes to instance); get_stats frame; get_ai_info info: 'path' (can a pawn walk there, and why not); analyze_level_layout (a level's rooms, corridors, chokes and dead ends); audit_widget (a menu or HUD checked at several screen sizes: cut-off text, overlaps, contrast, safe area).
  • Large results come in pages (page.nextCall), and search hands over a clear first hit (signature, executeCall).
  • nanite_rebuild_mesh assetPaths, inspect_asset diff, get_niagara_info values, setup_global_illumination saveToProject, four edit_dynamic_mesh operations.
  • Renders and sequences: frame_shot (a camera placed so one or two actors sit where asked on screen, in clear view), fly_through (a camera flown smoothly through points, clear of geometry, keyed into a sequence), auto_edit (a sequence cut between its cameras as an editor would: no crossing the line, no jump cuts), cancel_render, the path tracer's denoiser by name, camera shutter and overscan, set_section playRate, clips and keyed bones in the readers.
  • Sound: measure_loudness and normalize_loudness (Sound Waves measured in LUFS as broadcast measures them, and set to play at one loudness); analyze_acoustics (how long a room rings where a listener stands, and the reverb that fits it).
  • Animation: auto_blend_space (a locomotion blend space laid out from how its clips move).
  • World building: a hip roof over any footprint (create_primitive roof), its faces meeting along ridges, hips and valleys; erode_landscape wears terrain down the way water does (valleys, gullies, filled hollows) so every cell drains, and lists its rivers; plan_road finds a drivable road under a grade limit, round obstacles and wide enough at every turn, switchbacks on steep slopes; assemble_modules lays a modular kit out over a grid so every face where two pieces meet fits.
  • Assets found by what they show: thumbnail_sheet (a folder's thumbnails as one numbered picture), caption_assets (captions kept beside the project, never in the assets), find_assets_like (by words, an example asset, colour or size).
  • Writes are checked: sunk, floating, intersecting, z-fighting or untextured actors, placeholder text, pasted twins, Map Check findings, and Data Validation on assets.
  • Replies say what undo can revert; restore_point undoes only this server's steps and offers the delete of what they created.
  • inspect explain says why something does not happen and names the call that fixes it.
  • A call failing three times unchanged is refused (REPEATED_FAILURE).
  • Batches check every step first; build_graph, build_material_graph and add_widget_tree take dryRun; run_script runs many calls with loops and conditions in one request, rolled back on a failure; recipes keep such a script in the project to run again with other values, and search lists the ones a request names.
  • run_map_check, fix_placement, describe_relations, arrange_by_relations, arrange_widgets (a menu or HUD laid out by relations, held at every screen size), playtest (a pawn walked to a goal in Play, judged with evidence), settle_physics (props dropped and kept where they come to rest), explore_level (a pawn explores the level: falls, traps, unreachable areas), and execute's expect/require, checked after or before a call.
  • inspect changes_since and ue://changes subscriptions: what changed since a cursor, and by whom.
  • Domain playbooks as MCP prompts: Blueprint logic, input, UI, Niagara, materials, world building, animation, cinematics and play testing, each with the traps of its domain.
  • remove_sublevel: a sublevel leaves the open level, as the Levels panel's Remove does; its map file stays.
🔄 Changed
  • The npm package is a stdio proxy to the plugin's /mcp with no runtime dependencies: NOT_CONNECTED while the editor is down; UNREAL_MCP_URL picks the endpoint, UE_PROJECT_PATH finds the token.
  • Enable Native MCP Server is on by default.
  • Consent grants need the nonce describe minted: a missing or made-up one is refused (CONSENT_NOT_ISSUED).
🗑️ Removed
  • The TypeScript gateway and WebSocket client, with their resources, telemetry, mock mode and test:smoke; .env is not read.
  • Over stdio: search and describe with the editor down, the ue://assets/actors/editor/selection resources, TLS to a remote editor, protocols 2024-11-05 and 2024-10-07.
🔧 Fixed
  • Crashes: Ability System actions on non-Actor Blueprints, creates or bakes over another class's asset, and validate_assets dataValidation with the Data Validation plugin off are refused.
  • run_benchmark measures frames, FPS and thread times (it measured nothing).
  • Builds and links on UE 5.0-5.8, Windows and Mac: every file compiles on its own, Smart Objects and State Trees need no experimental engine module, and older Apple clang and UE 5.8's unreachable-code rule pass.
  • Small fixes: RayTraced GI refused from 5.4, runtime_report filters, retry hints, reads return 0 and false, a material instance can be another's parent, list_tracks answers again, a thumbnail's outputPath is a PNG on every 5.x, set_bone_key keys a sequence's last frame, create_primitive says its meshes have no collision, configure_landscape_splines shapes the terrain where its points are, placement warnings judge a spline mesh road where its segments lie and an actor on a landscape by its surface, undo takes back a new primitive mesh.
  • Removals take exact components, keep assets others use (through a chain of uses too) and undo for tracks and keys.
  • Nothing is overwritten unasked: taken names and paths are refused, unsent fields kept, engine content never edited in place.
  • Family variants enforce their own requirements, shown by describe.
  • Renders honour renderTimeoutMs; save_all and restart_editor wait for them.
  • An open editor dialog answers calls EDITOR_MODAL_ACTIVE with its title instead of a timeout.
  • Viewport screenshots wait for streaming and name video memory over budget.
  • Property writes refuse deprecated properties, restart placed Niagara effects, take object references and run components' own change handling.
  • Placement checks count simulated bodies and player starts; fix_coplanar handles several neighbours.
  • Animation and effects: whole track names, partial set_bone_key, key times across frame rates, curve read-back; Niagara creates refuse taken names.
  • Undo covers spawns, transforms, properties, meshes, landscape, foliage, sequences and more.
  • Finds stop at limit (default 200) and say how many matched.
  • Replies say what happened, failed saves and compiles included.
  • Successes that did nothing now act (foliage, water, AI, Play audio, splines, landscape and more).
  • manage_effect cleanup needs destructive consent and a filter, is one undo step and refuses Play; debug shapes clear through debug_shape.
  • Object paths work in open_level, load and add_sublevel; relative .t3d exports land in the project.
  • Git: any commit message is safe (a quote could inject options); checkout and submit list skipped paths.
  • /mcp discovery: search rows, describe by domain and family, cursor and param suggestions.
  • A disabled tool's nextCall turns it back on (configure enable_tools).
🔄 Dependencies
  • @modelcontextprotocol/sdk, ws and zod left the runtime (zod stays for the record build).

Release v0.6.0-beta-f

Release v0.6.0-beta-f Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 16 Oct 15:22

Note

Beta. Published as a semver prerelease (0.6.0-beta-f) under the npm beta dist-tag, so npm install keeps serving the newest stable release, 0.5.30. This section is everything on dev since the v0.6.0-beta-e tag, written from the code diff.

✨ Added
  • Gameplay in one call: add_behaviour, with a shortcut action for each kind (add_health, add_patrol and so on), writes health, damage on touch, pickups, sprint, shooting, chase, patrol, turrets, stomps, explosives, moving and falling platforms, player controls, respawn with checkpoints, goals, launch pads, teleporters, a time limit, spawners, dashes, HUD bars and counters, hints and game over into an Actor Blueprint as plain engine nodes.
  • Blueprint authoring: Blueprint Interfaces (implement_interface), timelines (edit_timeline), Bind Event, Switch on Enum, animation-graph nodes by class, a Math Expression's expression in batches, and remove_variable variableNames.
  • Reading graphs: find_functions finds a function by plain words, get_graph_details filter finds what reads or moves a variable, unusedOnly lists nodes that do nothing, and compile takes a folder.
  • Graph checks: edits and compiles flag pure nodes and random values read twice, timers that name nothing or restart every frame, waits inside loops, values changed in place, event values read after a wait, and sounds that never end on play-and-forget nodes.
  • Packaging: package_project executableName names the game's .exe, launch_build map smoke-runs one level, and enable_plugin targets keeps an editor-only plugin out of the packaged game.
  • Project setup: configure_rendering (Lumen, shadows, anti-aliasing, ray tracing, MegaLights) and create_cpp_class.
  • Many actors at once: spawn batch repeat (rows and grids) and properties, set_transform and edit_component with actorNames, set_folder and spawn folder and tags, and spawns and moves that name z-fighting faces.
  • Motion and physics: motion reads that wait for a spawn (spawnOf), name surfaces passed through and actors overlapped, and return what the game logged, as step_frame now does; analyze_animation, collision presets and per-channel responses, physical materials and apply_damage.
  • Effects and audio: several parameters on a placed effect at once, add_emitter from another system, get_niagara_info for one emitter, list_metasound_nodes and box-shaped sound zones.
  • More reads: get_property objectPaths, a child Blueprint's own values for its parent's components, widget_list texts and parent panels, describe_view actors, get_widget_animation, screenshot field of view, video memory over budget and validate_assets materialUsage.
  • More edits: skeletal mesh import onto a skeleton, a dynamic mesh started from a static mesh (meshPath), mesh_materials assetPaths, SDF relativeTo, input replaceKey and play unpauseGame.
🔄 Changed
  • The editor plugin is now EngineWire (was McpAutomationBridge), shipped as EngineWire-plugin-<version>.zip, with file names short enough for Fab; settings saved under the old name still load.
  • A Blueprint graph batch is all or nothing: a failed step undoes the steps before it, and a step works in the graph of the node it names.
  • Leaner replies: each actor is named once, runtime_report reports the session unless asked for more, get_component_details sends values only for propertyNames or detailed, spawn batches past 20 items list only failures, and transforms read as typed.
  • The HTTP door takes capability IDs as the stdio door does.
  • Widget templates take their content: a shop its items and currency, a dialog its text and buttons.
🔧 Fixed
  • Replies say what really happened: a widget rename refuses a taken name, a clean compile drops stale warnings, a Shipping smoke run says it wrote no log, compiler warnings reach the receipt, stop answers once play has ended, a link through a conversion node reads connected, and a self-destroying spawn, a destroyed actor, a game's own pause, a paused world, a minimized editor, a non-realtime screenshot and a widget holding the keyboard focus are named.
  • Blueprint graphs: enums keep their type, array pins say so, pins show a literal only where the graph reads one, call nodes take the names the editor shows, nodes made without a position find a free slot, refused nodes leave nothing, misspelled types are refused, child Blueprints edit their parent's components, and Math Expressions take a unary minus and &&/|| comparisons and still compile in a duplicated Blueprint.
  • Property values: Map, Set, array, float and Blueprint struct values read and write as sent, actor arrays take labels, a mesh component's StaticMesh goes through its setter, unknown variable names are refused, and set_project_setting resolves a class name and refuses an unknown one.
  • Gameplay: projectiles hit, hurt and expire, weapons fire, doors, chests, switches and triggers work, apply_force pushes, placed props simulate, batch references land before BeginPlay, and a mouse move reaches a running game.
  • Input and motion: a key held across stepped frames counts game time and its reply says it is still down, remove_mapping names the action's own actionMappings, a scripted mover reads its real velocity, and a reloaded level reads as levelChanged.
  • Placement checks: no false off-map, sunk or floating reports for floors over pits, enclosures, stacked items, stretched parts and complex collision.
  • Niagara: edits act only on the emitter the caller named (#658), create actions refuse a folder that cannot be a package (#668), modules go where their dependencies hold and are named as their inputs are, a duplicated system plays at once, and placed-effect parameters are typed and fully bindable.
  • Assets: deletes count what they removed, a filtered list names only matching folders, imports name the mesh, Fab adds a pack's Unreal build, dead material branches list as orphaned, and material usage flags are saved.
  • Geometry: appended faces face outwards, arrays are no longer one copy short, and SDF shapes mesh at the resolution asked for.
  • Editor: a level load answers once the level has settled, console_command keeps lines logged on other threads, and native replies write negative zero as 0, which strict clients rejected (#662).
  • Builds: the plugin declares Win64, Mac and Linux, so an Android build skips it (#666), and it compiles again with Fab's UE 5.0-5.4 toolchains.
  • Undo, search and guidance: volume and single-actor component edits are one undo step, more plain requests are found, a refusal names the parameter a stray key belongs to, a reply keeps the typed and project paths it quotes, and every pointer in record text names a real action.
🗑️ Removed
  • Level-call aliases that were always refused: open_level path and assetPath, focus_actor name, manage_level delete path and levelPaths, duplicate_level targetPath, and set_metadata and validate_level assetPath. Send levelPath, actorName or destinationPath.
⚠️ Migration
  • Plugin rename: delete Plugins/McpAutomationBridge and unpack EngineWire-plugin-<version>.zip in its place; a .uproject that names McpAutomationBridge should name EngineWire. Settings under [/Script/McpAutomationBridge.McpAutomationBridgeSettings] still load while [/Script/EngineWire.EngineWireSettings] is empty.
  • get_component_details lists property values only with propertyNames or detailed: true.
  • resume answers GAME_PAUSED when the game paused itself (a pause menu or a title screen); pass unpauseGame: true to lift that pause too.
  • A spawn whose actor destroys itself answers SPAWNED_THEN_DESTROYED, and property reads and writes refuse a destroyed actor.
  • Reply fields: remove_mapping and a per-mapping set_modifier return actionMappings (was mappingCount and mappings), and set_camera returns requestedLocation and requestedRotation only when the pose was not taken.
🔄 Dependencies
  • GitHub Actions only: release-drafter 7.10.0, CodeQL 4.38.3 and setup-node 7.1.0 (#670-#674). No npm package changed.
👥 Contributors
  • @SoloGorilla for making Niagara edits act only on the emitter the caller named (#658), and Niagara create actions refuse a folder that cannot be a package instead of reporting success with nothing saved (#668).
  • @Robin7-hub-code for reporting the negative zero that strict MCP clients rejected (#661), and @HeCPDF for reporting the Android packaging failure (#665).
📊 Change Statistics
Metric Count
Diff range v0.6.0-beta-e..v0.6.0-beta-f
Commits 212, the version bump and this release entry included
Files changed 1,976 (1,950 hand-written, not counting generated files or line-ending-only changes)
Insertions / deletions 34,715 / 11,597 (hand-written: 26,407 / 10,792)
Capability records 416
Callable {tool, action} pairs 1,554
C++ domain directories 55

Release v0.6.0-beta-e

Release v0.6.0-beta-e Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 09 Oct 15:32

Note

Beta. Published as a semver prerelease (0.6.0-beta-e) under the npm beta dist-tag, so npm install keeps serving the newest stable release, 0.5.30. This section is everything on dev since the v0.6.0-beta-d tag, written from the code diff.

✨ Added
  • Control Rig graphs: animation_physics edit_control_rig adds, wires, sets and removes rig units and adds or removes bones, nulls and controls (or imports a skeleton's bones), one edit or a batch, then compiles; get_control_rig reads the graph and hierarchy; list_rig_units finds units by name or category.
🛡️ Security
  • The proxy's tool-list cache moved out of the shared temp dir to the user's cache folder (%LOCALAPPDATA%, $XDG_CACHE_HOME or ~/.cache, under unreal-mcp), written owner-only, so another account cannot plant the tool list and instructions it serves.
  • package-plugin.mjs refuses an argument holding ", %, ! or a line break before it reaches cmd.exe, and runs it with delayed expansion off.
  • source-map-js 1.2.2 (development only) clears GHSA-68fv-2mgg-jv7q.
📊 Change Statistics
Metric Count
Diff range v0.6.0-beta-d..v0.6.0-beta-e
Commits 4, the version bump and this release entry included
Files changed 36 (27 hand-written, not counting generated files or line-ending-only changes)
Insertions / deletions 1,868 / 95 (hand-written: 800 / 33)
Capability records 405
Callable {tool, action} pairs 1,518
C++ domain directories 55

Release v0.6.0-beta-d

Release v0.6.0-beta-d Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 09 Oct 14:45

Note

Beta. Published as a semver prerelease (0.6.0-beta-d) under the npm beta dist-tag, so npm install keeps serving the newest stable release, 0.5.30. This section is everything on dev since the v0.6.0-beta-c tag, written from the code diff.

✨ Added
  • inspect.describe_view: what the level viewport's camera sees, as text: each actor's share of the frame, screen box, brightness and distance, plus the background share and the frame's brightness.
  • inspect.capture_passes: aligned id (PNG with a legend), depth (EXR, cm) and normal (PNG) passes of the view, each with a summary.
  • inspect.check_mesh: whether a static mesh is closed, with its holes, seams, inside-out and degenerate faces, parts, area and volume.
  • inspect.raycast_world: up to 256 line traces against collision, each with its hit point, normal, distance, actor and component.
  • manage_asset export_mesh: a static or skeletal mesh (or an animation) to glb, gltf, fbx or obj, without the exporters' dialogs.
  • process_asset mesh_collision: box, sphere, capsule, complex or no collision on a static mesh asset and its placed copies.
  • manage_geometry split_mesh: one static mesh per separate part or material slot, with dryRun.
  • Material Parameter Collections: create_material kind: parameter_collection and the CollectionParameter node.
  • system_control list_save_games / edit_save_game: read, edit, create and delete SaveGame slots.
  • play_sound measure: plays a sound and answers how loud it was (peakDb, averageDb, silent, a wave's wavePeakDb).
  • get_transform motion points: bone, socket or component positions per sample with ground heights and planted and slip stats; samples carry rotation.
  • validate_assets dataValidation runs the project's and engine's validators; run_build tests answers each test's result.
  • manage_tools get_task_result: reads a call that answered "still running"; the stdio server also answers so at 27 s.
  • get_stats worldTickMs: the game world's own tick time while Play In Editor runs.
  • add_function overrides a parent function such as OnKeyDown; add_variable exposeOnSpawn.
  • set_property objectPaths writes one value on many objects, and watch samples the written property by default; call_actor_function componentName calls a component's function.
  • A Blueprint compile warns about a sound played at a location with no attenuation.
  • query_asset text finds graph nodes by their title.
  • Widgets: add_widget_tree material paints an Image or Border; add_animation_keyframe keys writes a whole animation in one call.
  • Audio: create_metasound oneShot: false makes a continuous source; distance attenuation sets air absorption (lpf*) and reads back what it holds.
  • Sequences: add_keyframe keys, set_section, key interpolation and lookAt, remove_keyframe frames, particle keys (particleKey) and Niagara moduleEnabled.
  • Movie renders capture gameplay (gameModeOverride: level, a ui pass, audioOutput), take renderTimeoutMs, and create_render_job control: remove clears jobs.
  • advance_simulation reset previews an effect at an exact age, and the reply gives its age and complete.
🔄 Changed
  • Lean replies on both transports: no log-only fields or repeated values; batches list only steps with something to say; a screenshot's bytes travel once over stdio.
  • describe states where a call runs: the calls that test a running game list pie and simulate; Niagara activate, deactivate and reset work in the level editor too.
  • Vector arrays coerce only when complete and numeric: two numbers no longer become {x, y} with a default z; rotation arrays read [pitch, yaw, roll].
  • A missing parameter names the keys sent in its place, and a reply names what ran when a call used another name.
🛡️ Security
🔧 Fixed
  • Blueprint graphs: batches call custom events they create, check expressions before any step and name an unknown edit; math expressions name what is wrong and the pins they made.
  • Pins and nodes: connect_pins grows Sequence, Make Array and Switch on Int to the named pin, matches names without spaces and warns on a second Target object; create_node makes FlipFlop, DoOnce, DoN, Gate, typed GetAllActorsOfClass and native Break/Make nodes.
  • Blueprint assets: an unknown parent class is refused; class defaults reach placed actors and derived Blueprints; a removed root promotes its children; SCS adds say where a component went and what it set.
  • Properties: writes go through component setters, fail when put back, reach subobject owners and say whether they saved; markDirty: false stays clean; paths reach components by name and any mount; bools answer without b; struct reads keep zero fields.
  • Actors in a running game: delete and delete_by_tag remove them, call_actor_function reaches the GameInstance, role names work in every lookup, spawns keep their mesh, and spawn_batch variables land before BeginPlay.
  • Placement: a moved actor is solid where it stands; checks skip triggers, bodiless parts and invisible volumes and treat water as a surface; fix_coplanar parts a flush row in one pass; collision changes hold on placed copies; floaters float.
  • Lists and reads: list reads struct members and near skips debug and editor-only bounds; multi-property reads keep dotted paths apart; the mesh view follows a placed actor; a missing asset reads as not found.
  • Widgets: create by widgetPath, a tree root fills its canvas, a removed widget frees its names, new animations play from the graph at once, a key on an occupied frame replaces it, and previews show what the game shows.
  • Input: simulated keys reach a focused menu button and release on time while paused; widget input warns when a minimized editor holds widgets still.
  • Materials: enum settings take the Details panel's names and are checked before anything is made; Custom node pins wire like any node's; compile errors come after the shaders compile; batch steps take nodeKind; set_material_parameter says whether it saved.
  • Niagara: static switches read and set, standalone ribbons draw, renderer and mesh materials get their usage flags, objects support undo, bindings link the input, linked inputs show their source, parameter writes answer success, and autoActivate: false stays off.
  • Audio: MetaSound edits are heard at once and batches check classes and pins first and save once; placed sounds play in game; attenuation shapes take the radius on every axis; measure reads a wave's own level.
  • Sequences: keys land as authored (sections span the range, auto tangents, Visibility tracks, transform defaults from the actor); play and pause seek with startTime; skeletal tracks bind the root mesh; spawnables make their own template; full-path create and duplicate save.
  • Renders and retargets: a hung render frees the queue; add_render_pass names what it added; retargets keep pelvis motion and create_ik_rig builds from a mesh.
  • Captures: screenshots after a camera move, full-window captures and captures right after an edit show the current state.
  • Editor: console commands reach the running game; reflected calls run in the editor world; a restored window stays up; step_frame names its speed; paused motion runs end at once and startWhen reads component properties; read_log livecoding reads this editor.
  • Search and receipts: text search finds assets picked on pins and keeps to its paths; graph lookup names the reader for non-Blueprint assets; Enhanced Input, foliage, folder moves, legacy mappings and deletes name what they changed; save_all names what it left.
  • Environment: water bodies come out complete with varied waves; create_sdf names a too-thin shape; spline reads give both point spaces; create_primitive warns about a taken label.
  • Timing: Fab library and media waits count real time; an accepted file delete counts as done; a refused call's text summary no longer reads success: true.
  • Builds: the plugin compiles again on UE 5.0-5.4, on Fab's MSVC and clang toolchains, and without the Geometry Script plugin.
👥 Contributors
  • @SoloGorilla for stopping the gateway from making partial or non-numeric vectors out of arrays (#657).
📊 Change Statistics
Metric Count
Diff range v0.6.0-beta-c..v0.6.0-beta-d
Commits 171, the version bump and this release entry included
Files changed 467 (447 hand-written, not counting generated files or line-ending-only changes)
Insertions / deletions 19,964 / 4,034 (hand-written: 13,982 / 2,601)
Capability records 402
Callable {tool, action} pairs 1,515
C++ domain directories 55

Release v0.6.0-beta-c

Release v0.6.0-beta-c Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Oct 15:44

Note

Beta. Published as a semver prerelease (0.6.0-beta-c) under the npm beta dist-tag, so npm install keeps serving the newest stable release, 0.5.30. This section is everything on dev since the v0.6.0-beta-b tag, written from the code diff.

Important

🔍 The editor checks its own work, and long calls stay alive

Spawns, Blueprint component edits and mesh conversions measure where the result landed and name what is sunk, buried, floating or z-fighting; sample_motion plays and times a game over game time without the OS cursor; and a call that runs past the client's time limit answers that it is still running instead of failing. New one-call authoring covers smooth SDF shapes, polygon cages, text textures, whole widget layouts, palettes of material instances and several properties at once; Epic's 5.8 editor toolsets run behind the gateway's scopes and consent, and Fab imports run in the background. Contract changes are listed under ⚠️ Migration.

✨ Added
  • server/discover answers on both transports. The MCP 2026-07-28 discovery method (missing, it failed six conformance checks in #614) returns the protocol versions initialize negotiates, the same capabilities, instructions and server identity, and an hour-long public cache hint, with no session or handshake. The 2026-07-28 revision itself is not served, so a client on it falls back to initialize.
  • Epic's 5.8 editor toolsets run through the gateway, behind its scopes and consent. control_editor.list_editor_toolsets lists the tools of Epic's Toolset Registry (StateTree, PCG, GAS, Niagara, UMG, MVVM and more, as their plugins are enabled), each with an effect judged from its name, or returns one tool's input schema (toolName). call_editor_tool runs one and answers with its output; a tool named for deleting or resetting is refused with DESTRUCTIVE_EDITOR_TOOL and runs through call_editor_tool_destructive (destructive scope, elevated consent), and a tool that would run scripts or console code is never called (EDITOR_TOOL_BLOCKED), nor is any tool of ConfigSettingsToolset, which writes any settings section, this bridge's own included (project settings stay on system_control). Before 5.8 they answer EDITOR_TOOLSETS_UNAVAILABLE.
  • inspect.raycast_mesh finds a mesh's surface. Up to 256 rays at a static mesh asset in its own local space answer with the point each one meets, the surface normal (facing back along the ray), the material slot and the rotation a decal needs to print upright there, from the source triangles (full detail on a Nanite mesh), with no placed actor or collision. A part, print or decal can be put exactly on a curved surface.
  • Text becomes a texture. create_texture with kind: "text" (create_text_texture) draws words with any Font asset and face (fontFamily, typeface, default Roboto Bold), letterSpacing, justification and padding, at the largest font size whose lines (letter spacing included) fit the texture, in color over backgroundColor (default transparent, so the alpha channel is the text mask). The reply lists the font's faces and the pixel box the letters cover; a face the font lacks is refused with the faces it has.
  • A palette of material instances takes one consent. create_material_instance instances (up to 64 {name, parentMaterial, savePath, parameters, save}) makes each one as a single call would, with the call's own parentMaterial, savePath and save as every entry's defaults; the reply lists each under instances with created, and the call fails naming any that were not made. Seven instances of one parent took seven describes and seven consents. Retuning them is one consent too: set_material_parameter assets (up to 64 {assetPath, parameters} or {assetPath, parameterName, value}) writes each as a single call would and the receipt lists every instance it changed.
  • A whole widget layout is one call. add_panel_widget widgetKind: widget_tree builds a nested tree of panels, borders, text, images and bars with their looks (size, face, letter spacing, outline and shadow on text; rounded corners and an outline on a border) and their slots, refuses an unknown field instead of ignoring it, and lists every widget it made. A HUD cost an add call per widget and a style call per look.
  • Every material slot of an actor in one call. set_material materials puts entry i into slot i ("" leaves a slot alone) in one undo step: an SDF part with six slots took six calls.
  • Several properties in one call. set_property properties ({name or dotted path: value}) writes each as a single call would and reports them under properties; get_property propertyNames reads several, answering properties and naming any that do not resolve under missingProperties.
  • spawn takes a mesh path alone. The handler placed a mesh actor for a bare meshPath, but the schema refused the call without a class.
  • A server and plugin from different releases say so, and name the fix. The plugin reports its version in the bridge handshake; when it is not the server's (or a plugin too old to report one), the server logs a warning and every failed execute carries versionMismatch: both versions, the release page of the matching plugin, and the npx -y unreal-engine-mcp-server@<plugin version> pin that matches the server to the plugin instead.
  • unreal-engine-mcp-server proxy keeps a native session across editor restarts. A stdio server in front of the plugin's /mcp (UNREAL_MCP_URL, default http://127.0.0.1:3000/mcp): while the editor is down every call answers NOT_CONNECTED, and the first call after it is back opens a new upstream session and runs, so the client never reconnects. It sends the capability token the stdio server would find, relays progress notifications as they stream, and caches the editor's tool list and instructions (UNREAL_MCP_PROXY_CACHE) for sessions that start before the editor.
  • control_actor.sample_motion watches an actor over game time in PIE. It returns location, velocity and propertyNames ("Component.Property" ok) every intervalSeconds for durationSeconds (max 30 s, 400 samples) with start, end, min, max and endedBecause; the editor world gives NOT_SIMULATING. inputs (up to 32 {key, atSeconds, holdSeconds}) press keys at game-time offsets, startWhen holds the run until another actor's property takes a value, maxRealSeconds (default 25, max 50) caps wall time, and a start that never fires, keys that did not move the pawn or a slow frame rate warn. A minimized editor is shown without focus for the run (windowRestored) with the background CPU throttle off, then minimized again. Also get_transform's motion read.
  • control_actor.list finds actors by place and kind. near ([x, y, z] or {x, y, z}) sorts nearest first, then smaller bounds, and adds each row's distance to the actor's bounds; radius keeps those within it. tag, className (class or any parent, by name or path, _C optional) and folder (that folder and below, "(none)" for the root) filter, and every filter combines with summary and with each other; propertyNames reads "Component.Property", unmatched names under missingProperties.
  • set_transform moves by an offset. offset [dx, dy, dz], also per item in actors, moves relative to the current location; with location it is refused with INVALID_ARGUMENT.
  • control_actor.rename renames an actor. It sets the label (INVALID_NAME if refused) and, with renameObject, the object name too (made valid and unique); the reply has oldLabel, label, oldObjectName, objectName and actorPath.
  • audit_placement finds z-fighting and fix_coplanar fixes it. audit_placement reports coplanarFaces per finding (kind coplanar, byKind.coplanar, read from each mesh's LOD0 triangles, also for actors tagged mcp.placement.ok) and takes kinds to limit problem kinds. fix_coplanar moves each face distance (0.1-20, default 1) in up to 4 passes as one undo step (dryRun is one pass); parts of one Blueprint are fixed in the Blueprint itself (compiled and saved, every placed copy fixed; blueprintsFixed), and skipped holds only the pairs left alone, with a reason.
  • componentNames narrows a component listing on control_actor get_components, inspect get_components and inspect_cdo: it keeps the named components (case-insensitive) and lists misses under missingComponents. A mesh component's row names its staticMesh and materials on a world actor too, not only in a Blueprint.
  • Every spawn says where the actor ended up. spawn, spawn_blueprint and each spawn_batch row report what set_transform reports: placementWarning (sunk into the surface under it, floating, intersecting other actors or nothing below), groundZ, groundClearance, overlappingActors and suggestedLocation, where a mesh whose pivot is its bounds centre spawned half under the floor behind a bare success (spawn_blueprint never checked, and spawn_batch dropped what each item's spawn found). A batch measures each item after its tags, so mcp.placement.ok silences a deliberate placement; placementWarnings counts the flagged items (a warning is not a failure) and report: "failures" keeps them. suggestedLocation is the actor's own location raised by the depth it is sunk, whatever its pivot (it was the bounds centre, which moved a corner-pivot mesh sideways).
  • Blueprint parts that sink into each other are named. Every edit_scs edit that adds, moves, re-meshes, re-parents or sets a property on a component measures the mesh parts it touched against the rest of the actor, on their real triangles in a preview instance (the level is untouched), and returns partWarnings with a warnings sentence each: kind buried (inside...
Read more

Release v0.6.0-beta-b

Release v0.6.0-beta-b Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 25 Sep 14:15

Note

Beta. Published as a semver prerelease (0.6.0-beta-b) under the npm beta dist-tag, so npm install keeps serving the newest stable release, 0.5.30. This section is everything on dev since the v0.6.0-beta-a tag, written from the code diff.

Important

🧱 Fewer calls, honest replies, and a game you can drive from the tool

Batch forms turn a Blueprint graph, a material graph, a MetaSound, a whole level layout or a row of actors into one call each, and a Play-In-Editor game can be played, timed and inspected without the OS cursor. A long list of handlers that answered success for work they never did now report what actually happened. Two small contract changes are listed under ⚠️ Migration.

✨ Added

One call instead of many

  • manage_blueprint.build_graph — runs up to 200 graph edits (create_node, connect_pins, set_pin_default_value, set_node_property, create_reroute_node, add_variable) through the ordinary single-step handlers, with their replies captured instead of sent. A step names its node with id and later steps refer to it as "$id"; from/to take "$id.pin" shorthand; a create step can carry pinDefaults; "$entry" is the graph's own function-entry node (a Construction Script's start). Nodes without a position fill a grid to the right of the existing graph, and an overlap is retried at the guard's own suggestion. Before any step runs, every function and variable a step names is resolved, so a misspelled name fails the batch with nothing applied; any other failure stops at that step and returns the node ids of the steps that were applied. The Blueprint compiles and saves once at the end.
  • manage_material_authoring.build_material_graph — adds a material's nodes, wires them and sets blend mode, shading model, domain and two-sidedness in one consented call, then recompiles and saves once through compile_material and reports its errors. Only additive edits are batched; deleting and disconnecting keep their own consent. Auto-placed nodes are stacked by their reported height, so tall vector-parameter swatches no longer overlap.
  • manage_audio.build_metasound — MetaSound add_node, connect, set_default, add_input and add_output steps in one call, with the same $id aliases.
  • control_actor.spawn_batch — up to 500 actors per call, each item merged over shared defaults and run through the ordinary spawn path (mesh, class or Blueprint, per-item variables, folder, tags). A failed item is reported and the rest still spawn; report: "failures" returns counts and failed items only.
  • List forms of existing actions, each item running the single-item path and each reported, with a batch that fails naming only the items that did not apply: set_transform actors (each with its own location, rotation or scale, as {x,y,z} objects or arrays), set_blueprint_variables actors (each with its own values), set_material and add_tag actorNames, delete_by_tag tags, remove_scs_component componentNames, set_variable_metadata variableNames, set_material_parameter and create_material_instance parameters, and remove_foliage areas. One consent grant covers the whole list.
  • An omitted fold selector is inferred — a call that leaves out a family's selector (for example nodeKind) but sends parameters that only one variant declares now runs that variant on both gateways; parameters pointing at different variants still run the default.

Reading what is already there

  • control_actor.list pages with offset and nextOffset, carries each actor's location, rotation and scale, reads named variables on every row with propertyNames (a name the class lacks is listed under missingProperties instead of vanishing), and with summary: true counts actors by class, tag and outliner folder instead of listing them.
  • inspect_graph filters and pages a large graph, and a pin's links name the linked node's title.
  • get_blueprint with propertyName returns just that value (read off the class default object when the property is inherited) instead of the whole summary; Blueprint get_components gives each component's location, rotation, scale, visibility, mesh, materials and whether it is authored, inherited or native.
  • get_niagara_info lists every emitter's module inputs with their current values.
  • manage_asset.list narrows by name with a string filter (it used to be ignored).
  • system_control.read_log returns the recent editor log without a subscription, filtered by text, category or minimum verbosity. source reads the UnrealBuildTool log of the last compile (where "Live coding failed" keeps its compiler errors, with the file name kept readable), the Live Coding console log, or a previous editor run's log; runsBack reaches past the last restart, and logFile names the file read. console_command returns the lines the command logged.

Driving and testing a running game

  • simulate_input drives Enhanced Input — inputAction (an asset path), value and holdSeconds inject the action itself, which a raw key never reaches; the reply names injectedAction. Holds are measured in game seconds and all end when the editor shuts down; key_tap presses and releases, keeping the key down for at least two game frames. widget_list names every live UMG widget in a PIE session and widget_click presses a Button, toggles a CheckBox or sets a Slider by name, without moving the OS cursor or taking focus.
  • The game clock acts on the running game — set_game_speed and set_fixed_delta_time apply to the PIE world (a fixed step is switched off again when play stops), and step_frame steps the requested number of frames in the plugin and reports them.
  • control_editor.restore_editor_window restores a minimized editor window without activating it, and by default turns off the background CPU throttle that pins a minimized editor's PIE at about 3 fps.
  • control_editor.restart_editor relaunches the editor on the same project, with validateOnly, delaySeconds, and discardUnsaved (unsaved packages are refused otherwise).
  • system_control.launch_build smoke-runs the game that package_project produced (offscreen by default, 5 to 120 seconds) and package_status reports the maps it loaded, its error count and the tail of its log.

Authoring

  • MetaHuman Creator in manage_character — metahuman_status, create_metahuman, rig_metahuman (Epic's cloud auto-rig, non-blocking by default), build_metahuman and export_metahuman (geometry, materials or DNA).
  • Sequencer keys — list_track_keys and remove_keyframe in manage_sequence, resolving tracks the same way every other track edit does; onlyJob is honoured when a Movie Render Queue render starts.
  • Animation Blueprints — set_transition_rules builds the transition condition from conditionVariable, conditionComparison and conditionValue; delete_transition removes one; transitions honour crossfadeDuration (alias blendTime), priorityOrder, automaticRule and bidirectional; add_state wires the state's entry and, with an animation, a sequence player into its result.
  • animation_physics.skin_mesh_to_skeleton skins a static mesh (or a donor skeletal mesh) to a skeleton through GeometryScripting; retargeting builds real IK Rig definitions and a retarget pipeline.
  • Blueprint graphs — set_node_property reaches a node's reflected asset and object fields; add_variable stores object defaults and keeps isPublic: false.
  • Fab is driven through its own API by reflection: the tab opens without the web page, an already-open Fab window is reused, listings are claimed before download, and obj and usdz downloads are accepted alongside unreal-engine, gltf, glb and fbx.
  • FBX animation import — manage_asset.import brings in the animation an FBX carries as an AnimSequence on a named skeleton.

Finding the right capability

  • Plain phrasings rank the intended capability first, native search honours the effect and tool filters, and create_material, material instances, widget clicks and map cooking each have search topics of their own.
🔧 Changed
  • Native requests are timed from their last progress, not their start. While the game thread is alive, every open request gets a "still working" progress notification every 20 seconds, MaxLifetimeSeconds still ends a request that never answers, and progress percentages never go backwards. Long imports and builds are no longer killed and reported as failures.
  • A too-large result names the parameters that would narrow it on the native gateway as well, and summary counts as a narrowing parameter on both.
  • A world edit made during Play-In-Editor carries a receipt warning that it landed in the PIE world and is discarded when play stops.
  • Text summaries pair a record's display name with its path, asset path, object path or id.
  • The .env file is read from MCP_ENV_FILE when it is set, otherwise from the package root, otherwise from the working directory, using Node's own loader.
  • A client's capability profile comes from the capabilities the client declares, not from a lookup table of known client names.
  • The console command policy compiles each rule's pattern once instead of on every command, and every command-queue failure is logged.
  • Lighting and geometry records declare what their handlers read — configure_lumen takes quality, indirectLightingIntensity and bounces; configure_shadows takes the shadow quality, cascade, distance, contact, ray-traced and virtual-shadow-map settings; configure_exposure takes method; enable_volumetric_fog honours enabled: false; the geometry primitives take their own dimensions (box height...
Read more

Release v0.6.0-beta-a

Release v0.6.0-beta-a Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 18 Sep 14:03

Note

Beta. Published as a semver prerelease (0.6.0-beta-a) under the npm beta dist-tag, so npm install keeps serving the newest stable release. 0.6.0a is not valid semver — npm, the bump-version workflow and the version-consistency gate all reject it — so the release spells the beta out.

Important

🚪 Single-Tool Gateway, Capability Catalog & Full Source Reorganization

Everything on this branch since the 0.5.30 tag: the permanent cutover to a single public unreal gateway tool, a hand-authored capability catalog that now generates both the TypeScript and the C++ contract surfaces, cinematics/render/replay automation, and a top-to-bottom split of the TypeScript handlers and the C++ plugin into per-domain modules.
This release contains breaking changes — see the ⚠️ Migration section below.

✨ Added
  • Folded capability families — a record can stand for a whole family of bridge actions. routing.dispatchBy maps one selector parameter's value to the existing handler action, and every former name stays callable as a folded legacy pair whose pins supply the value it implied; both gateways apply the same two steps (pins before validation, action after it). The folds are data (records/folds/<parent>.folds.ts, applied by records/shared/fold.ts): 244 fold families across 22 parents (222 of the resulting records dispatch through a routing.dispatchBy selector — 221 of them from the fold specs, plus manage_level_structure.create_volume, whose volumeClass dispatch is authored on the record itself — and the remaining 23 families are pure-alias folds; 246 of the 380 records carry at least one folded legacy pair, across 1,166 pinned pairs) take the catalog from 1,379 authored pre-fold action entries to 380 records, while all 1,549 {tool, action} pairs (every shipped name plus 164 new family primaries) still resolve, describe and execute, the normalization audit total is unchanged at 1,341, and a fold whose primary is one of its members keeps the selector optional so every pre-fold call is unchanged. A consent grant may name the capability by any name it answers to (canonical id, alias, or a folded tool.action pair) on both doors; the native completion pool completes the old names too; the search index counts a name once per identifier field and stops re-scoring folded member ids as aliases. Per-action contract tests pin the authored, unfolded records (records/unfolded.ts), and the integration suites derive one twin case per family (tests/fold-twins.mjs) so every advertised primary and selector is exercised.

Gateway surface

  • unreal gateway tool with four operations — search, describe, execute, and configure are now the entire public MCP surface on both transports. The routing engine lives in src/server/gateway/ (26 TypeScript modules) and covers capability indexing and views, search filters, browse/capability describe modes, execute resolve → validate → policy → authorization → dispatch, receipt context, schema normalization, guidance, and availability probing.
  • Execute idempotency ledger — repeat execute calls carrying the same idempotency key return the original receipt instead of re-running the action. Mirrored on both sides of the bridge: TypeScript (src/server/gateway/idempotency-ledger.ts, cap 1024) and C++ (Private/Foundation/McpIdempotencyLedger, cap 4096).
  • Compensation receipts and capability principals — Private/Foundation/McpCompensationReceipt and McpCapabilityPrincipal/McpCapabilityAuthorization give the plugin its own authorization identity rather than trusting the caller's claim.
  • DIRECT_TOOL_CALL_REMOVED migration receipt — a direct tools/call on a canonical parent name returns a bounded, executable receipt whose nextCall re-runs the same request through the gateway.
  • Execute option validation and refusal — timeoutMs must be an integer in 1..600000 ms and idempotencyKey 1..128 characters — a malformed key previously bypassed the ledger entirely, so a retry re-ran the mutation with nothing reporting that dedup was off. preview is refused outright with UNSUPPORTED_PREVIEW (no dispatch path implements a dry run, and behavior.supportsPreview is deliberately not consulted, because honouring it would perform the real mutation and call it a preview), and an option that is accepted but not implemented (savePolicy, validationLevel, taskPreference) answers UNSUPPORTED_OPTION instead of being validated, echoed on a success receipt, and dropped. An expectedCatalogRevision that no longer matches answers STALE_STATE. A result that would exceed the transport budget is refused as RESULT_TOO_LARGE (100,000 characters, 6,000,000 for image-payload capabilities) on the failure path as well as the success path.
  • Bounded search — limit defaults to 12 and is capped at 25, a page is additionally held to maxBytes (default 24,576, floor 512, ceiling 262,144) by dropping whole trailing rows, and hasMore, truncated, truncationReason, nextCursor, coercions and budgetExceeded report exactly what happened: an argument that was clamped is named, a page that could not fit even one row answers budgetExceeded instead of returning an identical cursor forever, and a truncated page says why. A capability id or alias that collides in the index fails closed with GATEWAY_INDEX_CONFLICT rather than resolving to an arbitrary record.

Capability catalog and contract generation

  • Hand-authored capability records as the single source of truth — src/tools/catalog/capabilities/records/** holds 380 records across the 23 canonical parents, authored with buildCoreRecord() declaring deltas only. aggregate.ts hard-asserts the record count and throws on mismatch.
  • Generation pipeline — scripts/generate-canonical-registry.ts (+ the scripts/canonical-registry/ modules) emits the generated capability shards, the orchestration routing index, the docs action reference, and the C++ side: Private/MCP/Generated/ shards and McpGeneratedParentRegistry*. scripts/generate-gateway-manifest.ts (+ scripts/gateway-manifest/) emits src/gateway/gateway-manifest.generated.{ts,json} with content hashing and path policy.
  • New drift gates — registry:generate, registry:check, manifest:check, policy:generate, policy:check, normalization:check, normalization:audit, migration:check, primitives:check, security:check, eval:check, version:check, workflow:check.
  • Deterministic ordering helper — src/utils/serialization/ordering.ts provides byte-order comparison so generated shards are byte-identical across machines and locales (localeCompare is no longer used for ordering).

MCP protocol primitives

  • Resources, prompts, completions and progress — new src/server/mcp-primitives/ implements the primitive registry, wiring, handlers, notifications, catalog revision reader, and fallback pointers, with a prompt catalog and typed prompt errors, a completion provider (ranking, slots, sources, fixtures), and a progress reporter/token/sink registry.
  • MCP Tasks (2025-11-25) — a per-session bounded task store implementing the MCP SDK's own TaskStore contract, so tasks/get|list|cancel|result are auto-registered and reachable from the wire. It deliberately does not reuse the SDK's InMemoryTaskStore, which is unbounded, drives expiry off real setTimeout timers, and ignores sessionId entirely. Task checkpoints ride alongside it.
  • Resource subscriptions and revisions — a subscription store with a notification coalescer so bursts of editor changes collapse into one client notification, plus resource revision stamps for change detection.
  • Session capability profiles and configure state — a client profile store, a session capability profile and a session configure store model the gateway's configure operation and per-client capability negotiation. The session resolver is exercised by tests only — nothing in the stdio path installs one yet.
  • Elicitation decision policy — a decision policy (isSafeToElicit) that answers whether a field is safe to elicit. Elicitation itself is wired into the execute path: dispatchAndValidate() awaits maybeElicitMissingArgs(), which prefills only missing required primitive fields through the client's elicitation function, under a timeout and a missing-params fallback. It never elicits secrets, tokens, or credentials, and never a destructive-confirmation value. Mirrored natively for cross-transport parity.
  • Resource providers — new src/resources/ supplies capability resources, editor-state resources, knowledge resources, the resource catalog, read router, typed resource errors, and asset pagination.
  • Native primitive parity — the plugin gained matching Private/MCP/Primitives/, Resources/, Routing/, Execute/, Gateway/, and DynamicTools/ modules (task store and methods, subscription store, notification coalescer, completion pools and provider, prompt catalog/render/argument validation, client profile store, elicitation policy), audited by the primitives:check parity harness.
  • Protocol negotiation — support for 2025-11-25 plus the native transport's MCP-Protocol-Version header guard: a present-but-unsupported version is refused with HTTP 400, while an absent header derives from the session's negotiated version and otherwise falls back to the 2025-03-26 default. Native accepts the three modern versions; the TypeScript SDK additionally accepts two legacy ones, from the pinned SDK's own supported set rather than from code in this repository.
  • Bounded task store and progress — only search and describe may be task-augmented; any mutating operation, and any tool other than unreal, is refused with TASK_CHECKPOINT_REFUSED before any work runs. The per-session store is capped at 32 tasks w...
Read more

Release v0.5.30

Choose a tag to compare

@github-actions github-actions released this 05 Jun 10:29
b20b257

Important

🚀 Native MCP & Code-Backed Tool Parity Release

This release covers the v0.5.21 to 0.5.30 release diff, including the TypeScript MCP server, native bridge plugin, tests, scripts, docs, workflows, and dependency manifests. The summary below is based on code and test changes, not commit subjects alone.

✨ Added
  • Native MCP Streamable HTTP endpoint — added an opt-in in-plugin /mcp server with JSON-RPC 2.0 initialize/tools/list/tools/call handling, POST/GET/DELETE routing, Mcp-Session-Id session tracking, SSE tool-result streaming, progress notifications, persistent notification streams, notifications/tools/list_changed broadcasts, CORS handling, loopback-first binding, capability-token checks, and an editor status-bar indicator.
  • Self-describing native MCP tools — added C++ FMcpToolRegistry, FMcpSchemaBuilder, MCP_REGISTER_TOOL, canonical native tool filtering, cached schema generation, and native dynamic tool/category enablement for the 23 canonical parent tools.
  • PCG automation — added manage_pcg TypeScript/native schemas and handlers for graph/subgraph creation, PCG node aliases, pin connections, reflected node settings, component/world execution, partition grid configuration, save/overwrite behavior, and PCG plugin availability errors.
  • Environment systems automation — added build-environment coverage for heightmap import/export, landscape layer info/material/splines/LOD/streaming proxies, foliage type configuration/paint/remove flows, sky and volumetric-cloud setup, weather/wind/time-of-day systems, water bodies, water waves/material/collision, and buoyancy components.
  • Behavior Tree authoring and introspection — added add_subnode, root-sentinel decorators, decorator/service validation, subnode-aware lookup, FBlackboardKeySelector assignment, and get_tree runtime hierarchy serialization with root decorators, edge decorators, decorator ops, services, key properties, subtree references, and a success-with-null-root contract for graphless trees.
  • Blueprint, property, and inspection tools — added inspect_cdo, Class Default Object component/property export, SCS and inherited SCS component classification, typed Blueprint custom-event pins, Enhanced Input graph nodes, inherited variable/member-class graph node lookup, and property access for Blueprint-added SCS component templates.
  • Editor, world, and input capabilities — added full editor-window screenshots, game viewport screenshot routing, image content responses, simulated keyboard/mouse input aliases, active camera reporting, PIE runtime inspection, native get_current_level, actor material/view-target native actions, spawn scale support, and create-plane height handling.
  • Material, audio, animation, and system actions — added Material Function creation/editing/calls/info, FunctionInput/FunctionOutput graph support, source-effect chains and source-effect presets, force_rebuild_blend_space, legacy/per-key input mapping edits, project setting writes, native asset validation, and execute_python for inline or project-local Python files.
🛡️ Security
  • GraphQL attack surface removed — deleted the GraphQL server, schema/resolver/loaders, GraphQL docs, GraphQL unit tests, and direct GraphQL runtime dependencies.
  • Native MCP exposure controls — default native MCP binding stays loopback-only unless explicitly allowed; non-loopback hosts warn, sessions are validated, stale requests/streams are cleaned up, and native HTTP requests use explicit request-origin routing instead of socket inference.
  • Capability-token and dynamic-tool protections — native MCP validates X-MCP-Capability-Token when required, while both TypeScript and native dynamic tool managers protect manage_tools/inspect and protected categories from accidental disablement.
  • Python execution hardening — execute_python enforces code/file exclusivity, a 1 MB inline code limit, project-root path normalization, symlink escape checks, __file__ setup for file execution, temp-file cleanup, and direct PythonScriptPlugin execution.
  • Path, command, log, and workflow hardening — tightened UE path normalization, console-command validation, snapshot/log path handling, level save/load flows, image/log redaction, safe tmp/ cleanup, sync-script argument parsing, and GitHub Actions interpolation by moving untrusted values into environment variables.
🔧 Changed
  • Release metadata — updated package.json, package-lock.json, server.json, the src/index.ts fallback, and McpAutomationBridge.uplugin to 0.5.30.
  • Canonical TypeScript tool surface — kept the 23 parent tools but moved action lists into shared constants, grouped tools into core, world, gameplay, and utility, merged nested params into top-level arguments for constrained clients, centralized handler routing, and removed legacy per-domain tool files.
  • Dynamic tool listing — tools/list now checks known client support for tools.listChanged; dynamic clients can receive category-filtered tools, while clients without dynamic loading still see the full compatible tool surface.
  • Automation bridge lifecycle — refactored host/port parsing, multi-port WebSocket connection attempts, handshake metadata, request queueing, progress timeout extension, stale-progress detection, absolute timeout caps, rate/message-size boundaries, disconnect/error tracking, and image-payload redaction.
  • Native bridge runtime — split request dispatch out of the subsystem, added explicit ERequestOrigin, queued requests through the game thread, converted captured engine errors into failed responses, pumped GameThread tasks during native transport shutdown, and exposed native transport session/tool counts to UI.
  • Response and schema handling — improved response validation, summary text generation, image response content, scalar result promotion, safe JSON cleanup, schema reuse, action-specific parameter descriptions, and stricter error context on tool failures.
  • Plugin compatibility — updated bridge metadata for UE 5.8 Preview and added PythonScriptPlugin, StructUtils, Synthesis, and PCG plugin declarations where the new handlers need them.
  • Scripts and workflows — made smoke tests run through SDK InMemoryTransport, added native parity/parameter audit npm scripts, changed clean to remove tsconfig.tsbuildinfo, added Linux/macOS/Windows plugin packaging scripts, strengthened sync/cleanup scripts, and made CI/publish/release gates stricter.
🛠️ Fixed

Routing & Native Tool Parity

  • Fixed native/consolidated action routing for validation, audio creation, material graph pins, editor simulation, add_widget_child, get_current_level, AnimBP graph discovery, lighting, SCS edits, native actor/editor actions, exact action matching, and nested params payloads.

Blueprint, Graph & Property Handling

  • Fixed inherited UPROPERTY lookup for VariableGet/VariableSet with memberClass, stale K2Node_EnhancedInputAction title cache refresh, Blueprint SCS component introspection, SCS template get/set paths, typed custom-event pin reconstruction, transaction ordering, null pin checks, case-insensitive pin connections, graph allocation fallback, and Blueprint busy-state cleanup.

Editor, World & Gameplay Behavior

  • Fixed PIE/game viewport screenshots, full editor screenshot capture, simulated input dispatch, active camera view-state reporting, PIE runtime inspection, spawn scale application, plane height fields, landscape bounds fallback, prompt-save return codes, actor list response handling, editor/world handler stability, and native actor/editor contract alignment.

Asset, Level, Animation, Niagara & Audio

  • Fixed unloaded level info via AssetRegistry fallback, classNames-only recursive asset search, normalized level path validation, source audio persistence, source-effect routing, audio authoring saves, material expression aliases, material pin routing to main inputs, UMaterialFunction graph details, animation notify validation, BlendSpace grid rebuilds, Niagara crash paths, hollow getters, parameter aliases, FText and FText-array property serialization, and execute_python file mode/output capture.

Plugin Stability & Compatibility

  • Fixed native plugin compatibility across UE versions, macOS Clang audio literal builds, plugin package output detection, bridge socket/runtime handling, JSON key normalization, request telemetry, native MCP session validation, safe operations includes, handler review findings, and optional module/plugin availability paths.
🧪 Tests
  • Added/expanded Vitest coverage for automation bridge connection, handshake, message schema, request tracking, config defaults, resources, health/metrics services, response validation, command validation, log reading/redaction, safe JSON, type coercion, normalization, queues, elicitation, and consolidated handler routing.
  • Expanded MCP integration suites across core/world/gameplay/utility tools, including PCG, Behavior Tree subnodes/get-tree, networking/sessions/input, control-editor screenshots/input, actor list handling, audio/source effects, assets/material functions, Blueprints/SCS, levels, geometry, GAS, combat, inventory, interaction, sequence, environment, and system-control Python/project-setting flows.
  • Added static native MCP action parity auditing and strict parameter-combination auditing that compare TypeScript schemas, native C++ tool definitions, native canonical registration, and test coverage.
  • Hardened the custom test runner with richer assertions, captured variables, live/static reports, fake-success detection...
Read more