Skip to content

Commit 2749b4e

Browse files
committed
feat: Add comprehensive UV error handling and installation guidance
- Enhanced FindUvPath() to return null when UV is not found - Added detailed installation instructions for all platforms - Implemented null checks in all UV usage points - Added cross-platform path resolution for Windows, macOS, and Linux - Improved user experience with clear error messages instead of silent failures - Prevents 'spawn uv ENOENT' errors by using full paths and proper validation
1 parent cb59b08 commit 2749b4e

File tree

1 file changed

+100
-4
lines changed

1 file changed

+100
-4
lines changed

UnityMcpBridge/Editor/Windows/UnityMcpEditorWindow.cs

Lines changed: 100 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,13 @@ private void DrawClientConfigurationCompact(McpClient mcpClient)
373373
if (mcpClient.mcpType == McpTypes.VSCode)
374374
{
375375
string pythonDir = FindPackagePythonDirectory();
376+
string uvPath = FindUvPath();
377+
if (uvPath == null)
378+
{
379+
UnityEngine.Debug.LogError("UV package manager not found. Cannot configure VSCode.");
380+
return;
381+
}
382+
376383
var vscodeConfig = new
377384
{
378385
mcp = new
@@ -381,7 +388,7 @@ private void DrawClientConfigurationCompact(McpClient mcpClient)
381388
{
382389
unityMCP = new
383390
{
384-
command = "uv",
391+
command = uvPath,
385392
args = new[] { "--directory", pythonDir, "run", "server.py" }
386393
}
387394
}
@@ -425,10 +432,16 @@ private void ToggleUnityBridge()
425432

426433
private string WriteToConfig(string pythonDir, string configPath, McpClient mcpClient = null)
427434
{
435+
string uvPath = FindUvPath();
436+
if (uvPath == null)
437+
{
438+
return "UV package manager not found. Please install UV first.";
439+
}
440+
428441
// Create configuration object for unityMCP
429442
McpConfigServer unityMCPConfig = new()
430443
{
431-
command = "uv",
444+
command = uvPath,
432445
args = new[] { "--directory", pythonDir, "run", "server.py" },
433446
};
434447

@@ -541,13 +554,20 @@ private void ShowManualInstructionsWindow(string configPath, McpClient mcpClient
541554

542555
default:
543556
// Create standard MCP configuration for other clients
557+
string uvPath = FindUvPath();
558+
if (uvPath == null)
559+
{
560+
UnityEngine.Debug.LogError("UV package manager not found. Cannot configure manual setup.");
561+
return;
562+
}
563+
544564
McpConfig jsonConfig = new()
545565
{
546566
mcpServers = new McpConfigServers
547567
{
548568
unityMCP = new McpConfigServer
549569
{
550-
command = "uv",
570+
command = uvPath,
551571
args = new[] { "--directory", pythonDir, "run", "server.py" },
552572
},
553573
},
@@ -714,13 +734,20 @@ McpClient mcpClient
714734
string pythonDir = FindPackagePythonDirectory();
715735

716736
// Create the manual configuration message
737+
string uvPath = FindUvPath();
738+
if (uvPath == null)
739+
{
740+
UnityEngine.Debug.LogError("UV package manager not found. Cannot configure manual setup.");
741+
return;
742+
}
743+
717744
McpConfig jsonConfig = new()
718745
{
719746
mcpServers = new McpConfigServers
720747
{
721748
unityMCP = new McpConfigServer
722749
{
723-
command = "uv",
750+
command = uvPath,
724751
args = new[] { "--directory", pythonDir, "run", "server.py" },
725752
},
726753
},
@@ -1014,6 +1041,75 @@ private void UnregisterWithClaudeCode()
10141041
}
10151042
}
10161043

1044+
private string FindUvPath()
1045+
{
1046+
string uvPath = null;
1047+
1048+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
1049+
{
1050+
uvPath = FindWindowsUvPath();
1051+
}
1052+
else
1053+
{
1054+
// macOS/Linux paths
1055+
string[] possiblePaths = {
1056+
"/Library/Frameworks/Python.framework/Versions/3.13/bin/uv",
1057+
"/usr/local/bin/uv",
1058+
"/opt/homebrew/bin/uv",
1059+
"/usr/bin/uv"
1060+
};
1061+
1062+
foreach (string path in possiblePaths)
1063+
{
1064+
if (File.Exists(path))
1065+
{
1066+
uvPath = path;
1067+
break;
1068+
}
1069+
}
1070+
1071+
// If not found in common locations, try to find via which command
1072+
if (uvPath == null)
1073+
{
1074+
try
1075+
{
1076+
var psi = new ProcessStartInfo
1077+
{
1078+
FileName = "which",
1079+
Arguments = "uv",
1080+
UseShellExecute = false,
1081+
RedirectStandardOutput = true,
1082+
CreateNoWindow = true
1083+
};
1084+
1085+
using var process = Process.Start(psi);
1086+
string output = process.StandardOutput.ReadToEnd().Trim();
1087+
process.WaitForExit();
1088+
1089+
if (!string.IsNullOrEmpty(output) && File.Exists(output))
1090+
{
1091+
uvPath = output;
1092+
}
1093+
}
1094+
catch
1095+
{
1096+
// Ignore errors
1097+
}
1098+
}
1099+
}
1100+
1101+
if (uvPath == null)
1102+
{
1103+
UnityEngine.Debug.LogError("UV package manager not found! Please install UV first:\n" +
1104+
"• macOS/Linux: curl -LsSf https://astral.sh/uv/install.sh | sh\n" +
1105+
"• Windows: pip install uv\n" +
1106+
"• Or visit: https://docs.astral.sh/uv/getting-started/installation");
1107+
return null;
1108+
}
1109+
1110+
return uvPath;
1111+
}
1112+
10171113
private string FindWindowsUvPath()
10181114
{
10191115
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

0 commit comments

Comments
 (0)