-
Notifications
You must be signed in to change notification settings - Fork 493
Remove asset store download button #348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e7b2da8
b2b3362
1d384cf
99ef567
2fd7362
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -40,19 +40,50 @@ public static JObject ApplyUnityServerToExistingConfig(JObject root, string uvPa | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| return root; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Checks if we should use remote uvx (Asset Store install without embedded server) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static bool ShouldUseRemoteUvx(string directory) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If no directory provided, use remote | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (string.IsNullOrEmpty(directory)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If no embedded server exists, use remote | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!ServerInstaller.HasEmbeddedServer()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Centralized builder that applies all caveats consistently. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// - Sets command/args with provided directory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// - Sets command/args with provided directory OR remote uvx for Asset Store | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// - Ensures env exists | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// - Adds type:"stdio" for VSCode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// - Adds disabled:false for Windsurf/Kiro only when missing | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static void PopulateUnityNode(JObject unity, string uvPath, string directory, McpClient client, bool isVSCode) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unity["command"] = uvPath; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Check if we should use remote uvx (Asset Store without embedded server) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool useRemote = ShouldUseRemoteUvx(directory); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // For Cursor (non-VSCode) on macOS, prefer a no-spaces symlink path to avoid arg parsing issues in some runners | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| string effectiveDir = directory; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (useRemote) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Asset Store install - use remote uvx | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| string version = AssetPathUtility.GetPackageVersion(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| string remoteUrl = $"git+https://github.com/CoplayDev/unity-mcp@v{version}#subdirectory=MCPForUnity/UnityMcpServer~/src"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unity["command"] = "uvx"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unity["args"] = JArray.FromObject(new[] { "--from", remoteUrl, "mcp-for-unity" }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+68
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prevent null command: force remote when uvPath is null. If pythonDir is empty but an embedded server exists, builder may choose local while uvPath is null → writes command = null. Make useRemote depend on uvPath. Apply this diff: - // Check if we should use remote uvx (Asset Store without embedded server)
- bool useRemote = ShouldUseRemoteUvx(directory);
+ // Check if we should use remote uvx (also force remote if uvPath is null)
+ bool useRemote = string.IsNullOrEmpty(uvPath) || ShouldUseRemoteUvx(directory);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Comment on lines
+71
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add Windows env parity (SystemRoot) for JSON configs (remote and local). TOML adds SystemRoot for Windows; JSON path does not. This breaks some Windows clients. Add env consistently. Apply this diff (after setting command/args, before type handling): + // Windows env parity with TOML (issue #315): always include SystemRoot
+ try
+ {
+ var platform = MCPForUnity.Editor.Services.MCPServiceLocator.Platform;
+ if (platform.IsWindows())
+ {
+ var env = unity["env"] as JObject ?? new JObject();
+ env["SystemRoot"] = platform.GetSystemRoot();
+ unity["env"] = env;
+ }
+ }
+ catch { /* best-effort */ }And add the import at top: +using MCPForUnity.Editor.Services;Also applies to: 126-127 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is only needed for Codex, a bug on Codex requires this env var. Other clients, so far, do not need it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @msanatan, thank you for the clarification! I understand now — the SystemRoot environment variable is a Codex-specific requirement due to a bug in that client, and since Codex uses TOML configuration (handled separately in CodexConfigHelper.cs), the JSON configuration path in ConfigJsonBuilder.cs doesn't need it. I'll skip this suggestion for the JSON configs. ✏️ Learnings added
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Git/embedded install - use local path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unity["command"] = uvPath; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // For Cursor (non-VSCode) on macOS, prefer a no-spaces symlink path to avoid arg parsing issues in some runners | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| string effectiveDir = directory; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool isCursor = !isVSCode && (client == null || client.mcpType != McpTypes.VSCode); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isCursor && !string.IsNullOrEmpty(directory)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -92,7 +123,8 @@ private static void PopulateUnityNode(JObject unity, string uvPath, string direc | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unity["args"] = JArray.FromObject(new[] { "run", "--directory", effectiveDir, "server.py" }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unity["args"] = JArray.FromObject(new[] { "run", "--directory", effectiveDir, "server.py" }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isVSCode) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -93,19 +93,27 @@ public static string WriteMcpConfiguration(string pythonDir, string configPath, | |
| } | ||
| catch { } | ||
|
|
||
| // 1) Start from existing, only fill gaps (prefer trusted resolver) | ||
| string uvPath = ServerInstaller.FindUvPath(); | ||
| // Optionally trust existingCommand if it looks like uv/uv.exe | ||
| try | ||
| // 1) Check if we should use remote uvx (Asset Store without embedded server) | ||
| bool useRemote = !ServerInstaller.HasEmbeddedServer() || string.IsNullOrEmpty(pythonDir); | ||
|
|
||
| string uvPath = null; | ||
| if (!useRemote) | ||
| { | ||
| var name = Path.GetFileName((existingCommand ?? string.Empty).Trim()).ToLowerInvariant(); | ||
| if ((name == "uv" || name == "uv.exe") && IsValidUvBinary(existingCommand)) | ||
| // Git/embedded install - need UV path | ||
| uvPath = ServerInstaller.FindUvPath(); | ||
| // Optionally trust existingCommand if it looks like uv/uv.exe | ||
| try | ||
| { | ||
| uvPath = existingCommand; | ||
| var name = Path.GetFileName((existingCommand ?? string.Empty).Trim()).ToLowerInvariant(); | ||
| if ((name == "uv" || name == "uv.exe") && IsValidUvBinary(existingCommand)) | ||
| { | ||
| uvPath = existingCommand; | ||
| } | ||
| } | ||
| catch { } | ||
| if (uvPath == null) return "UV package manager not found. Please install UV first."; | ||
| } | ||
|
Comment on lines
+96
to
115
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Align remote/local decision with builders to avoid null-command configs. When useRemote is true, pass null serverSrc to the builder so it cannot pick local while uvPath is null. Apply this diff: @@
- string uvPath = null;
+ string uvPath = null;
if (!useRemote)
{
@@
- string serverSrc = ResolveServerDirectory(pythonDir, existingArgs);
+ string serverSrc = ResolveServerDirectory(pythonDir, existingArgs);
+ // Force remote downstream if requested
+ string serverDirForConfig = useRemote ? null : serverSrc;
@@
- existingRoot = ConfigJsonBuilder.ApplyUnityServerToExistingConfig(existingRoot, uvPath, serverSrc, mcpClient);
+ existingRoot = ConfigJsonBuilder.ApplyUnityServerToExistingConfig(existingRoot, uvPath, serverDirForConfig, mcpClient);Also applies to: 117-128 🤖 Prompt for AI Agents |
||
| catch { } | ||
| if (uvPath == null) return "UV package manager not found. Please install UV first."; | ||
|
|
||
| string serverSrc = ResolveServerDirectory(pythonDir, existingArgs); | ||
|
|
||
| // Ensure containers exist and write back configuration | ||
|
|
@@ -165,20 +173,28 @@ public static string ConfigureCodexClient(string pythonDir, string configPath, M | |
| CodexConfigHelper.TryParseCodexServer(existingToml, out existingCommand, out existingArgs); | ||
| } | ||
|
|
||
| string uvPath = ServerInstaller.FindUvPath(); | ||
| try | ||
| // Check if we should use remote uvx (Asset Store without embedded server) | ||
| bool useRemote = !ServerInstaller.HasEmbeddedServer() || string.IsNullOrEmpty(pythonDir); | ||
|
|
||
| string uvPath = null; | ||
| if (!useRemote) | ||
| { | ||
| var name = Path.GetFileName((existingCommand ?? string.Empty).Trim()).ToLowerInvariant(); | ||
| if ((name == "uv" || name == "uv.exe") && IsValidUvBinary(existingCommand)) | ||
| // Git/embedded install - need UV path | ||
| uvPath = ServerInstaller.FindUvPath(); | ||
| try | ||
| { | ||
| uvPath = existingCommand; | ||
| var name = Path.GetFileName((existingCommand ?? string.Empty).Trim()).ToLowerInvariant(); | ||
| if ((name == "uv" || name == "uv.exe") && IsValidUvBinary(existingCommand)) | ||
| { | ||
| uvPath = existingCommand; | ||
| } | ||
| } | ||
| } | ||
| catch { } | ||
| catch { } | ||
|
|
||
| if (uvPath == null) | ||
| { | ||
| return "UV package manager not found. Please install UV first."; | ||
| if (uvPath == null) | ||
| { | ||
| return "UV package manager not found. Please install UV first."; | ||
| } | ||
| } | ||
|
Comment on lines
+176
to
198
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same fix for Codex path: pass null serverSrc when remote. Mirrors the JSON path; prevents TOML with command=null if builder picks local. Apply this diff: @@
- string uvPath = null;
+ string uvPath = null;
if (!useRemote)
{
@@
- string serverSrc = ResolveServerDirectory(pythonDir, existingArgs);
+ string serverSrc = ResolveServerDirectory(pythonDir, existingArgs);
+ string serverDirForToml = useRemote ? null : serverSrc;
@@
- string updatedToml = CodexConfigHelper.UpsertCodexServerBlock(existingToml, uvPath, serverSrc);
+ string updatedToml = CodexConfigHelper.UpsertCodexServerBlock(existingToml, uvPath, serverDirForToml);Also applies to: 200-215 🤖 Prompt for AI Agents |
||
|
|
||
| string serverSrc = ResolveServerDirectory(pythonDir, existingArgs); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Force remote when uvPath is null to avoid invalid TOML.
Mirror the JSON fix so command is never null.
Apply this diff:
📝 Committable suggestion
🤖 Prompt for AI Agents