Skip to content

Commit cba0933

Browse files
authored
Fixes Windows installation failures caused by long path issues when cloning the full repository via git URL (MAX_PATH 260 char limit exceeded by files in TestProjects/). (#534)
* 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 * 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
1 parent 275422e commit cba0933

File tree

6 files changed

+39
-30
lines changed

6 files changed

+39
-30
lines changed

MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public override McpStatus CheckStatus(bool attemptAutoRewrite = true)
148148
bool matches = false;
149149
if (args != null && args.Length > 0)
150150
{
151-
string expectedUvxUrl = AssetPathUtility.GetMcpServerGitUrl();
151+
string expectedUvxUrl = AssetPathUtility.GetMcpServerPackageSource();
152152
string configuredUvxUrl = McpConfigurationHelper.ExtractUvxUrl(args);
153153
matches = !string.IsNullOrEmpty(configuredUvxUrl) &&
154154
McpConfigurationHelper.PathsEqual(configuredUvxUrl, expectedUvxUrl);
@@ -250,7 +250,7 @@ public override McpStatus CheckStatus(bool attemptAutoRewrite = true)
250250
}
251251
else if (args != null && args.Length > 0)
252252
{
253-
string expected = AssetPathUtility.GetMcpServerGitUrl();
253+
string expected = AssetPathUtility.GetMcpServerPackageSource();
254254
string configured = McpConfigurationHelper.ExtractUvxUrl(args);
255255
matches = !string.IsNullOrEmpty(configured) &&
256256
McpConfigurationHelper.PathsEqual(configured, expected);
@@ -585,12 +585,12 @@ public override string GetManualSnippet()
585585
return "# Error: Configuration not available - check paths in Advanced Settings";
586586
}
587587

588-
string gitUrl = AssetPathUtility.GetMcpServerGitUrl();
588+
string packageSource = AssetPathUtility.GetMcpServerPackageSource();
589589
// Use central helper that checks both DevModeForceServerRefresh AND local path detection.
590590
string devFlags = AssetPathUtility.ShouldForceUvxRefresh() ? "--no-cache --refresh " : string.Empty;
591591

592592
return "# Register the MCP server with Claude Code:\n" +
593-
$"claude mcp add --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{gitUrl}\" mcp-for-unity\n\n" +
593+
$"claude mcp add --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{packageSource}\" mcp-for-unity\n\n" +
594594
"# Unregister the MCP server:\n" +
595595
"claude mcp remove UnityMCP\n\n" +
596596
"# List registered servers:\n" +

MCPForUnity/Editor/Helpers/AssetPathUtility.cs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -149,38 +149,46 @@ public static JObject GetPackageJson()
149149
}
150150

151151
/// <summary>
152-
/// Gets just the git URL part for the MCP server package
153-
/// Checks for EditorPrefs override first, then falls back to package version
152+
/// Gets the package source for the MCP server (used with uvx --from).
153+
/// Checks for EditorPrefs override first (supports git URLs, file:// paths, etc.),
154+
/// then falls back to PyPI package reference.
154155
/// </summary>
155-
/// <returns>Git URL string, or empty string if version is unknown and no override</returns>
156-
public static string GetMcpServerGitUrl()
156+
/// <returns>Package source string for uvx --from argument</returns>
157+
public static string GetMcpServerPackageSource()
157158
{
158-
// Check for Git URL override first
159-
string gitUrlOverride = EditorPrefs.GetString(EditorPrefKeys.GitUrlOverride, "");
160-
if (!string.IsNullOrEmpty(gitUrlOverride))
159+
// Check for override first (supports git URLs, file:// paths, local paths)
160+
string sourceOverride = EditorPrefs.GetString(EditorPrefKeys.GitUrlOverride, "");
161+
if (!string.IsNullOrEmpty(sourceOverride))
161162
{
162-
return gitUrlOverride;
163+
return sourceOverride;
163164
}
164165

165-
// Fall back to default package version
166+
// Default to PyPI package (avoids Windows long path issues with git clone)
166167
string version = GetPackageVersion();
167168
if (version == "unknown")
168169
{
169-
// Fall back to main repo without pinned version so configs remain valid in test scenarios
170-
return "git+https://github.com/CoplayDev/unity-mcp#subdirectory=Server";
170+
// Fall back to latest PyPI version so configs remain valid in test scenarios
171+
return "mcpforunityserver";
171172
}
172173

173-
return $"git+https://github.com/CoplayDev/unity-mcp@v{version}#subdirectory=Server";
174+
return $"mcpforunityserver=={version}";
174175
}
175176

177+
/// <summary>
178+
/// Deprecated: Use GetMcpServerPackageSource() instead.
179+
/// Kept for backwards compatibility.
180+
/// </summary>
181+
[System.Obsolete("Use GetMcpServerPackageSource() instead")]
182+
public static string GetMcpServerGitUrl() => GetMcpServerPackageSource();
183+
176184
/// <summary>
177185
/// Gets structured uvx command parts for different client configurations
178186
/// </summary>
179187
/// <returns>Tuple containing (uvxPath, fromUrl, packageName)</returns>
180188
public static (string uvxPath, string fromUrl, string packageName) GetUvxCommandParts()
181189
{
182190
string uvxPath = MCPServiceLocator.Paths.GetUvxPath();
183-
string fromUrl = GetMcpServerGitUrl();
191+
string fromUrl = GetMcpServerPackageSource();
184192
string packageName = "mcp-for-unity";
185193

186194
return (uvxPath, fromUrl, packageName);
@@ -208,7 +216,7 @@ public static bool ShouldForceUvxRefresh()
208216
/// </summary>
209217
public static bool IsLocalServerPath()
210218
{
211-
string fromUrl = GetMcpServerGitUrl();
219+
string fromUrl = GetMcpServerPackageSource();
212220
if (string.IsNullOrEmpty(fromUrl))
213221
return false;
214222

@@ -226,7 +234,7 @@ public static string GetLocalServerPath()
226234
if (!IsLocalServerPath())
227235
return null;
228236

229-
string fromUrl = GetMcpServerGitUrl();
237+
string fromUrl = GetMcpServerPackageSource();
230238
if (fromUrl.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
231239
{
232240
// Strip file:// prefix

MCPForUnity/Editor/Services/PackageDeploymentService.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ public string GetTargetPath()
6969
public string GetTargetDisplayPath()
7070
{
7171
string target = GetTargetPath();
72-
return string.IsNullOrEmpty(target)
73-
? "Not found (check Packages/manifest.json)"
74-
: target;
72+
if (string.IsNullOrEmpty(target))
73+
return "Not found (check Packages/manifest.json)";
74+
// Use forward slashes to avoid backslash escape sequence issues in UI text
75+
return target.Replace('\\', '/');
7576
}
7677

7778
public string GetLastBackupPath()

MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,8 @@ private void UpdateDeploymentSection()
308308
string backupPath = deployService.GetLastBackupPath();
309309
if (deployService.HasBackup())
310310
{
311-
deployBackupLabel.text = $"Last backup: {backupPath}";
311+
// Use forward slashes to avoid backslash escape sequence issues in UI text
312+
deployBackupLabel.text = $"Last backup: {backupPath?.Replace('\\', '/')}";
312313
}
313314
else
314315
{

MCPForUnity/Editor/Windows/Components/Settings/McpSettingsSection.uxml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@
3838
<ui:Button name="browse-git-url-button" text="Select" class="icon-button" />
3939
<ui:Button name="clear-git-url-button" text="Clear" class="icon-button" />
4040
</ui:VisualElement>
41-
<ui:Label text="Examples:" class="help-text" style="margin-top: 5px;" />
42-
<ui:Label text="• Local: /Users/you/Projects/unity-mcp/Server" class="help-text" />
43-
<ui:Label text="• Remote: git+https://github.com/CoplayDev/unity-mcp@v6.3.0#subdirectory=Server" class="help-text" />
41+
<ui:Label text="Override example (default uses PyPI):" class="help-text" style="margin-top: 5px;" />
42+
<ui:Label text="• Local dev: /path/to/unity-mcp/Server" class="help-text" />
4443

4544
<ui:Label text="Dev Mode:" class="advanced-label" style="margin-top: 10px;" />
4645
<ui:Label text="When enabled, generated uvx commands add '--no-cache --refresh' before launching (slower startup, but avoids stale cached builds while iterating on the Server)." class="help-text" />

TestProjects/UnityMCPTests/Assets/Tests/EditMode/Helpers/CodexConfigHelperTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ public void BuildCodexServerBlock_OnWindows_IncludesSystemRootEnv()
248248
var thirdArg = (args[2] as TomlString).Value;
249249

250250
Assert.AreEqual("--from", firstArg, "First arg should be --from");
251-
Assert.IsTrue(secondArg.Contains("git+https://github.com/CoplayDev/unity-mcp"), "Second arg should be git URL");
251+
Assert.IsTrue(secondArg.Contains("mcpforunityserver"), "Second arg should be PyPI package reference");
252252
Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity");
253253

254254
// Verify env.SystemRoot is present on Windows
@@ -313,7 +313,7 @@ public void BuildCodexServerBlock_OnNonWindows_ExcludesEnv()
313313
var thirdArg = (args[2] as TomlString).Value;
314314

315315
Assert.AreEqual("--from", firstArg, "First arg should be --from");
316-
Assert.IsTrue(secondArg.Contains("git+https://github.com/CoplayDev/unity-mcp"), "Second arg should be git URL");
316+
Assert.IsTrue(secondArg.Contains("mcpforunityserver"), "Second arg should be PyPI package reference");
317317
Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity");
318318

319319
// Verify env is NOT present on non-Windows platforms
@@ -380,7 +380,7 @@ public void UpsertCodexServerBlock_OnWindows_IncludesSystemRootEnv()
380380
var thirdArg = (args[2] as TomlString).Value;
381381

382382
Assert.AreEqual("--from", firstArg, "First arg should be --from");
383-
Assert.IsTrue(secondArg.Contains("git+https://github.com/CoplayDev/unity-mcp"), "Second arg should be git URL");
383+
Assert.IsTrue(secondArg.Contains("mcpforunityserver"), "Second arg should be PyPI package reference");
384384
Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity");
385385

386386
// Verify env.SystemRoot is present on Windows
@@ -454,7 +454,7 @@ public void UpsertCodexServerBlock_OnNonWindows_ExcludesEnv()
454454
var thirdArg = (args[2] as TomlString).Value;
455455

456456
Assert.AreEqual("--from", firstArg, "First arg should be --from");
457-
Assert.IsTrue(secondArg.Contains("git+https://github.com/CoplayDev/unity-mcp"), "Second arg should be git URL");
457+
Assert.IsTrue(secondArg.Contains("mcpforunityserver"), "Second arg should be PyPI package reference");
458458
Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity");
459459

460460
// Verify env is NOT present on non-Windows platforms

0 commit comments

Comments
 (0)