unreal-engine-mcp-server 0.4.0 → 0.4.3
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 +1 -1
- 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
package/src/utils/validation.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Validation and sanitization utilities for Unreal Engine assets
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { toRotTuple, toVec3Tuple } from './normalize.js';
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* Maximum path length allowed in Unreal Engine
|
|
7
9
|
*/
|
|
@@ -78,13 +80,27 @@ export function sanitizePath(path: string): string {
|
|
|
78
80
|
return '/Game';
|
|
79
81
|
}
|
|
80
82
|
|
|
83
|
+
// Normalize slashes
|
|
84
|
+
path = path.replace(/\\/g, '/');
|
|
85
|
+
|
|
81
86
|
// Ensure path starts with /
|
|
82
87
|
if (!path.startsWith('/')) {
|
|
83
88
|
path = `/${path}`;
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
// Split path into segments and sanitize each
|
|
87
|
-
|
|
92
|
+
let segments = path.split('/').filter(s => s.length > 0);
|
|
93
|
+
|
|
94
|
+
if (segments.length === 0) {
|
|
95
|
+
return '/Game';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Ensure the first segment is a valid root (Game, Engine, Script, Temp)
|
|
99
|
+
const ROOTS = new Set(['Game', 'Engine', 'Script', 'Temp']);
|
|
100
|
+
if (!ROOTS.has(segments[0])) {
|
|
101
|
+
segments = ['Game', ...segments];
|
|
102
|
+
}
|
|
103
|
+
|
|
88
104
|
const sanitizedSegments = segments.map(segment => {
|
|
89
105
|
// Don't sanitize Game, Engine, or other root folders
|
|
90
106
|
if (['Game', 'Engine', 'Script', 'Temp'].includes(segment)) {
|
|
@@ -174,10 +190,14 @@ export function resolveSkeletalMeshPath(input: string): string | null {
|
|
|
174
190
|
|
|
175
191
|
// Common skeleton to mesh mappings
|
|
176
192
|
const skeletonToMeshMap: { [key: string]: string } = {
|
|
177
|
-
'/Game/Mannequin/Character/Mesh/UE4_Mannequin_Skeleton': '/Game/Characters/Mannequins/Meshes/
|
|
178
|
-
'/Game/Characters/Mannequins/Meshes/SK_Mannequin': '/Game/Characters/Mannequins/Meshes/
|
|
179
|
-
'/Game/Mannequin/Character/Mesh/SK_Mannequin': '/Game/Characters/Mannequins/Meshes/
|
|
180
|
-
'/Game/Characters/Mannequin_UE4/Meshes/UE4_Mannequin_Skeleton': '/Game/Characters/Mannequins/Meshes/
|
|
193
|
+
'/Game/Mannequin/Character/Mesh/UE4_Mannequin_Skeleton': '/Game/Characters/Mannequins/Meshes/SKM_Manny_Simple',
|
|
194
|
+
'/Game/Characters/Mannequins/Meshes/SK_Mannequin': '/Game/Characters/Mannequins/Meshes/SKM_Manny_Simple',
|
|
195
|
+
'/Game/Mannequin/Character/Mesh/SK_Mannequin': '/Game/Characters/Mannequins/Meshes/SKM_Manny_Simple',
|
|
196
|
+
'/Game/Characters/Mannequin_UE4/Meshes/UE4_Mannequin_Skeleton': '/Game/Characters/Mannequins/Meshes/SKM_Quinn_Simple',
|
|
197
|
+
'/Game/Characters/Mannequins/Skeletons/UE5_Mannequin_Skeleton': '/Game/Characters/Mannequins/Meshes/SKM_Manny_Simple',
|
|
198
|
+
'/Game/Characters/Mannequins/Skeletons/UE5_Female_Mannequin_Skeleton': '/Game/Characters/Mannequins/Meshes/SKM_Quinn_Simple',
|
|
199
|
+
'/Game/Characters/Mannequins/Skeletons/UE5_Manny_Skeleton': '/Game/Characters/Mannequins/Meshes/SKM_Manny_Simple',
|
|
200
|
+
'/Game/Characters/Mannequins/Skeletons/UE5_Quinn_Skeleton': '/Game/Characters/Mannequins/Meshes/SKM_Quinn_Simple'
|
|
181
201
|
};
|
|
182
202
|
|
|
183
203
|
// Check if this is a known skeleton path
|
|
@@ -189,8 +209,19 @@ export function resolveSkeletalMeshPath(input: string): string | null {
|
|
|
189
209
|
if (input.includes('_Skeleton')) {
|
|
190
210
|
// Try common replacements
|
|
191
211
|
let meshPath = input.replace('_Skeleton', '');
|
|
192
|
-
|
|
193
|
-
|
|
212
|
+
// Mapping for replacements
|
|
213
|
+
const replacements: { [key: string]: string } = {
|
|
214
|
+
'/SK_': '/SKM_',
|
|
215
|
+
'UE4_Mannequin': 'SKM_Manny',
|
|
216
|
+
'UE5_Mannequin': 'SKM_Manny',
|
|
217
|
+
'UE5_Manny': 'SKM_Manny',
|
|
218
|
+
'UE5_Quinn': 'SKM_Quinn'
|
|
219
|
+
};
|
|
220
|
+
// Apply all replacements using regex
|
|
221
|
+
meshPath = meshPath.replace(
|
|
222
|
+
new RegExp(Object.keys(replacements).join('|'), 'g'),
|
|
223
|
+
match => replacements[match]
|
|
224
|
+
);
|
|
194
225
|
return meshPath;
|
|
195
226
|
}
|
|
196
227
|
|
|
@@ -210,3 +241,59 @@ export function resolveSkeletalMeshPath(input: string): string | null {
|
|
|
210
241
|
export async function concurrencyDelay(ms: number = 100): Promise<void> {
|
|
211
242
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
212
243
|
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Ensure the provided value is a finite number within optional bounds.
|
|
247
|
+
* @throws if the value is not a finite number or violates bounds
|
|
248
|
+
*/
|
|
249
|
+
export function validateNumber(
|
|
250
|
+
value: unknown,
|
|
251
|
+
label: string,
|
|
252
|
+
{
|
|
253
|
+
min,
|
|
254
|
+
max,
|
|
255
|
+
allowZero = true
|
|
256
|
+
}: { min?: number; max?: number; allowZero?: boolean } = {}
|
|
257
|
+
): number {
|
|
258
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
259
|
+
throw new Error(`Invalid ${label}: expected a finite number`);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!allowZero && value === 0) {
|
|
263
|
+
throw new Error(`Invalid ${label}: zero is not allowed`);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (typeof min === 'number' && value < min) {
|
|
267
|
+
throw new Error(`Invalid ${label}: must be >= ${min}`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (typeof max === 'number' && value > max) {
|
|
271
|
+
throw new Error(`Invalid ${label}: must be <= ${max}`);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return value;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Validate an array (tuple) of finite numbers, preserving the original shape.
|
|
279
|
+
* @throws if the tuple has the wrong length or contains invalid values
|
|
280
|
+
*/
|
|
281
|
+
export function ensureVector3(value: unknown, label: string): [number, number, number] {
|
|
282
|
+
const tuple = toVec3Tuple(value);
|
|
283
|
+
if (!tuple) {
|
|
284
|
+
throw new Error(`Invalid ${label}: expected an object with x,y,z or an array of 3 numbers`);
|
|
285
|
+
}
|
|
286
|
+
return tuple;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export function ensureColorRGB(value: unknown, label: string): [number, number, number] {
|
|
290
|
+
return ensureVector3(value, label);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export function ensureRotation(value: unknown, label: string): [number, number, number] {
|
|
294
|
+
const tuple = toRotTuple(value);
|
|
295
|
+
if (!tuple) {
|
|
296
|
+
throw new Error(`Invalid ${label}: expected an object with pitch,yaw,roll or an array of 3 numbers`);
|
|
297
|
+
}
|
|
298
|
+
return tuple;
|
|
299
|
+
}
|