unity-mcp/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Helpers/WriteToConfigTests.cs

252 lines
11 KiB
C#
Raw Normal View History

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using UnityEditor;
Make it easier to add tools (#301) * Add a decorate that wraps around the `mcp.tool` decorator. This will allow us to more easily collect tools * Register tools that's defined in the tools folder * Update Python tools to use new decorator * Convert script_apply_edits tool * Convert last remaining tools with new decorator * Create an attribute so we can identify tools via Reflection * Add attribute to all C# tools * Use reflection to load tools * Initialize command registry to load tools at startup * Update tests * Move Dev docs to docs folder * Add docs for adding custom tools * Update function docs for Python decorator * Add working example of adding a screenshot tool * docs: update relative links in README files Updated the relative links in both README-DEV.md and README-DEV-zh.md to use direct filenames instead of paths relative to the docs directory, improving link correctness when files are accessed from the root directory. * docs: update telemetry documentation path reference Updated the link to TELEMETRY.md in README.md to point to the new docs/ directory location to ensure users can access the telemetry documentation correctly. Also moved the TELEMETRY.md file to the docs/ directory as part of the documentation restructuring. * rename CursorHelp.md to docs/CURSOR_HELP.md Moved the CursorHelp.md file to the docs directory to better organize documentation files and improve project structure. * docs: update CUSTOM_TOOLS.md with improved tool naming documentation and path corrections - Clarified that the `name` argument in `@mcp_for_unity_tool` decorator is optional and defaults to the function name - Added documentation about using all FastMCP `mcp.tool` function decorator options - Updated class naming documentation to mention snake_case conversion by default - Corrected Python file path from `tools/screenshot_tool.py` to `UnityMcpServer~/src/tools/screenshot_tool.py` - Enhanced documentation for tool discovery and usage examples * docs: restructure development documentation and add custom tools guide Rearranged the development section in README.md to better organize the documentation flow. Added a dedicated section for "Adding Custom Tools" with a link to the new CUSTOM_TOOLS.md file, and renamed the previous "For Developers" section to "Contributing to the Project" to better reflect its content. This improves discoverability and organization of the development setup documentation. * docs: update developer documentation and add README links - Added links to developer READMEs in CUSTOM_TOOLS.md to guide users to the appropriate documentation - Fixed typo in README-DEV.md ("roote" → "root") for improved clarity - These changes improve the developer experience by providing better documentation navigation and correcting technical inaccuracies * feat(tools): enhance tool registration with wrapped function assignment Updated the tool registration process to properly chain the mcp.tool decorator and telemetry wrapper, ensuring the wrapped function is correctly assigned to tool_info['func'] for proper tool execution and telemetry tracking. This change improves the reliability of tool registration and monitoring. * Remove AI generated code that was never used... * feat: Rebuild MCP server installation with embedded source Refactored the server repair logic to implement a full rebuild of the MCP server installation using the embedded source. The new RebuildMcpServer method now: - Uses embedded server source instead of attempting repair of existing installation - Deletes the entire existing server directory before re-copying - Handles UV process cleanup for the target path - Simplifies the installation flow by removing the complex Python environment repair logic - Maintains the same installation behavior but with a cleaner, more reliable rebuild approach This change improves reliability of server installations by ensuring a clean slate rebuild rather than attempting to repair potentially corrupted environments. * Add the rebuild server step * docs: clarify tool description field requirements and client compatibility * fix: move initialization flag after tool discovery to prevent race conditions * refactor: remove redundant TryParseVersion overrides in platform detectors * refactor: remove duplicate UV validation code from platform detectors * Update UnityMcpBridge/Editor/Tools/CommandRegistry.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: replace WriteToConfig reflection with direct McpConfigurationHelper call --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-04 06:53:09 +08:00
using MCPForUnity.Editor.Helpers;
using MCPForUnity.Editor.Models;
Make it easier to add tools (#301) * Add a decorate that wraps around the `mcp.tool` decorator. This will allow us to more easily collect tools * Register tools that's defined in the tools folder * Update Python tools to use new decorator * Convert script_apply_edits tool * Convert last remaining tools with new decorator * Create an attribute so we can identify tools via Reflection * Add attribute to all C# tools * Use reflection to load tools * Initialize command registry to load tools at startup * Update tests * Move Dev docs to docs folder * Add docs for adding custom tools * Update function docs for Python decorator * Add working example of adding a screenshot tool * docs: update relative links in README files Updated the relative links in both README-DEV.md and README-DEV-zh.md to use direct filenames instead of paths relative to the docs directory, improving link correctness when files are accessed from the root directory. * docs: update telemetry documentation path reference Updated the link to TELEMETRY.md in README.md to point to the new docs/ directory location to ensure users can access the telemetry documentation correctly. Also moved the TELEMETRY.md file to the docs/ directory as part of the documentation restructuring. * rename CursorHelp.md to docs/CURSOR_HELP.md Moved the CursorHelp.md file to the docs directory to better organize documentation files and improve project structure. * docs: update CUSTOM_TOOLS.md with improved tool naming documentation and path corrections - Clarified that the `name` argument in `@mcp_for_unity_tool` decorator is optional and defaults to the function name - Added documentation about using all FastMCP `mcp.tool` function decorator options - Updated class naming documentation to mention snake_case conversion by default - Corrected Python file path from `tools/screenshot_tool.py` to `UnityMcpServer~/src/tools/screenshot_tool.py` - Enhanced documentation for tool discovery and usage examples * docs: restructure development documentation and add custom tools guide Rearranged the development section in README.md to better organize the documentation flow. Added a dedicated section for "Adding Custom Tools" with a link to the new CUSTOM_TOOLS.md file, and renamed the previous "For Developers" section to "Contributing to the Project" to better reflect its content. This improves discoverability and organization of the development setup documentation. * docs: update developer documentation and add README links - Added links to developer READMEs in CUSTOM_TOOLS.md to guide users to the appropriate documentation - Fixed typo in README-DEV.md ("roote" → "root") for improved clarity - These changes improve the developer experience by providing better documentation navigation and correcting technical inaccuracies * feat(tools): enhance tool registration with wrapped function assignment Updated the tool registration process to properly chain the mcp.tool decorator and telemetry wrapper, ensuring the wrapped function is correctly assigned to tool_info['func'] for proper tool execution and telemetry tracking. This change improves the reliability of tool registration and monitoring. * Remove AI generated code that was never used... * feat: Rebuild MCP server installation with embedded source Refactored the server repair logic to implement a full rebuild of the MCP server installation using the embedded source. The new RebuildMcpServer method now: - Uses embedded server source instead of attempting repair of existing installation - Deletes the entire existing server directory before re-copying - Handles UV process cleanup for the target path - Simplifies the installation flow by removing the complex Python environment repair logic - Maintains the same installation behavior but with a cleaner, more reliable rebuild approach This change improves reliability of server installations by ensuring a clean slate rebuild rather than attempting to repair potentially corrupted environments. * Add the rebuild server step * docs: clarify tool description field requirements and client compatibility * fix: move initialization flag after tool discovery to prevent race conditions * refactor: remove redundant TryParseVersion overrides in platform detectors * refactor: remove duplicate UV validation code from platform detectors * Update UnityMcpBridge/Editor/Tools/CommandRegistry.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: replace WriteToConfig reflection with direct McpConfigurationHelper call --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-04 06:53:09 +08:00
namespace MCPForUnityTests.Editor.Helpers
{
public class WriteToConfigTests
{
private string _tempRoot;
private string _fakeUvPath;
private string _serverSrcDir;
[SetUp]
public void SetUp()
{
// Tests are designed for Linux/macOS runners. Skip on Windows due to ProcessStartInfo
// restrictions when UseShellExecute=false for .cmd/.bat scripts.
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Ignore("WriteToConfig tests are skipped on Windows (CI runs linux).\n" +
"ValidateUvBinarySafe requires launching an actual exe on Windows.");
}
_tempRoot = Path.Combine(Path.GetTempPath(), "UnityMCPTests", Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(_tempRoot);
// Create a fake uv executable that prints a valid version string
_fakeUvPath = Path.Combine(_tempRoot, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "uv.cmd" : "uv");
File.WriteAllText(_fakeUvPath, "#!/bin/sh\n\necho 'uv 9.9.9'\n");
TryChmodX(_fakeUvPath);
// Create a fake server directory with server.py
_serverSrcDir = Path.Combine(_tempRoot, "server-src");
Directory.CreateDirectory(_serverSrcDir);
File.WriteAllText(Path.Combine(_serverSrcDir, "server.py"), "# dummy server\n");
// Point the editor to our server dir (so ResolveServerSrc() uses this)
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]
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 { }
}
// --- Tests ---
[Test]
public void AddsEnvAndDisabledFalse_ForWindsurf()
{
var configPath = Path.Combine(_tempRoot, "windsurf.json");
Make it easier to add tools (#301) * Add a decorate that wraps around the `mcp.tool` decorator. This will allow us to more easily collect tools * Register tools that's defined in the tools folder * Update Python tools to use new decorator * Convert script_apply_edits tool * Convert last remaining tools with new decorator * Create an attribute so we can identify tools via Reflection * Add attribute to all C# tools * Use reflection to load tools * Initialize command registry to load tools at startup * Update tests * Move Dev docs to docs folder * Add docs for adding custom tools * Update function docs for Python decorator * Add working example of adding a screenshot tool * docs: update relative links in README files Updated the relative links in both README-DEV.md and README-DEV-zh.md to use direct filenames instead of paths relative to the docs directory, improving link correctness when files are accessed from the root directory. * docs: update telemetry documentation path reference Updated the link to TELEMETRY.md in README.md to point to the new docs/ directory location to ensure users can access the telemetry documentation correctly. Also moved the TELEMETRY.md file to the docs/ directory as part of the documentation restructuring. * rename CursorHelp.md to docs/CURSOR_HELP.md Moved the CursorHelp.md file to the docs directory to better organize documentation files and improve project structure. * docs: update CUSTOM_TOOLS.md with improved tool naming documentation and path corrections - Clarified that the `name` argument in `@mcp_for_unity_tool` decorator is optional and defaults to the function name - Added documentation about using all FastMCP `mcp.tool` function decorator options - Updated class naming documentation to mention snake_case conversion by default - Corrected Python file path from `tools/screenshot_tool.py` to `UnityMcpServer~/src/tools/screenshot_tool.py` - Enhanced documentation for tool discovery and usage examples * docs: restructure development documentation and add custom tools guide Rearranged the development section in README.md to better organize the documentation flow. Added a dedicated section for "Adding Custom Tools" with a link to the new CUSTOM_TOOLS.md file, and renamed the previous "For Developers" section to "Contributing to the Project" to better reflect its content. This improves discoverability and organization of the development setup documentation. * docs: update developer documentation and add README links - Added links to developer READMEs in CUSTOM_TOOLS.md to guide users to the appropriate documentation - Fixed typo in README-DEV.md ("roote" → "root") for improved clarity - These changes improve the developer experience by providing better documentation navigation and correcting technical inaccuracies * feat(tools): enhance tool registration with wrapped function assignment Updated the tool registration process to properly chain the mcp.tool decorator and telemetry wrapper, ensuring the wrapped function is correctly assigned to tool_info['func'] for proper tool execution and telemetry tracking. This change improves the reliability of tool registration and monitoring. * Remove AI generated code that was never used... * feat: Rebuild MCP server installation with embedded source Refactored the server repair logic to implement a full rebuild of the MCP server installation using the embedded source. The new RebuildMcpServer method now: - Uses embedded server source instead of attempting repair of existing installation - Deletes the entire existing server directory before re-copying - Handles UV process cleanup for the target path - Simplifies the installation flow by removing the complex Python environment repair logic - Maintains the same installation behavior but with a cleaner, more reliable rebuild approach This change improves reliability of server installations by ensuring a clean slate rebuild rather than attempting to repair potentially corrupted environments. * Add the rebuild server step * docs: clarify tool description field requirements and client compatibility * fix: move initialization flag after tool discovery to prevent race conditions * refactor: remove redundant TryParseVersion overrides in platform detectors * refactor: remove duplicate UV validation code from platform detectors * Update UnityMcpBridge/Editor/Tools/CommandRegistry.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: replace WriteToConfig reflection with direct McpConfigurationHelper call --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-04 06:53:09 +08:00
WriteInitialConfig(configPath, isVSCode: false, command: _fakeUvPath, directory: "/old/path");
var client = new McpClient { name = "Windsurf", mcpType = McpTypes.Windsurf };
InvokeWriteToConfig(configPath, client);
var root = JObject.Parse(File.ReadAllText(configPath));
var unity = (JObject)root.SelectToken("mcpServers.unityMCP");
Assert.NotNull(unity, "Expected mcpServers.unityMCP node");
Assert.NotNull(unity["env"], "env should be present for all clients");
Assert.IsTrue(unity["env"]!.Type == JTokenType.Object, "env should be an object");
Assert.AreEqual(false, (bool)unity["disabled"], "disabled:false should be set for Windsurf when missing");
}
[Test]
public void AddsEnvAndDisabledFalse_ForKiro()
{
var configPath = Path.Combine(_tempRoot, "kiro.json");
Make it easier to add tools (#301) * Add a decorate that wraps around the `mcp.tool` decorator. This will allow us to more easily collect tools * Register tools that's defined in the tools folder * Update Python tools to use new decorator * Convert script_apply_edits tool * Convert last remaining tools with new decorator * Create an attribute so we can identify tools via Reflection * Add attribute to all C# tools * Use reflection to load tools * Initialize command registry to load tools at startup * Update tests * Move Dev docs to docs folder * Add docs for adding custom tools * Update function docs for Python decorator * Add working example of adding a screenshot tool * docs: update relative links in README files Updated the relative links in both README-DEV.md and README-DEV-zh.md to use direct filenames instead of paths relative to the docs directory, improving link correctness when files are accessed from the root directory. * docs: update telemetry documentation path reference Updated the link to TELEMETRY.md in README.md to point to the new docs/ directory location to ensure users can access the telemetry documentation correctly. Also moved the TELEMETRY.md file to the docs/ directory as part of the documentation restructuring. * rename CursorHelp.md to docs/CURSOR_HELP.md Moved the CursorHelp.md file to the docs directory to better organize documentation files and improve project structure. * docs: update CUSTOM_TOOLS.md with improved tool naming documentation and path corrections - Clarified that the `name` argument in `@mcp_for_unity_tool` decorator is optional and defaults to the function name - Added documentation about using all FastMCP `mcp.tool` function decorator options - Updated class naming documentation to mention snake_case conversion by default - Corrected Python file path from `tools/screenshot_tool.py` to `UnityMcpServer~/src/tools/screenshot_tool.py` - Enhanced documentation for tool discovery and usage examples * docs: restructure development documentation and add custom tools guide Rearranged the development section in README.md to better organize the documentation flow. Added a dedicated section for "Adding Custom Tools" with a link to the new CUSTOM_TOOLS.md file, and renamed the previous "For Developers" section to "Contributing to the Project" to better reflect its content. This improves discoverability and organization of the development setup documentation. * docs: update developer documentation and add README links - Added links to developer READMEs in CUSTOM_TOOLS.md to guide users to the appropriate documentation - Fixed typo in README-DEV.md ("roote" → "root") for improved clarity - These changes improve the developer experience by providing better documentation navigation and correcting technical inaccuracies * feat(tools): enhance tool registration with wrapped function assignment Updated the tool registration process to properly chain the mcp.tool decorator and telemetry wrapper, ensuring the wrapped function is correctly assigned to tool_info['func'] for proper tool execution and telemetry tracking. This change improves the reliability of tool registration and monitoring. * Remove AI generated code that was never used... * feat: Rebuild MCP server installation with embedded source Refactored the server repair logic to implement a full rebuild of the MCP server installation using the embedded source. The new RebuildMcpServer method now: - Uses embedded server source instead of attempting repair of existing installation - Deletes the entire existing server directory before re-copying - Handles UV process cleanup for the target path - Simplifies the installation flow by removing the complex Python environment repair logic - Maintains the same installation behavior but with a cleaner, more reliable rebuild approach This change improves reliability of server installations by ensuring a clean slate rebuild rather than attempting to repair potentially corrupted environments. * Add the rebuild server step * docs: clarify tool description field requirements and client compatibility * fix: move initialization flag after tool discovery to prevent race conditions * refactor: remove redundant TryParseVersion overrides in platform detectors * refactor: remove duplicate UV validation code from platform detectors * Update UnityMcpBridge/Editor/Tools/CommandRegistry.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: replace WriteToConfig reflection with direct McpConfigurationHelper call --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-04 06:53:09 +08:00
WriteInitialConfig(configPath, isVSCode: false, command: _fakeUvPath, directory: "/old/path");
var client = new McpClient { name = "Kiro", mcpType = McpTypes.Kiro };
InvokeWriteToConfig(configPath, client);
var root = JObject.Parse(File.ReadAllText(configPath));
var unity = (JObject)root.SelectToken("mcpServers.unityMCP");
Assert.NotNull(unity, "Expected mcpServers.unityMCP node");
Assert.NotNull(unity["env"], "env should be present for all clients");
Assert.IsTrue(unity["env"]!.Type == JTokenType.Object, "env should be an object");
Assert.AreEqual(false, (bool)unity["disabled"], "disabled:false should be set for Kiro when missing");
}
[Test]
public void DoesNotAddEnvOrDisabled_ForCursor()
{
var configPath = Path.Combine(_tempRoot, "cursor.json");
Make it easier to add tools (#301) * Add a decorate that wraps around the `mcp.tool` decorator. This will allow us to more easily collect tools * Register tools that's defined in the tools folder * Update Python tools to use new decorator * Convert script_apply_edits tool * Convert last remaining tools with new decorator * Create an attribute so we can identify tools via Reflection * Add attribute to all C# tools * Use reflection to load tools * Initialize command registry to load tools at startup * Update tests * Move Dev docs to docs folder * Add docs for adding custom tools * Update function docs for Python decorator * Add working example of adding a screenshot tool * docs: update relative links in README files Updated the relative links in both README-DEV.md and README-DEV-zh.md to use direct filenames instead of paths relative to the docs directory, improving link correctness when files are accessed from the root directory. * docs: update telemetry documentation path reference Updated the link to TELEMETRY.md in README.md to point to the new docs/ directory location to ensure users can access the telemetry documentation correctly. Also moved the TELEMETRY.md file to the docs/ directory as part of the documentation restructuring. * rename CursorHelp.md to docs/CURSOR_HELP.md Moved the CursorHelp.md file to the docs directory to better organize documentation files and improve project structure. * docs: update CUSTOM_TOOLS.md with improved tool naming documentation and path corrections - Clarified that the `name` argument in `@mcp_for_unity_tool` decorator is optional and defaults to the function name - Added documentation about using all FastMCP `mcp.tool` function decorator options - Updated class naming documentation to mention snake_case conversion by default - Corrected Python file path from `tools/screenshot_tool.py` to `UnityMcpServer~/src/tools/screenshot_tool.py` - Enhanced documentation for tool discovery and usage examples * docs: restructure development documentation and add custom tools guide Rearranged the development section in README.md to better organize the documentation flow. Added a dedicated section for "Adding Custom Tools" with a link to the new CUSTOM_TOOLS.md file, and renamed the previous "For Developers" section to "Contributing to the Project" to better reflect its content. This improves discoverability and organization of the development setup documentation. * docs: update developer documentation and add README links - Added links to developer READMEs in CUSTOM_TOOLS.md to guide users to the appropriate documentation - Fixed typo in README-DEV.md ("roote" → "root") for improved clarity - These changes improve the developer experience by providing better documentation navigation and correcting technical inaccuracies * feat(tools): enhance tool registration with wrapped function assignment Updated the tool registration process to properly chain the mcp.tool decorator and telemetry wrapper, ensuring the wrapped function is correctly assigned to tool_info['func'] for proper tool execution and telemetry tracking. This change improves the reliability of tool registration and monitoring. * Remove AI generated code that was never used... * feat: Rebuild MCP server installation with embedded source Refactored the server repair logic to implement a full rebuild of the MCP server installation using the embedded source. The new RebuildMcpServer method now: - Uses embedded server source instead of attempting repair of existing installation - Deletes the entire existing server directory before re-copying - Handles UV process cleanup for the target path - Simplifies the installation flow by removing the complex Python environment repair logic - Maintains the same installation behavior but with a cleaner, more reliable rebuild approach This change improves reliability of server installations by ensuring a clean slate rebuild rather than attempting to repair potentially corrupted environments. * Add the rebuild server step * docs: clarify tool description field requirements and client compatibility * fix: move initialization flag after tool discovery to prevent race conditions * refactor: remove redundant TryParseVersion overrides in platform detectors * refactor: remove duplicate UV validation code from platform detectors * Update UnityMcpBridge/Editor/Tools/CommandRegistry.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: replace WriteToConfig reflection with direct McpConfigurationHelper call --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-04 06:53:09 +08:00
WriteInitialConfig(configPath, isVSCode: false, command: _fakeUvPath, directory: "/old/path");
var client = new McpClient { name = "Cursor", mcpType = McpTypes.Cursor };
InvokeWriteToConfig(configPath, client);
var root = JObject.Parse(File.ReadAllText(configPath));
var unity = (JObject)root.SelectToken("mcpServers.unityMCP");
Assert.NotNull(unity, "Expected mcpServers.unityMCP node");
Assert.IsNull(unity["env"], "env should not be added for non-Windsurf/Kiro clients");
Assert.IsNull(unity["disabled"], "disabled should not be added for non-Windsurf/Kiro clients");
}
[Test]
public void DoesNotAddEnvOrDisabled_ForVSCode()
{
var configPath = Path.Combine(_tempRoot, "vscode.json");
Make it easier to add tools (#301) * Add a decorate that wraps around the `mcp.tool` decorator. This will allow us to more easily collect tools * Register tools that's defined in the tools folder * Update Python tools to use new decorator * Convert script_apply_edits tool * Convert last remaining tools with new decorator * Create an attribute so we can identify tools via Reflection * Add attribute to all C# tools * Use reflection to load tools * Initialize command registry to load tools at startup * Update tests * Move Dev docs to docs folder * Add docs for adding custom tools * Update function docs for Python decorator * Add working example of adding a screenshot tool * docs: update relative links in README files Updated the relative links in both README-DEV.md and README-DEV-zh.md to use direct filenames instead of paths relative to the docs directory, improving link correctness when files are accessed from the root directory. * docs: update telemetry documentation path reference Updated the link to TELEMETRY.md in README.md to point to the new docs/ directory location to ensure users can access the telemetry documentation correctly. Also moved the TELEMETRY.md file to the docs/ directory as part of the documentation restructuring. * rename CursorHelp.md to docs/CURSOR_HELP.md Moved the CursorHelp.md file to the docs directory to better organize documentation files and improve project structure. * docs: update CUSTOM_TOOLS.md with improved tool naming documentation and path corrections - Clarified that the `name` argument in `@mcp_for_unity_tool` decorator is optional and defaults to the function name - Added documentation about using all FastMCP `mcp.tool` function decorator options - Updated class naming documentation to mention snake_case conversion by default - Corrected Python file path from `tools/screenshot_tool.py` to `UnityMcpServer~/src/tools/screenshot_tool.py` - Enhanced documentation for tool discovery and usage examples * docs: restructure development documentation and add custom tools guide Rearranged the development section in README.md to better organize the documentation flow. Added a dedicated section for "Adding Custom Tools" with a link to the new CUSTOM_TOOLS.md file, and renamed the previous "For Developers" section to "Contributing to the Project" to better reflect its content. This improves discoverability and organization of the development setup documentation. * docs: update developer documentation and add README links - Added links to developer READMEs in CUSTOM_TOOLS.md to guide users to the appropriate documentation - Fixed typo in README-DEV.md ("roote" → "root") for improved clarity - These changes improve the developer experience by providing better documentation navigation and correcting technical inaccuracies * feat(tools): enhance tool registration with wrapped function assignment Updated the tool registration process to properly chain the mcp.tool decorator and telemetry wrapper, ensuring the wrapped function is correctly assigned to tool_info['func'] for proper tool execution and telemetry tracking. This change improves the reliability of tool registration and monitoring. * Remove AI generated code that was never used... * feat: Rebuild MCP server installation with embedded source Refactored the server repair logic to implement a full rebuild of the MCP server installation using the embedded source. The new RebuildMcpServer method now: - Uses embedded server source instead of attempting repair of existing installation - Deletes the entire existing server directory before re-copying - Handles UV process cleanup for the target path - Simplifies the installation flow by removing the complex Python environment repair logic - Maintains the same installation behavior but with a cleaner, more reliable rebuild approach This change improves reliability of server installations by ensuring a clean slate rebuild rather than attempting to repair potentially corrupted environments. * Add the rebuild server step * docs: clarify tool description field requirements and client compatibility * fix: move initialization flag after tool discovery to prevent race conditions * refactor: remove redundant TryParseVersion overrides in platform detectors * refactor: remove duplicate UV validation code from platform detectors * Update UnityMcpBridge/Editor/Tools/CommandRegistry.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: replace WriteToConfig reflection with direct McpConfigurationHelper call --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-04 06:53:09 +08:00
WriteInitialConfig(configPath, isVSCode: true, command: _fakeUvPath, directory: "/old/path");
var client = new McpClient { name = "VSCode", mcpType = McpTypes.VSCode };
InvokeWriteToConfig(configPath, client);
var root = JObject.Parse(File.ReadAllText(configPath));
var unity = (JObject)root.SelectToken("servers.unityMCP");
Assert.NotNull(unity, "Expected servers.unityMCP node");
Assert.IsNull(unity["env"], "env should not be added for VSCode client");
Assert.IsNull(unity["disabled"], "disabled should not be added for VSCode client");
Assert.AreEqual("stdio", (string)unity["type"], "VSCode entry should include type=stdio");
}
2025-10-23 05:38:20 +08:00
[Test]
public void DoesNotAddEnvOrDisabled_ForTrae()
{
var configPath = Path.Combine(_tempRoot, "trae.json");
WriteInitialConfig(configPath, isVSCode: false, command: _fakeUvPath, directory: "/old/path");
Harden MCP tool parameter handling + add material workflow tests (TDD) (#343) * Add TDD tests for MCP material management issues - MCPMaterialTests.cs: Tests for material creation, assignment, and data reading - MCPParameterHandlingTests.cs: Tests for JSON parameter parsing issues - SphereMaterialWorkflowTests.cs: Tests for complete sphere material workflow These tests document the current issues with: - JSON parameter parsing in manage_asset and manage_gameobject tools - Material creation with properties - Material assignment to GameObjects - Material component data reading All tests currently fail (Red phase of TDD) and serve as specifications for what needs to be fixed in the MCP system. * Refine TDD tests to focus on actual MCP tool parameter parsing issues - Removed redundant tests that verify working functionality (GameObjectSerializer, Unity APIs) - Kept focused tests that document the real issue: MCP tool parameter validation - Tests now clearly identify the root cause: JSON string parsing in MCP tools - Tests specify exactly what needs to be fixed: parameter type flexibility The issue is NOT in Unity APIs or serialization (which work fine), but in MCP tool parameter validation being too strict. * Fix port discovery protocol mismatch - Update _try_probe_unity_mcp to recognize Unity bridge welcome message - Unity bridge sends 'WELCOME UNITY-MCP' instead of JSON pong response - Maintains backward compatibility with JSON pong format - Fixes MCP server connection to Unity Editor * Resolve merge: unify manage_gameobject param coercion and schema widening * Tests: add MaterialParameterToolTests; merge port probe fix; widen tool schemas for JSON-string params * refactor: extract JSON coercion helper; docs + exception narrowing\nfix: fail fast on bad component_properties JSON\ntest: unify setup, avoid test-to-test calls\nchore: use relative MCP package path * chore(tests): track MCPToolParameterTests.cs.meta to keep GUID stable * test: decouple MaterialParameterToolTests with helpers (no inter-test calls)
2025-10-24 08:57:27 +08:00
if (!Enum.TryParse<McpTypes>("Trae", out var traeValue))
{
Assert.Ignore("McpTypes.Trae not available in this package version; skipping test.");
}
var client = new McpClient { name = "Trae", mcpType = traeValue };
2025-10-23 05:38:20 +08:00
InvokeWriteToConfig(configPath, client);
var root = JObject.Parse(File.ReadAllText(configPath));
var unity = (JObject)root.SelectToken("mcpServers.unityMCP");
Assert.NotNull(unity, "Expected mcpServers.unityMCP node");
Assert.IsNull(unity["env"], "env should not be added for Trae client");
Assert.IsNull(unity["disabled"], "disabled should not be added for Trae client");
}
[Test]
public void PreservesExistingEnvAndDisabled()
{
var configPath = Path.Combine(_tempRoot, "preserve.json");
// Existing config with env and disabled=true should be preserved
var json = new JObject
{
["mcpServers"] = new JObject
{
["unityMCP"] = new JObject
{
["command"] = _fakeUvPath,
["args"] = new JArray("run", "--directory", "/old/path", "server.py"),
["env"] = new JObject { ["FOO"] = "bar" },
["disabled"] = true
}
}
};
File.WriteAllText(configPath, json.ToString());
var client = new McpClient { name = "Windsurf", mcpType = McpTypes.Windsurf };
InvokeWriteToConfig(configPath, client);
var root = JObject.Parse(File.ReadAllText(configPath));
var unity = (JObject)root.SelectToken("mcpServers.unityMCP");
Assert.NotNull(unity, "Expected mcpServers.unityMCP node");
Assert.AreEqual("bar", (string)unity["env"]!["FOO"], "Existing env should be preserved");
Assert.AreEqual(true, (bool)unity["disabled"], "Existing disabled value should be preserved");
}
// --- Helpers ---
private static void TryChmodX(string path)
{
try
{
var psi = new ProcessStartInfo
{
FileName = "/bin/chmod",
Arguments = "+x \"" + path + "\"",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
using var p = Process.Start(psi);
p?.WaitForExit(2000);
}
catch { /* best-effort on non-Unix */ }
}
private static void WriteInitialConfig(string configPath, bool isVSCode, string command, string directory)
{
Directory.CreateDirectory(Path.GetDirectoryName(configPath)!);
JObject root;
if (isVSCode)
{
root = new JObject
{
["servers"] = new JObject
{
["unityMCP"] = new JObject
{
["command"] = command,
["args"] = new JArray("run", "--directory", directory, "server.py"),
["type"] = "stdio"
}
}
};
}
else
{
root = new JObject
{
["mcpServers"] = new JObject
{
["unityMCP"] = new JObject
{
["command"] = command,
["args"] = new JArray("run", "--directory", directory, "server.py")
}
}
};
}
File.WriteAllText(configPath, root.ToString());
}
private static void InvokeWriteToConfig(string configPath, McpClient client)
{
Make it easier to add tools (#301) * Add a decorate that wraps around the `mcp.tool` decorator. This will allow us to more easily collect tools * Register tools that's defined in the tools folder * Update Python tools to use new decorator * Convert script_apply_edits tool * Convert last remaining tools with new decorator * Create an attribute so we can identify tools via Reflection * Add attribute to all C# tools * Use reflection to load tools * Initialize command registry to load tools at startup * Update tests * Move Dev docs to docs folder * Add docs for adding custom tools * Update function docs for Python decorator * Add working example of adding a screenshot tool * docs: update relative links in README files Updated the relative links in both README-DEV.md and README-DEV-zh.md to use direct filenames instead of paths relative to the docs directory, improving link correctness when files are accessed from the root directory. * docs: update telemetry documentation path reference Updated the link to TELEMETRY.md in README.md to point to the new docs/ directory location to ensure users can access the telemetry documentation correctly. Also moved the TELEMETRY.md file to the docs/ directory as part of the documentation restructuring. * rename CursorHelp.md to docs/CURSOR_HELP.md Moved the CursorHelp.md file to the docs directory to better organize documentation files and improve project structure. * docs: update CUSTOM_TOOLS.md with improved tool naming documentation and path corrections - Clarified that the `name` argument in `@mcp_for_unity_tool` decorator is optional and defaults to the function name - Added documentation about using all FastMCP `mcp.tool` function decorator options - Updated class naming documentation to mention snake_case conversion by default - Corrected Python file path from `tools/screenshot_tool.py` to `UnityMcpServer~/src/tools/screenshot_tool.py` - Enhanced documentation for tool discovery and usage examples * docs: restructure development documentation and add custom tools guide Rearranged the development section in README.md to better organize the documentation flow. Added a dedicated section for "Adding Custom Tools" with a link to the new CUSTOM_TOOLS.md file, and renamed the previous "For Developers" section to "Contributing to the Project" to better reflect its content. This improves discoverability and organization of the development setup documentation. * docs: update developer documentation and add README links - Added links to developer READMEs in CUSTOM_TOOLS.md to guide users to the appropriate documentation - Fixed typo in README-DEV.md ("roote" → "root") for improved clarity - These changes improve the developer experience by providing better documentation navigation and correcting technical inaccuracies * feat(tools): enhance tool registration with wrapped function assignment Updated the tool registration process to properly chain the mcp.tool decorator and telemetry wrapper, ensuring the wrapped function is correctly assigned to tool_info['func'] for proper tool execution and telemetry tracking. This change improves the reliability of tool registration and monitoring. * Remove AI generated code that was never used... * feat: Rebuild MCP server installation with embedded source Refactored the server repair logic to implement a full rebuild of the MCP server installation using the embedded source. The new RebuildMcpServer method now: - Uses embedded server source instead of attempting repair of existing installation - Deletes the entire existing server directory before re-copying - Handles UV process cleanup for the target path - Simplifies the installation flow by removing the complex Python environment repair logic - Maintains the same installation behavior but with a cleaner, more reliable rebuild approach This change improves reliability of server installations by ensuring a clean slate rebuild rather than attempting to repair potentially corrupted environments. * Add the rebuild server step * docs: clarify tool description field requirements and client compatibility * fix: move initialization flag after tool discovery to prevent race conditions * refactor: remove redundant TryParseVersion overrides in platform detectors * refactor: remove duplicate UV validation code from platform detectors * Update UnityMcpBridge/Editor/Tools/CommandRegistry.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: replace WriteToConfig reflection with direct McpConfigurationHelper call --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-04 06:53:09 +08:00
var result = McpConfigurationHelper.WriteMcpConfiguration(
pythonDir: string.Empty,
configPath: configPath,
mcpClient: client
);
Assert.AreEqual("Configured successfully", result, "WriteMcpConfiguration should return success");
}
}
}