From 5d6735b2f1e8cb67704eb760bd8f3c7f5393081e Mon Sep 17 00:00:00 2001 From: David Sarno Date: Mon, 2 Feb 2026 22:21:12 -0800 Subject: [PATCH 1/3] fix: Use beta server args for Claude Code registration Claude Code registration was still using gitUrl directly instead of GetBetaServerFromArgs(), meaning the beta server toggle had no effect on registration. Now uses GetBetaServerFromArgs(quoteFromPath: true) to properly generate --prerelease args for beta users. Co-Authored-By: Claude Opus 4.5 --- .../Editor/Clients/McpClientConfiguratorBase.cs | 17 +++++++++-------- .../ClientConfig/McpClientConfigSection.cs | 5 +++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs b/MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs index 2a201995d..b64f0b1ac 100644 --- a/MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs +++ b/MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs @@ -599,7 +599,7 @@ public override void Configure() public void ConfigureWithCapturedValues( string projectDir, string claudePath, string pathPrepend, bool useHttpTransport, string httpUrl, - string uvxPath, string gitUrl, string packageName, bool shouldForceRefresh, + string uvxPath, string fromArgs, string packageName, bool shouldForceRefresh, string apiKey, Models.ConfiguredTransport serverTransport) { @@ -610,7 +610,7 @@ public void ConfigureWithCapturedValues( else { RegisterWithCapturedValues(projectDir, claudePath, pathPrepend, - useHttpTransport, httpUrl, uvxPath, gitUrl, packageName, shouldForceRefresh, + useHttpTransport, httpUrl, uvxPath, fromArgs, packageName, shouldForceRefresh, apiKey, serverTransport); } } @@ -621,7 +621,7 @@ public void ConfigureWithCapturedValues( private void RegisterWithCapturedValues( string projectDir, string claudePath, string pathPrepend, bool useHttpTransport, string httpUrl, - string uvxPath, string gitUrl, string packageName, bool shouldForceRefresh, + string uvxPath, string fromArgs, string packageName, bool shouldForceRefresh, string apiKey, Models.ConfiguredTransport serverTransport) { @@ -650,7 +650,7 @@ private void RegisterWithCapturedValues( // Note: --reinstall is not supported by uvx, use --no-cache --refresh instead string devFlags = shouldForceRefresh ? "--no-cache --refresh " : string.Empty; // Use --scope local to register in the project-local config, avoiding conflicts with user-level config (#664) - args = $"mcp add --scope local --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{gitUrl}\" {packageName}"; + args = $"mcp add --scope local --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}{fromArgs} {packageName}"; } // Remove any existing registrations from ALL scopes to prevent stale config conflicts (#664) @@ -724,12 +724,13 @@ private void Register() } else { - var (uvxPath, gitUrl, packageName) = AssetPathUtility.GetUvxCommandParts(); + var (uvxPath, _, packageName) = AssetPathUtility.GetUvxCommandParts(); // 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; + string fromArgs = AssetPathUtility.GetBetaServerFromArgs(quoteFromPath: true); // Use --scope local to register in the project-local config, avoiding conflicts with user-level config (#664) - args = $"mcp add --scope local --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{gitUrl}\" {packageName}"; + args = $"mcp add --scope local --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}{fromArgs} {packageName}"; } string projectDir = Path.GetDirectoryName(Application.dataPath); @@ -834,13 +835,13 @@ public override string GetManualSnippet() return "# Error: Configuration not available - check paths in Advanced Settings"; } - string packageSource = AssetPathUtility.GetMcpServerPackageSource(); // 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; + string fromArgs = AssetPathUtility.GetBetaServerFromArgs(quoteFromPath: true); return "# Register the MCP server with Claude Code:\n" + - $"claude mcp add --scope local --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{packageSource}\" mcp-for-unity\n\n" + + $"claude mcp add --scope local --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}{fromArgs} mcp-for-unity\n\n" + "# Unregister the MCP server (from all scopes to clean up any stale configs):\n" + "claude mcp remove --scope local UnityMCP\n" + "claude mcp remove --scope user UnityMCP\n" + diff --git a/MCPForUnity/Editor/Windows/Components/ClientConfig/McpClientConfigSection.cs b/MCPForUnity/Editor/Windows/Components/ClientConfig/McpClientConfigSection.cs index 0e4d5fee2..6048475bd 100644 --- a/MCPForUnity/Editor/Windows/Components/ClientConfig/McpClientConfigSection.cs +++ b/MCPForUnity/Editor/Windows/Components/ClientConfig/McpClientConfigSection.cs @@ -293,7 +293,8 @@ private void ConfigureClaudeCliAsync(IMcpClientConfigurator client) bool useHttpTransport = EditorConfigurationCache.Instance.UseHttpTransport; string claudePath = MCPServiceLocator.Paths.GetClaudeCliPath(); string httpUrl = HttpEndpointUtility.GetMcpRpcUrl(); - var (uvxPath, gitUrl, packageName) = AssetPathUtility.GetUvxCommandParts(); + var (uvxPath, _, packageName) = AssetPathUtility.GetUvxCommandParts(); + string fromArgs = AssetPathUtility.GetBetaServerFromArgs(quoteFromPath: true); bool shouldForceRefresh = AssetPathUtility.ShouldForceUvxRefresh(); string apiKey = EditorPrefs.GetString(EditorPrefKeys.ApiKey, string.Empty); @@ -321,7 +322,7 @@ private void ConfigureClaudeCliAsync(IMcpClientConfigurator client) cliConfigurator.ConfigureWithCapturedValues( projectDir, claudePath, pathPrepend, useHttpTransport, httpUrl, - uvxPath, gitUrl, packageName, shouldForceRefresh, + uvxPath, fromArgs, packageName, shouldForceRefresh, apiKey, serverTransport); } return (success: true, error: (string)null); From 9492c37c312f691cdf05add6a9121789e5f00388 Mon Sep 17 00:00:00 2001 From: David Sarno Date: Mon, 2 Feb 2026 22:45:56 -0800 Subject: [PATCH 2/3] fix: EditorPrefs Manager shows 'Unset' for keys that haven't been set - Show "Unset. Default: [value]" for EditorPrefs that haven't been explicitly set - Disable value field and save button for unset items (grayed out at 60% opacity) - Fix search filter bug where reloading window showed filtered results with empty search field Co-Authored-By: Claude Opus 4.5 --- .../Windows/EditorPrefs/EditorPrefsWindow.cs | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs b/MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs index 9a2b86ad4..b36125d4f 100644 --- a/MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs +++ b/MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs @@ -92,6 +92,9 @@ public static void ShowWindow() public void CreateGUI() { + // Clear search filter on GUI recreation to avoid stale filtered results + searchFilter = ""; + string basePath = AssetPathUtility.GetMcpPackageRootPath(); // Load UXML @@ -245,24 +248,27 @@ private EditorPrefItem CreateEditorPrefItem(string key) // Check if we know the type of this pref if (knownPrefTypes.TryGetValue(key, out var knownType)) { + // Check if the key actually exists + item.IsUnset = !EditorPrefs.HasKey(key); + // Use the known type switch (knownType) { case EditorPrefType.Bool: item.Type = EditorPrefType.Bool; - item.Value = EditorPrefs.GetBool(key, false).ToString(); + item.Value = item.IsUnset ? "Unset. Default: False" : EditorPrefs.GetBool(key, false).ToString(); break; case EditorPrefType.Int: item.Type = EditorPrefType.Int; - item.Value = EditorPrefs.GetInt(key, 0).ToString(); + item.Value = item.IsUnset ? "Unset. Default: 0" : EditorPrefs.GetInt(key, 0).ToString(); break; case EditorPrefType.Float: item.Type = EditorPrefType.Float; - item.Value = EditorPrefs.GetFloat(key, 0f).ToString(); + item.Value = item.IsUnset ? "Unset. Default: 0" : EditorPrefs.GetFloat(key, 0f).ToString(); break; case EditorPrefType.String: item.Type = EditorPrefType.String; - item.Value = EditorPrefs.GetString(key, ""); + item.Value = item.IsUnset ? "Unset. Default: (empty)" : EditorPrefs.GetString(key, ""); break; } } @@ -324,6 +330,14 @@ private VisualElement CreateItemUI(EditorPrefItem item) // Buttons var saveButton = itemElement.Q