Skip to content

Commit 764e625

Browse files
committed
Added new Add asset to scene tool
Added scroller on the help tab to allow user to visualize all the data
1 parent e65f5ae commit 764e625

16 files changed

+405
-38
lines changed

Editor/Resources/GetConsoleLogsResource.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public GetConsoleLogsResource()
2828
{
2929
Name = "get_console_logs";
3030
Description = "Retrieves all logs from the Unity console";
31-
Uri = "logs://console";
31+
Uri = "unity://logs";
3232

3333
// Register for log messages
3434
Application.logMessageReceived += OnLogMessageReceived;
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
using System;
2+
using UnityEngine;
3+
using UnityEditor;
4+
using Newtonsoft.Json.Linq;
5+
using McpUnity.Unity;
6+
7+
namespace McpUnity.Tools
8+
{
9+
/// <summary>
10+
/// Tool for adding assets from the AssetDatabase to the Unity scene
11+
/// </summary>
12+
public class AddAssetToSceneTool : McpToolBase
13+
{
14+
public AddAssetToSceneTool()
15+
{
16+
Name = "add_asset_to_scene";
17+
Description = "Adds an asset from the AssetDatabase to the Unity scene";
18+
}
19+
20+
/// <summary>
21+
/// Execute the AddAssetToScene tool with the provided parameters
22+
/// </summary>
23+
/// <param name="parameters">Tool parameters as a JObject</param>
24+
public override JObject Execute(JObject parameters)
25+
{
26+
// Extract parameters
27+
string assetPath = parameters["assetPath"]?.ToObject<string>();
28+
string guid = parameters["guid"]?.ToObject<string>();
29+
Vector3 position = parameters["position"]?.ToObject<JObject>() != null
30+
? new Vector3(
31+
parameters["position"]["x"]?.ToObject<float>() ?? 0f,
32+
parameters["position"]["y"]?.ToObject<float>() ?? 0f,
33+
parameters["position"]["z"]?.ToObject<float>() ?? 0f
34+
)
35+
: Vector3.zero;
36+
37+
// Optional parent game object
38+
string parentPath = parameters["parentPath"]?.ToObject<string>();
39+
int? parentId = parameters["parentId"]?.ToObject<int?>();
40+
41+
// Validate parameters - require either assetPath or guid
42+
if (string.IsNullOrEmpty(assetPath) && string.IsNullOrEmpty(guid))
43+
{
44+
return McpUnitySocketHandler.CreateErrorResponse(
45+
"Required parameter 'assetPath' or 'guid' not provided",
46+
"validation_error"
47+
);
48+
}
49+
50+
// If we have a GUID but no path, convert GUID to path
51+
if (string.IsNullOrEmpty(assetPath) && !string.IsNullOrEmpty(guid))
52+
{
53+
assetPath = AssetDatabase.GUIDToAssetPath(guid);
54+
if (string.IsNullOrEmpty(assetPath))
55+
{
56+
return McpUnitySocketHandler.CreateErrorResponse(
57+
$"Asset with GUID '{guid}' not found",
58+
"not_found_error"
59+
);
60+
}
61+
}
62+
63+
// Load the asset
64+
UnityEngine.Object asset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetPath);
65+
if (asset == null)
66+
{
67+
return McpUnitySocketHandler.CreateErrorResponse(
68+
$"Failed to load asset at path '{assetPath}'",
69+
"not_found_error"
70+
);
71+
}
72+
73+
// Check if the asset is a prefab or another type that can be instantiated
74+
bool isPrefab = PrefabUtility.GetPrefabAssetType(asset) != PrefabAssetType.NotAPrefab;
75+
bool canInstantiate = asset is GameObject || isPrefab;
76+
77+
if (!canInstantiate)
78+
{
79+
return McpUnitySocketHandler.CreateErrorResponse(
80+
$"Asset of type '{asset.GetType().Name}' cannot be instantiated in the scene",
81+
"invalid_asset_type"
82+
);
83+
}
84+
85+
// Instantiate the asset
86+
GameObject instance = null;
87+
try
88+
{
89+
instance = (GameObject)PrefabUtility.InstantiatePrefab(asset);
90+
91+
// Set position
92+
instance.transform.position = position;
93+
94+
// Set parent if specified
95+
if (!string.IsNullOrEmpty(parentPath) || parentId.HasValue)
96+
{
97+
GameObject parent = null;
98+
99+
// Try to find parent by ID first
100+
if (parentId.HasValue)
101+
{
102+
parent = EditorUtility.InstanceIDToObject(parentId.Value) as GameObject;
103+
}
104+
// Otherwise try to find by path
105+
else if (!string.IsNullOrEmpty(parentPath))
106+
{
107+
parent = GameObject.Find(parentPath);
108+
}
109+
110+
if (parent != null)
111+
{
112+
instance.transform.SetParent(parent.transform, false);
113+
}
114+
else
115+
{
116+
Debug.LogWarning($"[MCP Unity] Parent object not found, asset will be created at the root of the scene");
117+
}
118+
}
119+
120+
// Select the newly created object
121+
Selection.activeGameObject = instance;
122+
EditorGUIUtility.PingObject(instance);
123+
}
124+
catch (Exception ex)
125+
{
126+
return McpUnitySocketHandler.CreateErrorResponse(
127+
$"Error instantiating asset: {ex.Message}",
128+
"instantiation_error"
129+
);
130+
}
131+
132+
// Log the action
133+
Debug.Log($"[MCP Unity] Added asset '{asset.name}' to scene from path '{assetPath}'");
134+
135+
// Create the response
136+
return new JObject
137+
{
138+
["success"] = true,
139+
["type"] = "text",
140+
["message"] = $"Successfully added asset '{asset.name}' with instance ID {instance.GetInstanceID()} to the scene",
141+
["instanceId"] = instance.GetInstanceID()
142+
};
143+
}
144+
}
145+
}

Editor/Tools/AddAssetToSceneTool.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/UnityBridge/McpUnityEditorWindow.cs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class McpUnityEditorWindow : EditorWindow
2121
private bool _isInitialized = false;
2222
private string _mcpConfigJson = "";
2323
private bool _tabsIndentationJson = false;
24+
private Vector2 _helpTabScrollPosition = Vector2.zero;
2425

2526
[MenuItem("Tools/MCP Unity/Server Window", false, 1)]
2627
public static void ShowWindow()
@@ -201,9 +202,12 @@ private void DrawServerTab()
201202

202203
EditorGUILayout.EndVertical();
203204
}
204-
205+
205206
private void DrawHelpTab()
206207
{
208+
// Begin scrollable area
209+
_helpTabScrollPosition = EditorGUILayout.BeginScrollView(_helpTabScrollPosition);
210+
207211
WrappedLabel("About MCP Unity", _subHeaderStyle);
208212
EditorGUILayout.BeginVertical(_boxStyle);
209213
WrappedLabel("MCP Unity is a Unity Editor integration of the Model Context Protocol (MCP), which enables standardized communication between AI models and applications.");
@@ -299,6 +303,15 @@ private void DrawHelpTab()
299303
EditorGUILayout.LabelField("Example prompt:", EditorStyles.miniLabel);
300304
WrappedLabel("Send a notification to Unity that the task has been completed", new GUIStyle(EditorStyles.miniLabel) { fontStyle = FontStyle.Italic });
301305
EditorGUILayout.EndVertical();
306+
EditorGUILayout.Space();
307+
308+
// add_asset_to_scene
309+
WrappedLabel("add_asset_to_scene", EditorStyles.boldLabel);
310+
WrappedLabel("Adds an asset from the AssetDatabase to the Unity scene");
311+
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
312+
EditorGUILayout.LabelField("Example prompt:", EditorStyles.miniLabel);
313+
WrappedLabel("Add the Player prefab from my project to the current scene", new GUIStyle(EditorStyles.miniLabel) { fontStyle = FontStyle.Italic });
314+
EditorGUILayout.EndVertical();
302315

303316
EditorGUILayout.EndVertical();
304317

@@ -308,62 +321,62 @@ private void DrawHelpTab()
308321

309322
EditorGUILayout.BeginVertical(_boxStyle);
310323

311-
// get_menu_items
312-
WrappedLabel("get_menu_items", EditorStyles.boldLabel);
324+
// unity://menu-items
325+
WrappedLabel("unity://menu-items", EditorStyles.boldLabel);
313326
WrappedLabel("Retrieves a list of all available menu items in the Unity Editor");
314327
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
315328
EditorGUILayout.LabelField("Example prompt:", EditorStyles.miniLabel);
316329
WrappedLabel("Show me all available menu items related to GameObject creation", new GUIStyle(EditorStyles.miniLabel) { fontStyle = FontStyle.Italic });
317330
EditorGUILayout.EndVertical();
318331
EditorGUILayout.Space();
319332

320-
// get_hierarchy
321-
WrappedLabel("get_hierarchy", EditorStyles.boldLabel);
333+
// unity://hierarchy
334+
WrappedLabel("unity://hierarchy", EditorStyles.boldLabel);
322335
WrappedLabel("Retrieves a list of all game objects in the Unity hierarchy");
323336
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
324337
EditorGUILayout.LabelField("Example prompt:", EditorStyles.miniLabel);
325338
WrappedLabel("Show me the current scene hierarchy structure", new GUIStyle(EditorStyles.miniLabel) { fontStyle = FontStyle.Italic });
326339
EditorGUILayout.EndVertical();
327340
EditorGUILayout.Space();
328341

329-
// get_gameobject
330-
WrappedLabel("get_gameobject", EditorStyles.boldLabel);
342+
// unity://gameobject/{id}
343+
WrappedLabel("unity://gameobject/{id}", EditorStyles.boldLabel);
331344
WrappedLabel("Retrieves detailed information about a specific GameObject, including all components with serialized properties and fields");
332345
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
333346
EditorGUILayout.LabelField("Example prompt:", EditorStyles.miniLabel);
334347
WrappedLabel("Get me detailed information about the Player GameObject", new GUIStyle(EditorStyles.miniLabel) { fontStyle = FontStyle.Italic });
335348
EditorGUILayout.EndVertical();
336349
EditorGUILayout.Space();
337350

338-
// get_console_logs
339-
WrappedLabel("get_console_logs", EditorStyles.boldLabel);
351+
// unity://logs
352+
WrappedLabel("unity://logs", EditorStyles.boldLabel);
340353
WrappedLabel("Retrieves a list of all logs from the Unity console");
341354
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
342355
EditorGUILayout.LabelField("Example prompt:", EditorStyles.miniLabel);
343356
WrappedLabel("Show me the recent error messages from the Unity console", new GUIStyle(EditorStyles.miniLabel) { fontStyle = FontStyle.Italic });
344357
EditorGUILayout.EndVertical();
345358
EditorGUILayout.Space();
346359

347-
// get_packages
348-
WrappedLabel("get_packages", EditorStyles.boldLabel);
360+
// unity://packages
361+
WrappedLabel("unity://packages", EditorStyles.boldLabel);
349362
WrappedLabel("Retrieves information about installed and available packages from the Unity Package Manager");
350363
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
351364
EditorGUILayout.LabelField("Example prompt:", EditorStyles.miniLabel);
352365
WrappedLabel("List all the packages currently installed in my Unity project", new GUIStyle(EditorStyles.miniLabel) { fontStyle = FontStyle.Italic });
353366
EditorGUILayout.EndVertical();
354367
EditorGUILayout.Space();
355368

356-
// get_assets
357-
WrappedLabel("get_assets", EditorStyles.boldLabel);
369+
// unity://assets
370+
WrappedLabel("unity://assets", EditorStyles.boldLabel);
358371
WrappedLabel("Retrieves information about assets in the Unity Asset Database");
359372
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
360373
EditorGUILayout.LabelField("Example prompt:", EditorStyles.miniLabel);
361374
WrappedLabel("Find all texture assets in my project", new GUIStyle(EditorStyles.miniLabel) { fontStyle = FontStyle.Italic });
362375
EditorGUILayout.EndVertical();
363376
EditorGUILayout.Space();
364377

365-
// get_tests
366-
WrappedLabel("get_tests", EditorStyles.boldLabel);
378+
// unity://tests/{testMode}
379+
WrappedLabel("unity://tests/{testMode}", EditorStyles.boldLabel);
367380
WrappedLabel("Retrieves information about tests in the Unity Test Runner");
368381
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
369382
EditorGUILayout.LabelField("Example prompt:", EditorStyles.miniLabel);
@@ -400,6 +413,9 @@ private void DrawHelpTab()
400413
EditorGUILayout.EndHorizontal();
401414

402415
EditorGUILayout.EndVertical();
416+
417+
// End scrollable area
418+
EditorGUILayout.EndScrollView();
403419
}
404420

405421
#endregion

Editor/UnityBridge/McpUnityServer.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ private void RegisterTools()
168168
// Register UpdateComponentTool
169169
UpdateComponentTool updateComponentTool = new UpdateComponentTool();
170170
_tools.Add(updateComponentTool.Name, updateComponentTool);
171+
172+
// Register AddAssetToSceneTool
173+
AddAssetToSceneTool addAssetToSceneTool = new AddAssetToSceneTool();
174+
_tools.Add(addAssetToSceneTool.Name, addAssetToSceneTool);
171175
}
172176

173177
/// <summary>

README.md

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ MCP Unity is an implementation of the Model Context Protocol for Unity Editor, a
4545

4646
## Features
4747

48+
<a href="https://glama.ai/mcp/servers/@CoderGamester/mcp-unity">
49+
<img width="400" height="200" src="https://glama.ai/mcp/servers/@CoderGamester/mcp-unity/badge" alt="Unity MCP server" />
50+
</a>
51+
4852
### IDE Integration - Package Cache Access
4953

5054
MCP Unity provides automatic integration with VSCode-like IDEs (Visual Studio Code, Cursor, Windsurf) by adding the Unity `Library/PackedCache` folder to your workspace. This feature:
@@ -55,53 +59,50 @@ MCP Unity provides automatic integration with VSCode-like IDEs (Visual Studio Co
5559

5660
### MCP Server Tools
5761

58-
This MCP currently provides the following <ins>tools</ins>:
59-
60-
- <ins>**execute_menu_item**</ins>: Executes Unity menu items (functions tagged with the MenuItem attribute)
62+
- `execute_menu_item`: Executes Unity menu items (functions tagged with the MenuItem attribute)
6163
> **Example prompt:** "Execute the menu item 'GameObject/Create Empty' to create a new empty GameObject"
6264
63-
- <ins>**select_gameobject**</ins>: Selects game objects in the Unity hierarchy by path or instance ID
65+
- `select_gameobject`: Selects game objects in the Unity hierarchy by path or instance ID
6466
> **Example prompt:** "Select the Main Camera object in my scene"
6567
66-
- <ins>**update_component**</ins>: Updates component fields on a GameObject or adds it to the GameObject if it does not contain the component
68+
- `update_component`: Updates component fields on a GameObject or adds it to the GameObject if it does not contain the component
6769
> **Example prompt:** "Add a Rigidbody component to the Player object and set its mass to 5"
6870
69-
- <ins>**add_package**</ins>: Installs new packages in the Unity Package Manager
71+
- `add_package`: Installs new packages in the Unity Package Manager
7072
> **Example prompt:** "Add the TextMeshPro package to my project"
7173
72-
- <ins>**run_tests**</ins>: Runs tests using the Unity Test Runner
74+
- `run_tests`: Runs tests using the Unity Test Runner
7375
> **Example prompt:** "Run all the EditMode tests in my project"
7476
75-
- <ins>**notify_message**</ins>: Displays messages in the Unity Editor
77+
- `notify_message`: Displays messages in the Unity Editor
7678
> **Example prompt:** "Send a notification to Unity that the task has been completed"
7779
80+
- `add_asset_to_scene`: Adds an asset from the AssetDatabase to the Unity scene
81+
> **Example prompt:** "Add the Player prefab from my project to the current scene"
82+
7883
### MCP Server Resources
7984

80-
- <ins>**get_menu_items**</ins>: Retrieves a list of all available menu items in the Unity Editor to facilitate <ins>**execute_menu_item**</ins> tool
85+
- `unity://menu-items`: Retrieves a list of all available menu items in the Unity Editor to facilitate `execute_menu_item` tool
8186
> **Example prompt:** "Show me all available menu items related to GameObject creation"
8287
83-
- <ins>**get_hierarchy**</ins>: Retrieves a list of all game objects in the Unity hierarchy
88+
- `unity://hierarchy`: Retrieves a list of all game objects in the Unity hierarchy
8489
> **Example prompt:** "Show me the current scene hierarchy structure"
8590
86-
- <ins>**get_gameobject**</ins>: Retrieves detailed information about a specific GameObject by instance ID, including all GameObject components with it's serialized properties and fields
91+
- `unity://gameobject/{id}`: Retrieves detailed information about a specific GameObject by instance ID or object path in the scene hierarchy, including all GameObject components with it's serialized properties and fields
8792
> **Example prompt:** "Get me detailed information about the Player GameObject"
8893
89-
- <ins>**get_console_logs**</ins>: Retrieves a list of all logs from the Unity console
94+
- `unity://logs`: Retrieves a list of all logs from the Unity console
9095
> **Example prompt:** "Show me the recent error messages from the Unity console"
9196
92-
- <ins>**get_packages**</ins>: Retrieves information about installed and available packages from the Unity Package Manager
97+
- `unity://packages`: Retrieves information about installed and available packages from the Unity Package Manager
9398
> **Example prompt:** "List all the packages currently installed in my Unity project"
9499
95-
- <ins>**get_assets**</ins>: Retrieves information about assets in the Unity Asset Database
100+
- `unity://assets`: Retrieves information about assets in the Unity Asset Database
96101
> **Example prompt:** "Find all texture assets in my project"
97102
98-
- <ins>**get_tests**</ins>: Retrieves information about tests in the Unity Test Runner
103+
- `unity://tests/{testMode}`: Retrieves information about tests in the Unity Test Runner
99104
> **Example prompt:** "List all available tests in my Unity project"
100105
101-
<a href="https://glama.ai/mcp/servers/@CoderGamester/mcp-unity">
102-
<img width="400" height="200" src="https://glama.ai/mcp/servers/@CoderGamester/mcp-unity/badge" alt="Unity MCP server" />
103-
</a>
104-
105106
## Requirements
106107
- Unity 2022.3 or later - to [install the server](#install-server)
107108
- Node.js 18 or later - to [start the server](#start-server)
@@ -342,8 +343,9 @@ Don't forget to shutdown the server with `Ctrl + C` before closing the terminal
342343
If you have any questions or need support, please open an [issue](https://github.com/CoderGamester/mcp-unity/issues) on this repository.
343344

344345
Alternative you can reach out on:
345-
- [![](https://img.shields.io/badge/LinkedIn-0077B5?style=flat&logo=linkedin&logoColor=white 'LinkedIn')](https://www.linkedin.com/in/miguel-tomas/)
346+
- Linkedin: [![](https://img.shields.io/badge/LinkedIn-0077B5?style=flat&logo=linkedin&logoColor=white 'LinkedIn')](https://www.linkedin.com/in/miguel-tomas/)
346347
- Discord: gamester7178
348+
- Email: game.gamester@gmail.com
347349

348350
## Contributing
349351

0 commit comments

Comments
 (0)