Skip to content

Commit 10e3ef1

Browse files
committed
feat(unity-mcp): add update_gameobject tool and improve GameObject handling prompt
- Implemented update_gameobject tool in both Node.js and Unity C# to allow updating or creating GameObjects via MCP, supporting name, tag, layer, active state, and static state. - Updated MCP gameobject_handling_strategy prompt to document and recommend the new update_gameobject tool, clarifying its use versus update_component. - Improved workflow guidance for GameObject and component operations in Unity.
1 parent 3004f95 commit 10e3ef1

17 files changed

+634
-59
lines changed

.windsurfrules

Lines changed: 95 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
## 1. Project Structure
22

33
- The project consists of two main parts:
4-
- Editor/: A C# Unity Editor package that exposes Unity Editor functionality via a WebSocket bridge.
5-
- Server/: A Node.js server implementing the Model Context Protocol (MCP), using the official TypeScript SDK.
4+
- **`Editor/` (Unity C#/Editor Package)**: A C# Unity Editor package that exposes Unity Editor functionality via a WebSocket bridge.
5+
- **`Server/` (Node.js/TypeScript)**: A Node.js server implementing the Model Context Protocol (MCP), using the official TypeScript SDK.
66

77
## 2. Communication & Protocol
88

9-
- Communication between the Unity Editor and the Node.js MCP server is handled via WebSockets.
10-
- The Unity side uses the `websocket-sharp` library: https://github.com/sta/websocket-sharp/tree/master/websocket-sharp/Server
11-
- The Node.js server uses the `@modelcontextprotocol/sdk` for protocol implementation and exposes tools/resources to LLMs and AI clients.
9+
* **Primary Protocol**: Model Context Protocol (MCP).
10+
* The Unity side uses the `websocket-sharp` library: https://github.com/sta/websocket-sharp/tree/master/websocket-sharp/Server
11+
* The Node.js server uses the `@modelcontextprotocol/sdk` for protocol implementation and exposes tools/resources/prompts to LLMs and AI clients.
12+
* **Transport Layer**: WebSockets.
13+
* Node.js server (`Server/`) acts as a WebSocket *client* to the WebSocket *server* running within the Unity Editor (`Editor/`).
14+
* **Message Format**: JSON. MCP defines the structure for tool/resource calls.
15+
* Node.js tools typically send a request like: `{ method: "csharp_tool_name", params: { ... } }` to Unity via `mcpUnity.sendRequest()`.
16+
* Unity C# tools receive this, execute, and return a `JObject` response.
17+
* **Response Format**: JSON. MCP defines the structure for tool/resource responses.
18+
* Unity C# tools return a `JObject` response.
19+
* Node.js tools receive this and return a `JObject` response.
20+
* **Error Handling**: MCP defines a standard error format.
21+
* Unity C# tools return an error object if an exception occurs.
22+
* Node.js tools receive this and return an error object.
23+
24+
**Communication Flow**:
25+
- Request: AI LLM Assistant -> Node.js MCP Server -> WebSocket Bridge -> Unity Editor Package -> Unity Editor API
26+
- Response: Unity Editor Package -> WebSocket Bridge -> Node.js MCP Server -> AI LLM Assistant
1227

1328
## 3. Minimum Supported Versions
1429

@@ -19,21 +34,38 @@
1934

2035
### Unity Editor Package (Editor/)
2136

22-
- **McpUnityServer**: Singleton entry point for the Unity-side server. Registers tools/resources, manages WebSocket connections, and handles requests from Node.js.
23-
- **McpUnitySocketHandler**: Handles WebSocket messages/events, dispatches tool/resource calls, and manages client connections.
24-
- **Tools**: Modular C# classes implementing various Unity actions (e.g., running tests, modifying the scene, package management).
25-
- **Resources**: Read-only endpoints for querying Unity state (e.g., assets, hierarchy, logs).
26-
- **Services**: Dependency-injected logic for test running, logging, etc., improving testability and maintainability.
27-
- **Utils**: Utility classes for configuration, logging, and workspace integration.
37+
* **`UnityBridge/`**:
38+
* `McpUnityServer.cs`: **Singleton**. The central nervous system on the Unity side. Initializes WebSocket server, registers tools/resources, and dispatches incoming requests to appropriate handlers.
39+
* *LLM Assistant Note*: When adding new tools/resources, they must be registered here in `RegisterTools()` or `RegisterResources()`. Pay attention to how existing tools are instantiated (currently direct `new Tool()`).
40+
* `McpUnitySocketHandler.cs`: Handles individual WebSocket client connections, message parsing, and routing requests to `McpUnityServer` for tool/resource execution.
41+
* `McpUnityEditorWindow.cs`: // TODO: Complete
42+
* **`Tools/`**: Contains C# classes inheriting from `McpToolBase`. Each class implements a specific action that can be triggered in Unity.
43+
* *LLM Assistant Note*: New tools should follow the `McpToolBase` pattern: define `Name` (matching Node.js tool name), `Description`, `IsAsync`, and override `Execute()` or `ExecuteAsync()`. Use `Undo.RecordObject` for actions that modify the scene or assets.
44+
* **`Resources/`**: Contains C# classes inheriting from `McpResourceBase` (assumption, or similar base). These provide read-only access to Unity Editor state.
45+
* *LLM Assistant Note*: New resources should follow the `McpResourceBase` pattern: define `Name` (matching Node.js resource name), `Description`, and override `Fetch()` or `FetchAsync()`
46+
* **`Services/`**: Contains classes providing specific functionalities, often designed for dependency injection.
47+
* Example: `TestRunnerService.cs`, `ConsoleLogsService.cs`.
48+
* *LLM Assistant Note*: Prefer dependency injection for new services. If a tool needs a complex piece of logic, consider abstracting it into a service.
49+
* **`Utils/`**: Utility classes for common tasks like logging (`McpLogger.cs`), settings management (`McpUnitySettings.cs`), GameObject creation (`GameObjectHierarchyCreator.cs`)
2850

2951
### Node.js Server (Server/)
3052

31-
- **index.ts**: Entry point. Sets up the MCP server, registers all tools/resources, and initializes the Unity bridge.
32-
- **unity/mcpUnity.js**: Handles low-level communication with the Unity Editor via WebSocket.
33-
- **tools/**: Implements MCP tool endpoints (e.g., run tests, add asset, select object).
34-
- **resources/**: Implements MCP resource endpoints (e.g., get hierarchy, get logs).
35-
- **utils/**: Logging and helper utilities.
36-
- **package.json**: Declares dependencies, including `@modelcontextprotocol/sdk`, `ws`, `express`, etc.
53+
* **`src/`**:
54+
* `index.ts`: **Entry point**. Initializes the MCP server, registers all MCP tools and resources, and starts the `McpUnity` WebSocket bridge.
55+
* *LLM Assistant Note*: New tools/resources implemented in TypeScript must be registered here using `server.tool(...)` or `server.resource(...)`.
56+
* `unity/mcpUnity.ts` (or [.js](cci:7://file:///c:/Users/migas/Desktop/mcp-unity/Server~/build/prompts/gameobjectHandlingPrompt.js:0:0-0:0) if compiled): Manages the WebSocket client connection *to* the Unity Editor. Handles sending requests and receiving responses.
57+
* **`tools/`**: TypeScript modules defining MCP tools. Each tool module typically:
58+
* Defines input/output schemas using `zod`.
59+
* Provides a registration function (e.g., `registerMyTool(server, mcpUnity, logger)`).
60+
* Implements a `toolHandler` function that interacts with `mcpUnity.sendRequest()` to call the corresponding C# tool in Unity.
61+
* *LLM Assistant Note*: Follow the existing pattern for new tools: define clear Zod schemas, structure the request for `mcpUnity.sendRequest` correctly (matching the C# tool's `Name` and expected parameters).
62+
* **`resources/`**: TypeScript modules defining MCP resources. Similar structure to tools but for read-only data.
63+
* **`prompts/`**: Contains predefined MCP prompts that guide LLMs in using the available tools and resources for specific workflows.
64+
* *LLM Assistant Note*: If a new complex workflow emerges, consider adding a prompt here. Prompts should clearly list relevant tools/resources and outline step-by-step procedures.
65+
* **`utils/`**: Helper utilities, e.g., `logger.ts`, `errors.ts`.
66+
* **`package.json`**: Manages Node.js dependencies, scripts for building (`tsc`), running, and debugging, including `@modelcontextprotocol/sdk`, `ws`, `express`, etc.
67+
* **`tsconfig.json`**: TypeScript compiler configuration.
68+
* **`build/`**: Output directory for compiled JavaScript files from `src/`.
3769

3870
## 5. Integration & Usage
3971

@@ -46,23 +78,58 @@
4678
- Configuration utilities are provided for generating and injecting MCP config into various IDEs (Cursor, Claude Desktop, Windsurf).
4779
- Unity-side settings are persisted in `ProjectSettings/McpUnitySettings.json`.
4880

49-
## 7. Extensibility
50-
51-
- Tools and resources can be extended by adding new C# classes (Unity) or TypeScript modules (Node.js).
52-
- Dependency injection is used on the Unity side for improved modularity and testability.
81+
## 7. Design Patterns & Best Practices
82+
83+
### 7.1. Node.js (Server/ - TypeScript)
84+
85+
* **Modularity**: Keep tools, resources, and utilities in separate files/modules.
86+
* **Schema Validation**: Use `zod` extensively for defining and validating the `inputSchema` for all tools and resources. This catches errors early.
87+
* **Async/Await**: Use `async/await` for all I/O operations, especially calls to Unity.
88+
* **Error Handling**: Implement robust error handling in tool handlers. Use the `McpUnityError` class for custom errors. Return meaningful error messages to the MCP client.
89+
* **Logging**: Use the provided `Logger` for comprehensive logging. Log entry/exit points of handlers, parameters, and significant events.
90+
* **Configuration**: Externalize configuration (e.g., WebSocket ports, though Unity side is primary for port).
91+
* **MCP SDK Adherence**: Follow best practices for the `@modelcontextprotocol/sdk` when registering tools and resources.
92+
93+
### 7.2. Unity C# (Editor/)
94+
95+
* **`McpToolBase` / `McpResourceBase`**: Adhere to the established base class patterns for tools and resources.
96+
* Ensure `Name` property in C# tools matches the `method` string sent from Node.js.
97+
* **Single Responsibility Principle (SRP)**: Tools should be focused on a single task. Complex logic can be delegated to services.
98+
* **Unity API Usage**:
99+
* Use `EditorUtility` for tasks like marking objects dirty (`EditorUtility.SetDirty()`), displaying progress bars, etc.
100+
* Use `Undo.RecordObject()` before modifying any `UnityEngine.Object` to support undo functionality in the editor. Use `Undo.RegisterCreatedObjectUndo()` for newly created objects.
101+
* Be mindful of operations that must run on Unity's main thread. If a tool is `IsAsync = true`, its `ExecuteAsync` method will be marshaled to the main thread.
102+
* **Immutability**: Prefer immutable data structures where possible, though Unity's API often requires direct object manipulation.
103+
* **Error Handling**: Return `JObject` responses indicating success or failure, with clear messages. Use `McpUnitySocketHandler.CreateErrorResponse()` or similar utility if available.
104+
* **Logging**: Use `McpLogger` for consistent logging within Unity.
105+
* **No Blocking Operations in WebSocket Handlers**: For long-running tasks, tools should be marked `IsAsync = true` and use `ExecuteAsync` to avoid blocking the WebSocket communication thread.
106+
* **Dependency Injection**: The project shows a trend towards DI (e.g., `TestRunnerService`). Prefer injecting dependencies into services and tools where practical, rather than relying on singletons or static access, to improve testability and maintainability.
107+
* If `McpUnityServer` needs to provide these, they should be initialized in its constructor or an `InitializeServices` method and passed down.
53108

54109
## 8. References
55110

56111
- MCP Protocol: https://modelcontextprotocol.io
57112
- TypeScript SDK: https://github.com/modelcontextprotocol/typescript-sdk
58113
- Inspector: https://github.com/modelcontextprotocol/inspector
59114

60-
## 9. Conventions
61-
62-
- Use WebSockets for all cross-process communication.
63-
- Follow the MCP protocol for all tool/resource definitions.
64-
- All new tools/resources should be registered in both Unity and Node.js server entry points.
65-
- Follow Conventional Commits for all commit messages.
115+
## 9. Guidelines for LLM assistant Contributions and Conventions
116+
117+
* **Understand the Flow**: Before adding/modifying, trace the call flow from the Node.js tool/resource definition to the corresponding C# handler.
118+
* **Consistency**:
119+
* **Naming**: Follow existing naming conventions for tools, methods, and parameters (e.g., `camelCase` for JSON/JS/TS, `PascalCase` for C#). Tool names (string identifiers) should be consistent across Node.js and C#.
120+
* **Parameter Passing**: If a Node.js tool sends `params.someData`, the C# tool should expect `parameters["someData"]`. For complex objects (like `gameObjectData` or `componentData`), keep them as nested JSON objects.
121+
* **Response Structure**: C# tools should return `JObject`s that the Node.js tool handler can easily process and convert into an MCP `CallToolResult`.
122+
* **Schema First (Node.js)**: When creating a new tool/resource on the Node.js side, define its `zod` schema for parameters first.
123+
* **C# Implementation Second**: Implement the corresponding C# `McpToolBase` (or resource equivalent). Ensure its `Name` matches what the Node.js tool will send.
124+
* **Registration**:
125+
* Register the Node.js tool/resource/prompt in `Server/src/index.ts`.
126+
* Register the C# tool/resource in `Editor/UnityBridge/McpUnityServer.cs`.
127+
* **Prompts**: If adding a significant new capability or workflow, update or add an MCP prompt in `Server/src/prompts/` to guide users/LLMs.
128+
* **Error Handling is Key**: Ensure errors are caught and propagated correctly with informative messages at both Node.js and C# levels.
129+
* **Idempotency**: Where possible, design tools to be idempotent (applying them multiple times with the same input yields the same result). This is not always feasible but is a good goal.
130+
* **Security/Safety**: Be cautious with tools that modify files or execute arbitrary code. Currently, the scope is within Unity, but general caution is advised.
131+
* **Testability**: Write code that is testable. DI helps significantly on the C# side.
132+
* **Conventional Commits**: Follow Conventional Commits for all commit messages. Example: `feat(unity): add new_tool_name for X functionality`.
66133

67134
## 10. Debugging with MCP Inspector
68135

@@ -72,4 +139,4 @@ To debug the MCP Node.js server using the Model Context Protocol Inspector, run
72139
npx @modelcontextprotocol/inspector node Server/build/index.js
73140
```
74141

75-
This will launch the MCP Inspector, allowing you to inspect and debug live MCP traffic between the Node.js server and connected clients (such as Unity or LLM IDEs).
142+
This will launch the MCP Inspector, allowing you to inspect and debug live MCP traffic between the Node.js server and connected clients (such as Unity or LLM AI Assistant IDEs).

Editor/Models.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using Newtonsoft.Json;
3+
4+
namespace McpUnity.Models
5+
{
6+
[Serializable]
7+
public class UpdateGameObjectRequest
8+
{
9+
[JsonProperty("instanceId")]
10+
public int? InstanceId { get; set; }
11+
12+
[JsonProperty("objectPath")]
13+
public string ObjectPath { get; set; }
14+
15+
[JsonProperty("name")]
16+
public string Name { get; set; }
17+
18+
[JsonProperty("tag")]
19+
public string Tag { get; set; }
20+
21+
[JsonProperty("layer")]
22+
public int? Layer { get; set; }
23+
24+
[JsonProperty("isActiveSelf")]
25+
public bool? IsActiveSelf { get; set; }
26+
27+
[JsonProperty("isStatic")]
28+
public bool? IsStatic { get; set; }
29+
}
30+
}

Editor/Resources/GetHierarchyResource.cs.meta renamed to Editor/Models/UpdateGameObjectRequest.cs.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/Resources/GetScenesHierarchyResource.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.

0 commit comments

Comments
 (0)