From 225b161e821d435327f9af96eb42ed2fcad65036 Mon Sep 17 00:00:00 2001
From: Shutong Wu <51266340+Scriptwonder@users.noreply.github.com>
Date: Sun, 1 Mar 2026 22:58:58 -0500
Subject: [PATCH 1/7] Initial update on tool list update
---
.claude/mcp.json | 12 +-
.claude/settings.json | 6 -
.gitignore | 6 +-
.../Editor/Services/IToolDiscoveryService.cs | 1 +
.../Editor/Services/ToolDiscoveryService.cs | 3 +-
.../Transports/WebSocketTransportClient.cs | 3 +-
.../Editor/Tools/Animation/ManageAnimation.cs | 2 +-
MCPForUnity/Editor/Tools/GetTestJob.cs | 2 +-
MCPForUnity/Editor/Tools/ManageScene.cs | 10 +
.../Editor/Tools/ManageScriptableObject.cs | 2 +-
MCPForUnity/Editor/Tools/ManageShader.cs | 2 +-
MCPForUnity/Editor/Tools/ManageTexture.cs | 2 +-
MCPForUnity/Editor/Tools/ManageUI.cs | 2 +-
.../Editor/Tools/McpForUnityToolAttribute.cs | 9 +
MCPForUnity/Editor/Tools/RunTests.cs | 2 +-
MCPForUnity/Editor/Tools/Vfx/ManageVFX.cs | 2 +-
.../Editor/Windows/Components/Common.uss | 9 +-
.../Components/Tools/McpToolsSection.cs | 129 ++++-
Server/pyproject.toml | 2 +-
Server/src/main.py | 22 +-
Server/src/services/custom_tool_service.py | 8 +-
Server/src/services/registry/__init__.py | 6 +
Server/src/services/registry/tool_registry.py | 52 ++
Server/src/services/resources/active_tool.py | 2 +-
Server/src/services/resources/custom_tools.py | 4 +-
Server/src/services/resources/editor_state.py | 6 +-
Server/src/services/resources/gameobject.py | 6 +-
Server/src/services/resources/layers.py | 2 +-
Server/src/services/resources/menu_items.py | 2 +-
Server/src/services/resources/prefab.py | 4 +-
Server/src/services/resources/prefab_stage.py | 2 +-
Server/src/services/resources/project_info.py | 2 +-
Server/src/services/resources/selection.py | 2 +-
Server/src/services/resources/tags.py | 2 +-
Server/src/services/resources/tests.py | 4 +-
Server/src/services/resources/tool_groups.py | 44 ++
.../src/services/resources/unity_instances.py | 4 +-
Server/src/services/resources/windows.py | 2 +-
Server/src/services/tools/__init__.py | 26 +-
Server/src/services/tools/batch_execute.py | 2 +-
.../services/tools/debug_request_context.py | 7 +-
.../src/services/tools/execute_custom_tool.py | 5 +-
.../src/services/tools/execute_menu_item.py | 2 +-
Server/src/services/tools/find_gameobjects.py | 2 +-
Server/src/services/tools/find_in_file.py | 2 +-
Server/src/services/tools/manage_animation.py | 3 +-
Server/src/services/tools/manage_asset.py | 2 +-
.../src/services/tools/manage_components.py | 2 +-
Server/src/services/tools/manage_editor.py | 2 +-
.../src/services/tools/manage_gameobject.py | 2 +-
Server/src/services/tools/manage_material.py | 2 +-
Server/src/services/tools/manage_prefabs.py | 2 +-
Server/src/services/tools/manage_scene.py | 2 +-
Server/src/services/tools/manage_script.py | 13 +-
.../tools/manage_scriptable_object.py | 3 +-
Server/src/services/tools/manage_shader.py | 3 +-
Server/src/services/tools/manage_texture.py | 3 +-
Server/src/services/tools/manage_tools.py | 112 ++++
Server/src/services/tools/manage_ui.py | 3 +-
Server/src/services/tools/manage_vfx.py | 3 +-
Server/src/services/tools/read_console.py | 2 +-
Server/src/services/tools/refresh_unity.py | 2 +-
Server/src/services/tools/run_tests.py | 6 +-
.../src/services/tools/script_apply_edits.py | 2 +-
.../src/services/tools/set_active_instance.py | 13 +-
Server/src/transport/plugin_hub.py | 87 ++-
.../transport/unity_instance_middleware.py | 58 +-
.../test_debug_request_context_diagnostics.py | 7 +-
Server/tests/integration/test_helpers.py | 4 +-
.../integration/test_inline_unity_instance.py | 134 +++--
.../integration/test_instance_autoselect.py | 31 +-
.../test_instance_routing_comprehensive.py | 98 ++--
.../test_instance_targeting_resolution.py | 8 +-
.../test_manage_scriptable_object_tool.py | 30 +-
.../test_middleware_auth_integration.py | 18 +-
.../test_multi_user_session_isolation.py | 8 +-
.../test_refresh_unity_retry_recovery.py | 2 +-
.../test_custom_tool_service_user_scope.py | 4 +-
Server/tests/test_manage_animation.py | 12 +-
Server/tests/test_manage_vfx_actions.py | 3 +-
.../tests/test_transport_characterization.py | 89 +--
Server/uv.lock | 530 ++++++------------
82 files changed, 1026 insertions(+), 707 deletions(-)
create mode 100644 Server/src/services/resources/tool_groups.py
create mode 100644 Server/src/services/tools/manage_tools.py
diff --git a/.claude/mcp.json b/.claude/mcp.json
index 63da78661..ae0c7a456 100644
--- a/.claude/mcp.json
+++ b/.claude/mcp.json
@@ -1,16 +1,8 @@
{
"mcpServers": {
"UnityMCP": {
- "type": "stdio",
- "command": "uv",
- "args": [
- "run",
- "--directory",
- "${workspaceFolder}/Server",
- "src/main.py",
- "--transport",
- "stdio"
- ]
+ "type": "http",
+ "url": "http://localhost:8080/mcp"
}
}
}
diff --git a/.claude/settings.json b/.claude/settings.json
index 127026519..29f403bcd 100644
--- a/.claude/settings.json
+++ b/.claude/settings.json
@@ -6,12 +6,6 @@
"MultiEdit(reports/**)"
],
"deny": [
- "WebFetch",
- "WebSearch",
- "Task",
- "TodoWrite",
- "NotebookEdit",
- "NotebookRead"
]
}
}
diff --git a/.gitignore b/.gitignore
index 6cd591730..88246fdde 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,9 +55,9 @@ TestProjects/UnityMCPTests/Assets/Temp/
# CI test reports (generated during test runs)
reports/
-# Local Claude configs (not for repo)
-.claude/local/
-
# Local testing harness
scripts/local-test/
.claude/settings.local.json
+
+# Ignore the .claude directory, since it might contain local/project-level setting such as deny and allowlist.
+/.claude
diff --git a/MCPForUnity/Editor/Services/IToolDiscoveryService.cs b/MCPForUnity/Editor/Services/IToolDiscoveryService.cs
index ee2c616b7..090b366c7 100644
--- a/MCPForUnity/Editor/Services/IToolDiscoveryService.cs
+++ b/MCPForUnity/Editor/Services/IToolDiscoveryService.cs
@@ -18,6 +18,7 @@ public class ToolMetadata
public bool RequiresPolling { get; set; } = false;
public string PollAction { get; set; } = "status";
public bool IsBuiltIn { get; set; }
+ public string Group { get; set; } = "core";
}
///
diff --git a/MCPForUnity/Editor/Services/ToolDiscoveryService.cs b/MCPForUnity/Editor/Services/ToolDiscoveryService.cs
index ac7cc1455..b7ef5d1eb 100644
--- a/MCPForUnity/Editor/Services/ToolDiscoveryService.cs
+++ b/MCPForUnity/Editor/Services/ToolDiscoveryService.cs
@@ -132,7 +132,8 @@ private ToolMetadata ExtractToolMetadata(Type type, McpForUnityToolAttribute too
AssemblyName = type.Assembly.GetName().Name,
AutoRegister = toolAttr.AutoRegister,
RequiresPolling = toolAttr.RequiresPolling,
- PollAction = string.IsNullOrEmpty(toolAttr.PollAction) ? "status" : toolAttr.PollAction
+ PollAction = string.IsNullOrEmpty(toolAttr.PollAction) ? "status" : toolAttr.PollAction,
+ Group = toolAttr.Group ?? "core"
};
metadata.IsBuiltIn = StringCaseUtility.IsBuiltInMcpType(
diff --git a/MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs b/MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs
index 8832b3227..71106a071 100644
--- a/MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs
+++ b/MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs
@@ -539,7 +539,8 @@ private async Task SendRegisterToolsAsync(CancellationToken token)
["description"] = tool.Description,
["structured_output"] = tool.StructuredOutput,
["requires_polling"] = tool.RequiresPolling,
- ["poll_action"] = tool.PollAction
+ ["poll_action"] = tool.PollAction,
+ ["group"] = tool.Group ?? "core"
};
var paramsArray = new JArray();
diff --git a/MCPForUnity/Editor/Tools/Animation/ManageAnimation.cs b/MCPForUnity/Editor/Tools/Animation/ManageAnimation.cs
index 98f737249..508994009 100644
--- a/MCPForUnity/Editor/Tools/Animation/ManageAnimation.cs
+++ b/MCPForUnity/Editor/Tools/Animation/ManageAnimation.cs
@@ -7,7 +7,7 @@
namespace MCPForUnity.Editor.Tools.Animation
{
- [McpForUnityTool("manage_animation", AutoRegister = false)]
+ [McpForUnityTool("manage_animation", AutoRegister = false, Group = "animation")]
public static class ManageAnimation
{
private static readonly Dictionary ParamAliases = new Dictionary(StringComparer.OrdinalIgnoreCase)
diff --git a/MCPForUnity/Editor/Tools/GetTestJob.cs b/MCPForUnity/Editor/Tools/GetTestJob.cs
index 4817ab9bc..ade8811e5 100644
--- a/MCPForUnity/Editor/Tools/GetTestJob.cs
+++ b/MCPForUnity/Editor/Tools/GetTestJob.cs
@@ -8,7 +8,7 @@ namespace MCPForUnity.Editor.Tools
///
/// Poll a previously started async test job by job_id.
///
- [McpForUnityTool("get_test_job", AutoRegister = false)]
+ [McpForUnityTool("get_test_job", AutoRegister = false, Group = "testing")]
public static class GetTestJob
{
public static object HandleCommand(JObject @params)
diff --git a/MCPForUnity/Editor/Tools/ManageScene.cs b/MCPForUnity/Editor/Tools/ManageScene.cs
index b07a34c3b..ec59533ae 100644
--- a/MCPForUnity/Editor/Tools/ManageScene.cs
+++ b/MCPForUnity/Editor/Tools/ManageScene.cs
@@ -240,6 +240,16 @@ public static object ExecuteScreenshot(string fileName = null, int? superSize =
return CaptureScreenshot(cmd);
}
+ ///
+ /// Captures a 6-angle contact-sheet around the scene bounds centre.
+ /// Public so the tools UI can reuse the same logic.
+ ///
+ public static object ExecuteMultiviewScreenshot(int maxResolution = 480)
+ {
+ var cmd = new SceneCommand { maxResolution = maxResolution };
+ return CaptureSurroundBatch(cmd);
+ }
+
private static object CreateScene(string fullPath, string relativePath)
{
if (File.Exists(fullPath))
diff --git a/MCPForUnity/Editor/Tools/ManageScriptableObject.cs b/MCPForUnity/Editor/Tools/ManageScriptableObject.cs
index 62d1c19a5..b5a4d78f3 100644
--- a/MCPForUnity/Editor/Tools/ManageScriptableObject.cs
+++ b/MCPForUnity/Editor/Tools/ManageScriptableObject.cs
@@ -17,7 +17,7 @@ namespace MCPForUnity.Editor.Tools
///
/// Patching is performed via SerializedObject/SerializedProperty paths (Unity-native), not reflection.
///
- [McpForUnityTool("manage_scriptable_object", AutoRegister = false)]
+ [McpForUnityTool("manage_scriptable_object", AutoRegister = false, Group = "scripting_ext")]
public static class ManageScriptableObject
{
private const string CodeCompilingOrReloading = "compiling_or_reloading";
diff --git a/MCPForUnity/Editor/Tools/ManageShader.cs b/MCPForUnity/Editor/Tools/ManageShader.cs
index 849a6f932..64cfbeb78 100644
--- a/MCPForUnity/Editor/Tools/ManageShader.cs
+++ b/MCPForUnity/Editor/Tools/ManageShader.cs
@@ -12,7 +12,7 @@ namespace MCPForUnity.Editor.Tools
///
/// Handles CRUD operations for shader files within the Unity project.
///
- [McpForUnityTool("manage_shader", AutoRegister = false)]
+ [McpForUnityTool("manage_shader", AutoRegister = false, Group = "vfx")]
public static class ManageShader
{
///
diff --git a/MCPForUnity/Editor/Tools/ManageTexture.cs b/MCPForUnity/Editor/Tools/ManageTexture.cs
index 86e429045..4ab66f720 100644
--- a/MCPForUnity/Editor/Tools/ManageTexture.cs
+++ b/MCPForUnity/Editor/Tools/ManageTexture.cs
@@ -13,7 +13,7 @@ namespace MCPForUnity.Editor.Tools
/// Supports patterns (checkerboard, stripes, dots, grid, brick),
/// gradients, noise, and direct pixel manipulation.
///
- [McpForUnityTool("manage_texture", AutoRegister = false)]
+ [McpForUnityTool("manage_texture", AutoRegister = false, Group = "vfx")]
public static class ManageTexture
{
private const int MaxTextureDimension = 1024;
diff --git a/MCPForUnity/Editor/Tools/ManageUI.cs b/MCPForUnity/Editor/Tools/ManageUI.cs
index c32253f4b..5947eb1f1 100644
--- a/MCPForUnity/Editor/Tools/ManageUI.cs
+++ b/MCPForUnity/Editor/Tools/ManageUI.cs
@@ -12,7 +12,7 @@
namespace MCPForUnity.Editor.Tools
{
- [McpForUnityTool("manage_ui", AutoRegister = false)]
+ [McpForUnityTool("manage_ui", AutoRegister = false, Group = "ui")]
public static class ManageUI
{
private static readonly HashSet ValidExtensions = new(StringComparer.OrdinalIgnoreCase)
diff --git a/MCPForUnity/Editor/Tools/McpForUnityToolAttribute.cs b/MCPForUnity/Editor/Tools/McpForUnityToolAttribute.cs
index e4db3a4c6..0d73fbb11 100644
--- a/MCPForUnity/Editor/Tools/McpForUnityToolAttribute.cs
+++ b/MCPForUnity/Editor/Tools/McpForUnityToolAttribute.cs
@@ -30,6 +30,15 @@ public class McpForUnityToolAttribute : Attribute
///
public bool AutoRegister { get; set; } = true;
+ ///
+ /// Tool group for dynamic visibility on the Python server.
+ /// Core tools are enabled by default; other groups start hidden and
+ /// can be activated per-session via the manage_tools meta-tool.
+ /// Valid groups: core, vfx, animation, ui, scripting_ext, testing, menu.
+ /// Set to null for server meta-tools that should always be visible.
+ ///
+ public string Group { get; set; } = "core";
+
///
/// Enables the polling middleware for long-running tools. When true, Unity
/// should return a PendingResponse and the Python side will poll using
diff --git a/MCPForUnity/Editor/Tools/RunTests.cs b/MCPForUnity/Editor/Tools/RunTests.cs
index abbf9225b..3c93e97d2 100644
--- a/MCPForUnity/Editor/Tools/RunTests.cs
+++ b/MCPForUnity/Editor/Tools/RunTests.cs
@@ -12,7 +12,7 @@ namespace MCPForUnity.Editor.Tools
/// Starts a Unity Test Runner run asynchronously and returns a job id immediately.
/// Use get_test_job(job_id) to poll status/results.
///
- [McpForUnityTool("run_tests", AutoRegister = false)]
+ [McpForUnityTool("run_tests", AutoRegister = false, Group = "testing")]
public static class RunTests
{
public static Task