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.
Files changed (135) hide show
  1. package/.env.production +1 -1
  2. package/.github/copilot-instructions.md +45 -0
  3. package/.github/workflows/publish-mcp.yml +3 -2
  4. package/README.md +21 -5
  5. package/dist/index.js +124 -31
  6. package/dist/prompts/index.d.ts +10 -3
  7. package/dist/prompts/index.js +186 -7
  8. package/dist/resources/actors.d.ts +19 -1
  9. package/dist/resources/actors.js +55 -64
  10. package/dist/resources/assets.js +46 -62
  11. package/dist/resources/levels.d.ts +21 -3
  12. package/dist/resources/levels.js +29 -54
  13. package/dist/tools/actors.d.ts +3 -14
  14. package/dist/tools/actors.js +246 -302
  15. package/dist/tools/animation.d.ts +57 -102
  16. package/dist/tools/animation.js +429 -450
  17. package/dist/tools/assets.d.ts +13 -2
  18. package/dist/tools/assets.js +52 -44
  19. package/dist/tools/audio.d.ts +22 -13
  20. package/dist/tools/audio.js +467 -121
  21. package/dist/tools/blueprint.d.ts +32 -13
  22. package/dist/tools/blueprint.js +699 -448
  23. package/dist/tools/build_environment_advanced.d.ts +0 -1
  24. package/dist/tools/build_environment_advanced.js +190 -45
  25. package/dist/tools/consolidated-tool-definitions.js +78 -252
  26. package/dist/tools/consolidated-tool-handlers.js +506 -133
  27. package/dist/tools/debug.d.ts +72 -10
  28. package/dist/tools/debug.js +167 -31
  29. package/dist/tools/editor.d.ts +9 -2
  30. package/dist/tools/editor.js +30 -44
  31. package/dist/tools/foliage.d.ts +34 -15
  32. package/dist/tools/foliage.js +97 -107
  33. package/dist/tools/introspection.js +19 -21
  34. package/dist/tools/landscape.d.ts +1 -2
  35. package/dist/tools/landscape.js +311 -168
  36. package/dist/tools/level.d.ts +3 -28
  37. package/dist/tools/level.js +642 -192
  38. package/dist/tools/lighting.d.ts +14 -3
  39. package/dist/tools/lighting.js +236 -123
  40. package/dist/tools/materials.d.ts +25 -7
  41. package/dist/tools/materials.js +102 -79
  42. package/dist/tools/niagara.d.ts +10 -12
  43. package/dist/tools/niagara.js +74 -94
  44. package/dist/tools/performance.d.ts +12 -4
  45. package/dist/tools/performance.js +38 -79
  46. package/dist/tools/physics.d.ts +34 -10
  47. package/dist/tools/physics.js +364 -292
  48. package/dist/tools/rc.js +97 -23
  49. package/dist/tools/sequence.d.ts +1 -0
  50. package/dist/tools/sequence.js +125 -22
  51. package/dist/tools/ui.d.ts +31 -4
  52. package/dist/tools/ui.js +83 -66
  53. package/dist/tools/visual.d.ts +11 -0
  54. package/dist/tools/visual.js +245 -30
  55. package/dist/types/tool-types.d.ts +0 -6
  56. package/dist/types/tool-types.js +1 -8
  57. package/dist/unreal-bridge.d.ts +32 -2
  58. package/dist/unreal-bridge.js +621 -127
  59. package/dist/utils/elicitation.d.ts +57 -0
  60. package/dist/utils/elicitation.js +104 -0
  61. package/dist/utils/error-handler.d.ts +0 -33
  62. package/dist/utils/error-handler.js +4 -111
  63. package/dist/utils/http.d.ts +2 -22
  64. package/dist/utils/http.js +12 -75
  65. package/dist/utils/normalize.d.ts +4 -4
  66. package/dist/utils/normalize.js +15 -7
  67. package/dist/utils/python-output.d.ts +18 -0
  68. package/dist/utils/python-output.js +290 -0
  69. package/dist/utils/python.d.ts +2 -0
  70. package/dist/utils/python.js +4 -0
  71. package/dist/utils/response-validator.js +28 -2
  72. package/dist/utils/result-helpers.d.ts +27 -0
  73. package/dist/utils/result-helpers.js +147 -0
  74. package/dist/utils/safe-json.d.ts +0 -2
  75. package/dist/utils/safe-json.js +0 -43
  76. package/dist/utils/validation.d.ts +16 -0
  77. package/dist/utils/validation.js +70 -7
  78. package/mcp-config-example.json +2 -2
  79. package/package.json +10 -9
  80. package/server.json +37 -14
  81. package/src/index.ts +130 -33
  82. package/src/prompts/index.ts +211 -13
  83. package/src/resources/actors.ts +59 -44
  84. package/src/resources/assets.ts +48 -51
  85. package/src/resources/levels.ts +35 -45
  86. package/src/tools/actors.ts +269 -313
  87. package/src/tools/animation.ts +556 -539
  88. package/src/tools/assets.ts +53 -43
  89. package/src/tools/audio.ts +507 -113
  90. package/src/tools/blueprint.ts +778 -462
  91. package/src/tools/build_environment_advanced.ts +266 -64
  92. package/src/tools/consolidated-tool-definitions.ts +90 -264
  93. package/src/tools/consolidated-tool-handlers.ts +630 -121
  94. package/src/tools/debug.ts +176 -33
  95. package/src/tools/editor.ts +35 -37
  96. package/src/tools/foliage.ts +110 -104
  97. package/src/tools/introspection.ts +24 -22
  98. package/src/tools/landscape.ts +334 -181
  99. package/src/tools/level.ts +683 -182
  100. package/src/tools/lighting.ts +244 -123
  101. package/src/tools/materials.ts +114 -83
  102. package/src/tools/niagara.ts +87 -81
  103. package/src/tools/performance.ts +49 -88
  104. package/src/tools/physics.ts +393 -299
  105. package/src/tools/rc.ts +102 -24
  106. package/src/tools/sequence.ts +136 -28
  107. package/src/tools/ui.ts +101 -70
  108. package/src/tools/visual.ts +250 -29
  109. package/src/types/tool-types.ts +0 -9
  110. package/src/unreal-bridge.ts +658 -140
  111. package/src/utils/elicitation.ts +129 -0
  112. package/src/utils/error-handler.ts +4 -159
  113. package/src/utils/http.ts +16 -115
  114. package/src/utils/normalize.ts +20 -10
  115. package/src/utils/python-output.ts +351 -0
  116. package/src/utils/python.ts +3 -0
  117. package/src/utils/response-validator.ts +25 -2
  118. package/src/utils/result-helpers.ts +193 -0
  119. package/src/utils/safe-json.ts +0 -50
  120. package/src/utils/validation.ts +94 -7
  121. package/tests/run-unreal-tool-tests.mjs +720 -0
  122. package/tsconfig.json +2 -2
  123. package/dist/python-utils.d.ts +0 -29
  124. package/dist/python-utils.js +0 -54
  125. package/dist/types/index.d.ts +0 -323
  126. package/dist/types/index.js +0 -28
  127. package/dist/utils/cache-manager.d.ts +0 -64
  128. package/dist/utils/cache-manager.js +0 -176
  129. package/dist/utils/errors.d.ts +0 -133
  130. package/dist/utils/errors.js +0 -256
  131. package/src/python/editor_compat.py +0 -181
  132. package/src/python-utils.ts +0 -57
  133. package/src/types/index.ts +0 -414
  134. package/src/utils/cache-manager.ts +0 -213
  135. package/src/utils/errors.ts +0 -312
@@ -1,312 +0,0 @@
1
- /**
2
- * Enhanced error types for better error handling and recovery
3
- */
4
-
5
- export enum ErrorCode {
6
- // Connection errors
7
- CONNECTION_FAILED = 'CONNECTION_FAILED',
8
- CONNECTION_TIMEOUT = 'CONNECTION_TIMEOUT',
9
- CONNECTION_REFUSED = 'CONNECTION_REFUSED',
10
-
11
- // API errors
12
- API_ERROR = 'API_ERROR',
13
- INVALID_RESPONSE = 'INVALID_RESPONSE',
14
- RATE_LIMITED = 'RATE_LIMITED',
15
-
16
- // Validation errors
17
- VALIDATION_ERROR = 'VALIDATION_ERROR',
18
- INVALID_PARAMETERS = 'INVALID_PARAMETERS',
19
- MISSING_REQUIRED_FIELD = 'MISSING_REQUIRED_FIELD',
20
-
21
- // Resource errors
22
- RESOURCE_NOT_FOUND = 'RESOURCE_NOT_FOUND',
23
- RESOURCE_LOCKED = 'RESOURCE_LOCKED',
24
- RESOURCE_UNAVAILABLE = 'RESOURCE_UNAVAILABLE',
25
-
26
- // Permission errors
27
- UNAUTHORIZED = 'UNAUTHORIZED',
28
- FORBIDDEN = 'FORBIDDEN',
29
-
30
- // System errors
31
- INTERNAL_ERROR = 'INTERNAL_ERROR',
32
- CIRCUIT_BREAKER_OPEN = 'CIRCUIT_BREAKER_OPEN',
33
- SERVICE_UNAVAILABLE = 'SERVICE_UNAVAILABLE'
34
- }
35
-
36
- export interface ErrorMetadata {
37
- code: ErrorCode;
38
- statusCode?: number;
39
- retriable: boolean;
40
- context?: Record<string, any>;
41
- timestamp: Date;
42
- correlationId?: string;
43
- }
44
-
45
- /**
46
- * Base application error with metadata
47
- */
48
- export class AppError extends Error {
49
- public readonly metadata: ErrorMetadata;
50
-
51
- constructor(message: string, metadata: Partial<ErrorMetadata> = {}) {
52
- super(message);
53
- this.name = this.constructor.name;
54
- this.metadata = {
55
- code: metadata.code || ErrorCode.INTERNAL_ERROR,
56
- retriable: metadata.retriable || false,
57
- timestamp: new Date(),
58
- ...metadata
59
- };
60
- Error.captureStackTrace(this, this.constructor);
61
- }
62
-
63
- toJSON() {
64
- return {
65
- name: this.name,
66
- message: this.message,
67
- ...this.metadata,
68
- stack: this.stack
69
- };
70
- }
71
- }
72
-
73
- /**
74
- * Connection-related errors
75
- */
76
- export class ConnectionError extends AppError {
77
- constructor(message: string, metadata: Partial<ErrorMetadata> = {}) {
78
- super(message, {
79
- code: ErrorCode.CONNECTION_FAILED,
80
- retriable: true,
81
- statusCode: 503,
82
- ...metadata
83
- });
84
- }
85
- }
86
-
87
- /**
88
- * API-related errors
89
- */
90
- export class ApiError extends AppError {
91
- constructor(message: string, statusCode: number, metadata: Partial<ErrorMetadata> = {}) {
92
- super(message, {
93
- code: ErrorCode.API_ERROR,
94
- statusCode,
95
- retriable: statusCode >= 500 || statusCode === 429,
96
- ...metadata
97
- });
98
- }
99
- }
100
-
101
- /**
102
- * Validation errors
103
- */
104
- export class ValidationError extends AppError {
105
- constructor(message: string, metadata: Partial<ErrorMetadata> = {}) {
106
- super(message, {
107
- code: ErrorCode.VALIDATION_ERROR,
108
- statusCode: 400,
109
- retriable: false,
110
- ...metadata
111
- });
112
- }
113
- }
114
-
115
- /**
116
- * Resource errors
117
- */
118
- export class ResourceError extends AppError {
119
- constructor(message: string, code: ErrorCode, metadata: Partial<ErrorMetadata> = {}) {
120
- super(message, {
121
- code,
122
- statusCode: code === ErrorCode.RESOURCE_NOT_FOUND ? 404 : 409,
123
- retriable: code === ErrorCode.RESOURCE_LOCKED,
124
- ...metadata
125
- });
126
- }
127
- }
128
-
129
- /**
130
- * Circuit Breaker implementation for fault tolerance
131
- */
132
- export enum CircuitState {
133
- CLOSED = 'CLOSED',
134
- OPEN = 'OPEN',
135
- HALF_OPEN = 'HALF_OPEN'
136
- }
137
-
138
- interface CircuitBreakerOptions {
139
- threshold: number;
140
- timeout: number;
141
- resetTimeout: number;
142
- onStateChange?: (oldState: CircuitState, newState: CircuitState) => void;
143
- }
144
-
145
- export class CircuitBreaker {
146
- private state: CircuitState = CircuitState.CLOSED;
147
- private failures = 0;
148
- private successCount = 0;
149
- private lastFailureTime?: Date;
150
- private readonly options: CircuitBreakerOptions;
151
-
152
- constructor(options: Partial<CircuitBreakerOptions> = {}) {
153
- this.options = {
154
- threshold: options.threshold || 5,
155
- timeout: options.timeout || 60000, // 1 minute
156
- resetTimeout: options.resetTimeout || 30000, // 30 seconds
157
- onStateChange: options.onStateChange
158
- };
159
- }
160
-
161
- /**
162
- * Execute function with circuit breaker protection
163
- */
164
- async execute<T>(fn: () => Promise<T>): Promise<T> {
165
- // Check circuit state
166
- if (this.state === CircuitState.OPEN) {
167
- if (this.shouldAttemptReset()) {
168
- this.transitionTo(CircuitState.HALF_OPEN);
169
- } else {
170
- throw new AppError('Circuit breaker is open', {
171
- code: ErrorCode.CIRCUIT_BREAKER_OPEN,
172
- retriable: true,
173
- context: {
174
- failures: this.failures,
175
- lastFailure: this.lastFailureTime
176
- }
177
- });
178
- }
179
- }
180
-
181
- try {
182
- const result = await fn();
183
- this.onSuccess();
184
- return result;
185
- } catch (error) {
186
- this.onFailure();
187
- throw error;
188
- }
189
- }
190
-
191
- private onSuccess(): void {
192
- this.failures = 0;
193
- if (this.state === CircuitState.HALF_OPEN) {
194
- this.successCount++;
195
- if (this.successCount >= 3) {
196
- this.transitionTo(CircuitState.CLOSED);
197
- }
198
- }
199
- }
200
-
201
- private onFailure(): void {
202
- this.failures++;
203
- this.lastFailureTime = new Date();
204
- this.successCount = 0;
205
-
206
- if (this.failures >= this.options.threshold) {
207
- this.transitionTo(CircuitState.OPEN);
208
- }
209
- }
210
-
211
- private shouldAttemptReset(): boolean {
212
- return (
213
- this.lastFailureTime !== undefined &&
214
- Date.now() - this.lastFailureTime.getTime() >= this.options.resetTimeout
215
- );
216
- }
217
-
218
- private transitionTo(newState: CircuitState): void {
219
- const oldState = this.state;
220
- this.state = newState;
221
-
222
- if (newState === CircuitState.CLOSED) {
223
- this.failures = 0;
224
- this.successCount = 0;
225
- }
226
-
227
- if (this.options.onStateChange && oldState !== newState) {
228
- this.options.onStateChange(oldState, newState);
229
- }
230
- }
231
-
232
- getState(): CircuitState {
233
- return this.state;
234
- }
235
-
236
- getMetrics() {
237
- return {
238
- state: this.state,
239
- failures: this.failures,
240
- successCount: this.successCount,
241
- lastFailureTime: this.lastFailureTime
242
- };
243
- }
244
- }
245
-
246
- /**
247
- * Error recovery strategies
248
- */
249
- export class ErrorRecovery {
250
- private static circuitBreakers = new Map<string, CircuitBreaker>();
251
-
252
- /**
253
- * Get or create circuit breaker for a service
254
- */
255
- static getCircuitBreaker(service: string, options?: Partial<CircuitBreakerOptions>): CircuitBreaker {
256
- if (!this.circuitBreakers.has(service)) {
257
- this.circuitBreakers.set(service, new CircuitBreaker(options));
258
- }
259
- const breaker = this.circuitBreakers.get(service);
260
- if (!breaker) {
261
- throw new Error(`Circuit breaker for service ${service} could not be created`);
262
- }
263
- return breaker;
264
- }
265
-
266
- /**
267
- * Wrap function with error recovery
268
- */
269
- static async withRecovery<T>(
270
- fn: () => Promise<T>,
271
- options: {
272
- service: string;
273
- fallback?: () => T | Promise<T>;
274
- onError?: (error: Error) => void;
275
- }
276
- ): Promise<T> {
277
- const breaker = this.getCircuitBreaker(options.service);
278
-
279
- try {
280
- return await breaker.execute(fn);
281
- } catch (error) {
282
- if (options.onError) {
283
- options.onError(error as Error);
284
- }
285
-
286
- // Try fallback if available
287
- if (options.fallback) {
288
- return await options.fallback();
289
- }
290
-
291
- throw error;
292
- }
293
- }
294
-
295
- /**
296
- * Check if error is retriable
297
- */
298
- static isRetriable(error: Error): boolean {
299
- if (error instanceof AppError) {
300
- return error.metadata.retriable;
301
- }
302
-
303
- // Check for network errors
304
- const message = error.message.toLowerCase();
305
- return (
306
- message.includes('timeout') ||
307
- message.includes('network') ||
308
- message.includes('econnrefused') ||
309
- message.includes('econnreset')
310
- );
311
- }
312
- }