@akiojin/unity-mcp-server 3.2.0 → 3.2.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akiojin/unity-mcp-server",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "MCP server and Unity Editor bridge — enables AI assistants to control Unity for AI-assisted workflows",
5
5
  "type": "module",
6
6
  "main": "src/core/server.js",
@@ -0,0 +1,10 @@
1
+ const TOOL_NAME_TO_UNITY_COMMAND_TYPE = Object.freeze({
2
+ // Animator tools: tool name (MCP) -> Unity command type (TCP)
3
+ analysis_animator_state_get: 'get_animator_state',
4
+ analysis_animator_runtime_info_get: 'get_animator_runtime_info'
5
+ });
6
+
7
+ export function normalizeUnityCommandType(type) {
8
+ if (typeof type !== 'string' || type.length === 0) return type;
9
+ return TOOL_NAME_TO_UNITY_COMMAND_TYPE[type] ?? type;
10
+ }
@@ -1,6 +1,7 @@
1
1
  import net from 'net';
2
2
  import { EventEmitter } from 'events';
3
3
  import { config, logger } from './config.js';
4
+ import { normalizeUnityCommandType } from './unityCommandType.js';
4
5
 
5
6
  /**
6
7
  * Manages TCP connection to Unity Editor
@@ -360,7 +361,8 @@ export class UnityConnection extends EventEmitter {
360
361
  * @returns {Promise<any>} - Response from Unity
361
362
  */
362
363
  async sendCommand(type, params = {}) {
363
- logger.info(`[Unity] enqueue sendCommand: ${type}`, { connected: this.connected });
364
+ const normalizedType = normalizeUnityCommandType(type);
365
+ logger.info(`[Unity] enqueue sendCommand: ${normalizedType}`, { connected: this.connected });
364
366
 
365
367
  if (!this.connected) {
366
368
  logger.warning('[Unity] Not connected; waiting for reconnection before sending command');
@@ -371,7 +373,7 @@ export class UnityConnection extends EventEmitter {
371
373
 
372
374
  // Create an external promise that will resolve when Unity responds
373
375
  return new Promise((outerResolve, outerReject) => {
374
- const task = { type, params, outerResolve, outerReject };
376
+ const task = { type: normalizedType, params, outerResolve, outerReject };
375
377
  this.sendQueue.push(task);
376
378
  this._pumpQueue();
377
379
  });
@@ -47,7 +47,7 @@ export async function analyzeSceneContentsHandler(unityConnection, args) {
47
47
  }
48
48
 
49
49
  // Send command to Unity with provided parameters
50
- const result = await unityConnection.sendCommand('analysis_scene_contents_analyze', args);
50
+ const result = await unityConnection.sendCommand('analyze_scene_contents', args);
51
51
 
52
52
  // The unityConnection.sendCommand already extracts the result field
53
53
  // from the response, so we access properties directly on result
@@ -48,10 +48,23 @@ export async function findByComponentHandler(unityConnection, args) {
48
48
  }
49
49
 
50
50
  // Send command to Unity
51
- const result = await unityConnection.sendCommand('analysis_component_find', args);
51
+ const result = await unityConnection.sendCommand('find_by_component', args);
52
52
 
53
- // Handle Unity response
54
- if (result.status === 'error') {
53
+ // The unityConnection.sendCommand already extracts the result field
54
+ // from the response, so we access properties directly on result
55
+ if (!result || typeof result === 'string') {
56
+ return {
57
+ content: [
58
+ {
59
+ type: 'text',
60
+ text: `Failed to find GameObjects: Invalid response format`
61
+ }
62
+ ],
63
+ isError: true
64
+ };
65
+ }
66
+
67
+ if (result.error) {
55
68
  return {
56
69
  content: [
57
70
  {
@@ -63,12 +76,14 @@ export async function findByComponentHandler(unityConnection, args) {
63
76
  };
64
77
  }
65
78
 
79
+ const summary = result.summary || `Found ${result.totalFound ?? 0} GameObjects`;
80
+
66
81
  // Success response
67
82
  return {
68
83
  content: [
69
84
  {
70
85
  type: 'text',
71
- text: result.result.summary || `Found ${result.result.totalFound} GameObjects`
86
+ text: summary
72
87
  }
73
88
  ],
74
89
  isError: false
@@ -99,8 +99,8 @@ export async function getAnimatorStateHandler(unityConnection, args) {
99
99
  };
100
100
  }
101
101
 
102
- // Send command to Unity
103
- const result = await unityConnection.sendCommand('analysis_animator_state_get', args);
102
+ // Send command to Unity (tool name is normalized to Unity command type in UnityConnection)
103
+ const result = await unityConnection.sendCommand(getAnimatorStateToolDefinition.name, args);
104
104
 
105
105
  // Check for errors
106
106
  if (!result || typeof result === 'string') {
@@ -221,8 +221,11 @@ export async function getAnimatorRuntimeInfoHandler(unityConnection, args) {
221
221
  };
222
222
  }
223
223
 
224
- // Send command to Unity
225
- const result = await unityConnection.sendCommand('analysis_animator_runtime_info_get', args);
224
+ // Send command to Unity (tool name is normalized to Unity command type in UnityConnection)
225
+ const result = await unityConnection.sendCommand(
226
+ getAnimatorRuntimeInfoToolDefinition.name,
227
+ args
228
+ );
226
229
 
227
230
  // Check for errors
228
231
  if (!result || typeof result === 'string') {
@@ -77,7 +77,7 @@ export async function getComponentValuesHandler(unityConnection, args) {
77
77
  }
78
78
 
79
79
  // Send command to Unity
80
- const result = await unityConnection.sendCommand('analysis_component_values_get', args);
80
+ const result = await unityConnection.sendCommand('get_component_values', args);
81
81
 
82
82
  // The unityConnection.sendCommand already extracts the result field
83
83
  // from the response, so we access properties directly on result
@@ -106,6 +106,7 @@ export async function getComponentValuesHandler(unityConnection, args) {
106
106
  };
107
107
  }
108
108
 
109
+ // Success response - result is already the unwrapped data
109
110
  let responseText = result.summary || `Component values retrieved`;
110
111
 
111
112
  // Add detailed property information if available
@@ -106,7 +106,7 @@ export async function getGameObjectDetailsHandler(unityConnection, args) {
106
106
  if (args.maxDepth !== undefined) params.maxDepth = args.maxDepth;
107
107
 
108
108
  // Send command to Unity
109
- const result = await unityConnection.sendCommand('analysis_gameobject_details_get', args);
109
+ const result = await unityConnection.sendCommand('get_gameobject_details', params);
110
110
 
111
111
  // The unityConnection.sendCommand already extracts the result field
112
112
  // from the response, so we access properties directly on result
@@ -75,7 +75,7 @@ export async function getInputActionsStateHandler(unityConnection, args) {
75
75
  }
76
76
 
77
77
  // Send command to Unity
78
- const result = await unityConnection.sendCommand('input_actions_state_get', args);
78
+ const result = await unityConnection.sendCommand('get_input_actions_state', args);
79
79
 
80
80
  // Check for errors
81
81
  if (!result || typeof result === 'string') {
@@ -216,7 +216,7 @@ export async function analyzeInputActionsAssetHandler(unityConnection, args) {
216
216
  }
217
217
 
218
218
  // Send command to Unity
219
- const result = await unityConnection.sendCommand('input_actions_asset_analyze', args);
219
+ const result = await unityConnection.sendCommand('analyze_input_actions_asset', args);
220
220
 
221
221
  // Check for errors
222
222
  if (!result || typeof result === 'string') {
@@ -47,10 +47,23 @@ export async function getObjectReferencesHandler(unityConnection, args) {
47
47
  }
48
48
 
49
49
  // Send command to Unity
50
- const result = await unityConnection.sendCommand('analysis_object_references_get', args);
50
+ const result = await unityConnection.sendCommand('get_object_references', args);
51
51
 
52
- // Handle Unity response
53
- if (result.status === 'error') {
52
+ // The unityConnection.sendCommand already extracts the result field
53
+ // from the response, so we access properties directly on result
54
+ if (!result || typeof result === 'string') {
55
+ return {
56
+ content: [
57
+ {
58
+ type: 'text',
59
+ text: `Failed to get object references: Invalid response format`
60
+ }
61
+ ],
62
+ isError: true
63
+ };
64
+ }
65
+
66
+ if (result.error) {
54
67
  return {
55
68
  content: [
56
69
  {
@@ -67,7 +80,7 @@ export async function getObjectReferencesHandler(unityConnection, args) {
67
80
  content: [
68
81
  {
69
82
  type: 'text',
70
- text: result.result.summary || `References analyzed for ${args.gameObjectName}`
83
+ text: result.summary || `References analyzed for ${args.gameObjectName}`
71
84
  }
72
85
  ],
73
86
  isError: false
@@ -303,7 +303,10 @@ function formatUnityResponse(result, successMessage) {
303
303
  }
304
304
 
305
305
  if (result.success) {
306
- let text = result.message || successMessage;
306
+ let text = successMessage || result.message || 'Operation completed';
307
+ if (successMessage && result.message && result.message !== successMessage) {
308
+ text += `\n${result.message}`;
309
+ }
307
310
  // Add any additional info from result
308
311
  Object.keys(result).forEach(key => {
309
312
  if (key !== 'success' && key !== 'message' && key !== 'error') {
@@ -348,7 +351,7 @@ export async function createActionMapHandler(unityConnection, args) {
348
351
  };
349
352
  }
350
353
 
351
- const result = await unityConnection.sendCommand('input_action_map_create', args);
354
+ const result = await unityConnection.sendCommand('create_action_map', args);
352
355
  return formatUnityResponse(result, `Created Action Map: ${args.mapName}`);
353
356
  } catch (error) {
354
357
  return {
@@ -377,7 +380,7 @@ export async function removeActionMapHandler(unityConnection, args) {
377
380
  };
378
381
  }
379
382
 
380
- const result = await unityConnection.sendCommand('input_action_map_remove', args);
383
+ const result = await unityConnection.sendCommand('remove_action_map', args);
381
384
  return formatUnityResponse(result, `Removed Action Map: ${args.mapName}`);
382
385
  } catch (error) {
383
386
  return {
@@ -407,7 +410,7 @@ export async function addInputActionHandler(unityConnection, args) {
407
410
  };
408
411
  }
409
412
 
410
- const result = await unityConnection.sendCommand('input_action_add', args);
413
+ const result = await unityConnection.sendCommand('add_input_action', args);
411
414
  return formatUnityResponse(result, `Added Action: ${args.actionName}`);
412
415
  } catch (error) {
413
416
  return {
@@ -436,7 +439,7 @@ export async function removeInputActionHandler(unityConnection, args) {
436
439
  };
437
440
  }
438
441
 
439
- const result = await unityConnection.sendCommand('input_action_remove', args);
442
+ const result = await unityConnection.sendCommand('remove_input_action', args);
440
443
  return formatUnityResponse(result, `Removed Action: ${args.actionName}`);
441
444
  } catch (error) {
442
445
  return {
@@ -466,7 +469,7 @@ export async function addInputBindingHandler(unityConnection, args) {
466
469
  };
467
470
  }
468
471
 
469
- const result = await unityConnection.sendCommand('input_binding_add', args);
472
+ const result = await unityConnection.sendCommand('add_input_binding', args);
470
473
  return formatUnityResponse(result, `Added Binding: ${args.path}`);
471
474
  } catch (error) {
472
475
  return {
@@ -495,7 +498,7 @@ export async function removeInputBindingHandler(unityConnection, args) {
495
498
  };
496
499
  }
497
500
 
498
- const result = await unityConnection.sendCommand('input_binding_remove', args);
501
+ const result = await unityConnection.sendCommand('remove_input_binding', args);
499
502
  return formatUnityResponse(result, 'Removed Binding');
500
503
  } catch (error) {
501
504
  return {
@@ -524,7 +527,7 @@ export async function removeAllBindingsHandler(unityConnection, args) {
524
527
  };
525
528
  }
526
529
 
527
- const result = await unityConnection.sendCommand('input_binding_remove_all', args);
530
+ const result = await unityConnection.sendCommand('remove_all_bindings', args);
528
531
  return formatUnityResponse(result, `Removed all bindings from ${args.actionName}`);
529
532
  } catch (error) {
530
533
  return {
@@ -553,7 +556,7 @@ export async function createCompositeBindingHandler(unityConnection, args) {
553
556
  };
554
557
  }
555
558
 
556
- const result = await unityConnection.sendCommand('input_binding_composite_create', args);
559
+ const result = await unityConnection.sendCommand('create_composite_binding', args);
557
560
  return formatUnityResponse(
558
561
  result,
559
562
  `Created composite binding: ${args.name || args.compositeType}`
@@ -586,7 +589,7 @@ export async function manageControlSchemesHandler(unityConnection, args) {
586
589
  };
587
590
  }
588
591
 
589
- const result = await unityConnection.sendCommand('input_control_schemes_manage', args);
592
+ const result = await unityConnection.sendCommand('manage_control_schemes', args);
590
593
  const operationText =
591
594
  args.operation === 'add' ? 'Added' : args.operation === 'remove' ? 'Removed' : 'Modified';
592
595
  return formatUnityResponse(result, `${operationText} control scheme: ${args.schemeName}`);