unreal-engine-mcp-server 0.5.0 → 0.5.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.
Files changed (139) hide show
  1. package/.env.example +1 -1
  2. package/.github/release-drafter-config.yml +51 -0
  3. package/.github/workflows/greetings.yml +5 -1
  4. package/.github/workflows/labeler.yml +2 -1
  5. package/.github/workflows/publish-mcp.yml +1 -0
  6. package/.github/workflows/release-drafter.yml +1 -1
  7. package/.github/workflows/release.yml +3 -3
  8. package/CHANGELOG.md +71 -0
  9. package/CONTRIBUTING.md +1 -1
  10. package/GEMINI.md +115 -0
  11. package/Public/Plugin_setup_guide.mp4 +0 -0
  12. package/README.md +166 -200
  13. package/dist/config.d.ts +0 -1
  14. package/dist/config.js +0 -1
  15. package/dist/constants.d.ts +4 -0
  16. package/dist/constants.js +4 -0
  17. package/dist/graphql/loaders.d.ts +64 -0
  18. package/dist/graphql/loaders.js +117 -0
  19. package/dist/graphql/resolvers.d.ts +3 -3
  20. package/dist/graphql/resolvers.js +33 -30
  21. package/dist/graphql/server.js +3 -1
  22. package/dist/graphql/types.d.ts +2 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.js +13 -2
  25. package/dist/server-setup.d.ts +0 -1
  26. package/dist/server-setup.js +0 -40
  27. package/dist/tools/actors.d.ts +40 -24
  28. package/dist/tools/actors.js +8 -2
  29. package/dist/tools/assets.d.ts +19 -71
  30. package/dist/tools/assets.js +28 -22
  31. package/dist/tools/base-tool.d.ts +4 -4
  32. package/dist/tools/base-tool.js +1 -1
  33. package/dist/tools/blueprint.d.ts +33 -61
  34. package/dist/tools/consolidated-tool-handlers.js +96 -110
  35. package/dist/tools/dynamic-handler-registry.d.ts +11 -9
  36. package/dist/tools/dynamic-handler-registry.js +17 -95
  37. package/dist/tools/editor.d.ts +19 -193
  38. package/dist/tools/editor.js +8 -0
  39. package/dist/tools/environment.d.ts +8 -14
  40. package/dist/tools/foliage.d.ts +18 -143
  41. package/dist/tools/foliage.js +4 -2
  42. package/dist/tools/handlers/actor-handlers.js +0 -5
  43. package/dist/tools/handlers/asset-handlers.js +454 -454
  44. package/dist/tools/landscape.d.ts +16 -116
  45. package/dist/tools/landscape.js +7 -3
  46. package/dist/tools/level.d.ts +22 -103
  47. package/dist/tools/level.js +24 -16
  48. package/dist/tools/lighting.js +5 -1
  49. package/dist/tools/materials.js +5 -1
  50. package/dist/tools/niagara.js +37 -2
  51. package/dist/tools/performance.d.ts +0 -1
  52. package/dist/tools/performance.js +0 -1
  53. package/dist/tools/physics.js +5 -1
  54. package/dist/tools/sequence.d.ts +24 -24
  55. package/dist/tools/sequence.js +13 -0
  56. package/dist/tools/ui.d.ts +0 -2
  57. package/dist/types/automation-responses.d.ts +115 -0
  58. package/dist/types/automation-responses.js +2 -0
  59. package/dist/types/responses.d.ts +249 -0
  60. package/dist/types/responses.js +2 -0
  61. package/dist/types/tool-interfaces.d.ts +135 -135
  62. package/dist/utils/command-validator.js +3 -2
  63. package/dist/utils/path-security.d.ts +2 -0
  64. package/dist/utils/path-security.js +24 -0
  65. package/dist/utils/response-factory.d.ts +4 -4
  66. package/dist/utils/response-factory.js +15 -21
  67. package/docs/Migration-Guide-v0.5.0.md +1 -9
  68. package/docs/testing-guide.md +2 -2
  69. package/package.json +12 -6
  70. package/scripts/run-all-tests.mjs +25 -20
  71. package/server.json +3 -2
  72. package/src/config.ts +1 -1
  73. package/src/constants.ts +7 -0
  74. package/src/graphql/loaders.ts +244 -0
  75. package/src/graphql/resolvers.ts +47 -49
  76. package/src/graphql/server.ts +3 -1
  77. package/src/graphql/types.ts +3 -0
  78. package/src/index.ts +15 -2
  79. package/src/resources/assets.ts +5 -4
  80. package/src/server-setup.ts +3 -37
  81. package/src/tools/actors.ts +36 -28
  82. package/src/tools/animation.ts +1 -0
  83. package/src/tools/assets.ts +74 -63
  84. package/src/tools/base-tool.ts +3 -3
  85. package/src/tools/blueprint.ts +59 -59
  86. package/src/tools/consolidated-tool-handlers.ts +129 -150
  87. package/src/tools/dynamic-handler-registry.ts +22 -140
  88. package/src/tools/editor.ts +39 -26
  89. package/src/tools/environment.ts +21 -27
  90. package/src/tools/foliage.ts +28 -25
  91. package/src/tools/handlers/actor-handlers.ts +2 -8
  92. package/src/tools/handlers/asset-handlers.ts +484 -484
  93. package/src/tools/handlers/sequence-handlers.ts +1 -1
  94. package/src/tools/landscape.ts +34 -28
  95. package/src/tools/level.ts +96 -76
  96. package/src/tools/lighting.ts +6 -1
  97. package/src/tools/materials.ts +8 -2
  98. package/src/tools/niagara.ts +44 -2
  99. package/src/tools/performance.ts +1 -2
  100. package/src/tools/physics.ts +7 -1
  101. package/src/tools/sequence.ts +41 -25
  102. package/src/tools/ui.ts +0 -2
  103. package/src/types/automation-responses.ts +119 -0
  104. package/src/types/responses.ts +355 -0
  105. package/src/types/tool-interfaces.ts +135 -135
  106. package/src/utils/command-validator.ts +3 -2
  107. package/src/utils/normalize.test.ts +162 -0
  108. package/src/utils/path-security.ts +43 -0
  109. package/src/utils/response-factory.ts +29 -24
  110. package/src/utils/safe-json.test.ts +90 -0
  111. package/src/utils/validation.test.ts +184 -0
  112. package/tests/test-animation.mjs +358 -33
  113. package/tests/test-asset-graph.mjs +311 -0
  114. package/tests/test-audio.mjs +314 -116
  115. package/tests/test-behavior-tree.mjs +327 -144
  116. package/tests/test-blueprint-graph.mjs +343 -12
  117. package/tests/test-control-editor.mjs +85 -53
  118. package/tests/test-graphql.mjs +58 -8
  119. package/tests/test-input.mjs +349 -0
  120. package/tests/test-inspect.mjs +291 -61
  121. package/tests/test-landscape.mjs +304 -48
  122. package/tests/test-lighting.mjs +428 -0
  123. package/tests/test-manage-level.mjs +70 -51
  124. package/tests/test-performance.mjs +539 -0
  125. package/tests/test-sequence.mjs +82 -46
  126. package/tests/test-system.mjs +72 -33
  127. package/tests/test-wasm.mjs +98 -8
  128. package/vitest.config.ts +35 -0
  129. package/.github/release-drafter.yml +0 -148
  130. package/dist/prompts/index.d.ts +0 -21
  131. package/dist/prompts/index.js +0 -217
  132. package/dist/tools/blueprint/helpers.d.ts +0 -29
  133. package/dist/tools/blueprint/helpers.js +0 -182
  134. package/src/prompts/index.ts +0 -249
  135. package/src/tools/blueprint/helpers.ts +0 -189
  136. package/tests/test-blueprint-events.mjs +0 -35
  137. package/tests/test-extra-tools.mjs +0 -38
  138. package/tests/test-render.mjs +0 -33
  139. package/tests/test-search-assets.mjs +0 -66
@@ -337,7 +337,7 @@ export async function handleSequenceTools(action: string, args: any, tools: IToo
337
337
  if (actorName) {
338
338
  const bindingsRes = await tools.sequenceTools.getBindings({ path });
339
339
  if (bindingsRes && bindingsRes.success) {
340
- const bindings = bindingsRes.bindings || [];
340
+ const bindings = (bindingsRes.bindings as any[]) || [];
341
341
  const isBound = bindings.some((b: any) => b.name === actorName);
342
342
  if (!isBound) {
343
343
  return cleanObject({
@@ -2,8 +2,10 @@
2
2
  import { UnrealBridge } from '../unreal-bridge.js';
3
3
  import { AutomationBridge } from '../automation/index.js';
4
4
  import { ensureVector3 } from '../utils/validation.js';
5
+ import { wasmIntegration } from '../wasm/index.js';
6
+ import { ILandscapeTools, StandardActionResponse } from '../types/tool-interfaces.js';
5
7
 
6
- export class LandscapeTools {
8
+ export class LandscapeTools implements ILandscapeTools {
7
9
  constructor(private bridge: UnrealBridge, private automationBridge?: AutomationBridge) { }
8
10
 
9
11
  setAutomationBridge(automationBridge?: AutomationBridge) { this.automationBridge = automationBridge; }
@@ -23,7 +25,7 @@ export class LandscapeTools {
23
25
  runtimeGrid?: string;
24
26
  isSpatiallyLoaded?: boolean;
25
27
  dataLayers?: string[];
26
- }) {
28
+ }): Promise<StandardActionResponse> {
27
29
  const name = params.name?.trim();
28
30
  if (!name) {
29
31
  return { success: false, error: 'Landscape name is required' };
@@ -46,6 +48,10 @@ export class LandscapeTools {
46
48
  }
47
49
 
48
50
  const [locX, locY, locZ] = ensureVector3(params.location ?? [0, 0, 0], 'landscape location');
51
+ // Use WASM vectorAdd for landscape location processing
52
+ const zeroVector: [number, number, number] = [0, 0, 0];
53
+ const processedLocation = wasmIntegration.vectorAdd(zeroVector, [locX, locY, locZ]);
54
+ console.error('[WASM] Using vectorAdd for landscape positioning');
49
55
  const sectionsPerComponent = Math.max(1, Math.floor(params.sectionsPerComponent ?? 1));
50
56
  const quadsPerSection = Math.max(1, Math.floor(params.quadsPerSection ?? 63));
51
57
 
@@ -57,9 +63,9 @@ export class LandscapeTools {
57
63
 
58
64
  const payload: Record<string, unknown> = {
59
65
  name,
60
- x: locX,
61
- y: locY,
62
- z: locZ,
66
+ x: processedLocation[0],
67
+ y: processedLocation[1],
68
+ z: processedLocation[2],
63
69
  componentsX,
64
70
  componentsY,
65
71
  quadsPerComponent,
@@ -101,7 +107,7 @@ export class LandscapeTools {
101
107
  result.spatiallyLoaded = params.isSpatiallyLoaded;
102
108
  }
103
109
 
104
- return result;
110
+ return result as StandardActionResponse;
105
111
  } catch (error) {
106
112
  return {
107
113
  success: false,
@@ -120,7 +126,7 @@ export class LandscapeTools {
120
126
  strength?: number;
121
127
  location?: [number, number, number];
122
128
  radius?: number;
123
- }) {
129
+ }): Promise<StandardActionResponse> {
124
130
  const [x, y, z] = ensureVector3(params.location ?? [0, 0, 0], 'sculpt location');
125
131
 
126
132
  const tool = (params.tool || '').trim();
@@ -161,7 +167,7 @@ export class LandscapeTools {
161
167
  success: true,
162
168
  message: `Sculpting applied to ${params.landscapeName}`,
163
169
  details: response
164
- };
170
+ } as StandardActionResponse;
165
171
  }
166
172
 
167
173
  // Paint landscape
@@ -174,7 +180,7 @@ export class LandscapeTools {
174
180
  targetValue?: number;
175
181
  radius?: number;
176
182
  density?: number;
177
- }) {
183
+ }): Promise<StandardActionResponse> {
178
184
  if (!this.automationBridge) {
179
185
  throw new Error('Automation Bridge not available.');
180
186
  }
@@ -208,7 +214,7 @@ export class LandscapeTools {
208
214
  success: true,
209
215
  message: `Painted layer ${params.layerName}`,
210
216
  details: response
211
- };
217
+ } as StandardActionResponse;
212
218
  }
213
219
 
214
220
  // Create procedural terrain using ProceduralMeshComponent
@@ -221,7 +227,7 @@ export class LandscapeTools {
221
227
  heightFunction?: string; // Expression for height calculation
222
228
  material?: string;
223
229
  settings?: Record<string, unknown>;
224
- }) {
230
+ }): Promise<StandardActionResponse> {
225
231
  if (!this.automationBridge) {
226
232
  throw new Error('Automation Bridge not available. Procedural terrain creation requires plugin support.');
227
233
  }
@@ -261,7 +267,7 @@ export class LandscapeTools {
261
267
  size: result?.size,
262
268
  subdivisions: result?.subdivisions,
263
269
  details: result
264
- };
270
+ } as StandardActionResponse;
265
271
  } catch (error) {
266
272
  return {
267
273
  success: false,
@@ -279,7 +285,7 @@ export class LandscapeTools {
279
285
  maxScale?: number;
280
286
  path?: string; // Legacy support
281
287
  staticMesh?: string; // Legacy support
282
- }): Promise<any> {
288
+ }): Promise<StandardActionResponse> {
283
289
  if (!this.automationBridge) {
284
290
  throw new Error('Automation Bridge not available. Landscape operations require plugin support.');
285
291
  }
@@ -323,7 +329,7 @@ export class LandscapeTools {
323
329
  success: true,
324
330
  message: response?.message || `Landscape grass type '${name}' created`,
325
331
  assetPath: result?.asset_path || response?.assetPath || response?.asset_path
326
- };
332
+ } as StandardActionResponse;
327
333
  } catch (error) {
328
334
  return {
329
335
  success: false,
@@ -333,7 +339,7 @@ export class LandscapeTools {
333
339
  }
334
340
 
335
341
  // Set the material used by an existing landscape actor
336
- async setLandscapeMaterial(params: { landscapeName: string; materialPath: string }): Promise<any> {
342
+ async setLandscapeMaterial(params: { landscapeName: string; materialPath: string }): Promise<StandardActionResponse> {
337
343
  const landscapeName = typeof params.landscapeName === 'string' ? params.landscapeName.trim() : '';
338
344
  const materialPath = typeof params.materialPath === 'string' ? params.materialPath.trim() : '';
339
345
 
@@ -366,7 +372,7 @@ export class LandscapeTools {
366
372
  message: response?.message || `Landscape material set on '${landscapeName}'`,
367
373
  landscapeName: response?.landscapeName || landscapeName,
368
374
  materialPath: response?.materialPath || materialPath
369
- };
375
+ } as StandardActionResponse;
370
376
  } catch (error) {
371
377
  return {
372
378
  success: false,
@@ -383,7 +389,7 @@ export class LandscapeTools {
383
389
  minScale?: number;
384
390
  maxScale?: number;
385
391
  randomRotation?: boolean;
386
- }) {
392
+ }): Promise<StandardActionResponse> {
387
393
  const commands: string[] = [];
388
394
 
389
395
  commands.push(`CreateLandscapeGrass ${params.landscapeName} ${params.grassType}`);
@@ -410,7 +416,7 @@ export class LandscapeTools {
410
416
  landscapeName: string;
411
417
  collisionMipLevel?: number;
412
418
  simpleCollision?: boolean;
413
- }) {
419
+ }): Promise<StandardActionResponse> {
414
420
  const commands: string[] = [];
415
421
 
416
422
  if (params.collisionMipLevel !== undefined) {
@@ -433,7 +439,7 @@ export class LandscapeTools {
433
439
  landscapeName: string;
434
440
  targetTriangleCount?: number;
435
441
  preserveDetails?: boolean;
436
- }) {
442
+ }): Promise<StandardActionResponse> {
437
443
  const commands: string[] = [];
438
444
 
439
445
  if (params.targetTriangleCount !== undefined) {
@@ -458,7 +464,7 @@ export class LandscapeTools {
458
464
  location?: [number, number, number];
459
465
  size?: [number, number];
460
466
  depth?: number;
461
- }) {
467
+ }): Promise<StandardActionResponse> {
462
468
  const loc = params.location || [0, 0, 0];
463
469
  const size = params.size || [1000, 1000];
464
470
  const depth = params.depth || 100;
@@ -475,7 +481,7 @@ export class LandscapeTools {
475
481
  runtimeGrid?: string;
476
482
  dataLayers?: string[];
477
483
  streamingDistance?: number;
478
- }) {
484
+ }): Promise<StandardActionResponse> {
479
485
  if (!this.automationBridge) {
480
486
  throw new Error('Automation Bridge not available. World Partition operations require plugin support.');
481
487
  }
@@ -502,7 +508,7 @@ export class LandscapeTools {
502
508
  success: true,
503
509
  message: response.message || 'World Partition configured',
504
510
  changes: response.changes
505
- };
511
+ } as StandardActionResponse;
506
512
  } catch (err) {
507
513
  return { success: false, error: `Failed to configure World Partition: ${err instanceof Error ? err.message : String(err)}` };
508
514
  }
@@ -513,7 +519,7 @@ export class LandscapeTools {
513
519
  landscapeName: string;
514
520
  dataLayerNames: string[];
515
521
  operation: 'add' | 'remove' | 'set';
516
- }) {
522
+ }): Promise<StandardActionResponse> {
517
523
  try {
518
524
  const commands = [];
519
525
 
@@ -535,7 +541,7 @@ export class LandscapeTools {
535
541
  success: true,
536
542
  message: `Data layers ${params.operation === 'add' ? 'added' : params.operation === 'remove' ? 'removed' : 'set'} for landscape`,
537
543
  layers: params.dataLayerNames
538
- };
544
+ } as StandardActionResponse;
539
545
  } catch (err) {
540
546
  return { success: false, error: `Failed to manage data layers: ${err}` };
541
547
  }
@@ -547,7 +553,7 @@ export class LandscapeTools {
547
553
  cellSize?: number;
548
554
  loadingRange?: number;
549
555
  enableHLOD?: boolean;
550
- }) {
556
+ }): Promise<StandardActionResponse> {
551
557
  const commands = [];
552
558
 
553
559
  // World Partition runtime commands
@@ -573,7 +579,7 @@ export class LandscapeTools {
573
579
  loadingRange: params.loadingRange,
574
580
  hlod: params.enableHLOD
575
581
  }
576
- };
582
+ } as StandardActionResponse;
577
583
  } catch (err) {
578
584
  return { success: false, error: `Failed to configure streaming cells: ${err}` };
579
585
  }
@@ -588,7 +594,7 @@ export class LandscapeTools {
588
594
  maxX: number;
589
595
  maxY: number;
590
596
  updateNormals?: boolean;
591
- }) {
597
+ }): Promise<StandardActionResponse> {
592
598
  if (!this.automationBridge) {
593
599
  throw new Error('Automation Bridge not available. Landscape operations require plugin support.');
594
600
  }
@@ -634,7 +640,7 @@ export class LandscapeTools {
634
640
  return {
635
641
  success: true,
636
642
  message: response.message || 'Heightmap modified successfully'
637
- };
643
+ } as StandardActionResponse;
638
644
  } catch (err) {
639
645
  return { success: false, error: `Failed to modify heightmap: ${err instanceof Error ? err.message : String(err)}` };
640
646
  }