From 137fcc2420329ca1ff4e6cc8c5367ec0a62ed87d Mon Sep 17 00:00:00 2001 From: Alex Hvesuk Date: Mon, 19 Jan 2026 19:19:04 +0400 Subject: [PATCH 1/3] Automatic uv setup --- .../PlatformDetectors/IPlatformDetector.cs | 6 +++ .../LinuxPlatformDetector.cs | 28 +++++++++++ .../MacOSPlatformDetector.cs | 28 +++++++++++ .../PlatformDetectors/PlatformDetectorBase.cs | 5 ++ .../WindowsPlatformDetector.cs | 30 +++++++++++- .../Editor/Services/PathResolverService.cs | 2 +- .../Services/ServerManagementService.cs | 42 +++++++++++++++++ MCPForUnity/Editor/Windows/MCPSetupWindow.cs | 47 +++++++++++++++++++ .../Editor/Windows/MCPSetupWindow.uxml | 1 + 9 files changed, 187 insertions(+), 2 deletions(-) diff --git a/MCPForUnity/Editor/Dependencies/PlatformDetectors/IPlatformDetector.cs b/MCPForUnity/Editor/Dependencies/PlatformDetectors/IPlatformDetector.cs index 3231105e9..9bf6be106 100644 --- a/MCPForUnity/Editor/Dependencies/PlatformDetectors/IPlatformDetector.cs +++ b/MCPForUnity/Editor/Dependencies/PlatformDetectors/IPlatformDetector.cs @@ -41,5 +41,11 @@ public interface IPlatformDetector /// Get platform-specific uv installation URL /// string GetUvInstallUrl(); + + /// + /// Automatically install uv on this platform + /// + /// True if installation was successful + bool InstallUv(); } } diff --git a/MCPForUnity/Editor/Dependencies/PlatformDetectors/LinuxPlatformDetector.cs b/MCPForUnity/Editor/Dependencies/PlatformDetectors/LinuxPlatformDetector.cs index be9db17f6..3497a9de9 100644 --- a/MCPForUnity/Editor/Dependencies/PlatformDetectors/LinuxPlatformDetector.cs +++ b/MCPForUnity/Editor/Dependencies/PlatformDetectors/LinuxPlatformDetector.cs @@ -92,6 +92,34 @@ public override string GetInstallationRecommendations() Note: Make sure ~/.local/bin is in your PATH for user-local installations."; } + public override bool InstallUv() + { + try + { + McpLog.Info("Attempting to install uv package manager via curl..."); + + var psi = new System.Diagnostics.ProcessStartInfo + { + FileName = "/bin/sh", + Arguments = "-c \"curl -LsSf https://astral.sh/uv/install.sh | sh\"", + UseShellExecute = false, + CreateNoWindow = false + }; + + using var process = System.Diagnostics.Process.Start(psi); + if (process == null) return false; + + process.WaitForExit(60000); + + return process.ExitCode == 0; + } + catch (Exception ex) + { + McpLog.Error($"Failed to install uv: {ex.Message}"); + return false; + } + } + public override DependencyStatus DetectUv() { // First, honor overrides and cross-platform resolution via the base implementation diff --git a/MCPForUnity/Editor/Dependencies/PlatformDetectors/MacOSPlatformDetector.cs b/MCPForUnity/Editor/Dependencies/PlatformDetectors/MacOSPlatformDetector.cs index b162f11ae..afbd8c9ea 100644 --- a/MCPForUnity/Editor/Dependencies/PlatformDetectors/MacOSPlatformDetector.cs +++ b/MCPForUnity/Editor/Dependencies/PlatformDetectors/MacOSPlatformDetector.cs @@ -90,6 +90,34 @@ public override string GetInstallationRecommendations() Note: If using Homebrew, make sure /opt/homebrew/bin is in your PATH."; } + public override bool InstallUv() + { + try + { + McpLog.Info("Attempting to install uv package manager via curl..."); + + var psi = new System.Diagnostics.ProcessStartInfo + { + FileName = "/bin/sh", + Arguments = "-c \"curl -LsSf https://astral.sh/uv/install.sh | sh\"", + UseShellExecute = false, + CreateNoWindow = false + }; + + using var process = System.Diagnostics.Process.Start(psi); + if (process == null) return false; + + process.WaitForExit(60000); + + return process.ExitCode == 0; + } + catch (Exception ex) + { + McpLog.Error($"Failed to install uv: {ex.Message}"); + return false; + } + } + public override DependencyStatus DetectUv() { // First, honor overrides and cross-platform resolution via the base implementation diff --git a/MCPForUnity/Editor/Dependencies/PlatformDetectors/PlatformDetectorBase.cs b/MCPForUnity/Editor/Dependencies/PlatformDetectors/PlatformDetectorBase.cs index c955381d1..53d9dd4bf 100644 --- a/MCPForUnity/Editor/Dependencies/PlatformDetectors/PlatformDetectorBase.cs +++ b/MCPForUnity/Editor/Dependencies/PlatformDetectors/PlatformDetectorBase.cs @@ -18,6 +18,11 @@ public abstract class PlatformDetectorBase : IPlatformDetector public abstract string GetUvInstallUrl(); public abstract string GetInstallationRecommendations(); + public virtual bool InstallUv() + { + return false; + } + public virtual DependencyStatus DetectUv() { var status = new DependencyStatus("uv Package Manager", isRequired: true) diff --git a/MCPForUnity/Editor/Dependencies/PlatformDetectors/WindowsPlatformDetector.cs b/MCPForUnity/Editor/Dependencies/PlatformDetectors/WindowsPlatformDetector.cs index 706e5030f..7d9a0376e 100644 --- a/MCPForUnity/Editor/Dependencies/PlatformDetectors/WindowsPlatformDetector.cs +++ b/MCPForUnity/Editor/Dependencies/PlatformDetectors/WindowsPlatformDetector.cs @@ -94,12 +94,40 @@ public override string GetInstallationRecommendations() - Direct download: https://python.org/downloads/windows/ 2. uv Package Manager: Install via PowerShell - - Run: powershell -ExecutionPolicy ByPass -c ""irm https://astral.sh/uv/install.ps1 | iex"" + - Run: powershell -NoProfile -ExecutionPolicy ByPass -c ""irm https://astral.sh/uv/install.ps1 | iex"" - Or download from: https://github.com/astral-sh/uv/releases 3. MCP Server: Will be installed automatically by MCP for Unity Bridge"; } + public override bool InstallUv() + { + try + { + McpLog.Info("Attempting to install uv package manager via PowerShell..."); + + var psi = new System.Diagnostics.ProcessStartInfo + { + FileName = "powershell.exe", + Arguments = "-NoProfile -ExecutionPolicy ByPass -Command \"irm https://astral.sh/uv/install.ps1 | iex\"", + UseShellExecute = false, + CreateNoWindow = false // Show window so user sees progress + }; + + using var process = System.Diagnostics.Process.Start(psi); + if (process == null) return false; + + process.WaitForExit(60000); // Wait up to 1 minute + + return process.ExitCode == 0; + } + catch (Exception ex) + { + McpLog.Error($"Failed to install uv: {ex.Message}"); + return false; + } + } + public override DependencyStatus DetectUv() { // First, honor overrides and cross-platform resolution via the base implementation diff --git a/MCPForUnity/Editor/Services/PathResolverService.cs b/MCPForUnity/Editor/Services/PathResolverService.cs index 4181cf4c6..3973cf072 100644 --- a/MCPForUnity/Editor/Services/PathResolverService.cs +++ b/MCPForUnity/Editor/Services/PathResolverService.cs @@ -55,7 +55,7 @@ public string GetUvxPath() } // Fallback to bare command - return "uvx"; + return null; } /// diff --git a/MCPForUnity/Editor/Services/ServerManagementService.cs b/MCPForUnity/Editor/Services/ServerManagementService.cs index cd62258d3..9ab399221 100644 --- a/MCPForUnity/Editor/Services/ServerManagementService.cs +++ b/MCPForUnity/Editor/Services/ServerManagementService.cs @@ -7,6 +7,7 @@ using System.Security.Cryptography; using System.Text; using MCPForUnity.Editor.Constants; +using MCPForUnity.Editor.Dependencies; using MCPForUnity.Editor.Helpers; using UnityEditor; using UnityEngine; @@ -410,6 +411,47 @@ public bool StartLocalHttpServer() /// Clean stale Python build artifacts when using a local dev server path AssetPathUtility.CleanLocalServerBuildArtifacts(); + // Check if uv is installed, and offer to install if missing. + var detector = DependencyManager.GetCurrentPlatformDetector(); + var uvStatus = detector.DetectUv(); + if (!uvStatus.IsAvailable) + { + if (EditorUtility.DisplayDialog( + "uv Package Manager Missing", + "The 'uv' package manager is required to run the local MCP server, but it was not found in your PATH.\n\n" + + "Would you like to attempt an automatic installation now?", + "Install uv", + "Cancel")) + { + if (detector.InstallUv()) + { + // Re-check after installation + uvStatus = detector.DetectUv(); + if (!uvStatus.IsAvailable) + { + EditorUtility.DisplayDialog( + "Installation Incomplete", + "uv was installed, but it is not yet detected in the current process PATH. " + + "You may need to restart Unity for the changes to take effect.", + "OK"); + return false; + } + } + else + { + EditorUtility.DisplayDialog( + "Installation Failed", + "Failed to automatically install uv. Please install it manually:\n\n" + detector.GetUvInstallUrl(), + "OK"); + return false; + } + } + else + { + return false; + } + } + if (!TryGetLocalHttpServerCommandParts(out _, out _, out var displayCommand, out var error)) { EditorUtility.DisplayDialog( diff --git a/MCPForUnity/Editor/Windows/MCPSetupWindow.cs b/MCPForUnity/Editor/Windows/MCPSetupWindow.cs index def559d0a..53f51c1ce 100644 --- a/MCPForUnity/Editor/Windows/MCPSetupWindow.cs +++ b/MCPForUnity/Editor/Windows/MCPSetupWindow.cs @@ -25,6 +25,7 @@ public class MCPSetupWindow : EditorWindow private Label installationInstructions; private Button openPythonLinkButton; private Button openUvLinkButton; + private Button autoInstallUvButton; private Button refreshButton; private Button doneButton; @@ -68,6 +69,7 @@ public void CreateGUI() installationInstructions = rootVisualElement.Q