Repository navigation
Releases
v0.22.0 — Server self-identification, command rename, Windows scene-folder fix
No wire/protocol change (1.0.0, 102 catalog commands, 0 drift).
Added
- Server self-identification.
list_unity_instancesnow returnsserver: { package, version }alongside
registryDir, and the startup log (stderr) states the package, version and registry directory. This tells a client
which server package answered — an unrelated package shares theunity-editor-mcpbin name.
Changed
- The installed command is now
unity-editor-mcp-server(wasunity-editor-mcp, a name also installed by the
unrelatedunity-editor-mcpnpm package).npx @burakaydinofficial/unity-editor-mcpis unaffected. A global install
now providesunity-editor-mcp-server; configs that invoke the bareunity-editor-mcpcommand must switch to it (or
to thenpxform). - One shared
HostPlatformInfoOS detector for both the registry directory (InstanceRegistry) and path-containment
case handling (PathContainment), detected once per process.
Fixed
create_scene/save_scenefailed on Windows for a folder that didn't exist yet ("Failed to save scene").
Path.GetDirectoryNamereturns\-separated paths on Windows and the folder-creation loop split only on/, so
no folder was created. Paths are now normalized first (one shared helper for both commands). Regression tests
added; scene-test assertions now print the handler's error message on failure.- Registry-directory fallback parity: with
USERPROFILE/HOMEmissing or empty, the C# side fell back to"."
(and treated an empty value as set) while Node usesenv.X || homedir()— so in such environments the editor would
publish to a different directory than the server reads. C# now falls back to the OS user-profile directory too.
Parity tests on both sides. - The registry-directory log line added in 0.21.5 fired on every domain reload; it now logs once per editor session
(and again only if the directory changes).
Removed
- Dead Node
derivePort/DEFAULT_PORT_RANGE(the Node mirror of the editor's port derivation — only reachable
through the removedUNITY_PROJECT_PATHbranch). The editor keeps its ownDerivePortfor its listen port.
Notes
- Breaking for global installs that run the bare
unity-editor-mcpcommand — useunity-editor-mcp-serveror the
npx @burakaydinofficial/unity-editor-mcpform. Both packages ship at 0.22.0. The README install URL is now pinned to
the release tag.
v0.21.5 — Registry-directory parity (Windows editor visibility)
Fixes a discovery bug where a Unity editor could be invisible to the server on the same machine — with no error — and removes a dead configuration knob. No wire/protocol change (1.0.0, 102 catalog commands, 0 drift). Both packages ship at 0.21.5.
Fixed
- The editor and server could resolve DIFFERENT registry directories. Same rules, but different OS detection — C# via
RuntimeInformation.IsOSPlatform, Node viaprocess.platform. On a disagreement (e.g.RuntimeInformationmisreporting under Unity's Mono whileHOMEis set), the editor published its descriptor to a directory the server never read → invisible editor, no error. C# now detects the OS with primitives stable on every Unity Mono down to the 2019.4 floor (Path.DirectorySeparatorChar/Environment.OSVersion.Platform+ a macOS probe), and both sides are pinned to the SAME per-platform path by parity tests. - The editor now logs its resolved registry directory once at startup, so a mismatch is diagnosable instead of silent.
Removed
UNITY_PROJECT_PATHenv resolution — vestigial under the 3-tool surface (every editor is targeted per-call by an explicitinstance;list_unity_instancesenumerates the whole registry). Pinning it only risked collapsing the multi-editor design to one project.UNITY_PORTand the discovery registry are unchanged.- The README's "alternative (if globally installed)" bare-
unity-editor-mcpclient config (bin-name collision that can launch the wrong server). Usenpx @burakaydinofficial/unity-editor-mcp. - Dead internal helper
isSameHost.
Gates: Node 304/0, dotnet Core 157/0, compat-lint / meta-check / drift all green.
v0.21.4 - test-runner: refuse-while-compiling + self-identifying results
More production feedback on the test runner. No wire/protocol change (1.0.0, 102 catalog commands, 0 drift).
Fixed
run_testsrefuses while the editor is compiling/importing (COMPILING) instead of silently dropping the run — Unity fires noRunFinishedfor a run started mid-compile, which then wedged the state. Wait withget_compilation_state waitForIdle:true, then retry.
Added
- Self-identifying test results —
run_testsreturns arunId;get_test_resultsreturns the stored run'srunId+testMode, and (givenexpectRunId) arunIdMismatchflag, so a caller can no longer be silently served a different run's or mode's results.runId+ mode are journaled, surviving domain reloads and editor restarts.testCountnow reports the real matched count.
Most of the feedback was already fixed in 0.21.1–0.21.3 (stale runner, .meta pollution, compile-error visibility, results-across-reloads) or false positives (save_scene exists; get_editor_info exposes editor state). The deeper timeout item — calls landing during compile/reload — needs a wire-contract change (an editorState envelope + busy-fast-return), scoped in the roadmap and deferred as a deliberate design.
Full details in CHANGELOG.md.
v0.21.3 - test-runner reliability: self-healing run state + run-and-wait
Acts on production feedback that the test runner could get stuck reporting "running" when no run was active, with no way to stop or clear it. No wire/protocol change (1.0.0, 102 catalog commands, 0 drift).
Fixed
- Self-healing run state — the
IsRunningTestslatch could sticktrue(a missedRunFinished, an empty run, or an interrupted run) and persist across domain reloads, so a later agent saw "running" having started nothing. It's now reconciled against a callback heartbeat: believed only while set AND a Test Runner callback fired within ~5 min (progress, not duration — a long suite is never falsely cleared). Stale state self-heals. run_testswon't latch a no-match run (Unity may fire noRunFinishedfor an empty run — the likely wedge trigger); returns "nothing to run".cancel_testsclears a stuck EditMode state — a live run is still refused (pollget_test_results), but a stale latch is reset sorun_testsis unblocked;force:trueresets regardless. (Was: EditMode cancel refused unconditionally → unrecoverable wedge.)- Honest
get_test_resultsmessaging; realtestCount.
Added
get_test_resultswaitForCompletion— server-side poll until the run finishes, tolerating the domain-reload reconnect, returns the final results + summary (mirrors 0.21.2'sget_compilation_state waitForIdle).forceonrun_tests/cancel_tests.
Aside (feedback): save_scene + save_assets are the dedicated save tools — File/Save via execute_menu_item is a valid fallback, not the only way. Full details in CHANGELOG.md.
v0.21.2 - production-feedback polish: compile-wait, menu logs, composite writes
Acts on feedback from an agent using the tool in production. No wire/protocol change (1.0.0, 102 catalog commands, 0 drift).
get_compilation_statewaitForIdlemode — a server-side poll that blocks until compilation + asset import finish, reconnecting across the domain reload, so an agent canrefresh_assetsthen wait instead of sleep-and-hope. Compile errors are inmessages(type "Error") +errorCount— the reliable compile-error channel.execute_menu_itemnow returns the console output emitted during the invoke (logs+errorCount). Menu methods are void — no return value — but their logs are captured, so an agent needn't a separate read to see what a menu did.SerializedValue.Writerecurses into a nested[Serializable]struct/class, soset_serialized_propertiesandmodify_serialized_array insertcan set a composite element/field in one call (was "Generic is read-only").- CI
meta-check— fails if a package.cs/.asmdeflacks its.meta(a missing.metawarns in every consumer's editor).
Deferred with reasons (see CHANGELOG.md): compile-error console mapping (use get_compilation_state), batch asset creation (a generic batch deserves its own cycle), asset snapshot/rollback (git + Undo cover it).
v0.21.1 - SDK modernization, fresh-dimensions hardening, and Unity 6 CI
Maintenance release — no wire/protocol change (still 1.0.0, 102 catalog commands, 0 drift) and no new tool surface.
- Dependency modernization: the Node server's
@modelcontextprotocol/sdkgoes0.5.0→1.x(25 versions of drift). This clears the high-severity DNS-rebinding advisory that surfaced in consumers'npm audit— not reachable here (the server is stdio-only; that advisory only affects the HTTP/SSE transport), but it's real hygiene. Noserver.jschange was needed (the low-levelServer+StdioServerTransportAPI is stable across the jump).npm auditnow reports 0 vulnerabilities (runtime + dev). Node floor unchanged (>=18). - Security:
update_script/delete_scriptare now contained toAssets/(were gated on the whole project root — a raw local TCP client, which bypasses the Node layer, could otherwise overwrite.git/config,Packages/manifest.json, or any existing file).read_script→Assets/+Packages/. - Robustness (fresh-dimensions audit — scale / DoS / fuzzing): caps on
modify_serialized_arrayresize andcapture_screenshotdimensions (OOM),analyze_scene_contentstriangle counting without allocating index buffers, Roslyn fetch timeouts, an O(1) framing-recovery scan, and areapStaleTOCTOU re-verify. manage_packages: explicitupdateaction +packageIdvalidation.- CI: Unity 6.0 (
6000.0.78f1) added to the floor-matrix — now cold-compiles + EditMode-tests 2019.4 / 2020.3 / 2021.3 / 2022.3 / 6000.0 (297/297 green on Unity 6).
Full details in CHANGELOG.md.
v0.21.0 - live-editor E2E harness, reload-recovery, and an 8-round hardening campaign
The largest correctness pass in the fork's history.
- Live-editor E2E harness — drives the real client → server → editor chain to cover the ~two dozen tools untestable in the EditMode floor matrix (play mode, script recompile, refresh), verifying each effect through both the bridge and an independent channel.
- Bridge reload-recovery (ADR 0007) — the editor now force-closes accepted client sockets on domain reload, so the server reconnects in ~1s instead of hanging. This was latent for every client after any reload (incl. script recompile), not just the harness.
- ~125 verified faults from a pre-release bug hunt + an eight-round loop-until-dry adversarial audit (convergence 31 → 27 → 13 → 7 → 5 → 2 → 0). Classes: silent data corruption/loss (Flags-enum ordinal, material shape-vs-type, composite zero-fill, ambiguous-scenePath wrong-object), false success (ignored API results, no-ops, partial applies, play-mode-evaporated mutations), security (capture-screenshot write-anywhere, create_script into Library/, File/Exit menu, invoke-policy over-exposure), reads-with-side-effects (material/mesh getters instancing on a read), prefab-stage scene-scoping, partial-mutation-under-error, and Node connection/wire robustness (project-path verification, oversize-command handling, reconnect-loop resurrection, Roslyn crash-safety).
No protocol change (wire stays at 1.0.0, 102 catalog commands, 0 drift). CI-verified across 2019.4 / 2020.3 / 2021.3 / 2022.3 (298 EditMode + 152 dotnet + 314 server unit tests) with the full live suite green.
Full details in CHANGELOG.md.
v0.20.6 - second-review fixes + docs refresh
A deeper second code review (a 5-lens panel with adversarial verification, over the released 0.20.5) plus a full documentation audit. CI-green on Unity 2019.4 / 2020.3 / 2021.3 / 2022.3 (296 EditMode tests).
Fixed:
create_gameobjectcomponentsno longer reports a rejected component as added — adding e.g. a 2ndRigidbody(a[DisallowMultipleComponent]violation, where Unity returnsnullrather than throwing) now fails all-or-nothing (INVALID_STATE), with a regression test. (A real false-success the first review missed.)get_hierarchynow declares its emittedtruncated/maxNodesresult fields (the strict schema omitted them — the pagination signal was undiscoverable).set_active_scene'ssceneNameselector is now captured by the H5 audit log;manage_toolslost a dead cache branch.- Four aftermath tests that re-read through the same path as the handler now assert against a genuinely independent source.
Documentation: corrected the compatibility floor across CONTRIBUTING / the setup + floor-testing guides / the roadmap — they still claimed 2020.3 / C# 8; the floor is 2019.4 / C# 7.3, CI-verified on all four LTS versions. Plus refreshed command/test counts, marked completed roadmap/ADR items done, added the Roslyn code-intelligence sidecar to the roadmap, and documented the deferred round-7 friction (FR1/FR3/FR5) + known placeholders.
Same commit on npm (@burakaydinofficial/unity-editor-mcp) and OpenUPM (com.burakk.unity-editor-mcp). See the CHANGELOG for the full list.
v0.20.5 - dogfood rounds 6-8, reviewed, + aftermath test suite
Dogfood rounds 6–8, an independent code review (no Critical/High), and a rigorous aftermath sweep (34 mutating tools driven read→act→independent-re-read→assert, zero false-successes) — plus a deterministic aftermath EditMode test suite covering the whole testable-in-EditMode tool surface. 295 EditMode tests, CI-green on Unity 2019.4 / 2020.3 / 2021.3 / 2022.3.
New / improved: set_active_scene; create_gameobject components array (now declared in the catalog, so it's discoverable); multi-scene get_hierarchy / analyze_scene_contents (loadedScenes + per-root scene); inactive GameObjects reachable by path (no longer stranded when deactivated); serialization tools (inspect_serialized_object / set_serialized_properties / modify_serialized_array) see the open prefab stage.
Fixed: play_game refuses in -batchmode (was bricking the bridge); create_gameobject rejects an empty name; delete_gameobject returns NOT_FOUND on no match (was a 0-count "success"); manage_tools reports real installed package versions; set_active_scene verifies the effect (Unity's bool return is unreliable); set_serialized_properties / modify_serialized_array — componentType match scoping + force/CAS bypass.
Same commit on npm (@burakaydinofficial/unity-editor-mcp) and OpenUPM (com.burakk.unity-editor-mcp). See the CHANGELOG for the full list.
v0.20.4 — prefab-stage shadowing fix (npm + OpenUPM re-sync)
Re-sync release — brings npm and OpenUPM back in lockstep on the corrected code.
Fixes the prefab-stage same-name shadowing bug present in 0.20.3 (the Unity/C# half): the by-path GameObject
resolvers now resolve the open prefab stage first, so a same-named main-scene object can't shadow the stage
object during an in-stage add_component / modify_gameobject / delete_gameobject. Found by code review; guarded
by a [UnityTest]. CI-green on Unity 2019.4 / 2020.3 / 2021.3 / 2022.3.
(0.20.3 reached OpenUPM with this bug, and npm without a 0.20.3 at all; 0.20.4 is the same corrected commit on both
registries — 0.20.3 = b182bba, 0.20.4 = 056a99a everywhere.)