unreal-engine-mcp-server 0.4.0 → 0.4.4
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/.env.production +1 -1
- package/.github/copilot-instructions.md +45 -0
- package/.github/workflows/publish-mcp.yml +3 -2
- package/README.md +21 -5
- package/dist/index.js +124 -31
- package/dist/prompts/index.d.ts +10 -3
- package/dist/prompts/index.js +186 -7
- package/dist/resources/actors.d.ts +19 -1
- package/dist/resources/actors.js +55 -64
- package/dist/resources/assets.js +46 -62
- package/dist/resources/levels.d.ts +21 -3
- package/dist/resources/levels.js +29 -54
- package/dist/tools/actors.d.ts +3 -14
- package/dist/tools/actors.js +246 -302
- package/dist/tools/animation.d.ts +57 -102
- package/dist/tools/animation.js +429 -450
- package/dist/tools/assets.d.ts +13 -2
- package/dist/tools/assets.js +52 -44
- package/dist/tools/audio.d.ts +22 -13
- package/dist/tools/audio.js +467 -121
- package/dist/tools/blueprint.d.ts +32 -13
- package/dist/tools/blueprint.js +699 -448
- package/dist/tools/build_environment_advanced.d.ts +0 -1
- package/dist/tools/build_environment_advanced.js +190 -45
- package/dist/tools/consolidated-tool-definitions.js +78 -252
- package/dist/tools/consolidated-tool-handlers.js +506 -133
- package/dist/tools/debug.d.ts +72 -10
- package/dist/tools/debug.js +167 -31
- package/dist/tools/editor.d.ts +9 -2
- package/dist/tools/editor.js +30 -44
- package/dist/tools/foliage.d.ts +34 -15
- package/dist/tools/foliage.js +97 -107
- package/dist/tools/introspection.js +19 -21
- package/dist/tools/landscape.d.ts +1 -2
- package/dist/tools/landscape.js +311 -168
- package/dist/tools/level.d.ts +3 -28
- package/dist/tools/level.js +642 -192
- package/dist/tools/lighting.d.ts +14 -3
- package/dist/tools/lighting.js +236 -123
- package/dist/tools/materials.d.ts +25 -7
- package/dist/tools/materials.js +102 -79
- package/dist/tools/niagara.d.ts +10 -12
- package/dist/tools/niagara.js +74 -94
- package/dist/tools/performance.d.ts +12 -4
- package/dist/tools/performance.js +38 -79
- package/dist/tools/physics.d.ts +34 -10
- package/dist/tools/physics.js +364 -292
- package/dist/tools/rc.js +97 -23
- package/dist/tools/sequence.d.ts +1 -0
- package/dist/tools/sequence.js +125 -22
- package/dist/tools/ui.d.ts +31 -4
- package/dist/tools/ui.js +83 -66
- package/dist/tools/visual.d.ts +11 -0
- package/dist/tools/visual.js +245 -30
- package/dist/types/tool-types.d.ts +0 -6
- package/dist/types/tool-types.js +1 -8
- package/dist/unreal-bridge.d.ts +32 -2
- package/dist/unreal-bridge.js +621 -127
- package/dist/utils/elicitation.d.ts +57 -0
- package/dist/utils/elicitation.js +104 -0
- package/dist/utils/error-handler.d.ts +0 -33
- package/dist/utils/error-handler.js +4 -111
- package/dist/utils/http.d.ts +2 -22
- package/dist/utils/http.js +12 -75
- package/dist/utils/normalize.d.ts +4 -4
- package/dist/utils/normalize.js +15 -7
- package/dist/utils/python-output.d.ts +18 -0
- package/dist/utils/python-output.js +290 -0
- package/dist/utils/python.d.ts +2 -0
- package/dist/utils/python.js +4 -0
- package/dist/utils/response-validator.js +28 -2
- package/dist/utils/result-helpers.d.ts +27 -0
- package/dist/utils/result-helpers.js +147 -0
- package/dist/utils/safe-json.d.ts +0 -2
- package/dist/utils/safe-json.js +0 -43
- package/dist/utils/validation.d.ts +16 -0
- package/dist/utils/validation.js +70 -7
- package/mcp-config-example.json +2 -2
- package/package.json +10 -9
- package/server.json +37 -14
- package/src/index.ts +130 -33
- package/src/prompts/index.ts +211 -13
- package/src/resources/actors.ts +59 -44
- package/src/resources/assets.ts +48 -51
- package/src/resources/levels.ts +35 -45
- package/src/tools/actors.ts +269 -313
- package/src/tools/animation.ts +556 -539
- package/src/tools/assets.ts +53 -43
- package/src/tools/audio.ts +507 -113
- package/src/tools/blueprint.ts +778 -462
- package/src/tools/build_environment_advanced.ts +266 -64
- package/src/tools/consolidated-tool-definitions.ts +90 -264
- package/src/tools/consolidated-tool-handlers.ts +630 -121
- package/src/tools/debug.ts +176 -33
- package/src/tools/editor.ts +35 -37
- package/src/tools/foliage.ts +110 -104
- package/src/tools/introspection.ts +24 -22
- package/src/tools/landscape.ts +334 -181
- package/src/tools/level.ts +683 -182
- package/src/tools/lighting.ts +244 -123
- package/src/tools/materials.ts +114 -83
- package/src/tools/niagara.ts +87 -81
- package/src/tools/performance.ts +49 -88
- package/src/tools/physics.ts +393 -299
- package/src/tools/rc.ts +102 -24
- package/src/tools/sequence.ts +136 -28
- package/src/tools/ui.ts +101 -70
- package/src/tools/visual.ts +250 -29
- package/src/types/tool-types.ts +0 -9
- package/src/unreal-bridge.ts +658 -140
- package/src/utils/elicitation.ts +129 -0
- package/src/utils/error-handler.ts +4 -159
- package/src/utils/http.ts +16 -115
- package/src/utils/normalize.ts +20 -10
- package/src/utils/python-output.ts +351 -0
- package/src/utils/python.ts +3 -0
- package/src/utils/response-validator.ts +25 -2
- package/src/utils/result-helpers.ts +193 -0
- package/src/utils/safe-json.ts +0 -50
- package/src/utils/validation.ts +94 -7
- package/tests/run-unreal-tool-tests.mjs +720 -0
- package/tsconfig.json +2 -2
- package/dist/python-utils.d.ts +0 -29
- package/dist/python-utils.js +0 -54
- package/dist/types/index.d.ts +0 -323
- package/dist/types/index.js +0 -28
- package/dist/utils/cache-manager.d.ts +0 -64
- package/dist/utils/cache-manager.js +0 -176
- package/dist/utils/errors.d.ts +0 -133
- package/dist/utils/errors.js +0 -256
- package/src/python/editor_compat.py +0 -181
- package/src/python-utils.ts +0 -57
- package/src/types/index.ts +0 -414
- package/src/utils/cache-manager.ts +0 -213
- package/src/utils/errors.ts +0 -312
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { interpretStandardResult, coerceBoolean, coerceNumber, coerceString, coerceStringArray } from '../utils/result-helpers.js';
|
|
1
2
|
/**
|
|
2
3
|
* Advanced Build Environment Tools
|
|
3
4
|
* Implements procedural terrain and foliage using documented Unreal Engine Python APIs
|
|
@@ -129,17 +130,69 @@ except Exception as e:
|
|
|
129
130
|
print(f"RESULT:{json.dumps(result)}")
|
|
130
131
|
`.trim();
|
|
131
132
|
const response = await this.bridge.executePython(pythonScript);
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
const interpreted = interpretStandardResult(response, {
|
|
134
|
+
successMessage: `Created procedural terrain '${params.name}'`,
|
|
135
|
+
failureMessage: `Failed to create procedural terrain '${params.name}'`
|
|
136
|
+
});
|
|
137
|
+
if (!interpreted.success) {
|
|
138
|
+
const failure = {
|
|
139
|
+
success: false,
|
|
140
|
+
error: interpreted.error ?? interpreted.message,
|
|
141
|
+
message: interpreted.message
|
|
142
|
+
};
|
|
143
|
+
if (interpreted.warnings) {
|
|
144
|
+
failure.warnings = interpreted.warnings;
|
|
137
145
|
}
|
|
138
|
-
|
|
139
|
-
|
|
146
|
+
if (interpreted.details) {
|
|
147
|
+
failure.details = interpreted.details;
|
|
140
148
|
}
|
|
149
|
+
if (interpreted.payload && Object.keys(interpreted.payload).length > 0) {
|
|
150
|
+
failure.payload = interpreted.payload;
|
|
151
|
+
}
|
|
152
|
+
return failure;
|
|
153
|
+
}
|
|
154
|
+
const payload = { ...interpreted.payload };
|
|
155
|
+
const actorName = coerceString(payload.actor_name) ?? coerceString(payload.actorName);
|
|
156
|
+
const vertices = coerceNumber(payload.vertices);
|
|
157
|
+
const triangles = coerceNumber(payload.triangles);
|
|
158
|
+
const subdivisions = coerceNumber(payload.subdivisions);
|
|
159
|
+
const sizeArray = Array.isArray(payload.size)
|
|
160
|
+
? payload.size.map(entry => {
|
|
161
|
+
if (typeof entry === 'number' && Number.isFinite(entry)) {
|
|
162
|
+
return entry;
|
|
163
|
+
}
|
|
164
|
+
if (typeof entry === 'string') {
|
|
165
|
+
const parsed = Number(entry);
|
|
166
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}).filter((entry) => typeof entry === 'number')
|
|
170
|
+
: undefined;
|
|
171
|
+
payload.success = true;
|
|
172
|
+
payload.message = interpreted.message;
|
|
173
|
+
if (actorName) {
|
|
174
|
+
payload.actor_name = actorName;
|
|
175
|
+
payload.actorName = actorName;
|
|
176
|
+
}
|
|
177
|
+
if (typeof vertices === 'number') {
|
|
178
|
+
payload.vertices = vertices;
|
|
179
|
+
}
|
|
180
|
+
if (typeof triangles === 'number') {
|
|
181
|
+
payload.triangles = triangles;
|
|
182
|
+
}
|
|
183
|
+
if (typeof subdivisions === 'number') {
|
|
184
|
+
payload.subdivisions = subdivisions;
|
|
185
|
+
}
|
|
186
|
+
if (sizeArray && sizeArray.length === 2) {
|
|
187
|
+
payload.size = sizeArray;
|
|
188
|
+
}
|
|
189
|
+
if (interpreted.warnings) {
|
|
190
|
+
payload.warnings = interpreted.warnings;
|
|
191
|
+
}
|
|
192
|
+
if (interpreted.details) {
|
|
193
|
+
payload.details = interpreted.details;
|
|
141
194
|
}
|
|
142
|
-
return
|
|
195
|
+
return payload;
|
|
143
196
|
}
|
|
144
197
|
/**
|
|
145
198
|
* Create procedural foliage using ProceduralFoliageSpawner
|
|
@@ -282,17 +335,64 @@ except Exception as e:
|
|
|
282
335
|
print(f"RESULT:{json.dumps(result)}")
|
|
283
336
|
`.trim();
|
|
284
337
|
const response = await this.bridge.executePython(pythonScript);
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
338
|
+
const interpreted = interpretStandardResult(response, {
|
|
339
|
+
successMessage: `Created procedural foliage volume '${params.name}'`,
|
|
340
|
+
failureMessage: `Failed to create procedural foliage volume '${params.name}'`
|
|
341
|
+
});
|
|
342
|
+
if (!interpreted.success) {
|
|
343
|
+
const failure = {
|
|
344
|
+
success: false,
|
|
345
|
+
error: interpreted.error ?? interpreted.message,
|
|
346
|
+
message: interpreted.message
|
|
347
|
+
};
|
|
348
|
+
if (interpreted.warnings) {
|
|
349
|
+
failure.warnings = interpreted.warnings;
|
|
290
350
|
}
|
|
291
|
-
|
|
292
|
-
|
|
351
|
+
if (interpreted.details) {
|
|
352
|
+
failure.details = interpreted.details;
|
|
293
353
|
}
|
|
354
|
+
if (interpreted.payload && Object.keys(interpreted.payload).length > 0) {
|
|
355
|
+
failure.payload = interpreted.payload;
|
|
356
|
+
}
|
|
357
|
+
return failure;
|
|
358
|
+
}
|
|
359
|
+
const payload = { ...interpreted.payload };
|
|
360
|
+
const volumeActor = coerceString(payload.volume_actor) ?? coerceString(payload.volumeActor);
|
|
361
|
+
const spawnerPath = coerceString(payload.spawner_path) ?? coerceString(payload.spawnerPath);
|
|
362
|
+
const foliageCount = coerceNumber(payload.foliage_types_count) ?? coerceNumber(payload.foliageTypesCount);
|
|
363
|
+
const resimulated = coerceBoolean(payload.resimulated);
|
|
364
|
+
const note = coerceString(payload.note);
|
|
365
|
+
const messages = coerceStringArray(payload.messages);
|
|
366
|
+
payload.success = true;
|
|
367
|
+
payload.message = interpreted.message;
|
|
368
|
+
if (volumeActor) {
|
|
369
|
+
payload.volume_actor = volumeActor;
|
|
370
|
+
payload.volumeActor = volumeActor;
|
|
371
|
+
}
|
|
372
|
+
if (spawnerPath) {
|
|
373
|
+
payload.spawner_path = spawnerPath;
|
|
374
|
+
payload.spawnerPath = spawnerPath;
|
|
375
|
+
}
|
|
376
|
+
if (typeof foliageCount === 'number') {
|
|
377
|
+
payload.foliage_types_count = foliageCount;
|
|
378
|
+
payload.foliageTypesCount = foliageCount;
|
|
379
|
+
}
|
|
380
|
+
if (typeof resimulated === 'boolean') {
|
|
381
|
+
payload.resimulated = resimulated;
|
|
382
|
+
}
|
|
383
|
+
if (note) {
|
|
384
|
+
payload.note = note;
|
|
385
|
+
}
|
|
386
|
+
if (messages && messages.length > 0) {
|
|
387
|
+
payload.messages = messages;
|
|
294
388
|
}
|
|
295
|
-
|
|
389
|
+
if (interpreted.warnings) {
|
|
390
|
+
payload.warnings = interpreted.warnings;
|
|
391
|
+
}
|
|
392
|
+
if (interpreted.details) {
|
|
393
|
+
payload.details = interpreted.details;
|
|
394
|
+
}
|
|
395
|
+
return payload;
|
|
296
396
|
}
|
|
297
397
|
/**
|
|
298
398
|
* Add foliage instances using InstancedFoliageActor
|
|
@@ -356,17 +456,43 @@ except Exception as e:
|
|
|
356
456
|
print(f"RESULT:{json.dumps(result)}")
|
|
357
457
|
`.trim();
|
|
358
458
|
const response = await this.bridge.executePython(pythonScript);
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
459
|
+
const interpreted = interpretStandardResult(response, {
|
|
460
|
+
successMessage: 'Foliage instances added',
|
|
461
|
+
failureMessage: 'Failed to add foliage instances'
|
|
462
|
+
});
|
|
463
|
+
if (!interpreted.success) {
|
|
464
|
+
const failure = {
|
|
465
|
+
success: false,
|
|
466
|
+
error: interpreted.error ?? interpreted.message,
|
|
467
|
+
message: interpreted.message
|
|
468
|
+
};
|
|
469
|
+
if (interpreted.warnings) {
|
|
470
|
+
failure.warnings = interpreted.warnings;
|
|
364
471
|
}
|
|
365
|
-
|
|
366
|
-
|
|
472
|
+
if (interpreted.details) {
|
|
473
|
+
failure.details = interpreted.details;
|
|
367
474
|
}
|
|
475
|
+
if (interpreted.payload && Object.keys(interpreted.payload).length > 0) {
|
|
476
|
+
failure.payload = interpreted.payload;
|
|
477
|
+
}
|
|
478
|
+
return failure;
|
|
479
|
+
}
|
|
480
|
+
const payload = { ...interpreted.payload };
|
|
481
|
+
const count = coerceNumber(payload.instances_count) ?? coerceNumber(payload.instancesCount);
|
|
482
|
+
const message = coerceString(payload.message) ?? interpreted.message;
|
|
483
|
+
payload.success = true;
|
|
484
|
+
payload.message = message;
|
|
485
|
+
if (typeof count === 'number') {
|
|
486
|
+
payload.instances_count = count;
|
|
487
|
+
payload.instancesCount = count;
|
|
368
488
|
}
|
|
369
|
-
|
|
489
|
+
if (interpreted.warnings) {
|
|
490
|
+
payload.warnings = interpreted.warnings;
|
|
491
|
+
}
|
|
492
|
+
if (interpreted.details) {
|
|
493
|
+
payload.details = interpreted.details;
|
|
494
|
+
}
|
|
495
|
+
return payload;
|
|
370
496
|
}
|
|
371
497
|
/**
|
|
372
498
|
* Create landscape grass type for automatic foliage on landscape
|
|
@@ -458,31 +584,50 @@ except Exception as e:
|
|
|
458
584
|
print(f"RESULT:{json.dumps(result)}")
|
|
459
585
|
`.trim();
|
|
460
586
|
const response = await this.bridge.executePython(pythonScript);
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
587
|
+
const interpreted = interpretStandardResult(response, {
|
|
588
|
+
successMessage: `Created landscape grass type '${params.name}'`,
|
|
589
|
+
failureMessage: `Failed to create landscape grass type '${params.name}'`
|
|
590
|
+
});
|
|
591
|
+
if (!interpreted.success) {
|
|
592
|
+
const failure = {
|
|
593
|
+
success: false,
|
|
594
|
+
error: interpreted.error ?? interpreted.message,
|
|
595
|
+
message: interpreted.message
|
|
596
|
+
};
|
|
597
|
+
if (interpreted.warnings) {
|
|
598
|
+
failure.warnings = interpreted.warnings;
|
|
466
599
|
}
|
|
467
|
-
|
|
468
|
-
|
|
600
|
+
if (interpreted.details) {
|
|
601
|
+
failure.details = interpreted.details;
|
|
469
602
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
parseResponse(response) {
|
|
474
|
-
if (response && typeof response === 'object') {
|
|
475
|
-
if (response.LogOutput && Array.isArray(response.LogOutput)) {
|
|
476
|
-
return response.LogOutput.map((log) => log.Output || '').join('');
|
|
477
|
-
}
|
|
478
|
-
else if (response.CommandResult) {
|
|
479
|
-
return response.CommandResult;
|
|
480
|
-
}
|
|
481
|
-
else if (response.ReturnValue) {
|
|
482
|
-
return JSON.stringify(response);
|
|
603
|
+
if (interpreted.payload && Object.keys(interpreted.payload).length > 0) {
|
|
604
|
+
failure.payload = interpreted.payload;
|
|
483
605
|
}
|
|
606
|
+
return failure;
|
|
607
|
+
}
|
|
608
|
+
const payload = { ...interpreted.payload };
|
|
609
|
+
const assetPath = coerceString(payload.asset_path) ?? coerceString(payload.assetPath);
|
|
610
|
+
const note = coerceString(payload.note);
|
|
611
|
+
const messages = coerceStringArray(payload.messages);
|
|
612
|
+
payload.success = true;
|
|
613
|
+
payload.message = interpreted.message;
|
|
614
|
+
if (assetPath) {
|
|
615
|
+
payload.asset_path = assetPath;
|
|
616
|
+
payload.assetPath = assetPath;
|
|
617
|
+
}
|
|
618
|
+
if (note) {
|
|
619
|
+
payload.note = note;
|
|
620
|
+
}
|
|
621
|
+
if (messages && messages.length > 0) {
|
|
622
|
+
payload.messages = messages;
|
|
623
|
+
}
|
|
624
|
+
if (interpreted.warnings) {
|
|
625
|
+
payload.warnings = interpreted.warnings;
|
|
626
|
+
}
|
|
627
|
+
if (interpreted.details) {
|
|
628
|
+
payload.details = interpreted.details;
|
|
484
629
|
}
|
|
485
|
-
return
|
|
630
|
+
return payload;
|
|
486
631
|
}
|
|
487
632
|
}
|
|
488
633
|
//# sourceMappingURL=build_environment_advanced.js.map
|