Skip to content

Conversation

@Scriptwonder
Copy link
Collaborator

@Scriptwonder Scriptwonder commented Dec 2, 2025

  1. Fix the Original Roslyn Compilation Custom Tool to fit the V8 standard
  2. Add a new panel in the GUI to see and toggle/untoggle the tools. The toggle feature will be implemented in the future, right now, it's implemented here to discuss with the team if this is a good feature to add.
    2.5 Some details: It right now detects the tools under Packages/MCPForUnity/Editor/Tools as built-in, and other tools as custom tools. I am still wondering how to untoggle it, looking for helps if possible. (It is a good-to-have feature for custom tools at least)
  3. Add a few missing summaries in certain tools
    Here is the current visualization of the tool panel (everything in settings panel remains the same):
image CC'ing @msanatan and @dsarno here as you might be interested. I will let this one sit for a while and work on batching next.

* Update the .Bat file to include runtime folder
* Fix the inconsistent EditorPrefs variable so the GUI change on Script Validation could cause real change.
String to Int for consistency
Allows users to generate/compile codes during Playmode
Upload the unity_claude_skill that can be uploaded to Claude for a combo of unity-mcp-skill.
1. Fix Original Roslyn Compilation Custom Tool to fit the V8 standard
2. Add a new panel in the GUI to see and toggle/untoggle the tools. The toggle feature will be implemented in the future, right now its implemented here to discuss with the team if this is a good feature to add;
3. Add few missing summary in certain tools
Merge and use the previous PR's solution to solve the windows issue.
Fix the layout problem of manage_script in the panel
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

Walkthrough

This PR introduces a tool management and enablement system to the MCP For Unity editor window, adds tool discovery filtering with EditorPrefs persistence, refactors Roslyn runtime compilation to use new response types, and removes the Python runtime compilation tool module.

Changes

Cohort / File(s) Summary
Tool Management UI & Editor Window
MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs, MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.uxml, MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs.meta, MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.uxml.meta, MCPForUnity/Editor/Windows/Components/Tools.meta, MCPForUnity/Editor/Windows/Components/Common.uss, MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs, MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml, MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uss
New UI controller class for displaying and managing tools with per-tool toggles, categorization, and metadata rendering. Editor window refactored with tabbed panel layout (Settings/Tools), new window management helpers, and UXML/USS styling for tools section. Tab state and tool visibility persisted in EditorPrefs.
Tool Discovery & Preferences System
MCPForUnity/Editor/Services/IToolDiscoveryService.cs, MCPForUnity/Editor/Services/ToolDiscoveryService.cs, MCPForUnity/Editor/Constants/EditorPrefKeys.cs, MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs
Extended tool metadata with AssemblyName, AssetPath, IsBuiltIn fields. Added methods to retrieve enabled tools only, check/set per-tool enabled state with EditorPrefs persistence. Implemented built-in tool classification and XML summary extraction with caching. Transport client now registers only enabled tools.
Roslyn Runtime Compilation Refactoring
CustomTools/RoslynRuntimeCompilation/ManageRuntimeCompilation.cs, CustomTools/RoslynRuntimeCompilation/RoslynRuntime.md, CustomTools/RoslynRuntimeCompilation/runtime_compilation_tool.py
Replaced Response error/success wrappers with ErrorResponse/SuccessResponse types. Updated McpForUnityTool attribute with description. Simplified assembly name resolution and removed file path sanitization. Deleted documentation file and entire Python MCP tool module.
Documentation Updates
MCPForUnity/Editor/Tools/ExecuteMenuItem.cs, MCPForUnity/Editor/Tools/ManageScript.cs, MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
Added or enhanced XML documentation summaries and remarks blocks to public tool classes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

  • McpToolsSection.cs: New UI controller with dynamic tool categorization, enablement toggle binding, and state persistence logic requires careful review of UI state management and preference synchronization
  • ToolDiscoveryService.cs: Enhanced with caching, built-in tool classification heuristics, and XML summary extraction; verify cache invalidation strategy and path resolution reliability
  • MCPForUnityEditorWindow.cs: Multiple integration points (tab switching, panel loading, window lifecycle helpers); ensure UXML/USS loading error handling and EditorPrefs key consistency
  • ManageRuntimeCompilation.cs: Response type replacement throughout; verify all error paths correctly return ErrorResponse and success paths return SuccessResponse with expected fields
  • Removed runtime_compilation_tool.py: Entire Python module removal; verify no external dependencies or call sites are broken

Possibly related PRs

Suggested reviewers

  • dsarno
  • justinpbarnett

Poem

🐰 A toolbox grows in the editor's nest,
With toggles and tabs—we're putting it to the test!
Built-in or custom, they line up so fine,
While Roslyn compiles at runtime—how divine!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.45% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: fixing the Roslyn Custom Tool to conform to V8 standard and adding an inspection window (GUI panel) for tool management.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

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

🧹 Nitpick comments (7)
MCPForUnity/Editor/Windows/Components/Common.uss (1)

472-487: Dark theme overrides look good.

The color adjustments for .tool-tag, .tool-item, and descriptions ensure proper contrast in dark mode.

Minor: Line 487 has an extra blank line that could be removed for consistency.

MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs (1)

29-34: Consider adding null guard for root parameter.

If root is passed as null, Root.Q<T>() calls in CacheUIElements() will throw a NullReferenceException. Consider adding a guard clause.

 public McpToolsSection(VisualElement root)
 {
-    Root = root;
+    Root = root ?? throw new ArgumentNullException(nameof(root));
     CacheUIElements();
     RegisterCallbacks();
 }
MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs (3)

1-20: Remove duplicate using statements.

Lines 5-9 are duplicated at lines 15-19. Remove the duplicate declarations to improve code clarity.

Apply this diff to remove the duplicates:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
-using MCPForUnity.Editor.Helpers;
-using MCPForUnity.Editor.Services;
-using MCPForUnity.Editor.Windows.Components.ClientConfig;
-using MCPForUnity.Editor.Windows.Components.Connection;
-using MCPForUnity.Editor.Windows.Components.Settings;
 using UnityEditor;
 using UnityEditor.UIElements;
 using UnityEngine;
 using UnityEngine.UIElements;
 using MCPForUnity.Editor.Constants;
 using MCPForUnity.Editor.Helpers;
 using MCPForUnity.Editor.Services;
 using MCPForUnity.Editor.Windows.Components.Settings;
 using MCPForUnity.Editor.Windows.Components.Connection;
 using MCPForUnity.Editor.Windows.Components.ClientConfig;
 using MCPForUnity.Editor.Windows.Components.Tools;

48-88: Consolidate duplicate window-closing methods.

Both CloseAllWindows() (lines 48-55) and CloseAllOpenWindows() (lines 69-88) perform the same task. The latter has better error handling and is public. Consider removing CloseAllWindows() and using CloseAllOpenWindows() throughout, or make CloseAllWindows() delegate to the more robust implementation.

Apply this diff to consolidate:

-internal static void CloseAllWindows()
-{
-    var windows = OpenWindows.Where(window => window != null).ToArray();
-    foreach (var window in windows)
-    {
-        window.Close();
-    }
-}
-
 public static void ShowWindow()
 {
     var window = GetWindow<MCPForUnityEditorWindow>("MCP For Unity");
     window.minSize = new Vector2(500, 600);
 }

 // Helper to check and manage open windows from other classes
 public static bool HasAnyOpenWindow()
 {
     return OpenWindows.Count > 0;
 }

 public static void CloseAllOpenWindows()

267-336: Consider consistent visibility approach.

The code removes the "hidden" CSS class from panels (lines 272-273) but then uses DisplayStyle.None/Flex to control visibility (lines 324-329). This mixed approach could lead to style conflicts if the "hidden" class also modifies display properties. Consider using one consistent method (preferably DisplayStyle for programmatic control).

If the "hidden" class is not needed, remove lines 272-273:

 private void SetupTabs()
 {
     settingsTabToggle = rootVisualElement.Q<ToolbarToggle>("settings-tab");
     toolsTabToggle = rootVisualElement.Q<ToolbarToggle>("tools-tab");

-    settingsPanel?.RemoveFromClassList("hidden");
-    toolsPanel?.RemoveFromClassList("hidden");
-
     if (settingsTabToggle != null)
MCPForUnity/Editor/Services/ToolDiscoveryService.cs (2)

79-94: Optional: Remove redundant default parameter.

On Line 89, the default parameter true in EditorPrefs.GetBool(key, true) is never used because the call is inside an if (HasKey) block. Consider simplifying to EditorPrefs.GetBool(key).

 if (EditorPrefs.HasKey(key))
 {
-    return EditorPrefs.GetBool(key, true);
+    return EditorPrefs.GetBool(key);
 }

354-404: Consider a more robust approach for summary extraction.

The regex-based parsing of XML documentation comments is fragile and may fail with different code formatting styles:

  1. Line 378: The class-specific pattern assumes specific ordering of comments, attributes, and keywords
  2. Line 383: The fallback pattern matches any <summary> in the file, which could extract documentation from a different symbol
  3. Different indentation, attribute placement, or comment styles may not match the patterns

While the caching and error handling ensure failures won't break the system, you might see inconsistent results across different coding styles.

Consider alternatives:

  • Use Roslyn's syntax API to parse the source and extract the documentation comment structurally
  • Accept that XML doc comments are best-effort and document the expected format
  • Investigate Unity's built-in documentation extraction APIs (if available)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84f7b85 and 5bcb6f4.

📒 Files selected for processing (19)
  • CustomTools/RoslynRuntimeCompilation/ManageRuntimeCompilation.cs (17 hunks)
  • CustomTools/RoslynRuntimeCompilation/RoslynRuntime.md (0 hunks)
  • CustomTools/RoslynRuntimeCompilation/runtime_compilation_tool.py (0 hunks)
  • MCPForUnity/Editor/Constants/EditorPrefKeys.cs (1 hunks)
  • MCPForUnity/Editor/Services/IToolDiscoveryService.cs (2 hunks)
  • MCPForUnity/Editor/Services/ToolDiscoveryService.cs (6 hunks)
  • MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs (1 hunks)
  • MCPForUnity/Editor/Tools/ExecuteMenuItem.cs (1 hunks)
  • MCPForUnity/Editor/Tools/ManageScript.cs (2 hunks)
  • MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs (1 hunks)
  • MCPForUnity/Editor/Windows/Components/Common.uss (2 hunks)
  • MCPForUnity/Editor/Windows/Components/Tools.meta (1 hunks)
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs (1 hunks)
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs.meta (1 hunks)
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.uxml (1 hunks)
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.uxml.meta (1 hunks)
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs (6 hunks)
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uss (1 hunks)
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml (1 hunks)
💤 Files with no reviewable changes (2)
  • CustomTools/RoslynRuntimeCompilation/runtime_compilation_tool.py
  • CustomTools/RoslynRuntimeCompilation/RoslynRuntime.md
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: JohanHoltby
Repo: CoplayDev/unity-mcp PR: 309
File: MCPForUnity/Editor/Helpers/ServerInstaller.cs:478-508
Timestamp: 2025-10-13T13:41:00.086Z
Learning: In the MCPForUnityTools feature (MCPForUnity/Editor/Helpers/ServerInstaller.cs), the design intentionally forces users to have only one .py file per MCPForUnityTools folder to keep file tracking simple. Package-style tools (subdirectories with __init__.py) are not supported.
Learnt from: dsarno
Repo: CoplayDev/unity-mcp PR: 0
File: :0-0
Timestamp: 2025-09-03T16:00:55.839Z
Learning: ComponentResolver in UnityMcpBridge/Editor/Tools/ManageGameObject.cs is a nested static class within ManageGameObject, not a sibling type. The `using static MCPForUnity.Editor.Tools.ManageGameObject;` import is required to access ComponentResolver methods directly without the outer class qualifier.
📚 Learning: 2025-11-05T18:23:12.349Z
Learnt from: msanatan
Repo: CoplayDev/unity-mcp PR: 368
File: MCPForUnity/UnityMcpServer~/src/resources/menu_items.py:15-15
Timestamp: 2025-11-05T18:23:12.349Z
Learning: In Unity MCP, the `name` parameter in the `mcp_for_unity_resource` decorator is the external API name exposed to MCP clients (LLMs, AI agents). The command string passed to `async_send_command_with_retry` or `async_send_with_unity_instance` (e.g., "get_menu_items") is the internal command identifier that must match the C# side. These are decoupled, allowing external API naming to evolve independently of internal command routing.

Applied to files:

  • MCPForUnity/Editor/Constants/EditorPrefKeys.cs
📚 Learning: 2025-10-13T13:27:23.040Z
Learnt from: msanatan
Repo: CoplayDev/unity-mcp PR: 316
File: TestProjects/UnityMCPTests/Assets/Tests/EditMode/Resources.meta:1-8
Timestamp: 2025-10-13T13:27:23.040Z
Learning: UnityMcpBridge is a legacy project kept for backwards compatibility; MCPForUnity is the only active Unity plugin project. GUID collisions between UnityMcpBridge and MCPForUnity are acceptable.

Applied to files:

  • MCPForUnity/Editor/Constants/EditorPrefKeys.cs
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.uxml.meta
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs.meta
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs
  • MCPForUnity/Editor/Windows/Components/Tools.meta
  • MCPForUnity/Editor/Services/ToolDiscoveryService.cs
📚 Learning: 2025-10-13T13:41:00.086Z
Learnt from: JohanHoltby
Repo: CoplayDev/unity-mcp PR: 309
File: MCPForUnity/Editor/Helpers/ServerInstaller.cs:478-508
Timestamp: 2025-10-13T13:41:00.086Z
Learning: In the MCPForUnityTools feature (MCPForUnity/Editor/Helpers/ServerInstaller.cs), the design intentionally forces users to have only one .py file per MCPForUnityTools folder to keep file tracking simple. Package-style tools (subdirectories with __init__.py) are not supported.

Applied to files:

  • MCPForUnity/Editor/Constants/EditorPrefKeys.cs
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs.meta
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.uxml
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs
📚 Learning: 2025-10-03T22:11:46.002Z
Learnt from: msanatan
Repo: CoplayDev/unity-mcp PR: 301
File: docs/CUSTOM_TOOLS.md:54-62
Timestamp: 2025-10-03T22:11:46.002Z
Learning: In Unity MCP, the `description` parameter in the `mcp_for_unity_tool` decorator is technically optional but should always be included as a best practice. Without it, there's a higher chance that MCP clients will not parse the tool correctly. All Unity MCP tools should include the description in the decorator for compatibility.

Applied to files:

  • MCPForUnity/Editor/Constants/EditorPrefKeys.cs
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs.meta
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs
  • MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
  • MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.uxml
  • MCPForUnity/Editor/Tools/ExecuteMenuItem.cs
📚 Learning: 2025-09-03T16:00:55.839Z
Learnt from: dsarno
Repo: CoplayDev/unity-mcp PR: 0
File: :0-0
Timestamp: 2025-09-03T16:00:55.839Z
Learning: ComponentResolver in UnityMcpBridge/Editor/Tools/ManageGameObject.cs is a nested static class within ManageGameObject, not a sibling type. The `using static MCPForUnity.Editor.Tools.ManageGameObject;` import is required to access ComponentResolver methods directly without the outer class qualifier.

Applied to files:

  • MCPForUnity/Editor/Tools/ManageScript.cs
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs
  • CustomTools/RoslynRuntimeCompilation/ManageRuntimeCompilation.cs
  • MCPForUnity/Editor/Services/ToolDiscoveryService.cs
📚 Learning: 2025-09-04T01:01:11.927Z
Learnt from: dsarno
Repo: CoplayDev/unity-mcp PR: 260
File: UnityMcpBridge/UnityMcpServer~/src/server_version.txt:1-1
Timestamp: 2025-09-04T01:01:11.927Z
Learning: The UnityMcpBridge project is not maintaining changelogs yet, so don't suggest adding changelog entries for version bumps.

Applied to files:

  • MCPForUnity/Editor/Windows/Components/Tools.meta
🧬 Code graph analysis (5)
MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs (1)
MCPForUnity/Editor/Helpers/McpLog.cs (2)
  • McpLog (7-52)
  • Info (37-41)
MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs (3)
MCPForUnity/Editor/Services/IToolDiscoveryService.cs (7)
  • List (44-44)
  • List (54-54)
  • ToolMetadata (8-22)
  • ToolMetadata (49-49)
  • InvalidateCache (69-69)
  • IsToolEnabled (59-59)
  • SetToolEnabled (64-64)
MCPForUnity/Editor/Services/ToolDiscoveryService.cs (8)
  • List (19-60)
  • List (72-77)
  • List (159-193)
  • ToolMetadata (62-70)
  • ToolMetadata (107-157)
  • InvalidateCache (233-236)
  • IsToolEnabled (79-94)
  • SetToolEnabled (96-105)
MCPForUnity/Editor/Constants/EditorPrefKeys.cs (1)
  • EditorPrefKeys (7-43)
MCPForUnity/Editor/Services/IToolDiscoveryService.cs (2)
MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs (1)
  • IsBuiltIn (268-268)
MCPForUnity/Editor/Services/ToolDiscoveryService.cs (4)
  • ToolMetadata (62-70)
  • ToolMetadata (107-157)
  • IsToolEnabled (79-94)
  • SetToolEnabled (96-105)
MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs (3)
MCPForUnity/Editor/Clients/IMcpClientConfigurator.cs (1)
  • System (39-39)
MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs (4)
  • McpToolsSection (16-269)
  • McpToolsSection (29-34)
  • VisualElement (146-203)
  • Refresh (77-117)
MCPForUnity/Editor/Constants/EditorPrefKeys.cs (1)
  • EditorPrefKeys (7-43)
MCPForUnity/Editor/Services/ToolDiscoveryService.cs (3)
MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs (1)
  • IsBuiltIn (268-268)
MCPForUnity/Editor/Constants/EditorPrefKeys.cs (1)
  • EditorPrefKeys (7-43)
MCPForUnity/Editor/Helpers/AssetPathUtility.cs (2)
  • AssetPathUtility (15-201)
  • GetMcpPackageRootPath (41-80)
🔇 Additional comments (37)
MCPForUnity/Editor/Tools/ManageScript.cs (1)

27-53: LGTM! Documentation structure improved.

The change properly separates the brief summary from the detailed Roslyn installation guide by moving the installation instructions into a <remarks> section. This follows XML documentation best practices.

MCPForUnity/Editor/Tools/ExecuteMenuItem.cs (1)

10-12: LGTM! Documentation added.

The XML summary clearly describes the tool's purpose. This aligns with the PR objective to add missing documentation comments.

MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs (1)

13-15: LGTM! Documentation added.

The XML summary clearly describes the prefab management capabilities. Consistent with the documentation improvements across the PR.

MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uss (1)

1-37: LGTM! UI styling updated to support Tools panel.

The CSS changes introduce layout structure for the new tabbed Tools UI:

  • Root container updated with proper flex layout properties
  • New tab toolbar and panel styling added
  • Utility classes for visibility control

These styling changes align with the PR's goal to add a new GUI panel for tool management.

CustomTools/RoslynRuntimeCompilation/ManageRuntimeCompilation.cs (4)

20-26: LGTM! Documentation and attribute updated.

The class documentation now clearly describes the runtime compilation benefits (avoiding domain reload), and the McpForUnityTool attribute now includes the name and Description parameters, aligning with V8 standards.


145-230: LGTM! Response wrapper migration complete.

All error and success responses have been consistently updated to use ErrorResponse and SuccessResponse. The response structures maintain backward compatibility with the same data fields.


233-441: LGTM! Remaining response wrappers updated consistently.

All methods (ListLoadedAssemblies, GetAssemblyTypes, ExecuteWithRoslyn, history management methods) have been consistently updated to use the new response wrappers.


47-96: Assembly name sanitization is properly implemented and safe.

The assembly name handling includes comprehensive protection against path traversal:

  • SanitizeAssemblyFileName() removes invalid filename characters using Path.GetInvalidFileNameChars()
  • Path.GetFullPath() normalizes the path (line 110)
  • Explicit validation ensures the resolved DLL path stays within DynamicAssembliesPath via StartsWith() check (lines 112-114)
  • If sanitization results in an empty string, it falls back to a generated name with ticks

The migration to ErrorResponse/SuccessResponse is consistent throughout.

MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs (1)

420-466: LGTM! Tool registration now respects enabled/disabled state.

The change from DiscoverAllTools() to GetEnabledTools() ensures that only enabled tools are registered with the bridge, supporting the new tool toggle functionality mentioned in the PR objectives. The added log message provides helpful visibility into the registration process.

MCPForUnity/Editor/Windows/Components/Tools.meta (1)

1-8: LGTM! Unity meta file for new Tools folder.

The meta file has been properly updated to reflect the new Tools folder asset structure with folderAsset: yes and DefaultImporter. The GUID change is expected for new assets.

MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.uxml.meta (1)

1-10: LGTM! Unity meta file for UXML asset.

The meta file has been properly updated for the new McpToolsSection.uxml asset. The script reference with fileID: 13804 is Unity's standard UXML importer, which is correct for UXML assets.

MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs.meta (1)

1-11: LGTM!

Standard Unity meta file with a unique GUID for the new McpToolsSection.cs asset.

MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml (2)

4-7: LGTM!

Tab toolbar structure is clean. The mutual exclusivity of toggles (radio-button behavior) will be managed by the C# code in MCPForUnityEditorWindow.cs, which is appropriate.


8-13: LGTM!

The two-panel layout with tools-panel hidden by default is well-structured. The flex-grow: 1 ensures proper space allocation.

MCPForUnity/Editor/Constants/EditorPrefKeys.cs (1)

28-30: LGTM!

New preference keys follow the established naming convention and are correctly placed. The prefix keys appropriately end with . for tool name concatenation.

MCPForUnity/Editor/Windows/Components/Common.uss (1)

296-364: LGTM!

Well-structured CSS for the Tools section. Flexbox patterns are consistent with existing styles, and proper spacing/padding creates good visual hierarchy.

MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.uxml (1)

1-15: LGTM!

Clean UXML structure with appropriate placeholder text and action buttons. The note on line 11 provides helpful guidance about when tool changes take effect.

MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs (7)

16-26: LGTM!

Class fields are well-organized with appropriate inline initialization. The toolToggleMap dictionary provides efficient lookup for toggle synchronization.


46-72: Event handlers are not unsubscribed.

The clicked event handlers are registered but never unsubscribed. In editor windows where the section may be recreated (e.g., on domain reload), this could accumulate handlers. However, since Unity editor windows typically manage element lifecycle internally and the handlers reference the same instance, this is likely acceptable for the current use case.

If the McpToolsSection is intended to be disposed/recreated during the editor session, consider implementing IDisposable or a cleanup method to unregister callbacks.


77-117: LGTM!

The Refresh() method has solid logic flow: clear state, discover tools, update UI conditionally, and handle edge cases (no tools). The ordering strategy (built-in first, then alphabetical) provides good UX.


119-144: LGTM!

Category building with foldout state persistence via EditorPrefs is well-implemented. The count in the foldout title provides helpful context.


146-203: LGTM!

Tool row creation is comprehensive:

  • Toggle state correctly sourced from IsToolEnabled()
  • Informative tags for default state, output type, and polling
  • Conditional rendering for description and parameters
  • Parameter summary format is clear and user-friendly.

215-235: LGTM!

Bulk enable/disable logic is well-designed:

  • Uses SetValueWithoutNotify() to prevent recursive callbacks
  • Defers summary update until after all changes
  • Defensively handles edge case where toggle is missing from map.

237-269: LGTM!

Helper methods are clean and focused. The summary message clearly communicates the current enablement state to users.

MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs (2)

195-209: LGTM!

The Tools section loading includes proper error handling and defensive null checks. The warning message clearly indicates that tool configuration will be unavailable if the UXML fails to load.


338-356: LGTM!

The health check scheduling correctly uses EditorApplication.delayCall for Unity editor context and includes proper null checks before awaiting async operations.

MCPForUnity/Editor/Services/IToolDiscoveryService.cs (2)

16-21: LGTM!

The new properties (AssemblyName, AssetPath, IsBuiltIn) are well-named and appropriately typed to support tool discovery filtering and UI categorization.


51-64: LGTM!

The new interface methods are well-documented and provide a clean API for tool enablement management. The method signatures are straightforward and follow C# naming conventions.

MCPForUnity/Editor/Services/ToolDiscoveryService.cs (9)

5-6: LGTM!

The new using statements are appropriate for the regex-based summary extraction and EditorPrefs key management functionality.


16-17: LGTM!

The caching strategy is a good optimization to avoid repeated AssetDatabase queries and source code parsing.


47-47: LGTM!

The preference initialization call is appropriately placed during tool discovery. Since discovery results are cached, this initialization happens once per session unless the cache is explicitly invalidated.


72-77: LGTM!

The filtering logic is clean and correctly delegates to IsToolEnabled for the enablement check.


96-105: LGTM!

The method correctly persists the enabled state with appropriate null checks.


125-150: LGTM!

The metadata enrichment logic correctly populates the new fields (AssemblyName, AssetPath, IsBuiltIn) and appropriately overrides descriptions for built-in tools when XML summaries are available. The exception handling covers potential issues with assembly access.


263-266: LGTM!

The helper method provides a clean abstraction for constructing preference keys consistently.


268-316: LGTM!

The asset path resolution is well-implemented with caching and error handling. The search filter appropriately includes the type name when available to narrow results, and the loop correctly identifies the exact matching script by comparing types.


318-352: LGTM!

The dual classification strategy (asset path prefix and assembly name) provides robust built-in tool detection. The case-insensitive path comparison and path normalization ensure cross-platform compatibility.

Comment on lines +238 to +261
private void EnsurePreferenceInitialized(ToolMetadata metadata)
{
if (metadata == null || string.IsNullOrEmpty(metadata.Name))
{
return;
}

string key = GetToolPreferenceKey(metadata.Name);
if (!EditorPrefs.HasKey(key))
{
bool defaultValue = metadata.AutoRegister || metadata.IsBuiltIn;
EditorPrefs.SetBool(key, defaultValue);
return;
}

if (metadata.IsBuiltIn && !metadata.AutoRegister)
{
bool currentValue = EditorPrefs.GetBool(key, metadata.AutoRegister);
if (currentValue == metadata.AutoRegister)
{
EditorPrefs.SetBool(key, true);
}
}
}
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

Clarify the preference override logic for built-in tools.

The logic in lines 253-260 may override user preferences unexpectedly:

  1. Line 255 has a redundant default parameter (same issue as Line 89)
  2. The condition if (currentValue == metadata.AutoRegister) checks if the stored value is false (when AutoRegister is false), then forces it to true
  3. This doesn't distinguish between "user explicitly disabled the tool" vs "value was initialized to false based on AutoRegister"

If a user intentionally disables a built-in tool that has AutoRegister=false, this logic will silently re-enable it the next time tools are discovered. Consider whether this override is intended, or if it should only apply during a one-time migration scenario.

Potential approaches:

  • Add a version flag to EditorPrefs to run this migration only once
  • Skip this override if the tool is already in a disabled state
  • Document that built-in tools cannot be permanently disabled
🤖 Prompt for AI Agents
In MCPForUnity/Editor/Services/ToolDiscoveryService.cs around lines 238-261, the
preference-migration logic can unintentionally re-enable built-in tools users
explicitly disabled and uses a redundant default parameter; change the behavior
to use a one-time migration flag and remove the redundant default: implement an
EditorPrefs migration key (e.g., "ToolDiscovery_Migration_v1") to guard the
upgrade so the override runs only once, remove the unnecessary default argument
from EditorPrefs.GetBool, and only flip the stored value to true during that
guarded migration when metadata.IsBuiltIn && !metadata.AutoRegister and the
migration flag indicates the migration hasn't yet run; after performing the
migration set the migration flag so user preferences are not modified on
subsequent discoveries.

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