@akiojin/unity-mcp-server 2.14.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +206 -0
  3. package/bin/unity-mcp-server +2 -0
  4. package/package.json +73 -0
  5. package/src/core/codeIndex.js +163 -0
  6. package/src/core/codeIndexDb.js +96 -0
  7. package/src/core/config.js +165 -0
  8. package/src/core/indexWatcher.js +52 -0
  9. package/src/core/projectInfo.js +111 -0
  10. package/src/core/server.js +294 -0
  11. package/src/core/unityConnection.js +426 -0
  12. package/src/handlers/analysis/AnalyzeSceneContentsToolHandler.js +35 -0
  13. package/src/handlers/analysis/FindByComponentToolHandler.js +20 -0
  14. package/src/handlers/analysis/GetAnimatorStateToolHandler.js +37 -0
  15. package/src/handlers/analysis/GetComponentValuesToolHandler.js +20 -0
  16. package/src/handlers/analysis/GetGameObjectDetailsToolHandler.js +35 -0
  17. package/src/handlers/analysis/GetInputActionsStateToolHandler.js +37 -0
  18. package/src/handlers/analysis/GetObjectReferencesToolHandler.js +20 -0
  19. package/src/handlers/asset/AssetDatabaseToolHandler.js +221 -0
  20. package/src/handlers/asset/AssetDependencyToolHandler.js +201 -0
  21. package/src/handlers/asset/AssetImportSettingsToolHandler.js +170 -0
  22. package/src/handlers/asset/CreateMaterialToolHandler.js +96 -0
  23. package/src/handlers/asset/CreatePrefabToolHandler.js +78 -0
  24. package/src/handlers/asset/ExitPrefabModeToolHandler.js +83 -0
  25. package/src/handlers/asset/InstantiatePrefabToolHandler.js +133 -0
  26. package/src/handlers/asset/ModifyMaterialToolHandler.js +76 -0
  27. package/src/handlers/asset/ModifyPrefabToolHandler.js +72 -0
  28. package/src/handlers/asset/OpenPrefabToolHandler.js +121 -0
  29. package/src/handlers/asset/SavePrefabToolHandler.js +106 -0
  30. package/src/handlers/base/BaseToolHandler.js +133 -0
  31. package/src/handlers/compilation/GetCompilationStateToolHandler.js +90 -0
  32. package/src/handlers/component/AddComponentToolHandler.js +126 -0
  33. package/src/handlers/component/GetComponentTypesToolHandler.js +100 -0
  34. package/src/handlers/component/ListComponentsToolHandler.js +85 -0
  35. package/src/handlers/component/ModifyComponentToolHandler.js +143 -0
  36. package/src/handlers/component/RemoveComponentToolHandler.js +108 -0
  37. package/src/handlers/console/ClearConsoleToolHandler.js +160 -0
  38. package/src/handlers/console/ReadConsoleToolHandler.js +276 -0
  39. package/src/handlers/editor/LayerManagementToolHandler.js +160 -0
  40. package/src/handlers/editor/SelectionToolHandler.js +141 -0
  41. package/src/handlers/editor/TagManagementToolHandler.js +129 -0
  42. package/src/handlers/editor/ToolManagementToolHandler.js +135 -0
  43. package/src/handlers/editor/WindowManagementToolHandler.js +125 -0
  44. package/src/handlers/gameobject/CreateGameObjectToolHandler.js +131 -0
  45. package/src/handlers/gameobject/DeleteGameObjectToolHandler.js +101 -0
  46. package/src/handlers/gameobject/FindGameObjectToolHandler.js +119 -0
  47. package/src/handlers/gameobject/GetHierarchyToolHandler.js +132 -0
  48. package/src/handlers/gameobject/ModifyGameObjectToolHandler.js +128 -0
  49. package/src/handlers/index.js +389 -0
  50. package/src/handlers/input/AddInputActionToolHandler.js +20 -0
  51. package/src/handlers/input/AddInputBindingToolHandler.js +20 -0
  52. package/src/handlers/input/CreateActionMapToolHandler.js +20 -0
  53. package/src/handlers/input/CreateCompositeBindingToolHandler.js +20 -0
  54. package/src/handlers/input/GamepadSimulationHandler.js +116 -0
  55. package/src/handlers/input/InputSystemHandler.js +80 -0
  56. package/src/handlers/input/KeyboardSimulationHandler.js +79 -0
  57. package/src/handlers/input/ManageControlSchemesToolHandler.js +20 -0
  58. package/src/handlers/input/MouseSimulationHandler.js +107 -0
  59. package/src/handlers/input/RemoveActionMapToolHandler.js +20 -0
  60. package/src/handlers/input/RemoveAllBindingsToolHandler.js +20 -0
  61. package/src/handlers/input/RemoveInputActionToolHandler.js +20 -0
  62. package/src/handlers/input/RemoveInputBindingToolHandler.js +20 -0
  63. package/src/handlers/input/TouchSimulationHandler.js +142 -0
  64. package/src/handlers/menu/ExecuteMenuItemToolHandler.js +304 -0
  65. package/src/handlers/package/PackageManagerToolHandler.js +248 -0
  66. package/src/handlers/package/RegistryConfigToolHandler.js +198 -0
  67. package/src/handlers/playmode/GetEditorStateToolHandler.js +81 -0
  68. package/src/handlers/playmode/PauseToolHandler.js +44 -0
  69. package/src/handlers/playmode/PlayToolHandler.js +91 -0
  70. package/src/handlers/playmode/StopToolHandler.js +77 -0
  71. package/src/handlers/playmode/WaitForEditorStateToolHandler.js +45 -0
  72. package/src/handlers/scene/CreateSceneToolHandler.js +91 -0
  73. package/src/handlers/scene/GetSceneInfoToolHandler.js +20 -0
  74. package/src/handlers/scene/ListScenesToolHandler.js +58 -0
  75. package/src/handlers/scene/LoadSceneToolHandler.js +92 -0
  76. package/src/handlers/scene/SaveSceneToolHandler.js +76 -0
  77. package/src/handlers/screenshot/AnalyzeScreenshotToolHandler.js +238 -0
  78. package/src/handlers/screenshot/CaptureScreenshotToolHandler.js +692 -0
  79. package/src/handlers/script/BuildCodeIndexToolHandler.js +163 -0
  80. package/src/handlers/script/ScriptCreateClassFileToolHandler.js +60 -0
  81. package/src/handlers/script/ScriptEditStructuredToolHandler.js +173 -0
  82. package/src/handlers/script/ScriptIndexStatusToolHandler.js +61 -0
  83. package/src/handlers/script/ScriptPackagesListToolHandler.js +103 -0
  84. package/src/handlers/script/ScriptReadToolHandler.js +106 -0
  85. package/src/handlers/script/ScriptRefactorRenameToolHandler.js +83 -0
  86. package/src/handlers/script/ScriptRefsFindToolHandler.js +144 -0
  87. package/src/handlers/script/ScriptRemoveSymbolToolHandler.js +79 -0
  88. package/src/handlers/script/ScriptSearchToolHandler.js +320 -0
  89. package/src/handlers/script/ScriptSymbolFindToolHandler.js +117 -0
  90. package/src/handlers/script/ScriptSymbolsGetToolHandler.js +96 -0
  91. package/src/handlers/settings/GetProjectSettingsToolHandler.js +161 -0
  92. package/src/handlers/settings/UpdateProjectSettingsToolHandler.js +272 -0
  93. package/src/handlers/system/GetCommandStatsToolHandler.js +25 -0
  94. package/src/handlers/system/PingToolHandler.js +53 -0
  95. package/src/handlers/system/RefreshAssetsToolHandler.js +45 -0
  96. package/src/handlers/ui/ClickUIElementToolHandler.js +110 -0
  97. package/src/handlers/ui/FindUIElementsToolHandler.js +63 -0
  98. package/src/handlers/ui/GetUIElementStateToolHandler.js +50 -0
  99. package/src/handlers/ui/SetUIElementValueToolHandler.js +49 -0
  100. package/src/handlers/ui/SimulateUIInputToolHandler.js +156 -0
  101. package/src/handlers/video/CaptureVideoForToolHandler.js +96 -0
  102. package/src/handlers/video/CaptureVideoStartToolHandler.js +38 -0
  103. package/src/handlers/video/CaptureVideoStatusToolHandler.js +30 -0
  104. package/src/handlers/video/CaptureVideoStopToolHandler.js +32 -0
  105. package/src/lsp/CSharpLspUtils.js +134 -0
  106. package/src/lsp/LspProcessManager.js +60 -0
  107. package/src/lsp/LspRpcClient.js +133 -0
  108. package/src/tools/analysis/analyzeSceneContents.js +100 -0
  109. package/src/tools/analysis/findByComponent.js +87 -0
  110. package/src/tools/analysis/getAnimatorState.js +326 -0
  111. package/src/tools/analysis/getComponentValues.js +182 -0
  112. package/src/tools/analysis/getGameObjectDetails.js +159 -0
  113. package/src/tools/analysis/getInputActionsState.js +329 -0
  114. package/src/tools/analysis/getObjectReferences.js +86 -0
  115. package/src/tools/input/inputActionsEditor.js +556 -0
  116. package/src/tools/scene/createScene.js +112 -0
  117. package/src/tools/scene/getSceneInfo.js +95 -0
  118. package/src/tools/scene/listScenes.js +82 -0
  119. package/src/tools/scene/loadScene.js +122 -0
  120. package/src/tools/scene/saveScene.js +91 -0
  121. package/src/tools/system/ping.js +72 -0
  122. package/src/tools/video/recordFor.js +31 -0
  123. package/src/tools/video/recordPlayMode.js +61 -0
  124. package/src/utils/csharpParse.js +88 -0
  125. package/src/utils/validators.js +90 -0
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Base class for all tool handlers
3
+ * Provides common functionality for validation, execution, and error handling
4
+ */
5
+ import { logger } from '../../core/config.js';
6
+
7
+ export class BaseToolHandler {
8
+ constructor(name, description, inputSchema = {}) {
9
+ this.name = name;
10
+ this.description = description;
11
+ this.inputSchema = inputSchema;
12
+ }
13
+
14
+ /**
15
+ * Validates the input parameters against the schema
16
+ * Override this method for custom validation
17
+ * @param {object} params - Input parameters
18
+ * @throws {Error} If validation fails
19
+ */
20
+ validate(params) {
21
+ // Basic validation - check required fields from schema
22
+ if (this.inputSchema.required) {
23
+ for (const field of this.inputSchema.required) {
24
+ if (params[field] === undefined || params[field] === null) {
25
+ throw new Error(`Missing required parameter: ${field}`);
26
+ }
27
+ }
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Executes the tool logic
33
+ * Must be implemented by subclasses
34
+ * @param {object} params - Validated input parameters
35
+ * @returns {Promise<object>} Tool result
36
+ */
37
+ async execute(params) {
38
+ throw new Error('execute() must be implemented by subclass');
39
+ }
40
+
41
+ /**
42
+ * Main handler method that orchestrates validation and execution
43
+ * @param {object} params - Input parameters
44
+ * @returns {Promise<object>} Standardized response
45
+ */
46
+ async handle(params = {}) {
47
+ logger.debug(`[Handler ${this.name}] Starting handle() with params:`, params);
48
+
49
+ try {
50
+ // Validate parameters
51
+ logger.debug(`[Handler ${this.name}] Validating parameters...`);
52
+ this.validate(params);
53
+ logger.debug(`[Handler ${this.name}] Validation passed`);
54
+
55
+ // Execute tool logic
56
+ logger.debug(`[Handler ${this.name}] Executing tool logic...`);
57
+ const startTime = Date.now();
58
+ const result = await this.execute(params);
59
+ const duration = Date.now() - startTime;
60
+ logger.info(`[Handler ${this.name}] Execution completed in ${duration}ms`);
61
+
62
+ // Return success response in new format
63
+ return {
64
+ status: 'success',
65
+ result
66
+ };
67
+ } catch (error) {
68
+ logger.error(`[Handler ${this.name}] Error occurred: ${error.message}`);
69
+ if (error.stack) {
70
+ logger.debug(`[Handler ${this.name}] Error stack: ${error.stack}`);
71
+ }
72
+
73
+ // Return error response in new format
74
+ return {
75
+ status: 'error',
76
+ error: error.message,
77
+ code: error.code || 'TOOL_ERROR',
78
+ details: {
79
+ tool: this.name,
80
+ params: this.summarizeParams(params),
81
+ stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
82
+ }
83
+ };
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Summarizes parameters for error reporting
89
+ * @param {object} params - Parameters to summarize
90
+ * @returns {string} Summary string
91
+ */
92
+ summarizeParams(params) {
93
+ if (!params || typeof params !== 'object') {
94
+ return 'No parameters';
95
+ }
96
+
97
+ const entries = Object.entries(params);
98
+ if (entries.length === 0) {
99
+ return 'Empty parameters';
100
+ }
101
+
102
+ return entries
103
+ .map(([key, value]) => {
104
+ let valueStr = '';
105
+ if (value === null) {
106
+ valueStr = 'null';
107
+ } else if (value === undefined) {
108
+ valueStr = 'undefined';
109
+ } else if (typeof value === 'string') {
110
+ // Truncate long strings
111
+ valueStr = value.length > 50 ? `"${value.substring(0, 47)}..."` : `"${value}"`;
112
+ } else if (typeof value === 'object') {
113
+ valueStr = Array.isArray(value) ? `[Array(${value.length})]` : '[Object]';
114
+ } else {
115
+ valueStr = String(value);
116
+ }
117
+ return `${key}: ${valueStr}`;
118
+ })
119
+ .join(', ');
120
+ }
121
+
122
+ /**
123
+ * Returns the tool definition for MCP
124
+ * @returns {object} Tool definition
125
+ */
126
+ getDefinition() {
127
+ return {
128
+ name: this.name,
129
+ description: this.description,
130
+ inputSchema: this.inputSchema
131
+ };
132
+ }
133
+ }
@@ -0,0 +1,90 @@
1
+ import { BaseToolHandler } from '../base/BaseToolHandler.js';
2
+
3
+ /**
4
+ * Handler for getting Unity compilation state and errors
5
+ */
6
+ export class GetCompilationStateToolHandler extends BaseToolHandler {
7
+ constructor(unityConnection) {
8
+ super(
9
+ 'get_compilation_state',
10
+ 'Get current Unity compilation state, errors, and warnings with enhanced detection',
11
+ {
12
+ type: 'object',
13
+ properties: {
14
+ includeMessages: {
15
+ type: 'boolean',
16
+ description: 'Include detailed compilation messages. Unity default: false. Set to true for debugging compilation issues'
17
+ },
18
+ maxMessages: {
19
+ type: 'number',
20
+ description: 'Maximum number of messages to return (default: 50)'
21
+ }
22
+ }
23
+ }
24
+ );
25
+
26
+ this.unityConnection = unityConnection;
27
+ }
28
+
29
+ /**
30
+ * Executes the get compilation state operation
31
+ * @param {Object} params - The validated input parameters
32
+ * @returns {Promise<Object>} The compilation state and messages
33
+ */
34
+ async execute(params) {
35
+ // Ensure connection to Unity
36
+ if (!this.unityConnection.isConnected()) {
37
+ await this.unityConnection.connect();
38
+ }
39
+
40
+ // Send command to Unity
41
+ const response = await this.unityConnection.sendCommand('get_compilation_state', params);
42
+
43
+ // Handle Unity response
44
+ if (response.error) {
45
+ throw new Error(response.error);
46
+ }
47
+
48
+ // Return result
49
+ return {
50
+ success: response.success,
51
+ isCompiling: response.isCompiling,
52
+ isUpdating: response.isUpdating,
53
+ isMonitoring: response.isMonitoring,
54
+ lastCompilationTime: response.lastCompilationTime,
55
+ messageCount: response.messageCount,
56
+ errorCount: response.errorCount,
57
+ warningCount: response.warningCount,
58
+ ...(response.messages !== undefined && { messages: response.messages })
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Gets example usage for this tool
64
+ * @returns {Object} Example usage scenarios
65
+ */
66
+ getExamples() {
67
+ return {
68
+ getBasicState: {
69
+ description: 'Get compilation state without detailed messages',
70
+ params: {
71
+ includeMessages: false
72
+ }
73
+ },
74
+ getFullState: {
75
+ description: 'Get compilation state with all error details',
76
+ params: {
77
+ includeMessages: true,
78
+ maxMessages: 100
79
+ }
80
+ },
81
+ getRecentErrors: {
82
+ description: 'Get recent compilation errors only',
83
+ params: {
84
+ includeMessages: true,
85
+ maxMessages: 10
86
+ }
87
+ }
88
+ };
89
+ }
90
+ }
@@ -0,0 +1,126 @@
1
+ import { BaseToolHandler } from '../base/BaseToolHandler.js';
2
+
3
+ /**
4
+ * Handler for adding components to GameObjects in Unity
5
+ */
6
+ export class AddComponentToolHandler extends BaseToolHandler {
7
+ constructor(unityConnection) {
8
+ super(
9
+ 'add_component',
10
+ 'Add a component to a GameObject (scene or prefab mode) with optional initial properties.',
11
+ {
12
+ type: 'object',
13
+ properties: {
14
+ gameObjectPath: {
15
+ type: 'string',
16
+ description: 'Scene path to the GameObject (e.g., "/Player" or "/Canvas/Button").'
17
+ },
18
+ componentType: {
19
+ type: 'string',
20
+ description: 'Type of component to add (e.g., "Rigidbody", "BoxCollider", "Light")'
21
+ },
22
+ properties: {
23
+ type: 'object',
24
+ description: 'Initial property values to set on the new component.',
25
+ additionalProperties: true
26
+ }
27
+ },
28
+ required: ['gameObjectPath', 'componentType']
29
+ }
30
+ );
31
+
32
+ this.unityConnection = unityConnection;
33
+ }
34
+
35
+ /**
36
+ * Validates the input parameters
37
+ * @param {Object} params - The input parameters
38
+ * @throws {Error} If validation fails
39
+ */
40
+ validate(params) {
41
+ super.validate(params); // Check required fields
42
+
43
+ const { gameObjectPath, componentType } = params;
44
+
45
+ if (!gameObjectPath || gameObjectPath.trim() === '') {
46
+ throw new Error('gameObjectPath cannot be empty');
47
+ }
48
+
49
+ if (!componentType || componentType.trim() === '') {
50
+ throw new Error('componentType cannot be empty');
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Executes the add component operation
56
+ * @param {Object} params - The validated input parameters
57
+ * @returns {Promise<Object>} The result of adding the component
58
+ */
59
+ async execute(params) {
60
+ // Ensure connection to Unity
61
+ if (!this.unityConnection.isConnected()) {
62
+ await this.unityConnection.connect();
63
+ }
64
+
65
+ // Send command to Unity
66
+ const response = await this.unityConnection.sendCommand('add_component', params);
67
+
68
+ // Handle Unity response
69
+ if (response.error) {
70
+ throw new Error(response.error);
71
+ }
72
+
73
+ // Return success result
74
+ return {
75
+ componentType: response.componentType,
76
+ gameObjectPath: response.gameObjectPath,
77
+ message: response.message || 'Component added successfully',
78
+ ...(response.properties && { appliedProperties: response.properties })
79
+ };
80
+ }
81
+
82
+ /**
83
+ * Gets example usage for this tool
84
+ * @returns {Object} Example usage scenarios
85
+ */
86
+ getExamples() {
87
+ return {
88
+ addRigidbody: {
89
+ description: 'Add Rigidbody with custom properties',
90
+ params: {
91
+ gameObjectPath: '/Player',
92
+ componentType: 'Rigidbody',
93
+ properties: {
94
+ mass: 2.0,
95
+ drag: 0.5,
96
+ useGravity: true,
97
+ isKinematic: false
98
+ }
99
+ }
100
+ },
101
+ addCollider: {
102
+ description: 'Add BoxCollider to GameObject',
103
+ params: {
104
+ gameObjectPath: '/Player/Hitbox',
105
+ componentType: 'BoxCollider',
106
+ properties: {
107
+ isTrigger: true,
108
+ size: { x: 1, y: 2, z: 1 }
109
+ }
110
+ }
111
+ },
112
+ addLight: {
113
+ description: 'Add Light component',
114
+ params: {
115
+ gameObjectPath: '/Lighting/MainLight',
116
+ componentType: 'Light',
117
+ properties: {
118
+ type: 'Directional',
119
+ intensity: 1.5,
120
+ color: { r: 1, g: 0.95, b: 0.8, a: 1 }
121
+ }
122
+ }
123
+ }
124
+ };
125
+ }
126
+ }
@@ -0,0 +1,100 @@
1
+ import { BaseToolHandler } from '../base/BaseToolHandler.js';
2
+
3
+ /**
4
+ * Handler for discovering available component types in Unity
5
+ */
6
+ export class GetComponentTypesToolHandler extends BaseToolHandler {
7
+ constructor(unityConnection) {
8
+ super(
9
+ 'get_component_types',
10
+ 'Get available component types in Unity',
11
+ {
12
+ type: 'object',
13
+ properties: {
14
+ category: {
15
+ type: 'string',
16
+ description: 'Filter by category (e.g., "Physics", "Rendering", "UI")'
17
+ },
18
+ search: {
19
+ type: 'string',
20
+ description: 'Search for component types by name'
21
+ },
22
+ onlyAddable: {
23
+ type: 'boolean',
24
+ description: 'Return only components that can be added to GameObjects (default: false)'
25
+ }
26
+ }
27
+ }
28
+ );
29
+
30
+ this.unityConnection = unityConnection;
31
+ }
32
+
33
+ /**
34
+ * Executes the get component types operation
35
+ * @param {Object} params - The validated input parameters
36
+ * @returns {Promise<Object>} The list of available component types
37
+ */
38
+ async execute(params) {
39
+ // Ensure connection to Unity
40
+ if (!this.unityConnection.isConnected()) {
41
+ await this.unityConnection.connect();
42
+ }
43
+
44
+ // Send command to Unity
45
+ const response = await this.unityConnection.sendCommand('get_component_types', params);
46
+
47
+ // Handle Unity response
48
+ if (response.error) {
49
+ throw new Error(response.error);
50
+ }
51
+
52
+ // Return result
53
+ return {
54
+ componentTypes: response.componentTypes || [],
55
+ totalCount: response.totalCount || 0,
56
+ categories: response.categories || [],
57
+ ...(response.searchTerm !== undefined && { searchTerm: response.searchTerm }),
58
+ ...(response.onlyAddable !== undefined && { onlyAddable: response.onlyAddable })
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Gets example usage for this tool
64
+ * @returns {Object} Example usage scenarios
65
+ */
66
+ getExamples() {
67
+ return {
68
+ getAllTypes: {
69
+ description: 'Get all available component types',
70
+ params: {}
71
+ },
72
+ getPhysicsComponents: {
73
+ description: 'Get only physics-related components',
74
+ params: {
75
+ category: 'Physics'
76
+ }
77
+ },
78
+ searchColliders: {
79
+ description: 'Search for collider components',
80
+ params: {
81
+ search: 'collider'
82
+ }
83
+ },
84
+ getAddableComponents: {
85
+ description: 'Get only components that can be added',
86
+ params: {
87
+ onlyAddable: true
88
+ }
89
+ },
90
+ searchPhysicsAddable: {
91
+ description: 'Search for addable physics components',
92
+ params: {
93
+ category: 'Physics',
94
+ onlyAddable: true,
95
+ search: 'body'
96
+ }
97
+ }
98
+ };
99
+ }
100
+ }
@@ -0,0 +1,85 @@
1
+ import { BaseToolHandler } from '../base/BaseToolHandler.js';
2
+
3
+ /**
4
+ * Handler for listing components on GameObjects in Unity
5
+ */
6
+ export class ListComponentsToolHandler extends BaseToolHandler {
7
+ constructor(unityConnection) {
8
+ super(
9
+ 'list_components',
10
+ 'List all components on a GameObject in Unity (works in both scene and prefab mode)',
11
+ {
12
+ type: 'object',
13
+ properties: {
14
+ gameObjectPath: {
15
+ type: 'string',
16
+ description: 'Path to the GameObject (e.g., "/Player" or "/Canvas/Button")'
17
+ },
18
+ includeInherited: {
19
+ type: 'boolean',
20
+ description: 'Include inherited base component types (default: false)'
21
+ }
22
+ },
23
+ required: ['gameObjectPath']
24
+ }
25
+ );
26
+
27
+ this.unityConnection = unityConnection;
28
+ }
29
+
30
+ /**
31
+ * Executes the list components operation
32
+ * @param {Object} params - The validated input parameters
33
+ * @returns {Promise<Object>} The list of components
34
+ */
35
+ async execute(params) {
36
+ // Ensure connection to Unity
37
+ if (!this.unityConnection.isConnected()) {
38
+ await this.unityConnection.connect();
39
+ }
40
+
41
+ // Send command to Unity
42
+ const response = await this.unityConnection.sendCommand('list_components', params);
43
+
44
+ // Handle Unity response
45
+ if (response.error) {
46
+ throw new Error(response.error);
47
+ }
48
+
49
+ // Return result
50
+ return {
51
+ gameObjectPath: response.gameObjectPath,
52
+ components: response.components || [],
53
+ componentCount: response.componentCount || 0,
54
+ ...(response.includesInherited !== undefined && { includesInherited: response.includesInherited })
55
+ };
56
+ }
57
+
58
+ /**
59
+ * Gets example usage for this tool
60
+ * @returns {Object} Example usage scenarios
61
+ */
62
+ getExamples() {
63
+ return {
64
+ listBasicComponents: {
65
+ description: 'List all components on a GameObject',
66
+ params: {
67
+ gameObjectPath: '/Player'
68
+ }
69
+ },
70
+ listWithInherited: {
71
+ description: 'List components including inherited types',
72
+ params: {
73
+ gameObjectPath: '/Player',
74
+ includeInherited: true
75
+ }
76
+ },
77
+ listUIComponents: {
78
+ description: 'List components on a UI element',
79
+ params: {
80
+ gameObjectPath: '/Canvas/Button'
81
+ }
82
+ }
83
+ };
84
+ }
85
+ }
@@ -0,0 +1,143 @@
1
+ import { BaseToolHandler } from '../base/BaseToolHandler.js';
2
+
3
+ /**
4
+ * Handler for modifying component properties on GameObjects in Unity
5
+ */
6
+ export class ModifyComponentToolHandler extends BaseToolHandler {
7
+ constructor(unityConnection) {
8
+ super(
9
+ 'modify_component',
10
+ 'Modify properties of a component on a GameObject in Unity (works in both scene and prefab mode)',
11
+ {
12
+ type: 'object',
13
+ properties: {
14
+ gameObjectPath: {
15
+ type: 'string',
16
+ description: 'Path to the GameObject (e.g., "/Player" or "/Canvas/Button")'
17
+ },
18
+ componentType: {
19
+ type: 'string',
20
+ description: 'Type of component to modify (e.g., "Rigidbody", "Light")'
21
+ },
22
+ componentIndex: {
23
+ type: 'number',
24
+ description: 'Index of component if multiple of same type exist (default: 0)'
25
+ },
26
+ properties: {
27
+ type: 'object',
28
+ description: 'Properties to modify with their new values',
29
+ additionalProperties: true
30
+ }
31
+ },
32
+ required: ['gameObjectPath', 'componentType', 'properties']
33
+ }
34
+ );
35
+
36
+ this.unityConnection = unityConnection;
37
+ }
38
+
39
+ /**
40
+ * Validates the input parameters
41
+ * @param {Object} params - The input parameters
42
+ * @throws {Error} If validation fails
43
+ */
44
+ validate(params) {
45
+ super.validate(params); // Check required fields
46
+
47
+ const { properties } = params;
48
+
49
+ // Validate properties is not empty
50
+ if (!properties || Object.keys(properties).length === 0) {
51
+ throw new Error('properties cannot be empty');
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Executes the modify component operation
57
+ * @param {Object} params - The validated input parameters
58
+ * @returns {Promise<Object>} The result of modifying the component
59
+ */
60
+ async execute(params) {
61
+ // Ensure connection to Unity
62
+ if (!this.unityConnection.isConnected()) {
63
+ await this.unityConnection.connect();
64
+ }
65
+
66
+ // Send command to Unity
67
+ const response = await this.unityConnection.sendCommand('modify_component', params);
68
+
69
+ // Handle Unity response
70
+ if (response.error) {
71
+ throw new Error(response.error);
72
+ }
73
+
74
+ // Return result
75
+ return {
76
+ componentType: response.componentType,
77
+ modifiedProperties: response.modifiedProperties || [],
78
+ message: response.message || 'Component properties updated',
79
+ ...(response.componentIndex !== undefined && { componentIndex: response.componentIndex })
80
+ };
81
+ }
82
+
83
+ /**
84
+ * Gets example usage for this tool
85
+ * @returns {Object} Example usage scenarios
86
+ */
87
+ getExamples() {
88
+ return {
89
+ modifyRigidbody: {
90
+ description: 'Modify Rigidbody properties',
91
+ params: {
92
+ gameObjectPath: '/Player',
93
+ componentType: 'Rigidbody',
94
+ properties: {
95
+ mass: 5.0,
96
+ drag: 0.5,
97
+ angularDrag: 0.05,
98
+ useGravity: true,
99
+ isKinematic: false
100
+ }
101
+ }
102
+ },
103
+ modifyLight: {
104
+ description: 'Modify Light component settings',
105
+ params: {
106
+ gameObjectPath: '/Lighting/MainLight',
107
+ componentType: 'Light',
108
+ properties: {
109
+ intensity: 2.0,
110
+ color: { r: 1, g: 0.95, b: 0.8, a: 1 },
111
+ range: 50,
112
+ type: 'Point'
113
+ }
114
+ }
115
+ },
116
+ modifyNestedProperties: {
117
+ description: 'Modify nested properties using dot notation',
118
+ params: {
119
+ gameObjectPath: '/Player',
120
+ componentType: 'Rigidbody',
121
+ properties: {
122
+ 'constraints.freezePositionX': true,
123
+ 'constraints.freezePositionY': false,
124
+ 'constraints.freezeRotationZ': true
125
+ }
126
+ }
127
+ },
128
+ modifyCamera: {
129
+ description: 'Modify Camera settings',
130
+ params: {
131
+ gameObjectPath: '/MainCamera',
132
+ componentType: 'Camera',
133
+ properties: {
134
+ fieldOfView: 75,
135
+ nearClipPlane: 0.1,
136
+ farClipPlane: 1000,
137
+ depth: -1
138
+ }
139
+ }
140
+ }
141
+ };
142
+ }
143
+ }