fix: Windows Claude Desktop stdio + Codex beta/timeout config (#650)
* fix: Remove cmd.exe wrapper for Claude Desktop on Windows The cmd.exe /c wrapper was causing stdio pipe issues on Windows, resulting in "Server disconnected" errors in Claude Desktop. Testing confirmed that calling uvx.exe directly works reliably. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Codex config uses centralized beta args and adds startup timeout - Use GetBetaServerFromArgsList() for consistent --prerelease handling - Add startup_timeout_sec = 60 to allow time for uvx package downloads Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>main
parent
62c015d873
commit
13aca5fb1c
|
|
@ -48,16 +48,16 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Stdio mode: Use command and args
|
// Stdio mode: Use command and args
|
||||||
var (uvxPath, fromUrl, packageName) = AssetPathUtility.GetUvxCommandParts();
|
var (uvxPath, _, packageName) = AssetPathUtility.GetUvxCommandParts();
|
||||||
|
|
||||||
unityMCP["command"] = uvxPath;
|
unityMCP["command"] = uvxPath;
|
||||||
|
|
||||||
var args = new TomlArray();
|
var args = new TomlArray();
|
||||||
AddDevModeArgs(args);
|
AddDevModeArgs(args);
|
||||||
if (!string.IsNullOrEmpty(fromUrl))
|
// Use centralized helper for beta server / prerelease args
|
||||||
|
foreach (var arg in AssetPathUtility.GetBetaServerFromArgsList())
|
||||||
{
|
{
|
||||||
args.Add(new TomlString { Value = "--from" });
|
args.Add(new TomlString { Value = arg });
|
||||||
args.Add(new TomlString { Value = fromUrl });
|
|
||||||
}
|
}
|
||||||
args.Add(new TomlString { Value = packageName });
|
args.Add(new TomlString { Value = packageName });
|
||||||
args.Add(new TomlString { Value = "--transport" });
|
args.Add(new TomlString { Value = "--transport" });
|
||||||
|
|
@ -73,6 +73,9 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
envTable["SystemRoot"] = new TomlString { Value = platformService.GetSystemRoot() };
|
envTable["SystemRoot"] = new TomlString { Value = platformService.GetSystemRoot() };
|
||||||
unityMCP["env"] = envTable;
|
unityMCP["env"] = envTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow extra time for uvx to download packages on first run
|
||||||
|
unityMCP["startup_timeout_sec"] = new TomlInteger { Value = 60 };
|
||||||
}
|
}
|
||||||
|
|
||||||
mcpServers["unityMCP"] = unityMCP;
|
mcpServers["unityMCP"] = unityMCP;
|
||||||
|
|
@ -197,16 +200,16 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Stdio mode: Use command and args
|
// Stdio mode: Use command and args
|
||||||
var (uvxPath, fromUrl, packageName) = AssetPathUtility.GetUvxCommandParts();
|
var (uvxPath, _, packageName) = AssetPathUtility.GetUvxCommandParts();
|
||||||
|
|
||||||
unityMCP["command"] = new TomlString { Value = uvxPath };
|
unityMCP["command"] = new TomlString { Value = uvxPath };
|
||||||
|
|
||||||
var argsArray = new TomlArray();
|
var argsArray = new TomlArray();
|
||||||
AddDevModeArgs(argsArray);
|
AddDevModeArgs(argsArray);
|
||||||
if (!string.IsNullOrEmpty(fromUrl))
|
// Use centralized helper for beta server / prerelease args
|
||||||
|
foreach (var arg in AssetPathUtility.GetBetaServerFromArgsList())
|
||||||
{
|
{
|
||||||
argsArray.Add(new TomlString { Value = "--from" });
|
argsArray.Add(new TomlString { Value = arg });
|
||||||
argsArray.Add(new TomlString { Value = fromUrl });
|
|
||||||
}
|
}
|
||||||
argsArray.Add(new TomlString { Value = packageName });
|
argsArray.Add(new TomlString { Value = packageName });
|
||||||
argsArray.Add(new TomlString { Value = "--transport" });
|
argsArray.Add(new TomlString { Value = "--transport" });
|
||||||
|
|
@ -221,6 +224,9 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
envTable["SystemRoot"] = new TomlString { Value = platformService.GetSystemRoot() };
|
envTable["SystemRoot"] = new TomlString { Value = platformService.GetSystemRoot() };
|
||||||
unityMCP["env"] = envTable;
|
unityMCP["env"] = envTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow extra time for uvx to download packages on first run
|
||||||
|
unityMCP["startup_timeout_sec"] = new TomlInteger { Value = 60 };
|
||||||
}
|
}
|
||||||
|
|
||||||
return unityMCP;
|
return unityMCP;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MCPForUnity.Editor.Clients.Configurators;
|
|
||||||
using MCPForUnity.Editor.Constants;
|
using MCPForUnity.Editor.Constants;
|
||||||
using MCPForUnity.Editor.Services;
|
using MCPForUnity.Editor.Services;
|
||||||
using MCPForUnity.Editor.Models;
|
using MCPForUnity.Editor.Models;
|
||||||
|
|
@ -90,20 +88,8 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
|
|
||||||
var toolArgs = BuildUvxArgs(fromUrl, packageName);
|
var toolArgs = BuildUvxArgs(fromUrl, packageName);
|
||||||
|
|
||||||
if (ShouldUseWindowsCmdShim(client))
|
unity["command"] = uvxPath;
|
||||||
{
|
unity["args"] = JArray.FromObject(toolArgs.ToArray());
|
||||||
unity["command"] = ResolveCmdPath();
|
|
||||||
|
|
||||||
var cmdArgs = new List<string> { "/c", uvxPath };
|
|
||||||
cmdArgs.AddRange(toolArgs);
|
|
||||||
|
|
||||||
unity["args"] = JArray.FromObject(cmdArgs.ToArray());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unity["command"] = uvxPath;
|
|
||||||
unity["args"] = JArray.FromObject(toolArgs.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove url/serverUrl if they exist from previous config
|
// Remove url/serverUrl if they exist from previous config
|
||||||
if (unity["url"] != null) unity.Remove("url");
|
if (unity["url"] != null) unity.Remove("url");
|
||||||
|
|
@ -184,27 +170,5 @@ namespace MCPForUnity.Editor.Helpers
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ShouldUseWindowsCmdShim(McpClient client)
|
|
||||||
{
|
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Application.platform == RuntimePlatform.WindowsEditor &&
|
|
||||||
string.Equals(client.name, ClaudeDesktopConfigurator.ClientName, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ResolveCmdPath()
|
|
||||||
{
|
|
||||||
var comSpec = Environment.GetEnvironmentVariable("ComSpec");
|
|
||||||
if (!string.IsNullOrEmpty(comSpec) && File.Exists(comSpec))
|
|
||||||
{
|
|
||||||
return comSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
string system32Cmd = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe");
|
|
||||||
return File.Exists(system32Cmd) ? system32Cmd : "cmd.exe";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue