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 labelmain
parent
275422e765
commit
cba0933d33
|
|
@ -148,7 +148,7 @@ namespace MCPForUnity.Editor.Clients
|
||||||
bool matches = false;
|
bool matches = false;
|
||||||
if (args != null && args.Length > 0)
|
if (args != null && args.Length > 0)
|
||||||
{
|
{
|
||||||
string expectedUvxUrl = AssetPathUtility.GetMcpServerGitUrl();
|
string expectedUvxUrl = AssetPathUtility.GetMcpServerPackageSource();
|
||||||
string configuredUvxUrl = McpConfigurationHelper.ExtractUvxUrl(args);
|
string configuredUvxUrl = McpConfigurationHelper.ExtractUvxUrl(args);
|
||||||
matches = !string.IsNullOrEmpty(configuredUvxUrl) &&
|
matches = !string.IsNullOrEmpty(configuredUvxUrl) &&
|
||||||
McpConfigurationHelper.PathsEqual(configuredUvxUrl, expectedUvxUrl);
|
McpConfigurationHelper.PathsEqual(configuredUvxUrl, expectedUvxUrl);
|
||||||
|
|
@ -250,7 +250,7 @@ namespace MCPForUnity.Editor.Clients
|
||||||
}
|
}
|
||||||
else if (args != null && args.Length > 0)
|
else if (args != null && args.Length > 0)
|
||||||
{
|
{
|
||||||
string expected = AssetPathUtility.GetMcpServerGitUrl();
|
string expected = AssetPathUtility.GetMcpServerPackageSource();
|
||||||
string configured = McpConfigurationHelper.ExtractUvxUrl(args);
|
string configured = McpConfigurationHelper.ExtractUvxUrl(args);
|
||||||
matches = !string.IsNullOrEmpty(configured) &&
|
matches = !string.IsNullOrEmpty(configured) &&
|
||||||
McpConfigurationHelper.PathsEqual(configured, expected);
|
McpConfigurationHelper.PathsEqual(configured, expected);
|
||||||
|
|
@ -585,12 +585,12 @@ namespace MCPForUnity.Editor.Clients
|
||||||
return "# Error: Configuration not available - check paths in Advanced Settings";
|
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.
|
// Use central helper that checks both DevModeForceServerRefresh AND local path detection.
|
||||||
string devFlags = AssetPathUtility.ShouldForceUvxRefresh() ? "--no-cache --refresh " : string.Empty;
|
string devFlags = AssetPathUtility.ShouldForceUvxRefresh() ? "--no-cache --refresh " : string.Empty;
|
||||||
|
|
||||||
return "# Register the MCP server with Claude Code:\n" +
|
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" +
|
"# Unregister the MCP server:\n" +
|
||||||
"claude mcp remove UnityMCP\n\n" +
|
"claude mcp remove UnityMCP\n\n" +
|
||||||
"# List registered servers:\n" +
|
"# List registered servers:\n" +
|
||||||
|
|
|
||||||
|
|
@ -149,30 +149,38 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets just the git URL part for the MCP server package
|
/// Gets the package source for the MCP server (used with uvx --from).
|
||||||
/// Checks for EditorPrefs override first, then falls back to package version
|
/// Checks for EditorPrefs override first (supports git URLs, file:// paths, etc.),
|
||||||
|
/// then falls back to PyPI package reference.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Git URL string, or empty string if version is unknown and no override</returns>
|
/// <returns>Package source string for uvx --from argument</returns>
|
||||||
public static string GetMcpServerGitUrl()
|
public static string GetMcpServerPackageSource()
|
||||||
{
|
{
|
||||||
// Check for Git URL override first
|
// Check for override first (supports git URLs, file:// paths, local paths)
|
||||||
string gitUrlOverride = EditorPrefs.GetString(EditorPrefKeys.GitUrlOverride, "");
|
string sourceOverride = EditorPrefs.GetString(EditorPrefKeys.GitUrlOverride, "");
|
||||||
if (!string.IsNullOrEmpty(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();
|
string version = GetPackageVersion();
|
||||||
if (version == "unknown")
|
if (version == "unknown")
|
||||||
{
|
{
|
||||||
// Fall back to main repo without pinned version so configs remain valid in test scenarios
|
// Fall back to latest PyPI version so configs remain valid in test scenarios
|
||||||
return "git+https://github.com/CoplayDev/unity-mcp#subdirectory=Server";
|
return "mcpforunityserver";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"git+https://github.com/CoplayDev/unity-mcp@v{version}#subdirectory=Server";
|
return $"mcpforunityserver=={version}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deprecated: Use GetMcpServerPackageSource() instead.
|
||||||
|
/// Kept for backwards compatibility.
|
||||||
|
/// </summary>
|
||||||
|
[System.Obsolete("Use GetMcpServerPackageSource() instead")]
|
||||||
|
public static string GetMcpServerGitUrl() => GetMcpServerPackageSource();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets structured uvx command parts for different client configurations
|
/// Gets structured uvx command parts for different client configurations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -180,7 +188,7 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
public static (string uvxPath, string fromUrl, string packageName) GetUvxCommandParts()
|
public static (string uvxPath, string fromUrl, string packageName) GetUvxCommandParts()
|
||||||
{
|
{
|
||||||
string uvxPath = MCPServiceLocator.Paths.GetUvxPath();
|
string uvxPath = MCPServiceLocator.Paths.GetUvxPath();
|
||||||
string fromUrl = GetMcpServerGitUrl();
|
string fromUrl = GetMcpServerPackageSource();
|
||||||
string packageName = "mcp-for-unity";
|
string packageName = "mcp-for-unity";
|
||||||
|
|
||||||
return (uvxPath, fromUrl, packageName);
|
return (uvxPath, fromUrl, packageName);
|
||||||
|
|
@ -208,7 +216,7 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool IsLocalServerPath()
|
public static bool IsLocalServerPath()
|
||||||
{
|
{
|
||||||
string fromUrl = GetMcpServerGitUrl();
|
string fromUrl = GetMcpServerPackageSource();
|
||||||
if (string.IsNullOrEmpty(fromUrl))
|
if (string.IsNullOrEmpty(fromUrl))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -226,7 +234,7 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
if (!IsLocalServerPath())
|
if (!IsLocalServerPath())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
string fromUrl = GetMcpServerGitUrl();
|
string fromUrl = GetMcpServerPackageSource();
|
||||||
if (fromUrl.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
|
if (fromUrl.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
// Strip file:// prefix
|
// Strip file:// prefix
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,10 @@ namespace MCPForUnity.Editor.Services
|
||||||
public string GetTargetDisplayPath()
|
public string GetTargetDisplayPath()
|
||||||
{
|
{
|
||||||
string target = GetTargetPath();
|
string target = GetTargetPath();
|
||||||
return string.IsNullOrEmpty(target)
|
if (string.IsNullOrEmpty(target))
|
||||||
? "Not found (check Packages/manifest.json)"
|
return "Not found (check Packages/manifest.json)";
|
||||||
: target;
|
// Use forward slashes to avoid backslash escape sequence issues in UI text
|
||||||
|
return target.Replace('\\', '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetLastBackupPath()
|
public string GetLastBackupPath()
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,8 @@ namespace MCPForUnity.Editor.Windows.Components.Settings
|
||||||
string backupPath = deployService.GetLastBackupPath();
|
string backupPath = deployService.GetLastBackupPath();
|
||||||
if (deployService.HasBackup())
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,8 @@
|
||||||
<ui:Button name="browse-git-url-button" text="Select" class="icon-button" />
|
<ui:Button name="browse-git-url-button" text="Select" class="icon-button" />
|
||||||
<ui:Button name="clear-git-url-button" text="Clear" class="icon-button" />
|
<ui:Button name="clear-git-url-button" text="Clear" class="icon-button" />
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
<ui:Label text="Examples:" class="help-text" style="margin-top: 5px;" />
|
<ui:Label text="Override example (default uses PyPI):" class="help-text" style="margin-top: 5px;" />
|
||||||
<ui:Label text="• Local: /Users/you/Projects/unity-mcp/Server" class="help-text" />
|
<ui:Label text="• Local dev: /path/to/unity-mcp/Server" class="help-text" />
|
||||||
<ui:Label text="• Remote: git+https://github.com/CoplayDev/unity-mcp@v6.3.0#subdirectory=Server" class="help-text" />
|
|
||||||
|
|
||||||
<ui:Label text="Dev Mode:" class="advanced-label" style="margin-top: 10px;" />
|
<ui:Label text="Dev Mode:" class="advanced-label" style="margin-top: 10px;" />
|
||||||
<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" />
|
<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" />
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ namespace MCPForUnityTests.Editor.Helpers
|
||||||
var thirdArg = (args[2] as TomlString).Value;
|
var thirdArg = (args[2] as TomlString).Value;
|
||||||
|
|
||||||
Assert.AreEqual("--from", firstArg, "First arg should be --from");
|
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");
|
Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity");
|
||||||
|
|
||||||
// Verify env.SystemRoot is present on Windows
|
// Verify env.SystemRoot is present on Windows
|
||||||
|
|
@ -313,7 +313,7 @@ namespace MCPForUnityTests.Editor.Helpers
|
||||||
var thirdArg = (args[2] as TomlString).Value;
|
var thirdArg = (args[2] as TomlString).Value;
|
||||||
|
|
||||||
Assert.AreEqual("--from", firstArg, "First arg should be --from");
|
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");
|
Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity");
|
||||||
|
|
||||||
// Verify env is NOT present on non-Windows platforms
|
// Verify env is NOT present on non-Windows platforms
|
||||||
|
|
@ -380,7 +380,7 @@ namespace MCPForUnityTests.Editor.Helpers
|
||||||
var thirdArg = (args[2] as TomlString).Value;
|
var thirdArg = (args[2] as TomlString).Value;
|
||||||
|
|
||||||
Assert.AreEqual("--from", firstArg, "First arg should be --from");
|
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");
|
Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity");
|
||||||
|
|
||||||
// Verify env.SystemRoot is present on Windows
|
// Verify env.SystemRoot is present on Windows
|
||||||
|
|
@ -454,7 +454,7 @@ namespace MCPForUnityTests.Editor.Helpers
|
||||||
var thirdArg = (args[2] as TomlString).Value;
|
var thirdArg = (args[2] as TomlString).Value;
|
||||||
|
|
||||||
Assert.AreEqual("--from", firstArg, "First arg should be --from");
|
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");
|
Assert.AreEqual("mcp-for-unity", thirdArg, "Third arg should be mcp-for-unity");
|
||||||
|
|
||||||
// Verify env is NOT present on non-Windows platforms
|
// Verify env is NOT present on non-Windows platforms
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue