From bbd09d44a5708b776a0cd8136f190329d6ed2fcd Mon Sep 17 00:00:00 2001 From: dsarno Date: Thu, 8 Jan 2026 06:45:05 -0800 Subject: [PATCH 1/2] fix: use PyPI as default server source instead of git URL Fixes Windows installation failures caused by long path issues when cloning the full repository (MAX_PATH 260 char limit exceeded). - Change default from git+https://github.com/CoplayDev/unity-mcp to mcpforunityserver=={version} PyPI package - Rename GetMcpServerGitUrl() to GetMcpServerPackageSource() - Keep deprecated wrapper for backwards compatibility - Update UI help text to show local dev override example only - Update tests to expect PyPI package reference --- .../Clients/McpClientConfiguratorBase.cs | 8 ++-- .../Editor/Helpers/AssetPathUtility.cs | 38 +++++++++++-------- .../Settings/McpSettingsSection.uxml | 5 +-- .../Helpers/CodexConfigHelperTests.cs | 8 ++-- 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs b/MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs index c0ab8695b..ed8d6a690 100644 --- a/MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs +++ b/MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs @@ -148,7 +148,7 @@ public override McpStatus CheckStatus(bool attemptAutoRewrite = true) bool matches = false; if (args != null && args.Length > 0) { - string expectedUvxUrl = AssetPathUtility.GetMcpServerGitUrl(); + string expectedUvxUrl = AssetPathUtility.GetMcpServerPackageSource(); string configuredUvxUrl = McpConfigurationHelper.ExtractUvxUrl(args); matches = !string.IsNullOrEmpty(configuredUvxUrl) && McpConfigurationHelper.PathsEqual(configuredUvxUrl, expectedUvxUrl); @@ -250,7 +250,7 @@ public override McpStatus CheckStatus(bool attemptAutoRewrite = true) } else if (args != null && args.Length > 0) { - string expected = AssetPathUtility.GetMcpServerGitUrl(); + string expected = AssetPathUtility.GetMcpServerPackageSource(); string configured = McpConfigurationHelper.ExtractUvxUrl(args); matches = !string.IsNullOrEmpty(configured) && McpConfigurationHelper.PathsEqual(configured, expected); @@ -585,12 +585,12 @@ public override string GetManualSnippet() return "# Error: Configuration not available - check paths in Advanced Settings"; } - string gitUrl = AssetPathUtility.GetMcpServerGitUrl(); + string packageSource = AssetPathUtility.GetMcpServerPackageSource(); // Use central helper that checks both DevModeForceServerRefresh AND local path detection. string devFlags = AssetPathUtility.ShouldForceUvxRefresh() ? "--no-cache --refresh " : string.Empty; return "# Register the MCP server with Claude Code:\n" + - $"claude mcp add --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{gitUrl}\" mcp-for-unity\n\n" + + $"claude mcp add --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{packageSource}\" mcp-for-unity\n\n" + "# Unregister the MCP server:\n" + "claude mcp remove UnityMCP\n\n" + "# List registered servers:\n" + diff --git a/MCPForUnity/Editor/Helpers/AssetPathUtility.cs b/MCPForUnity/Editor/Helpers/AssetPathUtility.cs index f7a6b4782..34c9ea49d 100644 --- a/MCPForUnity/Editor/Helpers/AssetPathUtility.cs +++ b/MCPForUnity/Editor/Helpers/AssetPathUtility.cs @@ -149,30 +149,38 @@ public static JObject GetPackageJson() } /// - /// Gets just the git URL part for the MCP server package - /// Checks for EditorPrefs override first, then falls back to package version + /// Gets the package source for the MCP server (used with uvx --from). + /// Checks for EditorPrefs override first (supports git URLs, file:// paths, etc.), + /// then falls back to PyPI package reference. /// - /// Git URL string, or empty string if version is unknown and no override - public static string GetMcpServerGitUrl() + /// Package source string for uvx --from argument + public static string GetMcpServerPackageSource() { - // Check for Git URL override first - string gitUrlOverride = EditorPrefs.GetString(EditorPrefKeys.GitUrlOverride, ""); - if (!string.IsNullOrEmpty(gitUrlOverride)) + // Check for override first (supports git URLs, file:// paths, local paths) + string sourceOverride = EditorPrefs.GetString(EditorPrefKeys.GitUrlOverride, ""); + if (!string.IsNullOrEmpty(sourceOverride)) { - return gitUrlOverride; + return sourceOverride; } - // Fall back to default package version + // Default to PyPI package (avoids Windows long path issues with git clone) string version = GetPackageVersion(); if (version == "unknown") { - // Fall back to main repo without pinned version so configs remain valid in test scenarios - return "git+https://github.com/CoplayDev/unity-mcp#subdirectory=Server"; + // Fall back to latest PyPI version so configs remain valid in test scenarios + return "mcpforunityserver"; } - return $"git+https://github.com/CoplayDev/unity-mcp@v{version}#subdirectory=Server"; + return $"mcpforunityserver=={version}"; } + /// + /// Deprecated: Use GetMcpServerPackageSource() instead. + /// Kept for backwards compatibility. + /// + [System.Obsolete("Use GetMcpServerPackageSource() instead")] + public static string GetMcpServerGitUrl() => GetMcpServerPackageSource(); + /// /// Gets structured uvx command parts for different client configurations /// @@ -180,7 +188,7 @@ public static string GetMcpServerGitUrl() public static (string uvxPath, string fromUrl, string packageName) GetUvxCommandParts() { string uvxPath = MCPServiceLocator.Paths.GetUvxPath(); - string fromUrl = GetMcpServerGitUrl(); + string fromUrl = GetMcpServerPackageSource(); string packageName = "mcp-for-unity"; return (uvxPath, fromUrl, packageName); @@ -208,7 +216,7 @@ public static bool ShouldForceUvxRefresh() /// public static bool IsLocalServerPath() { - string fromUrl = GetMcpServerGitUrl(); + string fromUrl = GetMcpServerPackageSource(); if (string.IsNullOrEmpty(fromUrl)) return false; @@ -226,7 +234,7 @@ public static string GetLocalServerPath() if (!IsLocalServerPath()) return null; - string fromUrl = GetMcpServerGitUrl(); + string fromUrl = GetMcpServerPackageSource(); if (fromUrl.StartsWith("file://", StringComparison.OrdinalIgnoreCase)) { // Strip file:// prefix diff --git a/MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.uxml b/MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.uxml index 50038f3ce..1f15748c6 100644 --- a/MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.uxml +++ b/MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.uxml @@ -38,9 +38,8 @@ - - - + + diff --git a/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Helpers/CodexConfigHelperTests.cs b/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Helpers/CodexConfigHelperTests.cs index 405417427..95d1a0407 100644 --- a/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Helpers/CodexConfigHelperTests.cs +++ b/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Helpers/CodexConfigHelperTests.cs @@ -248,7 +248,7 @@ public void BuildCodexServerBlock_OnWindows_IncludesSystemRootEnv() var thirdArg = (args[2] as TomlString).Value; Assert.AreEqual("--from", firstArg, "First arg should be --from"); - Assert.IsTrue(secondArg.Contains("git+https://github.com/CoplayDev/unity-mcp"), "Second arg should be git URL"); + Assert.IsTrue(secondArg.Contains("mcpforunityserver"), "Second arg should be PyPI package reference"); Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity"); // Verify env.SystemRoot is present on Windows @@ -313,7 +313,7 @@ public void BuildCodexServerBlock_OnNonWindows_ExcludesEnv() var thirdArg = (args[2] as TomlString).Value; Assert.AreEqual("--from", firstArg, "First arg should be --from"); - Assert.IsTrue(secondArg.Contains("git+https://github.com/CoplayDev/unity-mcp"), "Second arg should be git URL"); + Assert.IsTrue(secondArg.Contains("mcpforunityserver"), "Second arg should be PyPI package reference"); Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity"); // Verify env is NOT present on non-Windows platforms @@ -380,7 +380,7 @@ public void UpsertCodexServerBlock_OnWindows_IncludesSystemRootEnv() var thirdArg = (args[2] as TomlString).Value; Assert.AreEqual("--from", firstArg, "First arg should be --from"); - Assert.IsTrue(secondArg.Contains("git+https://github.com/CoplayDev/unity-mcp"), "Second arg should be git URL"); + Assert.IsTrue(secondArg.Contains("mcpforunityserver"), "Second arg should be PyPI package reference"); Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity"); // Verify env.SystemRoot is present on Windows @@ -454,7 +454,7 @@ public void UpsertCodexServerBlock_OnNonWindows_ExcludesEnv() var thirdArg = (args[2] as TomlString).Value; Assert.AreEqual("--from", firstArg, "First arg should be --from"); - Assert.IsTrue(secondArg.Contains("git+https://github.com/CoplayDev/unity-mcp"), "Second arg should be git URL"); + Assert.IsTrue(secondArg.Contains("mcpforunityserver"), "Second arg should be PyPI package reference"); Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity"); // Verify env is NOT present on non-Windows platforms From 63002e16475eb580959ce3b712c5a1f7369c84e8 Mon Sep 17 00:00:00 2001 From: dsarno Date: Thu, 8 Jan 2026 07:03:12 -0800 Subject: [PATCH 2/2] fix: use forward slashes in deployment path display Fixes UI rendering issue where backslashes in Windows paths were interpreted as escape sequences (e.g. \U, \u showing as boxes). Convert backslashes to forward slashes for display in: - Target path label - Backup path label --- MCPForUnity/Editor/Services/PackageDeploymentService.cs | 7 ++++--- .../Windows/Components/Settings/McpSettingsSection.cs | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/MCPForUnity/Editor/Services/PackageDeploymentService.cs b/MCPForUnity/Editor/Services/PackageDeploymentService.cs index 3024ded38..7c0e27c65 100644 --- a/MCPForUnity/Editor/Services/PackageDeploymentService.cs +++ b/MCPForUnity/Editor/Services/PackageDeploymentService.cs @@ -69,9 +69,10 @@ public string GetTargetPath() public string GetTargetDisplayPath() { string target = GetTargetPath(); - return string.IsNullOrEmpty(target) - ? "Not found (check Packages/manifest.json)" - : target; + if (string.IsNullOrEmpty(target)) + return "Not found (check Packages/manifest.json)"; + // Use forward slashes to avoid backslash escape sequence issues in UI text + return target.Replace('\\', '/'); } public string GetLastBackupPath() diff --git a/MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.cs b/MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.cs index c732052eb..7f782f8ae 100644 --- a/MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.cs +++ b/MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.cs @@ -308,7 +308,8 @@ private void UpdateDeploymentSection() string backupPath = deployService.GetLastBackupPath(); if (deployService.HasBackup()) { - deployBackupLabel.text = $"Last backup: {backupPath}"; + // Use forward slashes to avoid backslash escape sequence issues in UI text + deployBackupLabel.text = $"Last backup: {backupPath?.Replace('\\', '/')}"; } else {