From b69ee80da99e822e7597ad32e3ede19b0876029c Mon Sep 17 00:00:00 2001 From: Marcus Sanatan Date: Wed, 21 Jan 2026 13:07:52 -0400 Subject: [PATCH] Project scoped tools (#596) * feat: Add project-scoped tools flag to control custom tool registration behavior Add `--project-scoped-tools` CLI flag and `UNITY_MCP_PROJECT_SCOPED_TOOLS` environment variable to control whether custom tools are registered globally or scoped to specific Unity projects. Closes #416 * Add .meta file * feat: Add project-scoped tools toggle for local HTTP transport Add UI toggle in Connection section to control project-scoped tools flag when using HTTP Local transport. The toggle: - Defaults to enabled (true) - Persists state in EditorPrefs - Only displays when HTTP Local transport is selected - Automatically appends `--project-scoped-tools` flag to uvx server command - Updates manual config display when toggled * Update Server/src/services/custom_tool_service.py Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Pass project_scoped_tools flag directly without environment variable conversion Remove unnecessary environment variable conversion for project_scoped_tools flag. * fix: Improve error handling and logging in global custom tool registration Split exception handling to distinguish between expected RuntimeError (service not initialized) and unexpected errors. --------- Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --- .../Editor/Constants/EditorPrefKeys.cs | 1 + .../Services/ServerManagementService.cs | 9 +- .../Connection/McpConnectionSection.cs | 38 ++++ .../Connection/McpConnectionSection.uxml | 4 + .../Windows/EditorPrefs/EditorPrefsWindow.cs | 1 + Server/src/main.py | 98 ++++++---- Server/src/services/custom_tool_service.py | 170 ++++++++++++++++-- Server/src/services/resources/__init__.py | 7 +- Server/src/services/tools/__init__.py | 7 +- Server/src/transport/plugin_hub.py | 17 ++ .../UIDocumentSerializationTests.cs.meta | 11 ++ 11 files changed, 309 insertions(+), 54 deletions(-) create mode 100644 TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/UIDocumentSerializationTests.cs.meta diff --git a/MCPForUnity/Editor/Constants/EditorPrefKeys.cs b/MCPForUnity/Editor/Constants/EditorPrefKeys.cs index dfa6852..a6e81b4 100644 --- a/MCPForUnity/Editor/Constants/EditorPrefKeys.cs +++ b/MCPForUnity/Editor/Constants/EditorPrefKeys.cs @@ -28,6 +28,7 @@ namespace MCPForUnity.Editor.Constants internal const string WebSocketUrlOverride = "MCPForUnity.WebSocketUrl"; internal const string GitUrlOverride = "MCPForUnity.GitUrlOverride"; internal const string DevModeForceServerRefresh = "MCPForUnity.DevModeForceServerRefresh"; + internal const string ProjectScopedToolsLocalHttp = "MCPForUnity.ProjectScopedTools.LocalHttp"; internal const string PackageDeploySourcePath = "MCPForUnity.PackageDeploy.SourcePath"; internal const string PackageDeployLastBackupPath = "MCPForUnity.PackageDeploy.LastBackupPath"; diff --git a/MCPForUnity/Editor/Services/ServerManagementService.cs b/MCPForUnity/Editor/Services/ServerManagementService.cs index 69ca6d5..b9e5ecd 100644 --- a/MCPForUnity/Editor/Services/ServerManagementService.cs +++ b/MCPForUnity/Editor/Services/ServerManagementService.cs @@ -1312,9 +1312,14 @@ namespace MCPForUnity.Editor.Services // Use central helper that checks both DevModeForceServerRefresh AND local path detection. // Note: --reinstall is not supported by uvx, use --no-cache --refresh instead string devFlags = AssetPathUtility.ShouldForceUvxRefresh() ? "--no-cache --refresh " : string.Empty; + bool projectScopedTools = EditorPrefs.GetBool( + EditorPrefKeys.ProjectScopedToolsLocalHttp, + true + ); + string scopedFlag = projectScopedTools ? " --project-scoped-tools" : string.Empty; string args = string.IsNullOrEmpty(fromUrl) - ? $"{devFlags}{packageName} --transport http --http-url {httpUrl}" - : $"{devFlags}--from {fromUrl} {packageName} --transport http --http-url {httpUrl}"; + ? $"{devFlags}{packageName} --transport http --http-url {httpUrl}{scopedFlag}" + : $"{devFlags}--from {fromUrl} {packageName} --transport http --http-url {httpUrl}{scopedFlag}"; fileName = uvxPath; arguments = args; diff --git a/MCPForUnity/Editor/Windows/Components/Connection/McpConnectionSection.cs b/MCPForUnity/Editor/Windows/Components/Connection/McpConnectionSection.cs index 7d70d47..e984721 100644 --- a/MCPForUnity/Editor/Windows/Components/Connection/McpConnectionSection.cs +++ b/MCPForUnity/Editor/Windows/Components/Connection/McpConnectionSection.cs @@ -35,6 +35,8 @@ namespace MCPForUnity.Editor.Windows.Components.Connection private TextField httpUrlField; private Button startHttpServerButton; private Button stopHttpServerButton; + private VisualElement projectScopedToolsRow; + private Toggle projectScopedToolsToggle; private VisualElement unitySocketPortRow; private TextField unityPortField; private VisualElement statusIndicator; @@ -83,6 +85,8 @@ namespace MCPForUnity.Editor.Windows.Components.Connection httpUrlField = Root.Q("http-url"); startHttpServerButton = Root.Q