Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions TestProjects/UnityMCPTests/Assets/Tests/EditMode/Helpers.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using NUnit.Framework;
using MCPForUnity.Editor.Helpers;

namespace MCPForUnityTests.Editor.Helpers
{
public class CodexConfigHelperTests
{
[Test]
public void TryParseCodexServer_SingleLineArgs_ParsesSuccessfully()
{
string toml = string.Join("\n", new[]
{
"[mcp_servers.unityMCP]",
"command = \"uv\"",
"args = [\"run\", \"--directory\", \"/abs/path\", \"server.py\"]"
});

bool result = CodexConfigHelper.TryParseCodexServer(toml, out string command, out string[] args);

Assert.IsTrue(result, "Parser should detect server definition");
Assert.AreEqual("uv", command);
CollectionAssert.AreEqual(new[] { "run", "--directory", "/abs/path", "server.py" }, args);
}

[Test]
public void TryParseCodexServer_MultiLineArgsWithTrailingComma_ParsesSuccessfully()
{
string toml = string.Join("\n", new[]
{
"[mcp_servers.unityMCP]",
"command = \"uv\"",
"args = [",
" \"run\",",
" \"--directory\",",
" \"/abs/path\",",
" \"server.py\",",
"]"
});

bool result = CodexConfigHelper.TryParseCodexServer(toml, out string command, out string[] args);

Assert.IsTrue(result, "Parser should handle multi-line arrays with trailing comma");
Assert.AreEqual("uv", command);
CollectionAssert.AreEqual(new[] { "run", "--directory", "/abs/path", "server.py" }, args);
}

[Test]
public void TryParseCodexServer_MultiLineArgsWithComments_IgnoresComments()
{
string toml = string.Join("\n", new[]
{
"[mcp_servers.unityMCP]",
"command = \"uv\"",
"args = [",
" \"run\", # launch command",
" \"--directory\",",
" \"/abs/path\",",
" \"server.py\"",
"]"
});

bool result = CodexConfigHelper.TryParseCodexServer(toml, out string command, out string[] args);

Assert.IsTrue(result, "Parser should tolerate comments within the array block");
Assert.AreEqual("uv", command);
CollectionAssert.AreEqual(new[] { "run", "--directory", "/abs/path", "server.py" }, args);
}

[Test]
public void TryParseCodexServer_HeaderWithComment_StillDetected()
{
string toml = string.Join("\n", new[]
{
"[mcp_servers.unityMCP] # annotated header",
"command = \"uv\"",
"args = [\"run\", \"--directory\", \"/abs/path\", \"server.py\"]"
});

bool result = CodexConfigHelper.TryParseCodexServer(toml, out string command, out string[] args);

Assert.IsTrue(result, "Parser should recognize section headers even with inline comments");
Assert.AreEqual("uv", command);
CollectionAssert.AreEqual(new[] { "run", "--directory", "/abs/path", "server.py" }, args);
}

[Test]
public void TryParseCodexServer_SingleQuotedArgsWithApostrophes_ParsesSuccessfully()
{
string toml = string.Join("\n", new[]
{
"[mcp_servers.unityMCP]",
"command = 'uv'",
"args = ['run', '--directory', '/Users/O''Connor/codex', 'server.py']"
});

bool result = CodexConfigHelper.TryParseCodexServer(toml, out string command, out string[] args);

Assert.IsTrue(result, "Parser should accept single-quoted arrays with escaped apostrophes");
Assert.AreEqual("uv", command);
CollectionAssert.AreEqual(new[] { "run", "--directory", "/Users/O'Connor/codex", "server.py" }, args);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public void SetUp()
EditorPrefs.SetString("MCPForUnity.ServerSrc", _serverSrcDir);
// Ensure no lock is enabled
EditorPrefs.SetBool("MCPForUnity.LockCursorConfig", false);
// Disable auto-registration to avoid hitting user configs during tests
EditorPrefs.SetBool("MCPForUnity.AutoRegisterEnabled", false);
}

[TearDown]
Expand All @@ -54,6 +56,7 @@ public void TearDown()
// Clean up editor preferences set during SetUp
EditorPrefs.DeleteKey("MCPForUnity.ServerSrc");
EditorPrefs.DeleteKey("MCPForUnity.LockCursorConfig");
EditorPrefs.DeleteKey("MCPForUnity.AutoRegisterEnabled");

// Remove temp files
try { if (Directory.Exists(_tempRoot)) Directory.Delete(_tempRoot, true); } catch { }
Expand Down
23 changes: 22 additions & 1 deletion UnityMcpBridge/Editor/Data/McpClients.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,28 @@ public class McpClients
mcpType = McpTypes.Kiro,
configStatus = "Not Configured",
},
// 4) Codex CLI
new()
{
name = "Codex CLI",
windowsConfigPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".codex",
"config.toml"
),
macConfigPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".codex",
"config.toml"
),
linuxConfigPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".codex",
"config.toml"
),
mcpType = McpTypes.Codex,
configStatus = "Not Configured",
},
};

// Initialize status enums after construction
Expand All @@ -174,4 +196,3 @@ public McpClients()
}
}
}

8 changes: 8 additions & 0 deletions UnityMcpBridge/Editor/External.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading