Skip to content

feat: Enhance MCP tools and add test framework #15

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

Closed
wants to merge 5 commits into from
Closed
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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
**/[Uu]ser[Ss]ettings/
**/[Oo]bj/Debug/

# Development logs and scripts
log.txt
log.txt.meta
**/run_mcp_server_with_logging.sh
**/run_mcp_server_with_logging.sh.meta

# Asset meta data should only be ignored when the corresponding asset is also ignored
!**/[Aa]ssets/**/*.meta

Expand Down
2 changes: 1 addition & 1 deletion Editor/Services/TestRunnerService.cs
Copy link
Owner

Choose a reason for hiding this comment

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

this are too many minutes by default.
If necessary the MCP can define a bigger timeout for a project with huge test suite to pass.

Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public async void ExecuteTests(
TestMode testMode,
string testFilter,
TaskCompletionSource<JObject> completionSource,
int timeoutMinutes = 1)
int timeoutMinutes = 10)
{
// Create filter
var filter = new Filter
Expand Down
8 changes: 8 additions & 0 deletions Editor/Tests.meta

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

7 changes: 6 additions & 1 deletion Editor/Tools/AddAssetToSceneTool.cs
Copy link
Owner

Choose a reason for hiding this comment

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

It should be fine if the instance is created in the root if the parent is not found.
Why return an error to the MCP?

Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,12 @@ public override JObject Execute(JObject parameters)
}
else
{
Debug.LogWarning($"[MCP Unity] Parent object not found, asset will be created at the root of the scene");
// Parent not found, return an error instead of adding to root
string identifier = parentId.HasValue ? $"ID {parentId.Value}" : $"path '{parentPath}'";
return McpUnitySocketHandler.CreateErrorResponse(
$"Parent GameObject not found with {identifier}",
"parent_not_found"
);
}
}

Expand Down
48 changes: 35 additions & 13 deletions Editor/Tools/NotifyMessageTool.cs
Copy link
Owner

Choose a reason for hiding this comment

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

good improvement for more deterministic code development for the AI to guide from

Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
using System;
using System.Threading.Tasks;
using McpUnity.Unity;
using UnityEngine;
using UnityEditor;
using Newtonsoft.Json.Linq;

namespace McpUnity.Tools
{
/// <summary>
/// Tool for sending notification messages to the Unity console
/// Tool for displaying messages in the Unity console
/// </summary>
public class NotifyMessageTool : McpToolBase
{
/// <summary>
/// Supported message types for Unity console output
/// </summary>
private enum MessageType
{
Info,
Warning,
Error
}

public NotifyMessageTool()
{
Name = "notify_message";
Expand All @@ -25,35 +37,45 @@ public override JObject Execute(JObject parameters)
// Extract parameters
string message = parameters["message"]?.ToObject<string>();
string type = parameters["type"]?.ToObject<string>()?.ToLower() ?? "info";


// Validate message
if (string.IsNullOrEmpty(message))
{
return McpUnitySocketHandler.CreateErrorResponse(
"Required parameter 'message' not provided",
"Required parameter 'message' not provided or is empty",
"validation_error"
);
}

// Parse and validate message type
if (!Enum.TryParse<MessageType>(type, true, out var messageType))
{
return McpUnitySocketHandler.CreateErrorResponse(
$"Invalid message type '{type}'. Valid types are: info, warning, error",
"validation_error"
);
}

// Log the message based on type
switch (type)
switch (messageType)
{
case "error":
Debug.LogError($"[MCP]: {message}");
case MessageType.Warning:
Debug.LogWarning($"[MCP Unity] {message}");
break;
case "warning":
Debug.LogWarning($"[MCP]: {message}");
case MessageType.Error:
Debug.LogError($"[MCP Unity] {message}");
break;
default:
Debug.Log($"[MCP]: {message}");
Debug.Log($"[MCP Unity] {message}");
break;
}

// Create the response
return new JObject
{
["success"] = true,
["type"] = "text",
["message"] = $"Message displayed: {message}"
["message"] = $"Message displayed: {message}",
["type"] = "text"
};
}
}
Expand Down
Loading