Skip to content
Closed
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
204e95a
fix: resolve UV path override not being detected in System Requirements
whatevertogo Jan 11, 2026
25e5d05
fix: improve uv/uvx detection robustness on macOS and Linux
whatevertogo Jan 11, 2026
cc22320
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 11, 2026
8d5fa2f
refactor: unify process execution with ExecPath.TryRun and add Window…
whatevertogo Jan 11, 2026
84cee8c
fix: improve version parsing to handle both spaces and parentheses
whatevertogo Jan 11, 2026
510e631
refactor: improve platform detectors with absolute path resolution
whatevertogo Jan 11, 2026
bf41479
fix: improve error handling in PathResolverService by logging exceptions
whatevertogo Jan 11, 2026
f39857c
Remove .meta files added after fork and update .gitignore
whatevertogo Jan 11, 2026
c4be11c
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 12, 2026
1832715
Update .gitignore
whatevertogo Jan 12, 2026
554ddd0
save .meta
whatevertogo Jan 12, 2026
fb5909d
refactor: unify uv/uvx naming and path detection across platforms
whatevertogo Jan 12, 2026
254125a
fix: improve validation light(uvxPathStatus) logic for UVX path overr…
whatevertogo Jan 12, 2026
f9ae5d5
refactor: streamline UV version validation and unify path detection m…
whatevertogo Jan 12, 2026
84cb9c6
fix: add type handling for Claude Code client in config JSON builder
whatevertogo Jan 12, 2026
ee33077
fix: correct command from 'uvx' to 'uv' for Python version listing in…
whatevertogo Jan 12, 2026
2c3ebcd
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 14, 2026
66fe194
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 15, 2026
79bce47
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 16, 2026
1877cc2
feat: add uvx path fallback with warning UI
whatevertogo Jan 17, 2026
f9b0563
refactor: remove GetDetails method from PlatformDetectorBase
whatevertogo Jan 17, 2026
c86eb78
Update ExecPath.cs
Scriptwonder Jan 17, 2026
a05d1c7
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 18, 2026
396f248
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 19, 2026
a0c07ec
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 20, 2026
4916b12
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 21, 2026
a3c2f30
Merge branch 'CoplayDev:main' into main
whatevertogo Jan 21, 2026
2d3dd3e
refactor: update configuration paths for Rider GitHub Copilot and str…
whatevertogo Jan 21, 2026
293db3b
fix: enhance error handling for package source and uvx command arguments
whatevertogo Jan 21, 2026
e0bfd96
Update MCPForUnity/Editor/Clients/Configurators/RiderConfigurator.cs
whatevertogo Jan 21, 2026
9e83f83
Update MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs
whatevertogo Jan 21, 2026
88deaf0
chore: remove unnecessary exception documentation from GetMcpServerPa…
whatevertogo Jan 21, 2026
cde5795
Merge branch 'main' of github.com:whatevertogo/unity-mcp
whatevertogo Jan 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions MCPForUnity/Editor/Clients/Configurators/RiderConfigurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ public class RiderConfigurator : JsonFileMcpConfigurator
public RiderConfigurator() : base(new McpClient
{
name = "Rider GitHub Copilot",
windowsConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "JetBrains", "Rider", "mcp.json"),
macConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Application Support", "JetBrains", "Rider", "mcp.json"),
linuxConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".config", "JetBrains", "Rider", "mcp.json"),
// Rider GitHub Copilot uses github-copilot/intellij path under LocalApplicationData
windowsConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "github-copilot", "intellij", "mcp.json"),
macConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "github-copilot", "intellij", "mcp.json"),
linuxConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "github-copilot", "intellij", "mcp.json"),
Comment thread
whatevertogo marked this conversation as resolved.
Outdated
IsVsCodeLayout = true
})
{ }
Comment on lines 10 to 19

@coderabbitai coderabbitai Bot Jan 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

GitHub Copilot IntelliJ Rider MCP configuration file path location mcp.json

💡 Result:

Put the mcp.json in Rider’s IDE configuration directory. Default locations:

  • Windows: %APPDATA%\JetBrains\Rider\ (e.g. C:\Users<you>\AppData\Roaming\JetBrains\Rider2025.3). [1][2]
  • macOS: ~/Library/Application Support/JetBrains/Rider. [1][2]
  • Linux: ~/.config/JetBrains/Rider. [1][2]

Rider also exposes the same mcp.json via the Copilot/MCP UI (Open Chat → Agent mode → Configure/Add MCP Tools) which opens the client JSON in the editor. [3]

Sources: JetBrains directories & Rider MCP docs, GitHub Copilot MCP docs. [1] [2] [3]


🏁 Script executed:

# Search for any documentation or comments about Rider configuration paths in the repository
rg -i "rider|intellij" --type md --type cs | head -30

Repository: CoplayDev/unity-mcp

Length of output: 1451


🏁 Script executed:

# Search for any existing Rider or JetBrains related paths in the codebase
rg "Rider|JetBrains" -i --type cs

Repository: CoplayDev/unity-mcp

Length of output: 782


🏁 Script executed:

# Check if there's any documentation or comments about the old ApplicationData path
rg "ApplicationData" -i --type cs -B2 -A2 | head -50

Repository: CoplayDev/unity-mcp

Length of output: 5704


🏁 Script executed:

# Check the retrieved learnings and ServerInstaller reference to understand path conventions
rg "ServerInstaller|AppSupport" --type cs

Repository: CoplayDev/unity-mcp

Length of output: 45


Correct the Rider MCP configuration paths to match JetBrains standards.

The configuration paths must use the JetBrains IDE config directories, not the github-copilot/intellij subdirectory. Update to:

  • Windows: %APPDATA%\JetBrains\Rider<version>\mcp.json (use ApplicationData, not LocalApplicationData)
  • macOS: ~/Library/Application Support/JetBrains/Rider<version>/mcp.json
  • Linux: ~/.config/JetBrains/Rider<version>/mcp.json (use UserProfile/.config, not LocalApplicationData)
🤖 Prompt for AI Agents
In `@MCPForUnity/Editor/Clients/Configurators/RiderConfigurator.cs` around lines
10 - 19, Update the RiderConfigurator McpClient paths to use JetBrains standard
config locations: replace the current github-copilot/intellij
LocalApplicationData-based paths by setting windowsConfigPath to
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"JetBrains", "Rider<version>", "mcp.json") (use ApplicationData, not
LocalApplicationData), set macConfigPath to
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),
"Library", "Application Support", "JetBrains", "Rider<version>", "mcp.json"),
and set linuxConfigPath to
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".config", "JetBrains", "Rider<version>", "mcp.json"); update these three
properties inside the RiderConfigurator() constructor where the McpClient is
created (fields: windowsConfigPath, macConfigPath, linuxConfigPath).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The configuration requires the github copilot's mcp server settings, not the rider's mcp server

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🌐 Web query:

GitHub Copilot MCP configuration JetBrains IntelliJ Rider mcp.json location

💡 Result:

Place depends on scope:

  • Global (all projects): ~/.junie/mcp/mcp.json. [1]
  • Project-level: /.junie/mcp/mcp.json. [1]

You can also open/edit the mcp.json from the Copilot/Agent UI in JetBrains (Configure MCP/Add MCP Tools) which launches the same file editor. [2]

Sources: [1] JetBrains Junie MCP docs; [2] GitHub Copilot MCP docs.


🌐 Web query:

github-copilot intellij configuration path LocalApplicationData

💡 Result:

On Windows:

  • Global/custom instructions and Copilot state: %LOCALAPPDATA%\github-copilot\intellij\ (e.g. C:\Users<you>\AppData\Local\github-copilot\intellij). [1][2]

  • Per‑IDE plugin settings (language allowlist, etc.) are stored in the IDE config/options folder as github-copilot.xml — e.g. in your IntelliJ config directory under ...\JetBrains<IDE>\options\github-copilot.xml. (JetBrains stores IDE config under your user AppData folders on Windows.) [3][1]

Sources:
[1] GitHub Docs — Configuring GitHub Copilot in your environment / Viewing logs.
[2] GitHub Docs mirror / “Manually creating a global custom instructions file” (Windows path).
[3] GitHub blog / github-copilot.xml location (maps to IDE options folder).


@whatevertogo Thank you for the clarification! You're absolutely right. I apologize for the incorrect review comment.

GitHub Copilot, as a plugin within JetBrains IDEs like Rider, maintains its own configuration separate from the IDE's native settings. The LocalApplicationData/github-copilot/intellij/mcp.json path you're using is indeed the correct location for GitHub Copilot's MCP server configuration across JetBrains IDEs.

The paths in your PR correctly target GitHub Copilot's plugin configuration, not Rider's native MCP server settings. This distinction is important, and your implementation is correct.


✏️ Learnings added
Learnt from: whatevertogo
Repo: CoplayDev/unity-mcp PR: 601
File: MCPForUnity/Editor/Clients/Configurators/RiderConfigurator.cs:10-19
Timestamp: 2026-01-21T13:08:37.625Z
Learning: GitHub Copilot plugin in JetBrains IDEs (including Rider) uses its own MCP configuration path separate from the IDE's native configuration: LocalApplicationData/github-copilot/intellij/mcp.json on all platforms (Windows, macOS, Linux). This is distinct from JetBrains native MCP paths like ApplicationData/JetBrains/Rider/mcp.json.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: msanatan
Repo: CoplayDev/unity-mcp PR: 401
File: MCPForUnity/Editor/Clients/Configurators/VSCodeConfigurator.cs:10-18
Timestamp: 2025-11-27T21:09:35.011Z
Learning: VS Code GitHub Copilot MCP configuration supports mcp.json files placed directly in the Code/User directory: %APPDATA%\Code\User\mcp.json on Windows, ~/Library/Application Support/Code/User/mcp.json on macOS, and ~/.config/Code/User/mcp.json on Linux. This is in addition to workspace-scoped .vscode/mcp.json files.

Learnt from: dsarno
Repo: CoplayDev/unity-mcp PR: 265
File: README.md:204-204
Timestamp: 2025-09-05T16:22:04.960Z
Learning: In the Unity MCP project, the ServerInstaller.cs creates a symlink from ~/Library/AppSupport to ~/Library/Application Support on macOS to mitigate argument parsing and quoting issues in some MCP clients. The README documentation should use the shortened AppSupport path, not the full "Application Support" path with spaces.

Learnt from: dsarno
Repo: CoplayDev/unity-mcp PR: 265
File: README.md:204-204
Timestamp: 2025-09-05T16:22:04.960Z
Learning: In the Unity MCP project, the ServerInstaller.cs creates a symlink from ~/Library/AppSupport to ~/Library/Application Support on macOS to mitigate argument parsing and quoting issues in some MCP clients. The README documentation should use the shortened AppSupport path, not the full "Application Support" path with spaces.

Learnt from: msanatan
Repo: CoplayDev/unity-mcp PR: 348
File: MCPForUnity/Editor/Helpers/ConfigJsonBuilder.cs:71-79
Timestamp: 2025-10-24T14:09:08.615Z
Learning: The SystemRoot environment variable on Windows is only required for Codex MCP client configurations due to a Codex bug. Other MCP clients (VSCode, Cursor, Windsurf, Kiro) do not need this environment variable. Codex configurations use TOML format (CodexConfigHelper.cs), while other clients use JSON format (ConfigJsonBuilder.cs).

Learnt from: dsarno
Repo: CoplayDev/unity-mcp PR: 265
File: README.md:204-204
Timestamp: 2025-09-05T16:22:04.960Z
Learning: In the Unity MCP project, the ServerInstaller.cs creates a symlink from ~/Library/AppSupport to ~/Library/Application Support on macOS to avoid spaces in paths that can cause arg parsing and quoting issues in some MCP clients. The README documentation should use the shortened AppSupport path, not the full "Application Support" path.

Expand Down
49 changes: 37 additions & 12 deletions MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,8 @@ private void RegisterWithCapturedValues(
}
else
{
// Note: --reinstall is not supported by uvx, use --no-cache --refresh instead
string devFlags = shouldForceRefresh ? "--no-cache --refresh " : string.Empty;
args = $"mcp add --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{gitUrl}\" {packageName}";
string packageArgs = BuildClaudeUvxArgs(uvxPath, gitUrl, packageName, shouldForceRefresh);
args = $"mcp add --transport stdio UnityMCP -- {packageArgs}";
}

// Remove any existing registrations - handle both "UnityMCP" and "unityMCP" (legacy)
Expand Down Expand Up @@ -599,10 +598,9 @@ private void Register()
else
{
var (uvxPath, gitUrl, packageName) = AssetPathUtility.GetUvxCommandParts();
// Use central helper that checks both DevModeForceServerRefresh AND local path detection.
// Note: --reinstall is not supported by uvx, use --no-cache --refresh instead
string devFlags = AssetPathUtility.ShouldForceUvxRefresh() ? "--no-cache --refresh " : string.Empty;
args = $"mcp add --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{gitUrl}\" {packageName}";
bool shouldForceRefresh = AssetPathUtility.ShouldForceUvxRefresh();
string packageArgs = BuildClaudeUvxArgs(uvxPath, gitUrl, packageName, shouldForceRefresh);
args = $"mcp add --transport stdio UnityMCP -- {packageArgs}";
}

string projectDir = Path.GetDirectoryName(Application.dataPath);
Expand Down Expand Up @@ -698,13 +696,12 @@ public override string GetManualSnippet()
return "# Error: Configuration not available - check paths in Advanced Settings";
}

string packageSource = AssetPathUtility.GetMcpServerPackageSource();
// Use central helper that checks both DevModeForceServerRefresh AND local path detection.
// Note: --reinstall is not supported by uvx, use --no-cache --refresh instead
string devFlags = AssetPathUtility.ShouldForceUvxRefresh() ? "--no-cache --refresh " : string.Empty;
var (_, gitUrl, packageName) = AssetPathUtility.GetUvxCommandParts();
bool shouldForceRefresh = AssetPathUtility.ShouldForceUvxRefresh();
string packageArgs = BuildClaudeUvxArgs(uvxPath, gitUrl, packageName, shouldForceRefresh);

return "# Register the MCP server with Claude Code:\n" +
$"claude mcp add --transport stdio UnityMCP -- \"{uvxPath}\" {devFlags}--from \"{packageSource}\" mcp-for-unity\n\n" +
$"claude mcp add --transport stdio UnityMCP -- {packageArgs}\n\n" +
"# Unregister the MCP server:\n" +
"claude mcp remove UnityMCP\n\n" +
"# List registered servers:\n" +
Expand Down Expand Up @@ -763,5 +760,33 @@ private static string ExtractPackageSourceFromCliOutput(string cliOutput)

return null;
}

/// <summary>
/// Builds the correct uvx package arguments for Claude CLI mcp add command.
/// IMPORTANT: We always need --from because the PyPI package name (mcpforunityserver)
/// differs from the executable name (mcp-for-unity). The uvx command format is:
/// uvx --from PACKAGE_SOURCE EXECUTABLE_NAME --transport stdio
/// Example: uvx --from mcpforunityserver==9.0.8 mcp-for-unity --transport stdio
/// </summary>
private static string BuildClaudeUvxArgs(string uvxPath, string fromUrl, string packageName, bool shouldForceRefresh)
{
// Dev flags
string devFlags = shouldForceRefresh ? "--no-cache --refresh " : string.Empty;

string packageArgs;
if (!string.IsNullOrEmpty(fromUrl))
{
// Always use --from because package name != executable name
// Example: uvx --from mcpforunityserver==9.0.8 mcp-for-unity
packageArgs = $"\"{uvxPath}\" {devFlags}--from \"{fromUrl}\" {packageName}";
}
else
{
// Fallback: packageName only (should not happen in normal use)
packageArgs = $"\"{uvxPath}\" {devFlags}{packageName}";
}
Comment thread
whatevertogo marked this conversation as resolved.
Outdated

Copilot AI Jan 21, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better.

Suggested change
string packageArgs;
if (!string.IsNullOrEmpty(fromUrl))
{
// Always use --from because package name != executable name
// Example: uvx --from mcpforunityserver==9.0.8 mcp-for-unity
packageArgs = $"\"{uvxPath}\" {devFlags}--from \"{fromUrl}\" {packageName}";
}
else
{
// Fallback: packageName only (should not happen in normal use)
packageArgs = $"\"{uvxPath}\" {devFlags}{packageName}";
}
string packageArgs = !string.IsNullOrEmpty(fromUrl)
? $"\"{uvxPath}\" {devFlags}--from \"{fromUrl}\" {packageName}"
: $"\"{uvxPath}\" {devFlags}{packageName}";

Copilot uses AI. Check for mistakes.

return packageArgs;
}
}
}
19 changes: 16 additions & 3 deletions MCPForUnity/Editor/Helpers/AssetPathUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ public static JObject GetPackageJson()
/// Checks for EditorPrefs override first (supports git URLs, file:// paths, etc.),
/// then falls back to PyPI package reference.
/// </summary>
/// <returns>Package source string for uvx --from argument</returns>
/// <returns>Package source string for uvx --from argument (guaranteed non-null)</returns>
/// <exception cref="InvalidOperationException">Thrown when package source cannot be determined</exception>
public static string GetMcpServerPackageSource()
{
// Check for override first (supports git URLs, file:// paths, local paths)
Expand Down Expand Up @@ -182,13 +183,25 @@ public static string GetMcpServerPackageSource()
public static string GetMcpServerGitUrl() => GetMcpServerPackageSource();

/// <summary>
/// Gets structured uvx command parts for different client configurations
/// Gets structured uvx command parts for different client configurations.
/// </summary>
/// <returns>Tuple containing (uvxPath, fromUrl, packageName)</returns>
/// <returns>Tuple containing (uvxPath, fromUrl, packageName) - fromUrl is guaranteed non-null</returns>
/// <exception cref="InvalidOperationException">Thrown when uvx path cannot be determined</exception>
public static (string uvxPath, string fromUrl, string packageName) GetUvxCommandParts()
{
string uvxPath = MCPServiceLocator.Paths.GetUvxPath();
if (string.IsNullOrEmpty(uvxPath))
{
throw new InvalidOperationException("Cannot determine uvx path. Please ensure uv is installed and configured.");
}

string fromUrl = GetMcpServerPackageSource();
// GetMcpServerPackageSource() guarantees non-null, but validate for defense in depth
if (string.IsNullOrEmpty(fromUrl))
{
throw new InvalidOperationException("Cannot determine MCP server package source. This should never happen - please report this bug.");
}

string packageName = "mcp-for-unity";

return (uvxPath, fromUrl, packageName);
Expand Down
41 changes: 29 additions & 12 deletions MCPForUnity/Editor/Helpers/CodexConfigHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,33 @@ private static void AddDevModeArgs(TomlArray args)
args.Add(new TomlString { Value = "--refresh" });
}

/// <summary>
/// Adds package arguments to the TOML array.
/// IMPORTANT: We always need --from because the PyPI package name (mcpforunityserver)
/// differs from the executable name (mcp-for-unity). The uvx command format is:
/// uvx --from PACKAGE_SOURCE EXECUTABLE_NAME --transport stdio
/// Example: uvx --from mcpforunityserver==9.0.8 mcp-for-unity --transport stdio
/// </summary>
/// <param name="args">The TOML array to add arguments to</param>
/// <param name="fromUrl">Package source for --from argument (guaranteed non-null from GetUvxCommandParts)</param>
/// <param name="packageName">Executable name to run</param>
private static void AddPackageArgs(TomlArray args, string fromUrl, string packageName)
{
if (args == null) return;

// fromUrl is guaranteed non-null by GetUvxCommandParts(), but validate for defense in depth
if (string.IsNullOrEmpty(fromUrl))
{
throw new InvalidOperationException("Package source (--from argument) cannot be empty. This should never happen - please report this bug.");
}
Comment thread
sourcery-ai[bot] marked this conversation as resolved.

// Always use --from because package name != executable name
args.Add(new TomlString { Value = "--from" });
args.Add(new TomlString { Value = fromUrl });

args.Add(new TomlString { Value = packageName });
}

public static string BuildCodexServerBlock(string uvPath)
{
var table = new TomlTable();
Expand Down Expand Up @@ -54,12 +81,7 @@ public static string BuildCodexServerBlock(string uvPath)

var args = new TomlArray();
AddDevModeArgs(args);
if (!string.IsNullOrEmpty(fromUrl))
{
args.Add(new TomlString { Value = "--from" });
args.Add(new TomlString { Value = fromUrl });
}
args.Add(new TomlString { Value = packageName });
AddPackageArgs(args, fromUrl, packageName);
args.Add(new TomlString { Value = "--transport" });
args.Add(new TomlString { Value = "stdio" });

Expand Down Expand Up @@ -203,12 +225,7 @@ private static TomlTable CreateUnityMcpTable(string uvPath)

var argsArray = new TomlArray();
AddDevModeArgs(argsArray);
if (!string.IsNullOrEmpty(fromUrl))
{
argsArray.Add(new TomlString { Value = "--from" });
argsArray.Add(new TomlString { Value = fromUrl });
}
argsArray.Add(new TomlString { Value = packageName });
AddPackageArgs(argsArray, fromUrl, packageName);
argsArray.Add(new TomlString { Value = "--transport" });
argsArray.Add(new TomlString { Value = "stdio" });
unityMCP["args"] = argsArray;
Expand Down
17 changes: 12 additions & 5 deletions MCPForUnity/Editor/Helpers/ConfigJsonBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ private static IList<string> BuildUvxArgs(string fromUrl, string packageName)
// Dev mode: force a fresh install/resolution (avoids stale cached builds while iterating).
// `--no-cache` avoids reading from cache; `--refresh` ensures metadata is revalidated.
// Note: --reinstall is not supported by uvx and will cause a warning.
// Keep ordering consistent with other uvx builders: dev flags first, then --from <url>, then package name.
var args = new List<string>();

// Use central helper that checks both DevModeForceServerRefresh AND local path detection.
Expand All @@ -170,13 +169,21 @@ private static IList<string> BuildUvxArgs(string fromUrl, string packageName)
args.Add("--no-cache");
args.Add("--refresh");
}
if (!string.IsNullOrEmpty(fromUrl))

// IMPORTANT: We always need --from because the PyPI package name (mcpforunityserver)
// differs from the executable name (mcp-for-unity). The uvx command format is:
// uvx --from PACKAGE_SOURCE EXECUTABLE_NAME --transport stdio
// Example: uvx --from mcpforunityserver==9.0.8 mcp-for-unity --transport stdio
// fromUrl is guaranteed non-null by GetUvxCommandParts(), but validate for defense in depth
if (string.IsNullOrEmpty(fromUrl))
{
args.Add("--from");
args.Add(fromUrl);
throw new InvalidOperationException("Package source (--from argument) cannot be empty. This should never happen - please report this bug.");
}
args.Add(packageName);

Comment thread
sourcery-ai[bot] marked this conversation as resolved.
args.Add("--from");
args.Add(fromUrl);

args.Add(packageName);
args.Add("--transport");
args.Add("stdio");

Expand Down
Loading