Skip to content

Commit 7541289

Browse files
committed
Fixed resources and tools to properly work with Unity response type.
Improved information of data that is optional for both resources and tools Renamed PackageManagerTool to AppPackageTool to better reflect it's behaviour
1 parent cd4f21a commit 7541289

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+769
-122
lines changed

Editor/Resources/GetAssetsResource.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public override JObject Fetch(JObject parameters)
3737
return new JObject
3838
{
3939
["success"] = true,
40+
["message"] = $"Retrieved {assets.Count} assets",
4041
["assets"] = assets
4142
};
4243
}

Editor/Resources/GetPackagesResource.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public override JObject Fetch(JObject parameters)
3939
return new JObject
4040
{
4141
["success"] = true,
42+
["message"] = $"Retrieved {projectPackages.Count} project packages and {registryPackages.Count} registry packages",
4243
["projectPackages"] = projectPackages,
4344
["registryPackages"] = registryPackages
4445
};

Editor/Resources/GetTestsResource.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,17 @@ public override JObject Fetch(JObject parameters)
6767
["name"] = test.Name,
6868
["fullName"] = test.FullName,
6969
["path"] = test.Path,
70-
["testMode"] = test.TestMode
70+
["testMode"] = test.TestMode,
71+
["runState"] = test.RunState
7172
});
7273
}
7374

7475
// Return the results
7576
return new JObject
7677
{
78+
["success"] = true,
79+
["message"] = $"Retrieved {allTests.Count} tests",
7780
["tests"] = results,
78-
["count"] = allTests.Count,
7981
["editModeCount"] = allTests.Count(t => t.TestMode.Equals("EditMode", StringComparison.OrdinalIgnoreCase)),
8082
["playModeCount"] = allTests.Count(t => t.TestMode.Equals("PlayMode", StringComparison.OrdinalIgnoreCase))
8183
};

Editor/Services/TestRunnerService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ private void CollectTestItems(ITestAdaptor testAdaptor, List<TestItemInfo> tests
6767
Name = testAdaptor.Name,
6868
FullName = testAdaptor.FullName,
6969
Path = fullPath,
70-
TestMode = testAdaptor.TestMode.ToString()
70+
TestMode = testAdaptor.TestMode.ToString(),
71+
RunState = testAdaptor.RunState.ToString()
7172
});
7273
}
7374
}
@@ -126,5 +127,6 @@ public class TestItemInfo
126127
public string FullName { get; set; }
127128
public string Path { get; set; }
128129
public string TestMode { get; set; }
130+
public string RunState { get; set; }
129131
}
130132
}
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
namespace McpUnity.Tools
1414
{
1515
/// <summary>
16-
/// Tool for managing packages in the Unity Package Manager
16+
/// Tool for adding packages into the Unity Package Manager
1717
/// </summary>
18-
public class PackageManagerTool : McpToolBase
18+
public class AddPackageTool : McpToolBase
1919
{
2020
// Class to track each package operation
2121
private class PackageOperation
@@ -30,28 +30,28 @@ private class PackageOperation
3030
// Flag to track if the update callback is registered
3131
private bool _updateCallbackRegistered = false;
3232

33-
public PackageManagerTool()
33+
public AddPackageTool()
3434
{
35-
Name = "package_manager";
36-
Description = "Manages packages in the Unity Package Manager";
35+
Name = "add_package";
36+
Description = "Adds packages into the Unity Package Manager";
3737
IsAsync = true; // Package Manager operations are asynchronous
3838
}
3939

4040
/// <summary>
41-
/// Execute the PackageManager tool asynchronously
41+
/// Execute the AddPackage tool asynchronously
4242
/// </summary>
4343
/// <param name="parameters">Tool parameters as a JObject</param>
4444
/// <param name="tcs">TaskCompletionSource to set the result or exception</param>
4545
public override void ExecuteAsync(JObject parameters, TaskCompletionSource<JObject> tcs)
4646
{
4747
try
4848
{
49-
// Extract method parameter
50-
string method = parameters["methodSource"]?.ToObject<string>();
51-
if (string.IsNullOrEmpty(method))
49+
// Extract source parameter
50+
string source = parameters["source"]?.ToObject<string>();
51+
if (string.IsNullOrEmpty(source))
5252
{
5353
tcs.SetResult(McpUnitySocketHandler.CreateErrorResponse(
54-
"Required parameter 'methodSource' not provided",
54+
"Required parameter 'source' not provided",
5555
"validation_error"
5656
));
5757
return;
@@ -63,7 +63,7 @@ public override void ExecuteAsync(JObject parameters, TaskCompletionSource<JObje
6363
CompletionSource = tcs
6464
};
6565

66-
switch (method.ToLowerInvariant())
66+
switch (source.ToLowerInvariant())
6767
{
6868
case "registry":
6969
operation.Request = AddFromRegistry(parameters, tcs);
@@ -76,7 +76,7 @@ public override void ExecuteAsync(JObject parameters, TaskCompletionSource<JObje
7676
break;
7777
default:
7878
tcs.SetResult(McpUnitySocketHandler.CreateErrorResponse(
79-
$"Unknown method '{method}'. Valid methods are: registry, github, disk",
79+
$"Unknown method '{source}'. Valid methods are: registry, github, disk",
8080
"validation_error"
8181
));
8282
return;
@@ -103,7 +103,7 @@ public override void ExecuteAsync(JObject parameters, TaskCompletionSource<JObje
103103
catch (Exception ex)
104104
{
105105
// Handle any uncaught exceptions
106-
Debug.LogError($"[MCP Unity] Exception in PackageManagerTool.ExecuteAsync: {ex}");
106+
Debug.LogError($"[MCP Unity] Exception in AddPackageTool.ExecuteAsync: {ex}");
107107
tcs.SetResult(McpUnitySocketHandler.CreateErrorResponse(
108108
$"Internal error: {ex.Message}",
109109
"internal_error"

Editor/Tools/RunTestsTool.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public RunTestsTool(TestRunnerService testRunnerService)
3535
{
3636
Name = "run_tests";
3737
Description = "Runs tests using Unity's Test Runner";
38+
IsAsync = true;
3839

3940
_testRunnerService = testRunnerService;
4041

Editor/Tools/UpdateComponentTool.cs

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ public override JObject Execute(JObject parameters)
2828
{
2929
// Extract parameters
3030
int? instanceId = parameters["instanceId"]?.ToObject<int?>();
31+
string objectPath = parameters["objectPath"]?.ToObject<string>();
3132
string componentName = parameters["componentName"]?.ToObject<string>();
3233
JObject componentData = parameters["componentData"] as JObject;
3334

34-
// Validate parameters
35-
if (!instanceId.HasValue)
35+
// Validate parameters - require either instanceId or objectPath
36+
if (!instanceId.HasValue && string.IsNullOrEmpty(objectPath))
3637
{
3738
return McpUnitySocketHandler.CreateErrorResponse(
38-
"Required parameter 'instanceId' not provided",
39+
"Either 'instanceId' or 'objectPath' must be provided",
3940
"validation_error"
4041
);
4142
}
@@ -48,17 +49,45 @@ public override JObject Execute(JObject parameters)
4849
);
4950
}
5051

51-
// Find the GameObject by instance ID
52-
GameObject gameObject = EditorUtility.InstanceIDToObject(instanceId.Value) as GameObject;
53-
if (gameObject == null)
52+
// Find the GameObject by instance ID or path
53+
GameObject gameObject = null;
54+
string identifier = "unknown";
55+
56+
if (instanceId.HasValue)
5457
{
55-
return McpUnitySocketHandler.CreateErrorResponse(
56-
$"GameObject with instance ID {instanceId.Value} not found",
57-
"not_found_error"
58-
);
58+
gameObject = EditorUtility.InstanceIDToObject(instanceId.Value) as GameObject;
59+
identifier = $"ID {instanceId.Value}";
60+
61+
if (gameObject == null)
62+
{
63+
return McpUnitySocketHandler.CreateErrorResponse(
64+
$"GameObject with instance ID {instanceId.Value} not found",
65+
"not_found_error"
66+
);
67+
}
68+
}
69+
else
70+
{
71+
// Find by path
72+
gameObject = GameObject.Find(objectPath);
73+
identifier = $"path '{objectPath}'";
74+
75+
if (gameObject == null)
76+
{
77+
// Try to find using the Unity Scene hierarchy path
78+
gameObject = FindGameObjectByPath(objectPath);
79+
80+
if (gameObject == null)
81+
{
82+
return McpUnitySocketHandler.CreateErrorResponse(
83+
$"GameObject with path '{objectPath}' not found",
84+
"not_found_error"
85+
);
86+
}
87+
}
5988
}
6089

61-
Debug.Log($"[MCP Unity] Updating component '{componentName}' on GameObject '{gameObject.name}'");
90+
Debug.Log($"[MCP Unity] Updating component '{componentName}' on GameObject '{gameObject.name}' (found by {identifier})");
6291

6392
// Try to find the component by name
6493
Component component = gameObject.GetComponent(componentName);
@@ -105,6 +134,53 @@ public override JObject Execute(JObject parameters)
105134
};
106135
}
107136

137+
/// <summary>
138+
/// Find a GameObject by its hierarchy path
139+
/// </summary>
140+
/// <param name="path">The path to the GameObject (e.g. "Canvas/Panel/Button")</param>
141+
/// <returns>The GameObject if found, null otherwise</returns>
142+
private GameObject FindGameObjectByPath(string path)
143+
{
144+
// Split the path by '/'
145+
string[] pathParts = path.Split('/');
146+
147+
// If the path is empty, return null
148+
if (pathParts.Length == 0)
149+
{
150+
return null;
151+
}
152+
153+
// Search through all root GameObjects in all scenes
154+
foreach (GameObject rootObj in UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects())
155+
{
156+
if (rootObj.name == pathParts[0])
157+
{
158+
// Found the root object, now traverse down the path
159+
GameObject current = rootObj;
160+
161+
// Start from index 1 since we've already matched the root
162+
for (int i = 1; i < pathParts.Length; i++)
163+
{
164+
Transform child = current.transform.Find(pathParts[i]);
165+
if (child == null)
166+
{
167+
// Path segment not found
168+
return null;
169+
}
170+
171+
// Move to the next level
172+
current = child.gameObject;
173+
}
174+
175+
// If we got here, we found the full path
176+
return current;
177+
}
178+
}
179+
180+
// Not found
181+
return null;
182+
}
183+
108184
/// <summary>
109185
/// Find a component type by name
110186
/// </summary>

Editor/UnityBridge/McpUnityEditorWindow.cs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ public class McpUnityEditorWindow : EditorWindow
1313
private GUIStyle _subHeaderStyle;
1414
private GUIStyle _boxStyle;
1515
private GUIStyle _wrappedLabelStyle;
16+
private GUIStyle _connectedClientBoxStyle; // Style for individual connected clients
17+
private GUIStyle _connectedClientLabelStyle; // Style for labels in connected client boxes
1618
private int _selectedTab = 0;
17-
private string[] _tabNames = new string[] { "Server", "Help" };
19+
private readonly string[] _tabNames = { "Server", "Help" };
1820
private bool _isInitialized = false;
1921
private string _mcpConfigJson = "";
2022
private bool _tabsIndentationJson = false;
@@ -125,24 +127,24 @@ private void DrawServerTab()
125127
EditorGUILayout.Space();
126128

127129
EditorGUILayout.LabelField("Connected Clients", EditorStyles.boldLabel);
128-
EditorGUILayout.BeginVertical("box");
130+
EditorGUILayout.BeginVertical("box"); // Keep the default gray box for the container
129131

130132
var clients = mcpUnityServer.GetConnectedClients();
131133

132134
if (clients.Count > 0)
133135
{
134136
foreach (var client in clients)
135137
{
136-
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
138+
EditorGUILayout.BeginVertical(_connectedClientBoxStyle); // Use green background for each client
137139

138140
EditorGUILayout.BeginHorizontal();
139-
EditorGUILayout.LabelField("ID:", GUILayout.Width(50));
141+
EditorGUILayout.LabelField("ID:", _connectedClientLabelStyle, GUILayout.Width(50));
140142
EditorGUILayout.LabelField(client.ID, EditorStyles.boldLabel);
141143
EditorGUILayout.EndHorizontal();
142144

143145
EditorGUILayout.BeginHorizontal();
144-
EditorGUILayout.LabelField("Name:", GUILayout.Width(50));
145-
EditorGUILayout.LabelField(client.Name);
146+
EditorGUILayout.LabelField("Name:", _connectedClientLabelStyle, GUILayout.Width(50));
147+
EditorGUILayout.LabelField(client.Name, _connectedClientLabelStyle);
146148
EditorGUILayout.EndHorizontal();
147149

148150
EditorGUILayout.EndVertical();
@@ -151,7 +153,7 @@ private void DrawServerTab()
151153
}
152154
else
153155
{
154-
EditorGUILayout.LabelField("No clients connected", EditorStyles.label);
156+
EditorGUILayout.LabelField("No clients connected", EditorStyles.centeredGreyMiniLabel);
155157
}
156158

157159
EditorGUILayout.EndVertical();
@@ -287,6 +289,26 @@ private void InitializeStyles()
287289
margin = new RectOffset(0, 0, 10, 10)
288290
};
289291

292+
// Connected client box style with green background
293+
_connectedClientBoxStyle = new GUIStyle(EditorStyles.helpBox)
294+
{
295+
padding = new RectOffset(10, 10, 10, 10),
296+
margin = new RectOffset(0, 0, 5, 5)
297+
};
298+
299+
// Create a light green texture for the background
300+
Texture2D greenTexture = new Texture2D(1, 1);
301+
greenTexture.SetPixel(0, 0, new Color(0.8f, 1.0f, 0.8f, 1.0f)); // Light green color
302+
greenTexture.Apply();
303+
304+
_connectedClientBoxStyle.normal.background = greenTexture;
305+
306+
// Label style for text in connected client boxes (black text for contrast)
307+
_connectedClientLabelStyle = new GUIStyle(EditorStyles.label)
308+
{
309+
normal = { textColor = Color.black }
310+
};
311+
290312
// Wrapped label style for text that needs to wrap
291313
_wrappedLabelStyle = new GUIStyle(EditorStyles.label)
292314
{

Editor/UnityBridge/McpUnityServer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ private void RegisterTools()
149149
_tools.Add(selectGameObjectTool.Name, selectGameObjectTool);
150150

151151
// Register PackageManagerTool
152-
PackageManagerTool packageManagerTool = new PackageManagerTool();
153-
_tools.Add(packageManagerTool.Name, packageManagerTool);
152+
AddPackageTool addPackageTool = new AddPackageTool();
153+
_tools.Add(addPackageTool.Name, addPackageTool);
154154

155155
// Register RunTestsTool
156156
RunTestsTool runTestsTool = new RunTestsTool(_testRunnerService);

0 commit comments

Comments
 (0)