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/tools/assets.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { UnrealBridge } from '../unreal-bridge.js';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { bestEffortInterpretedText, coerceNumber, coerceStringArray, interpretStandardResult } from '../utils/result-helpers.js';
|
|
4
5
|
|
|
5
6
|
export class AssetTools {
|
|
6
7
|
constructor(private bridge: UnrealBridge) {}
|
|
7
8
|
|
|
8
9
|
async importAsset(sourcePath: string, destinationPath: string) {
|
|
10
|
+
let createdTestFile = false;
|
|
9
11
|
try {
|
|
10
12
|
// Sanitize destination path (remove trailing slash) and normalize UE path
|
|
11
13
|
let cleanDest = destinationPath.replace(/\/$/, '');
|
|
@@ -18,16 +20,18 @@ export class AssetTools {
|
|
|
18
20
|
if (sourcePath.includes('test_model.fbx')) {
|
|
19
21
|
// Create the file outside of Python, before import
|
|
20
22
|
try {
|
|
21
|
-
this.createTestFBX(sourcePath);
|
|
22
|
-
|
|
23
|
+
await this.createTestFBX(sourcePath);
|
|
24
|
+
createdTestFile = true;
|
|
25
|
+
} catch (_err) {
|
|
23
26
|
// If we can't create the file, we'll handle it in Python
|
|
24
27
|
}
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
// Use Python API to import asset with file creation fallback
|
|
28
|
-
|
|
31
|
+
const pythonCode = `
|
|
29
32
|
import unreal
|
|
30
33
|
import os
|
|
34
|
+
import json
|
|
31
35
|
|
|
32
36
|
# Create test FBX if needed
|
|
33
37
|
source_path = r'${sourcePath}'
|
|
@@ -148,52 +152,58 @@ task.options = options
|
|
|
148
152
|
|
|
149
153
|
# Use AssetTools to import
|
|
150
154
|
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
|
|
155
|
+
result = {'success': False, 'error': 'No assets imported', 'source': task.filename}
|
|
156
|
+
|
|
151
157
|
try:
|
|
152
158
|
asset_tools.import_asset_tasks([task])
|
|
153
159
|
if task.imported_object_paths:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
160
|
+
result = {
|
|
161
|
+
'success': True,
|
|
162
|
+
'imported': len(task.imported_object_paths),
|
|
163
|
+
'paths': list(task.imported_object_paths)
|
|
164
|
+
}
|
|
157
165
|
except Exception as e:
|
|
158
|
-
|
|
166
|
+
result = {'success': False, 'error': str(e), 'source': task.filename}
|
|
167
|
+
|
|
168
|
+
print('RESULT:' + json.dumps(result))
|
|
159
169
|
`.trim();
|
|
160
170
|
|
|
161
171
|
const pyResp = await this.bridge.executePython(pythonCode);
|
|
162
172
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
const interpreted = interpretStandardResult(pyResp, {
|
|
174
|
+
successMessage: `Imported assets to ${cleanDest}`,
|
|
175
|
+
failureMessage: 'Import failed'
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (interpreted.success) {
|
|
179
|
+
const count = coerceNumber(interpreted.payload.imported) ?? 0;
|
|
180
|
+
const paths = coerceStringArray(interpreted.payload.paths) ?? [];
|
|
181
|
+
return {
|
|
182
|
+
success: true,
|
|
183
|
+
message: `Imported ${count} assets to ${cleanDest}`,
|
|
184
|
+
imported: count,
|
|
185
|
+
paths
|
|
186
|
+
};
|
|
175
187
|
}
|
|
176
188
|
|
|
177
|
-
const
|
|
178
|
-
|
|
189
|
+
const errorMessage = `Import failed: ${interpreted.error ?? 'Unknown error'} (source: ${interpreted.payload.source ?? sourcePath})`;
|
|
190
|
+
return {
|
|
191
|
+
success: false,
|
|
192
|
+
message: errorMessage,
|
|
193
|
+
error: errorMessage,
|
|
194
|
+
details: bestEffortInterpretedText(interpreted)
|
|
195
|
+
};
|
|
196
|
+
} catch (err) {
|
|
197
|
+
return { success: false, error: `Failed to import asset: ${err}` };
|
|
198
|
+
} finally {
|
|
199
|
+
if (createdTestFile) {
|
|
179
200
|
try {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
return { success: true, message: `Imported ${count} assets to ${cleanDest}`, paths };
|
|
185
|
-
} else {
|
|
186
|
-
return { error: `Import failed: ${parsed.error || 'Unknown error'} (source: ${parsed.source || sourcePath})` };
|
|
187
|
-
}
|
|
188
|
-
} catch {
|
|
189
|
-
// Fall through
|
|
201
|
+
await fs.rm(sourcePath, { force: true });
|
|
202
|
+
} catch (cleanupError) {
|
|
203
|
+
// Swallow cleanup error but log for debug visibility
|
|
204
|
+
console.warn(`Failed to clean up temporary FBX ${sourcePath}:`, cleanupError);
|
|
190
205
|
}
|
|
191
206
|
}
|
|
192
|
-
|
|
193
|
-
// If unable to parse, return generic attempt result
|
|
194
|
-
return { error: `Import did not report success for source ${sourcePath}` };
|
|
195
|
-
} catch (err) {
|
|
196
|
-
return { error: `Failed to import asset: ${err}` };
|
|
197
207
|
}
|
|
198
208
|
}
|
|
199
209
|
|
|
@@ -243,7 +253,7 @@ except Exception as e:
|
|
|
243
253
|
}
|
|
244
254
|
}
|
|
245
255
|
|
|
246
|
-
private createTestFBX(filePath: string) {
|
|
256
|
+
private async createTestFBX(filePath: string): Promise<void> {
|
|
247
257
|
// Create a minimal valid FBX ASCII file for testing
|
|
248
258
|
const fbxContent = `; FBX 7.5.0 project file
|
|
249
259
|
FBXHeaderExtension: {
|
|
@@ -299,11 +309,11 @@ Connections: {
|
|
|
299
309
|
|
|
300
310
|
// Ensure directory exists
|
|
301
311
|
const dir = path.dirname(filePath);
|
|
302
|
-
|
|
303
|
-
fs.
|
|
304
|
-
}
|
|
312
|
+
try {
|
|
313
|
+
await fs.mkdir(dir, { recursive: true });
|
|
314
|
+
} catch {}
|
|
305
315
|
|
|
306
316
|
// Write the FBX file
|
|
307
|
-
fs.
|
|
317
|
+
await fs.writeFile(filePath, fbxContent, 'utf8');
|
|
308
318
|
}
|
|
309
319
|
}
|