Skip to content

feat: add open prefab stage editor action#947

Open
jiajunfeng wants to merge 1 commit intoCoplayDev:betafrom
jiajunfeng:beta
Open

feat: add open prefab stage editor action#947
jiajunfeng wants to merge 1 commit intoCoplayDev:betafrom
jiajunfeng:beta

Conversation

@jiajunfeng
Copy link

@jiajunfeng jiajunfeng commented Mar 17, 2026

Summary

  • add manage_editor(action="open_prefab_stage") to open a prefab asset in Prefab Stage
  • expose the new action through the Python MCP tool surface and update prefab resource wording
  • add Python + Unity edit-mode coverage, including the missing Unity .meta file

Validation

  • cd Server && uv run pytest tests/test_manage_editor.py -q
  • rebuilt MCPForUnity/Editor/Tools/ManageEditor.cs successfully

Summary by Sourcery

Add support for opening Unity prefab stages via the manage_editor tool and document its usage.

New Features:

  • Introduce an open_prefab_stage action in the Unity ManageEditor tooling to open prefab assets in Prefab Stage with validation and structured responses.
  • Expose the open_prefab_stage action through the Python manage_editor MCP tool with prefab_path and backward-compatible path parameters for prefab selection.

Enhancements:

  • Update prefab-related resource documentation and tool references to route prefab stage UI transitions through manage_editor rather than manage_prefabs, clarifying responsibilities between tools.

Tests:

  • Add Unity edit-mode tests covering prefab stage open/close behavior and parameter validation for the new action.
  • Add Python tests ensuring the manage_editor tool surface exposes the new prefab path parameters and correctly forwards them to the Unity backend.

Summary by CodeRabbit

  • New Features

    • Added open_prefab_stage action to manage_editor to open prefabs in prefab-editing mode
    • New prefab_path (and compatibility alias path) parameters to target prefabs
    • Built-in validation to ensure safe, valid prefab paths
  • Documentation

    • Tools reference and API docs updated with open_prefab_stage usage
  • Tests

    • Unit tests and Unity editor tests added for prefab-stage workflows and parameter behavior

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Mar 17, 2026

Reviewer's Guide

Adds a new manage_editor action to open prefab assets in Prefab Stage, wires it through the Python MCP tool surface and documentation, and adds both Unity edit-mode and Python tests (plus missing meta file) to cover the new behavior.

Sequence diagram for manage_editor open_prefab_stage flow

sequenceDiagram
    actor User
    participant LLMClient
    participant ServerManageEditorTool
    participant UnityConnection
    participant UnityManageEditor
    participant AssetDatabase
    participant PrefabStageUtility

    User->>LLMClient: Request to edit prefab by path
    LLMClient->>ServerManageEditorTool: Call manage_editor action=open_prefab_stage prefab_path
    ServerManageEditorTool->>UnityConnection: async_send_command_with_retry action=open_prefab_stage prefabPath path
    UnityConnection->>UnityManageEditor: HandleCommand(params)

    UnityManageEditor->>UnityManageEditor: Extract action prefabPath path
    UnityManageEditor->>UnityManageEditor: Select case open_prefab_stage
    UnityManageEditor->>UnityManageEditor: OpenPrefabStage(prefabPath)

    UnityManageEditor->>UnityManageEditor: Validate prefabPath not empty
    UnityManageEditor->>UnityManageEditor: AssetPathUtility.SanitizeAssetPath
    UnityManageEditor->>UnityManageEditor: Check path under Assets and ends with .prefab

    UnityManageEditor->>AssetDatabase: LoadAssetAtPath GameObject
    AssetDatabase-->>UnityManageEditor: prefabAsset or null
    alt prefabAsset null
        UnityManageEditor-->>UnityConnection: ErrorResponse prefab asset not found
    else prefabAsset found
        UnityManageEditor->>AssetDatabase: OpenAsset prefabAsset
        AssetDatabase-->>UnityManageEditor: opened flag
        UnityManageEditor->>PrefabStageUtility: GetCurrentPrefabStage
        PrefabStageUtility-->>UnityManageEditor: prefabStage
        UnityManageEditor->>UnityManageEditor: Determine enteredPrefabStage
        alt not opened and not enteredPrefabStage
            UnityManageEditor-->>UnityConnection: ErrorResponse failed to open prefab stage
        else opened or enteredPrefabStage
            UnityManageEditor-->>UnityConnection: SuccessResponse with prefabPath openedPrefabPath rootName enteredPrefabStage
        end
    end

    UnityConnection-->>ServerManageEditorTool: Response payload
    ServerManageEditorTool-->>LLMClient: Forward response
    LLMClient-->>User: Report prefab editing state and details
Loading

Class diagram for updated ManageEditor prefab stage support

classDiagram
    class ManageEditor {
        +static object HandleCommand(JObject params)
        -static object OpenPrefabStage(string requestedPath)
        -static object ClosePrefabStage()
    }

    class AssetPathUtility {
        +static string SanitizeAssetPath(string requestedPath)
    }

    class ErrorResponse {
        +ErrorResponse(string message)
    }

    class SuccessResponse {
        +SuccessResponse(string message, object data)
    }

    class PrefabStageUtility {
        +static PrefabStage GetCurrentPrefabStage()
    }

    class PrefabStage {
        +string assetPath
        +GameObject prefabContentsRoot
    }

    class AssetDatabase {
        +static T LoadAssetAtPath~T~(string path)
        +static bool OpenAsset(Object asset)
    }

    class GameObject {
        +string name
    }

    ManageEditor ..> AssetPathUtility : uses
    ManageEditor ..> ErrorResponse : returns
    ManageEditor ..> SuccessResponse : returns
    ManageEditor ..> PrefabStageUtility : queries
    ManageEditor ..> PrefabStage : reads
    ManageEditor ..> AssetDatabase : loads and opens assets
    ManageEditor ..> GameObject : handles prefab assets
Loading

File-Level Changes

Change Details Files
Add Unity-side manage_editor support for opening prefab assets in Prefab Stage with validation and structured responses.
  • Introduce prefabPath/path parameter extraction in the command handler.
  • Add open_prefab_stage routing case alongside existing prefab stage actions.
  • Implement OpenPrefabStage with asset path sanitization, validation for Assets/ scope and .prefab extension, asset loading, prefab stage opening, and detailed success/error responses.
  • Update unknown-action error message to advertise the new action.
MCPForUnity/Editor/Tools/ManageEditor.cs
Expose open_prefab_stage through the Python manage_editor MCP tool interface and update prefab-related docs.
  • Extend manage_editor tool description and action Literal to include open_prefab_stage with semantics.
  • Add prefab_path and path parameters to the Python manage_editor function and forward them to Unity as prefabPath/path.
  • Update prefab API docs to point prefab stage operations to manage_editor instead of manage_prefabs and clarify roles of related tools.
  • Add an example manage_editor(open_prefab_stage, prefab_path=...) invocation to the tools reference.
Server/src/services/tools/manage_editor.py
Server/src/services/resources/prefab.py
unity-mcp-skill/references/tools-reference.md
Add tests to cover the new open_prefab_stage behavior and Python tool surface, including required Unity metadata.
  • Add Unity edit-mode tests verifying parameter requirements, non-prefab rejection, successful stage open/close with returned metadata, and support for the path alias.
  • Add Python tests to assert manage_editor exposes prefab_path/path parameters, that the tool description mentions open_prefab_stage, and that parameter forwarding to Unity is correct for both prefab_path and path.
  • Add the missing .meta file for the new Unity test script.
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageEditorPrefabStageTests.cs
Server/tests/test_manage_editor.py
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageEditorPrefabStageTests.cs.meta

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: be748bb0-5a74-464d-b904-f307c2eb4a28

📥 Commits

Reviewing files that changed from the base of the PR and between 9035584 and 9f911e4.

📒 Files selected for processing (7)
  • MCPForUnity/Editor/Tools/ManageEditor.cs
  • Server/src/services/resources/prefab.py
  • Server/src/services/tools/manage_editor.py
  • Server/tests/test_manage_editor.py
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageEditorPrefabStageTests.cs
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageEditorPrefabStageTests.cs.meta
  • unity-mcp-skill/references/tools-reference.md
✅ Files skipped from review due to trivial changes (1)
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageEditorPrefabStageTests.cs.meta
🚧 Files skipped from review as they are similar to previous changes (1)
  • Server/src/services/resources/prefab.py

📝 Walkthrough

Walkthrough

Adds an "open_prefab_stage" editor action and wiring to open a prefab in Unity's prefab-editing stage, including path validation and payload propagation; updates server tool surface, docs, and adds unit and Unity editor tests for the new workflow.

Changes

Cohort / File(s) Summary
Unity Editor Implementation
MCPForUnity/Editor/Tools/ManageEditor.cs
Adds handling for "open_prefab_stage", new OpenPrefabStage(string requestedPath) method with validation (non-empty, no traversal, starts with Assets/, ends with .prefab), loads asset and opens prefab stage, returns success/error response; adds using UnityEngine.
Server tool surface
Server/src/services/tools/manage_editor.py
Adds prefab_path and compatibility path parameters, extends action Literal to include open_prefab_stage/close_prefab_stage, validates conflicting inputs, and includes prefabPath / path in the command payload when provided.
Server docs
Server/src/services/resources/prefab.py
Rewrote documentation strings to indicate prefab stage UI transitions are handled via manage_editor instead of using the previous tool for stage operations.
Skill docs
unity-mcp-skill/references/tools-reference.md
Adds example/documentation entry for manage_editor(action="open_prefab_stage", prefab_path="...").
Python tests
Server/tests/test_manage_editor.py
Adds tests asserting new parameters (prefab_path, path) are present, description lists open_prefab_stage, and parameter mapping to Unity payload (prefab_pathprefabPath, path preserved as alias).
Unity editor tests
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageEditorPrefabStageTests.cs, ...cs.meta
Adds an EditMode test suite covering missing/invalid paths, opening prefab stage and returned metadata, closing stage, path alias behavior, and precedence of prefabPath over path; includes asset meta file.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Server
  participant UnityEditor

  Client->>Server: manage_editor(action="open_prefab_stage", prefab_path)
  Server->>UnityEditor: send command {"action":"open_prefab_stage", "params":{"prefabPath": "..."}}
  UnityEditor->>UnityEditor: validate & sanitize path
  UnityEditor->>UnityEditor: load prefab asset, open PrefabStage
  UnityEditor-->>Server: response { success, data:{prefabPath, openedPrefabPath, rootName, enteredPrefabStage} }
  Server-->>Client: forward response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

codex

Suggested reviewers

  • dsarno
  • justinpbarnett

Poem

🐇 I hopped through Assets, a path kept so neat,
I nudged the stage open with a tiny soft beat.
A prefab now waits with its root shining bright,
Edit and flourish beneath editor light! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding an open prefab stage editor action, which aligns directly with the core functionality being introduced across all modified files.
Description check ✅ Passed The PR description covers the key changes, type (new feature implied), specific modifications, validation steps, and testing; however, it does not follow the repository's template structure with explicit sections for Type of Change, Documentation Updates checklist, and Related Issues.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use OpenGrep to find security vulnerabilities and bugs across 17+ programming languages.

OpenGrep is compatible with Semgrep configurations. Add an opengrep.yml or semgrep.yml configuration file to your project to enable OpenGrep analysis.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="MCPForUnity/Editor/Tools/ManageEditor.cs" line_range="407" />
<code_context>
+                    return new ErrorResponse($"Prefab asset not found at '{sanitizedPath}'.");
+                }
+
+                bool opened = AssetDatabase.OpenAsset(prefabAsset);
+                var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
+                bool enteredStage = prefabStage != null
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider using prefab-stage-specific APIs instead of AssetDatabase.OpenAsset to guarantee entering prefab editing mode.

`AssetDatabase.OpenAsset(prefabAsset)` may only ping/select the asset or open it in an inspector depending on editor preferences, so `GetCurrentPrefabStage()` can still be null while `opened` is true. That means you may treat the operation as successful without actually entering prefab mode. To ensure the action truly opens the prefab stage, use the dedicated prefab stage APIs (e.g. `PrefabStageUtility.OpenPrefab`) and treat failure to enter a prefab stage as an error rather than relying on `OpenAsset`’s return value.
</issue_to_address>

### Comment 2
<location path="TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageEditorPrefabStageTests.cs" line_range="98" />
<code_context>
+        }
+
+        [Test]
+        public void OpenPrefabStage_AcceptsPathAlias()
+        {
+            string prefabPath = CreateTestPrefab("AliasRoot");
</code_context>
<issue_to_address>
**suggestion (testing):** Consider adding a test where both `prefabPath` and `path` are present in the request

Given `ManageEditor.HandleCommand` uses `prefabPath = p.Get("prefabPath") ?? p.Get("path")`, an extra test where both keys are present—and `prefabPath` is chosen—would explicitly verify and document that precedence behavior.

Suggested implementation:

```csharp
                Assert.IsTrue(result.Value<bool>("success"));

```

Please add the following new test method to `ManageEditorPrefabStageTests` (ideally directly after `OpenPrefabStage_AcceptsPathAlias`), at class scope:

```csharp
        [Test]
        public void OpenPrefabStage_PrefabPathTakesPrecedenceOverPath()
        {
            string prefabPath = CreateTestPrefab("PrefabPathRoot");
            string aliasPath = CreateTestPrefab("AliasPathRoot");

            try
            {
                var result = ToJObject(ManageEditor.HandleCommand(new JObject
                {
                    ["action"] = "open_prefab_stage",
                    ["prefabPath"] = prefabPath,
                    ["path"] = aliasPath
                }));

                Assert.IsTrue(result.Value<bool>("success"));

                var currentStage = PrefabStageUtility.GetCurrentPrefabStage();
                Assert.IsNotNull(currentStage, "Expected a prefab stage to be open.");
                Assert.AreEqual(
                    prefabPath,
                    currentStage.prefabAssetPath,
                    "prefabPath should take precedence over path when both are provided."
                );
            }
            finally
            {
                StageUtility.GoToMainStage();
                SafeDeleteAsset(prefabPath);
                SafeDeleteAsset(aliasPath);
            }
        }
```

Notes/assumptions:
- This mirrors the pattern from the surrounding tests: `CreateTestPrefab(...)`, `try/finally` with `StageUtility.GoToMainStage()` and `SafeDeleteAsset(...)`.
- `prefabAssetPath` on `PrefabStageUtility.GetCurrentPrefabStage()` is used as in other tests (if they use `assetPath` or another property, adjust accordingly to match existing conventions).
- Ensure necessary `using` directives (e.g., `UnityEditor.SceneManagement`) are already present; they likely are given existing tests use `PrefabStageUtility` and `StageUtility`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

}

[Test]
public void OpenPrefabStage_AcceptsPathAlias()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Consider adding a test where both prefabPath and path are present in the request

Given ManageEditor.HandleCommand uses prefabPath = p.Get("prefabPath") ?? p.Get("path"), an extra test where both keys are present—and prefabPath is chosen—would explicitly verify and document that precedence behavior.

Suggested implementation:

                Assert.IsTrue(result.Value<bool>("success"));

Please add the following new test method to ManageEditorPrefabStageTests (ideally directly after OpenPrefabStage_AcceptsPathAlias), at class scope:

        [Test]
        public void OpenPrefabStage_PrefabPathTakesPrecedenceOverPath()
        {
            string prefabPath = CreateTestPrefab("PrefabPathRoot");
            string aliasPath = CreateTestPrefab("AliasPathRoot");

            try
            {
                var result = ToJObject(ManageEditor.HandleCommand(new JObject
                {
                    ["action"] = "open_prefab_stage",
                    ["prefabPath"] = prefabPath,
                    ["path"] = aliasPath
                }));

                Assert.IsTrue(result.Value<bool>("success"));

                var currentStage = PrefabStageUtility.GetCurrentPrefabStage();
                Assert.IsNotNull(currentStage, "Expected a prefab stage to be open.");
                Assert.AreEqual(
                    prefabPath,
                    currentStage.prefabAssetPath,
                    "prefabPath should take precedence over path when both are provided."
                );
            }
            finally
            {
                StageUtility.GoToMainStage();
                SafeDeleteAsset(prefabPath);
                SafeDeleteAsset(aliasPath);
            }
        }

Notes/assumptions:

  • This mirrors the pattern from the surrounding tests: CreateTestPrefab(...), try/finally with StageUtility.GoToMainStage() and SafeDeleteAsset(...).
  • prefabAssetPath on PrefabStageUtility.GetCurrentPrefabStage() is used as in other tests (if they use assetPath or another property, adjust accordingly to match existing conventions).
  • Ensure necessary using directives (e.g., UnityEditor.SceneManagement) are already present; they likely are given existing tests use PrefabStageUtility and StageUtility.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Server/src/services/tools/manage_editor.py (1)

44-52: ⚠️ Potential issue | 🟡 Minor

Guard against conflicting prefab_path and path inputs.

If both are provided with different values, the payload forwards both and downstream resolution is implicit. Add an explicit conflict check and send only one key to avoid ambiguous behavior.

Suggested fix
-        params = {
-            "action": action,
-            "toolName": tool_name,
-            "tagName": tag_name,
-            "layerName": layer_name,
-            "prefabPath": prefab_path,
-            "path": path,
-        }
+        if prefab_path and path and prefab_path != path:
+            return {
+                "success": False,
+                "message": "Provide only one of prefab_path or path, or ensure both values match.",
+            }
+
+        params = {
+            "action": action,
+            "toolName": tool_name,
+            "tagName": tag_name,
+            "layerName": layer_name,
+        }
+        if prefab_path is not None:
+            params["prefabPath"] = prefab_path
+        elif path is not None:
+            params["path"] = path
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Server/src/services/tools/manage_editor.py` around lines 44 - 52, Detect when
both prefab_path and path are provided with different values before building
params in manage_editor.py: after the local variables (action, tool_name,
tag_name, layer_name, prefab_path, path) are set but before creating the params
dict, add an explicit conflict check that if prefab_path is not None and path is
not None and prefab_path != path, then raise a ValueError (or a custom
exception) explaining the conflict; otherwise proceed and include only the
provided key (prefab_path or path) in the params dict so the subsequent params =
{k: v for k, v in params.items() if v is not None} step does not send
ambiguous/contradictory inputs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@MCPForUnity/Editor/Tools/ManageEditor.cs`:
- Around line 417-427: The current handler returns a SuccessResponse before
prefab editing is actually entered (enteredPrefabStage may be false); change the
method in ManageEditor.cs so it does not return success until the prefabStage is
fully entered by implementing an EditorApplication.update polling loop with a
TaskCompletionSource (same pattern as RefreshUnity.cs): start opening the
prefab, create a TaskCompletionSource<bool>, subscribe a callback to
EditorApplication.update that checks prefabStage/enteredPrefabStage (and
prefabStage.prefabContentsRoot) until true, then set the TCS result, unsubscribe
the update handler, and only then construct and return the SuccessResponse
(include prefabPath, openedPrefabPath, rootName, enteredPrefabStage) to ensure
callers only see success after entry is confirmed.

---

Outside diff comments:
In `@Server/src/services/tools/manage_editor.py`:
- Around line 44-52: Detect when both prefab_path and path are provided with
different values before building params in manage_editor.py: after the local
variables (action, tool_name, tag_name, layer_name, prefab_path, path) are set
but before creating the params dict, add an explicit conflict check that if
prefab_path is not None and path is not None and prefab_path != path, then raise
a ValueError (or a custom exception) explaining the conflict; otherwise proceed
and include only the provided key (prefab_path or path) in the params dict so
the subsequent params = {k: v for k, v in params.items() if v is not None} step
does not send ambiguous/contradictory inputs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 80e98298-3755-4704-ad63-623491690196

📥 Commits

Reviewing files that changed from the base of the PR and between ec25df8 and 9035584.

📒 Files selected for processing (7)
  • MCPForUnity/Editor/Tools/ManageEditor.cs
  • Server/src/services/resources/prefab.py
  • Server/src/services/tools/manage_editor.py
  • Server/tests/test_manage_editor.py
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageEditorPrefabStageTests.cs
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageEditorPrefabStageTests.cs.meta
  • unity-mcp-skill/references/tools-reference.md

Comment on lines +417 to +427
return new SuccessResponse(
enteredStage
? $"Opened prefab stage for '{sanitizedPath}'."
: $"Requested prefab stage open for '{sanitizedPath}'. Unity may still be transitioning into prefab editing mode.",
new
{
prefabPath = sanitizedPath,
openedPrefabPath = enteredStage ? prefabStage.assetPath : sanitizedPath,
rootName = enteredStage && prefabStage.prefabContentsRoot != null ? prefabStage.prefabContentsRoot.name : prefabAsset.name,
enteredPrefabStage = enteredStage
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Do not return success before prefab stage entry is confirmed.

At Line 417, success is returned even when enteredPrefabStage is false (Line 420 message). That can break callers that issue immediate prefab-stage operations after a “successful” open.

Suggested fix
-                return new SuccessResponse(
-                    enteredStage
-                        ? $"Opened prefab stage for '{sanitizedPath}'."
-                        : $"Requested prefab stage open for '{sanitizedPath}'. Unity may still be transitioning into prefab editing mode.",
-                    new
-                    {
-                        prefabPath = sanitizedPath,
-                        openedPrefabPath = enteredStage ? prefabStage.assetPath : sanitizedPath,
-                        rootName = enteredStage && prefabStage.prefabContentsRoot != null ? prefabStage.prefabContentsRoot.name : prefabAsset.name,
-                        enteredPrefabStage = enteredStage
-                    }
-                );
+                if (!enteredStage)
+                {
+                    return new ErrorResponse(
+                        $"Failed to confirm prefab stage open for '{sanitizedPath}'."
+                    );
+                }
+
+                return new SuccessResponse(
+                    $"Opened prefab stage for '{sanitizedPath}'.",
+                    new
+                    {
+                        prefabPath = sanitizedPath,
+                        openedPrefabPath = prefabStage.assetPath,
+                        rootName = prefabStage.prefabContentsRoot != null ? prefabStage.prefabContentsRoot.name : prefabAsset.name,
+                        enteredPrefabStage = true
+                    }
+                );

As per coding guidelines, "C# async tool handlers must use EditorApplication.update polling with TaskCompletionSource pattern as shown in RefreshUnity.cs".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return new SuccessResponse(
enteredStage
? $"Opened prefab stage for '{sanitizedPath}'."
: $"Requested prefab stage open for '{sanitizedPath}'. Unity may still be transitioning into prefab editing mode.",
new
{
prefabPath = sanitizedPath,
openedPrefabPath = enteredStage ? prefabStage.assetPath : sanitizedPath,
rootName = enteredStage && prefabStage.prefabContentsRoot != null ? prefabStage.prefabContentsRoot.name : prefabAsset.name,
enteredPrefabStage = enteredStage
}
if (!enteredStage)
{
return new ErrorResponse(
$"Failed to confirm prefab stage open for '{sanitizedPath}'."
);
}
return new SuccessResponse(
$"Opened prefab stage for '{sanitizedPath}'.",
new
{
prefabPath = sanitizedPath,
openedPrefabPath = prefabStage.assetPath,
rootName = prefabStage.prefabContentsRoot != null ? prefabStage.prefabContentsRoot.name : prefabAsset.name,
enteredPrefabStage = true
}
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@MCPForUnity/Editor/Tools/ManageEditor.cs` around lines 417 - 427, The current
handler returns a SuccessResponse before prefab editing is actually entered
(enteredPrefabStage may be false); change the method in ManageEditor.cs so it
does not return success until the prefabStage is fully entered by implementing
an EditorApplication.update polling loop with a TaskCompletionSource (same
pattern as RefreshUnity.cs): start opening the prefab, create a
TaskCompletionSource<bool>, subscribe a callback to EditorApplication.update
that checks prefabStage/enteredPrefabStage (and prefabStage.prefabContentsRoot)
until true, then set the TCS result, unsubscribe the update handler, and only
then construct and return the SuccessResponse (include prefabPath,
openedPrefabPath, rootName, enteredPrefabStage) to ensure callers only see
success after entry is confirmed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant