unreal-engine-mcp-server 0.4.7 → 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 (454) hide show
  1. package/.env.example +26 -0
  2. package/.env.production +38 -7
  3. package/.eslintrc.json +0 -54
  4. package/.eslintrc.override.json +8 -0
  5. package/.github/ISSUE_TEMPLATE/bug_report.yml +94 -0
  6. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  7. package/.github/ISSUE_TEMPLATE/feature_request.yml +56 -0
  8. package/.github/copilot-instructions.md +478 -45
  9. package/.github/dependabot.yml +19 -0
  10. package/.github/labeler.yml +24 -0
  11. package/.github/labels.yml +70 -0
  12. package/.github/pull_request_template.md +42 -0
  13. package/.github/release-drafter-config.yml +51 -0
  14. package/.github/workflows/auto-merge.yml +38 -0
  15. package/.github/workflows/ci.yml +38 -0
  16. package/.github/workflows/dependency-review.yml +17 -0
  17. package/.github/workflows/gemini-issue-triage.yml +172 -0
  18. package/.github/workflows/greetings.yml +27 -0
  19. package/.github/workflows/labeler.yml +17 -0
  20. package/.github/workflows/links.yml +80 -0
  21. package/.github/workflows/pr-size-labeler.yml +137 -0
  22. package/.github/workflows/publish-mcp.yml +13 -7
  23. package/.github/workflows/release-drafter.yml +23 -0
  24. package/.github/workflows/release.yml +112 -0
  25. package/.github/workflows/semantic-pull-request.yml +35 -0
  26. package/.github/workflows/smoke-test.yml +36 -0
  27. package/.github/workflows/stale.yml +28 -0
  28. package/CHANGELOG.md +338 -31
  29. package/CONTRIBUTING.md +140 -0
  30. package/GEMINI.md +115 -0
  31. package/Public/Plugin_setup_guide.mp4 +0 -0
  32. package/README.md +189 -128
  33. package/claude_desktop_config_example.json +7 -6
  34. package/dist/automation/bridge.d.ts +50 -0
  35. package/dist/automation/bridge.js +452 -0
  36. package/dist/automation/connection-manager.d.ts +23 -0
  37. package/dist/automation/connection-manager.js +107 -0
  38. package/dist/automation/handshake.d.ts +11 -0
  39. package/dist/automation/handshake.js +89 -0
  40. package/dist/automation/index.d.ts +3 -0
  41. package/dist/automation/index.js +3 -0
  42. package/dist/automation/message-handler.d.ts +12 -0
  43. package/dist/automation/message-handler.js +149 -0
  44. package/dist/automation/request-tracker.d.ts +25 -0
  45. package/dist/automation/request-tracker.js +98 -0
  46. package/dist/automation/types.d.ts +130 -0
  47. package/dist/automation/types.js +2 -0
  48. package/dist/cli.js +32 -5
  49. package/dist/config.d.ts +26 -0
  50. package/dist/config.js +59 -0
  51. package/dist/constants.d.ts +16 -0
  52. package/dist/constants.js +16 -0
  53. package/dist/graphql/loaders.d.ts +64 -0
  54. package/dist/graphql/loaders.js +117 -0
  55. package/dist/graphql/resolvers.d.ts +268 -0
  56. package/dist/graphql/resolvers.js +746 -0
  57. package/dist/graphql/schema.d.ts +5 -0
  58. package/dist/graphql/schema.js +437 -0
  59. package/dist/graphql/server.d.ts +26 -0
  60. package/dist/graphql/server.js +117 -0
  61. package/dist/graphql/types.d.ts +9 -0
  62. package/dist/graphql/types.js +2 -0
  63. package/dist/handlers/resource-handlers.d.ts +20 -0
  64. package/dist/handlers/resource-handlers.js +180 -0
  65. package/dist/index.d.ts +33 -18
  66. package/dist/index.js +130 -619
  67. package/dist/resources/actors.d.ts +17 -12
  68. package/dist/resources/actors.js +56 -76
  69. package/dist/resources/assets.d.ts +6 -14
  70. package/dist/resources/assets.js +115 -147
  71. package/dist/resources/levels.d.ts +13 -13
  72. package/dist/resources/levels.js +25 -34
  73. package/dist/server/resource-registry.d.ts +20 -0
  74. package/dist/server/resource-registry.js +37 -0
  75. package/dist/server/tool-registry.d.ts +23 -0
  76. package/dist/server/tool-registry.js +322 -0
  77. package/dist/server-setup.d.ts +20 -0
  78. package/dist/server-setup.js +71 -0
  79. package/dist/services/health-monitor.d.ts +34 -0
  80. package/dist/services/health-monitor.js +105 -0
  81. package/dist/services/metrics-server.d.ts +11 -0
  82. package/dist/services/metrics-server.js +105 -0
  83. package/dist/tools/actors.d.ts +163 -9
  84. package/dist/tools/actors.js +356 -311
  85. package/dist/tools/animation.d.ts +135 -4
  86. package/dist/tools/animation.js +510 -411
  87. package/dist/tools/assets.d.ts +75 -29
  88. package/dist/tools/assets.js +265 -284
  89. package/dist/tools/audio.d.ts +102 -42
  90. package/dist/tools/audio.js +272 -685
  91. package/dist/tools/base-tool.d.ts +17 -0
  92. package/dist/tools/base-tool.js +46 -0
  93. package/dist/tools/behavior-tree.d.ts +94 -0
  94. package/dist/tools/behavior-tree.js +39 -0
  95. package/dist/tools/blueprint.d.ts +208 -126
  96. package/dist/tools/blueprint.js +685 -832
  97. package/dist/tools/consolidated-tool-definitions.d.ts +5462 -1781
  98. package/dist/tools/consolidated-tool-definitions.js +829 -496
  99. package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
  100. package/dist/tools/consolidated-tool-handlers.js +198 -1027
  101. package/dist/tools/debug.d.ts +143 -85
  102. package/dist/tools/debug.js +234 -180
  103. package/dist/tools/dynamic-handler-registry.d.ts +13 -0
  104. package/dist/tools/dynamic-handler-registry.js +23 -0
  105. package/dist/tools/editor.d.ts +30 -83
  106. package/dist/tools/editor.js +247 -244
  107. package/dist/tools/engine.d.ts +10 -4
  108. package/dist/tools/engine.js +13 -5
  109. package/dist/tools/environment.d.ts +30 -0
  110. package/dist/tools/environment.js +267 -0
  111. package/dist/tools/foliage.d.ts +65 -99
  112. package/dist/tools/foliage.js +221 -331
  113. package/dist/tools/handlers/actor-handlers.d.ts +3 -0
  114. package/dist/tools/handlers/actor-handlers.js +227 -0
  115. package/dist/tools/handlers/animation-handlers.d.ts +3 -0
  116. package/dist/tools/handlers/animation-handlers.js +185 -0
  117. package/dist/tools/handlers/argument-helper.d.ts +16 -0
  118. package/dist/tools/handlers/argument-helper.js +80 -0
  119. package/dist/tools/handlers/asset-handlers.d.ts +3 -0
  120. package/dist/tools/handlers/asset-handlers.js +496 -0
  121. package/dist/tools/handlers/audio-handlers.d.ts +3 -0
  122. package/dist/tools/handlers/audio-handlers.js +166 -0
  123. package/dist/tools/handlers/blueprint-handlers.d.ts +4 -0
  124. package/dist/tools/handlers/blueprint-handlers.js +358 -0
  125. package/dist/tools/handlers/common-handlers.d.ts +14 -0
  126. package/dist/tools/handlers/common-handlers.js +56 -0
  127. package/dist/tools/handlers/editor-handlers.d.ts +3 -0
  128. package/dist/tools/handlers/editor-handlers.js +119 -0
  129. package/dist/tools/handlers/effect-handlers.d.ts +3 -0
  130. package/dist/tools/handlers/effect-handlers.js +171 -0
  131. package/dist/tools/handlers/environment-handlers.d.ts +3 -0
  132. package/dist/tools/handlers/environment-handlers.js +170 -0
  133. package/dist/tools/handlers/graph-handlers.d.ts +3 -0
  134. package/dist/tools/handlers/graph-handlers.js +90 -0
  135. package/dist/tools/handlers/input-handlers.d.ts +3 -0
  136. package/dist/tools/handlers/input-handlers.js +21 -0
  137. package/dist/tools/handlers/inspect-handlers.d.ts +3 -0
  138. package/dist/tools/handlers/inspect-handlers.js +383 -0
  139. package/dist/tools/handlers/level-handlers.d.ts +3 -0
  140. package/dist/tools/handlers/level-handlers.js +237 -0
  141. package/dist/tools/handlers/lighting-handlers.d.ts +3 -0
  142. package/dist/tools/handlers/lighting-handlers.js +144 -0
  143. package/dist/tools/handlers/performance-handlers.d.ts +3 -0
  144. package/dist/tools/handlers/performance-handlers.js +130 -0
  145. package/dist/tools/handlers/pipeline-handlers.d.ts +3 -0
  146. package/dist/tools/handlers/pipeline-handlers.js +110 -0
  147. package/dist/tools/handlers/sequence-handlers.d.ts +3 -0
  148. package/dist/tools/handlers/sequence-handlers.js +376 -0
  149. package/dist/tools/handlers/system-handlers.d.ts +4 -0
  150. package/dist/tools/handlers/system-handlers.js +506 -0
  151. package/dist/tools/input.d.ts +19 -0
  152. package/dist/tools/input.js +89 -0
  153. package/dist/tools/introspection.d.ts +103 -40
  154. package/dist/tools/introspection.js +425 -568
  155. package/dist/tools/landscape.d.ts +54 -93
  156. package/dist/tools/landscape.js +284 -409
  157. package/dist/tools/level.d.ts +66 -27
  158. package/dist/tools/level.js +647 -675
  159. package/dist/tools/lighting.d.ts +77 -38
  160. package/dist/tools/lighting.js +445 -943
  161. package/dist/tools/logs.d.ts +3 -3
  162. package/dist/tools/logs.js +5 -57
  163. package/dist/tools/materials.d.ts +91 -24
  164. package/dist/tools/materials.js +194 -118
  165. package/dist/tools/niagara.d.ts +149 -39
  166. package/dist/tools/niagara.js +267 -182
  167. package/dist/tools/performance.d.ts +27 -13
  168. package/dist/tools/performance.js +203 -122
  169. package/dist/tools/physics.d.ts +32 -77
  170. package/dist/tools/physics.js +175 -582
  171. package/dist/tools/property-dictionary.d.ts +13 -0
  172. package/dist/tools/property-dictionary.js +82 -0
  173. package/dist/tools/sequence.d.ts +85 -60
  174. package/dist/tools/sequence.js +208 -747
  175. package/dist/tools/tool-definition-utils.d.ts +59 -0
  176. package/dist/tools/tool-definition-utils.js +35 -0
  177. package/dist/tools/ui.d.ts +64 -34
  178. package/dist/tools/ui.js +134 -214
  179. package/dist/types/automation-responses.d.ts +115 -0
  180. package/dist/types/automation-responses.js +2 -0
  181. package/dist/types/env.d.ts +0 -3
  182. package/dist/types/env.js +0 -7
  183. package/dist/types/responses.d.ts +249 -0
  184. package/dist/types/responses.js +2 -0
  185. package/dist/types/tool-interfaces.d.ts +898 -0
  186. package/dist/types/tool-interfaces.js +2 -0
  187. package/dist/types/tool-types.d.ts +183 -19
  188. package/dist/types/tool-types.js +0 -4
  189. package/dist/unreal-bridge.d.ts +24 -131
  190. package/dist/unreal-bridge.js +364 -1506
  191. package/dist/utils/command-validator.d.ts +9 -0
  192. package/dist/utils/command-validator.js +68 -0
  193. package/dist/utils/elicitation.d.ts +1 -1
  194. package/dist/utils/elicitation.js +12 -15
  195. package/dist/utils/error-handler.d.ts +2 -51
  196. package/dist/utils/error-handler.js +11 -87
  197. package/dist/utils/ini-reader.d.ts +3 -0
  198. package/dist/utils/ini-reader.js +69 -0
  199. package/dist/utils/logger.js +9 -6
  200. package/dist/utils/normalize.d.ts +3 -0
  201. package/dist/utils/normalize.js +56 -0
  202. package/dist/utils/path-security.d.ts +2 -0
  203. package/dist/utils/path-security.js +24 -0
  204. package/dist/utils/response-factory.d.ts +7 -0
  205. package/dist/utils/response-factory.js +27 -0
  206. package/dist/utils/response-validator.d.ts +3 -24
  207. package/dist/utils/response-validator.js +130 -81
  208. package/dist/utils/result-helpers.d.ts +4 -5
  209. package/dist/utils/result-helpers.js +15 -16
  210. package/dist/utils/safe-json.js +5 -11
  211. package/dist/utils/unreal-command-queue.d.ts +24 -0
  212. package/dist/utils/unreal-command-queue.js +120 -0
  213. package/dist/utils/validation.d.ts +0 -40
  214. package/dist/utils/validation.js +1 -78
  215. package/dist/wasm/index.d.ts +70 -0
  216. package/dist/wasm/index.js +535 -0
  217. package/docs/GraphQL-API.md +888 -0
  218. package/docs/Migration-Guide-v0.5.0.md +684 -0
  219. package/docs/Roadmap.md +53 -0
  220. package/docs/WebAssembly-Integration.md +628 -0
  221. package/docs/editor-plugin-extension.md +370 -0
  222. package/docs/handler-mapping.md +242 -0
  223. package/docs/native-automation-progress.md +128 -0
  224. package/docs/testing-guide.md +423 -0
  225. package/mcp-config-example.json +6 -6
  226. package/package.json +67 -28
  227. package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +8 -0
  228. package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +64 -0
  229. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +189 -0
  230. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +22 -0
  231. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +30 -0
  232. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +1983 -0
  233. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +72 -0
  234. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +46 -0
  235. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +581 -0
  236. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +2394 -0
  237. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +300 -0
  238. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +2807 -0
  239. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +1087 -0
  240. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +488 -0
  241. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +643 -0
  242. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +31 -0
  243. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +1184 -0
  244. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +5652 -0
  245. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +152 -0
  246. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +2614 -0
  247. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +42 -0
  248. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +1237 -0
  249. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +1701 -0
  250. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +2145 -0
  251. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +954 -0
  252. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +209 -0
  253. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +41 -0
  254. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +1164 -0
  255. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +762 -0
  256. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +634 -0
  257. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +136 -0
  258. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +494 -0
  259. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +278 -0
  260. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +625 -0
  261. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +401 -0
  262. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +67 -0
  263. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +735 -0
  264. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +2634 -0
  265. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +189 -0
  266. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +917 -0
  267. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +39 -0
  268. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +2670 -0
  269. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +519 -0
  270. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +38 -0
  271. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +668 -0
  272. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +346 -0
  273. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +1330 -0
  274. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +149 -0
  275. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +783 -0
  276. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +115 -0
  277. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +796 -0
  278. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +117 -0
  279. package/scripts/check-unreal-connection.mjs +19 -0
  280. package/scripts/clean-tmp.js +23 -0
  281. package/scripts/patch-wasm.js +26 -0
  282. package/scripts/run-all-tests.mjs +136 -0
  283. package/scripts/smoke-test.ts +94 -0
  284. package/scripts/sync-mcp-plugin.js +143 -0
  285. package/scripts/test-no-plugin-alternates.mjs +113 -0
  286. package/scripts/validate-server.js +46 -0
  287. package/scripts/verify-automation-bridge.js +200 -0
  288. package/server.json +58 -21
  289. package/src/automation/bridge.ts +558 -0
  290. package/src/automation/connection-manager.ts +130 -0
  291. package/src/automation/handshake.ts +99 -0
  292. package/src/automation/index.ts +2 -0
  293. package/src/automation/message-handler.ts +167 -0
  294. package/src/automation/request-tracker.ts +123 -0
  295. package/src/automation/types.ts +107 -0
  296. package/src/cli.ts +33 -6
  297. package/src/config.ts +73 -0
  298. package/src/constants.ts +19 -0
  299. package/src/graphql/loaders.ts +244 -0
  300. package/src/graphql/resolvers.ts +1008 -0
  301. package/src/graphql/schema.ts +452 -0
  302. package/src/graphql/server.ts +156 -0
  303. package/src/graphql/types.ts +10 -0
  304. package/src/handlers/resource-handlers.ts +186 -0
  305. package/src/index.ts +166 -664
  306. package/src/resources/actors.ts +58 -76
  307. package/src/resources/assets.ts +148 -134
  308. package/src/resources/levels.ts +28 -33
  309. package/src/server/resource-registry.ts +47 -0
  310. package/src/server/tool-registry.ts +354 -0
  311. package/src/server-setup.ts +114 -0
  312. package/src/services/health-monitor.ts +132 -0
  313. package/src/services/metrics-server.ts +142 -0
  314. package/src/tools/actors.ts +426 -323
  315. package/src/tools/animation.ts +672 -461
  316. package/src/tools/assets.ts +364 -289
  317. package/src/tools/audio.ts +323 -766
  318. package/src/tools/base-tool.ts +52 -0
  319. package/src/tools/behavior-tree.ts +45 -0
  320. package/src/tools/blueprint.ts +792 -970
  321. package/src/tools/consolidated-tool-definitions.ts +993 -515
  322. package/src/tools/consolidated-tool-handlers.ts +258 -1146
  323. package/src/tools/debug.ts +292 -187
  324. package/src/tools/dynamic-handler-registry.ts +33 -0
  325. package/src/tools/editor.ts +329 -253
  326. package/src/tools/engine.ts +14 -3
  327. package/src/tools/environment.ts +281 -0
  328. package/src/tools/foliage.ts +330 -392
  329. package/src/tools/handlers/actor-handlers.ts +265 -0
  330. package/src/tools/handlers/animation-handlers.ts +237 -0
  331. package/src/tools/handlers/argument-helper.ts +142 -0
  332. package/src/tools/handlers/asset-handlers.ts +532 -0
  333. package/src/tools/handlers/audio-handlers.ts +194 -0
  334. package/src/tools/handlers/blueprint-handlers.ts +380 -0
  335. package/src/tools/handlers/common-handlers.ts +87 -0
  336. package/src/tools/handlers/editor-handlers.ts +123 -0
  337. package/src/tools/handlers/effect-handlers.ts +220 -0
  338. package/src/tools/handlers/environment-handlers.ts +183 -0
  339. package/src/tools/handlers/graph-handlers.ts +116 -0
  340. package/src/tools/handlers/input-handlers.ts +28 -0
  341. package/src/tools/handlers/inspect-handlers.ts +450 -0
  342. package/src/tools/handlers/level-handlers.ts +252 -0
  343. package/src/tools/handlers/lighting-handlers.ts +147 -0
  344. package/src/tools/handlers/performance-handlers.ts +132 -0
  345. package/src/tools/handlers/pipeline-handlers.ts +127 -0
  346. package/src/tools/handlers/sequence-handlers.ts +415 -0
  347. package/src/tools/handlers/system-handlers.ts +564 -0
  348. package/src/tools/input.ts +101 -0
  349. package/src/tools/introspection.ts +493 -584
  350. package/src/tools/landscape.ts +418 -507
  351. package/src/tools/level.ts +786 -708
  352. package/src/tools/lighting.ts +588 -984
  353. package/src/tools/logs.ts +9 -57
  354. package/src/tools/materials.ts +237 -121
  355. package/src/tools/niagara.ts +335 -168
  356. package/src/tools/performance.ts +320 -169
  357. package/src/tools/physics.ts +274 -613
  358. package/src/tools/property-dictionary.ts +98 -0
  359. package/src/tools/sequence.ts +276 -820
  360. package/src/tools/tool-definition-utils.ts +35 -0
  361. package/src/tools/ui.ts +205 -283
  362. package/src/types/automation-responses.ts +119 -0
  363. package/src/types/env.ts +0 -10
  364. package/src/types/responses.ts +355 -0
  365. package/src/types/tool-interfaces.ts +250 -0
  366. package/src/types/tool-types.ts +243 -21
  367. package/src/unreal-bridge.ts +460 -1550
  368. package/src/utils/command-validator.ts +76 -0
  369. package/src/utils/elicitation.ts +10 -7
  370. package/src/utils/error-handler.ts +14 -90
  371. package/src/utils/ini-reader.ts +86 -0
  372. package/src/utils/logger.ts +8 -3
  373. package/src/utils/normalize.test.ts +162 -0
  374. package/src/utils/normalize.ts +60 -0
  375. package/src/utils/path-security.ts +43 -0
  376. package/src/utils/response-factory.ts +44 -0
  377. package/src/utils/response-validator.ts +176 -56
  378. package/src/utils/result-helpers.ts +21 -19
  379. package/src/utils/safe-json.test.ts +90 -0
  380. package/src/utils/safe-json.ts +14 -11
  381. package/src/utils/unreal-command-queue.ts +152 -0
  382. package/src/utils/validation.test.ts +184 -0
  383. package/src/utils/validation.ts +4 -1
  384. package/src/wasm/index.ts +838 -0
  385. package/test-server.mjs +100 -0
  386. package/tests/run-unreal-tool-tests.mjs +242 -14
  387. package/tests/test-animation.mjs +369 -0
  388. package/tests/test-asset-advanced.mjs +82 -0
  389. package/tests/test-asset-errors.mjs +35 -0
  390. package/tests/test-asset-graph.mjs +311 -0
  391. package/tests/test-audio.mjs +417 -0
  392. package/tests/test-automation-timeouts.mjs +98 -0
  393. package/tests/test-behavior-tree.mjs +444 -0
  394. package/tests/test-blueprint-graph.mjs +410 -0
  395. package/tests/test-blueprint.mjs +577 -0
  396. package/tests/test-client-mode.mjs +86 -0
  397. package/tests/test-console-command.mjs +56 -0
  398. package/tests/test-control-actor.mjs +425 -0
  399. package/tests/test-control-editor.mjs +112 -0
  400. package/tests/test-graphql.mjs +372 -0
  401. package/tests/test-input.mjs +349 -0
  402. package/tests/test-inspect.mjs +302 -0
  403. package/tests/test-landscape.mjs +316 -0
  404. package/tests/test-lighting.mjs +428 -0
  405. package/tests/test-manage-asset.mjs +438 -0
  406. package/tests/test-manage-level.mjs +89 -0
  407. package/tests/test-materials.mjs +356 -0
  408. package/tests/test-niagara.mjs +185 -0
  409. package/tests/test-no-inline-python.mjs +122 -0
  410. package/tests/test-performance.mjs +539 -0
  411. package/tests/test-plugin-handshake.mjs +82 -0
  412. package/tests/test-runner.mjs +933 -0
  413. package/tests/test-sequence.mjs +104 -0
  414. package/tests/test-system.mjs +96 -0
  415. package/tests/test-wasm.mjs +283 -0
  416. package/tests/test-world-partition.mjs +215 -0
  417. package/tsconfig.json +3 -3
  418. package/vitest.config.ts +35 -0
  419. package/wasm/Cargo.lock +363 -0
  420. package/wasm/Cargo.toml +42 -0
  421. package/wasm/LICENSE +21 -0
  422. package/wasm/README.md +253 -0
  423. package/wasm/src/dependency_resolver.rs +377 -0
  424. package/wasm/src/lib.rs +153 -0
  425. package/wasm/src/property_parser.rs +271 -0
  426. package/wasm/src/transform_math.rs +396 -0
  427. package/wasm/tests/integration.rs +109 -0
  428. package/.github/workflows/smithery-build.yml +0 -29
  429. package/dist/prompts/index.d.ts +0 -21
  430. package/dist/prompts/index.js +0 -217
  431. package/dist/tools/build_environment_advanced.d.ts +0 -65
  432. package/dist/tools/build_environment_advanced.js +0 -633
  433. package/dist/tools/rc.d.ts +0 -110
  434. package/dist/tools/rc.js +0 -437
  435. package/dist/tools/visual.d.ts +0 -40
  436. package/dist/tools/visual.js +0 -282
  437. package/dist/utils/http.d.ts +0 -6
  438. package/dist/utils/http.js +0 -151
  439. package/dist/utils/python-output.d.ts +0 -18
  440. package/dist/utils/python-output.js +0 -290
  441. package/dist/utils/python.d.ts +0 -2
  442. package/dist/utils/python.js +0 -4
  443. package/dist/utils/stdio-redirect.d.ts +0 -2
  444. package/dist/utils/stdio-redirect.js +0 -20
  445. package/docs/unreal-tool-test-cases.md +0 -574
  446. package/smithery.yaml +0 -29
  447. package/src/prompts/index.ts +0 -249
  448. package/src/tools/build_environment_advanced.ts +0 -732
  449. package/src/tools/rc.ts +0 -515
  450. package/src/tools/visual.ts +0 -281
  451. package/src/utils/http.ts +0 -187
  452. package/src/utils/python-output.ts +0 -351
  453. package/src/utils/python.ts +0 -3
  454. package/src/utils/stdio-redirect.ts +0 -18
@@ -1,31 +1,36 @@
1
1
  import { UnrealBridge } from '../unreal-bridge.js';
2
2
  export declare class ActorResources {
3
3
  private bridge;
4
+ private automationBridge?;
4
5
  private cache;
5
6
  private readonly CACHE_TTL_MS;
6
- constructor(bridge: UnrealBridge);
7
+ private automationBridgeAvailable;
8
+ constructor(bridge: UnrealBridge, automationBridge?: any | undefined);
7
9
  private getFromCache;
8
10
  private setCache;
9
11
  listActors(): Promise<any>;
10
12
  getActorByName(actorName: string): Promise<{
13
+ success: boolean;
14
+ error: string;
15
+ name?: undefined;
16
+ path?: undefined;
17
+ class?: undefined;
18
+ } | {
11
19
  success: true;
12
20
  name: string;
13
21
  path: string | undefined;
14
22
  class: string | undefined;
15
23
  error?: undefined;
16
- } | {
17
- success: false;
24
+ }>;
25
+ getActorTransform(actorPath: string): Promise<Record<string, any>>;
26
+ listActorComponents(actorPath: string): Promise<{
27
+ success: boolean;
18
28
  error: string;
19
- name?: undefined;
20
- path?: undefined;
21
- class?: undefined;
29
+ components?: undefined;
22
30
  } | {
23
- error: string;
24
- success?: undefined;
25
- name?: undefined;
26
- path?: undefined;
27
- class?: undefined;
31
+ success: true;
32
+ components: any;
33
+ error?: undefined;
28
34
  }>;
29
- getActorTransform(actorPath: string): Promise<any>;
30
35
  }
31
36
  //# sourceMappingURL=actors.d.ts.map
@@ -1,10 +1,14 @@
1
- import { bestEffortInterpretedText, coerceNumber, coerceString, interpretStandardResult } from '../utils/result-helpers.js';
1
+ import { coerceNumber, coerceString } from '../utils/result-helpers.js';
2
2
  export class ActorResources {
3
3
  bridge;
4
+ automationBridge;
4
5
  cache = new Map();
5
- CACHE_TTL_MS = 5000; // 5 seconds cache for actors (they change more frequently)
6
- constructor(bridge) {
6
+ CACHE_TTL_MS = 5000;
7
+ automationBridgeAvailable = false;
8
+ constructor(bridge, automationBridge) {
7
9
  this.bridge = bridge;
10
+ this.automationBridge = automationBridge;
11
+ this.automationBridgeAvailable = Boolean(automationBridge && typeof automationBridge.sendAutomationRequest === 'function');
8
12
  }
9
13
  getFromCache(key) {
10
14
  const entry = this.cache.get(key);
@@ -18,115 +22,91 @@ export class ActorResources {
18
22
  this.cache.set(key, { data, timestamp: Date.now() });
19
23
  }
20
24
  async listActors() {
21
- // Check cache first
22
25
  const cached = this.getFromCache('listActors');
23
26
  if (cached !== null) {
24
27
  return cached;
25
28
  }
26
- // Use Python to get actors via EditorActorSubsystem
27
29
  try {
28
- const pythonCode = `
29
- import unreal, json
30
- actor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
31
- actors = actor_subsystem.get_all_level_actors() if actor_subsystem else []
32
- actor_list = []
33
- for actor in actors:
34
- try:
35
- if actor:
36
- actor_list.append({
37
- 'name': actor.get_name(),
38
- 'class': actor.get_class().get_name(),
39
- 'path': actor.get_path_name()
40
- })
41
- except Exception:
42
- pass
43
- print('RESULT:' + json.dumps({'success': True, 'count': len(actor_list), 'actors': actor_list}))
44
- `.trim();
45
- const response = await this.bridge.executePython(pythonCode);
46
- const interpreted = interpretStandardResult(response, {
47
- successMessage: 'Retrieved actor list',
48
- failureMessage: 'Failed to retrieve actor list'
49
- });
50
- if (interpreted.success && Array.isArray(interpreted.payload.actors)) {
51
- const actors = interpreted.payload.actors;
52
- const count = coerceNumber(interpreted.payload.count) ?? actors.length;
53
- const payload = {
54
- success: true,
55
- count,
56
- actors
57
- };
30
+ if (!this.automationBridgeAvailable) {
31
+ return { success: false, error: 'Automation bridge is not available. Please ensure Unreal Engine is running with the MCP Automation Bridge plugin.' };
32
+ }
33
+ const resp = await this.automationBridge.sendAutomationRequest('control_actor', { action: 'list' });
34
+ if (resp && resp.success !== false && Array.isArray((resp.result || resp).actors)) {
35
+ const actors = (resp.result || resp).actors;
36
+ const count = coerceNumber((resp.result || resp).count) ?? actors.length;
37
+ const payload = { success: true, count, actors };
58
38
  this.setCache('listActors', payload);
59
39
  return payload;
60
40
  }
61
- return {
62
- success: false,
63
- error: coerceString(interpreted.payload.error) ?? interpreted.error ?? 'Failed to parse actors list',
64
- note: bestEffortInterpretedText(interpreted)
65
- };
41
+ return { success: false, error: 'Failed to retrieve actor list from automation bridge' };
66
42
  }
67
43
  catch (err) {
68
44
  return { success: false, error: `Failed to list actors: ${err}` };
69
45
  }
70
46
  }
71
47
  async getActorByName(actorName) {
72
- // GetActorOfClass expects a class, not a name. Use Python to find by name
73
48
  try {
74
- const pythonCode = `
75
- import unreal
76
- import json
77
-
78
- actor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
79
- actors = actor_subsystem.get_all_level_actors() if actor_subsystem else []
80
-
81
- found = None
82
- for actor in actors:
83
- if actor and actor.get_name() == ${JSON.stringify(actorName)}:
84
- found = {
85
- 'success': True,
86
- 'name': actor.get_name(),
87
- 'path': actor.get_path_name(),
88
- 'class': actor.get_class().get_name()
89
- }
90
- break
91
-
92
- if not found:
93
- found = {'success': False, 'error': f"Actor not found: {actorName}"}
94
-
95
- print('RESULT:' + json.dumps(found))
96
- `.trim();
97
- const response = await this.bridge.executePython(pythonCode);
98
- const interpreted = interpretStandardResult(response, {
99
- successMessage: `Actor resolved: ${actorName}`,
100
- failureMessage: `Actor not found: ${actorName}`
49
+ if (!this.automationBridgeAvailable) {
50
+ return { success: false, error: 'Automation bridge is not available' };
51
+ }
52
+ const resp = await this.automationBridge.sendAutomationRequest('control_actor', {
53
+ action: 'find_by_name',
54
+ name: actorName
101
55
  });
102
- if (interpreted.success) {
56
+ if (resp && resp.success !== false && resp.result) {
103
57
  return {
104
58
  success: true,
105
- name: coerceString(interpreted.payload.name) ?? actorName,
106
- path: coerceString(interpreted.payload.path),
107
- class: coerceString(interpreted.payload.class)
59
+ name: coerceString(resp.result.name) ?? actorName,
60
+ path: coerceString(resp.result.path),
61
+ class: coerceString(resp.result.class)
108
62
  };
109
63
  }
110
64
  return {
111
65
  success: false,
112
- error: coerceString(interpreted.payload.error) ?? interpreted.error ?? `Actor not found: ${actorName}`
66
+ error: `Actor not found: ${actorName}`
113
67
  };
114
68
  }
115
69
  catch (err) {
116
- return { error: `Failed to get actor: ${err}` };
70
+ return { success: false, error: `Failed to get actor: ${err}` };
117
71
  }
118
72
  }
119
73
  async getActorTransform(actorPath) {
120
74
  try {
121
- const res = await this.bridge.httpCall('/remote/object/property', 'GET', {
75
+ return await this.bridge.getObjectProperty({
122
76
  objectPath: actorPath,
123
77
  propertyName: 'ActorTransform'
124
78
  });
125
- return res;
126
79
  }
127
80
  catch (err) {
128
81
  return { error: `Failed to get transform: ${err}` };
129
82
  }
130
83
  }
84
+ async listActorComponents(actorPath) {
85
+ try {
86
+ if (!this.automationBridgeAvailable) {
87
+ return { success: false, error: 'Automation bridge is not available' };
88
+ }
89
+ const resp = await this.automationBridge.sendAutomationRequest('control_actor', {
90
+ action: 'list_components',
91
+ actor_path: actorPath
92
+ });
93
+ if (resp && resp.success !== false && Array.isArray(resp.result?.components)) {
94
+ return {
95
+ success: true,
96
+ components: resp.result.components
97
+ };
98
+ }
99
+ return {
100
+ success: false,
101
+ error: `Failed to resolve components for ${actorPath}`
102
+ };
103
+ }
104
+ catch (err) {
105
+ return {
106
+ success: false,
107
+ error: `Component lookup failed: ${err}`
108
+ };
109
+ }
110
+ }
131
111
  }
132
112
  //# sourceMappingURL=actors.js.map
@@ -1,24 +1,16 @@
1
- import { UnrealBridge } from '../unreal-bridge.js';
2
- export declare class AssetResources {
3
- private bridge;
4
- constructor(bridge: UnrealBridge);
1
+ import { BaseTool } from '../tools/base-tool.js';
2
+ import { IAssetResources } from '../types/tool-interfaces.js';
3
+ export declare class AssetResources extends BaseTool implements IAssetResources {
5
4
  private cache;
6
5
  private get ttlMs();
7
6
  private makeKey;
8
7
  private normalizeDir;
8
+ clearCache(dir?: string): void;
9
+ invalidateAssetPaths(paths: string[]): void;
9
10
  list(dir?: string, _recursive?: boolean, limit?: number): Promise<any>;
10
- /**
11
- * List assets with pagination support
12
- * @param dir Directory to list assets from
13
- * @param page Page number (0-based)
14
- * @param pageSize Number of assets per page (max 50 to avoid socket failures)
15
- */
16
11
  listPaged(dir?: string, page?: number, pageSize?: number, recursive?: boolean): Promise<any>;
17
- /**
18
- * Directory-based listing of immediate children using AssetRegistry.
19
- * Returns both subfolders and assets at the given path.
20
- */
21
12
  private listDirectoryOnly;
22
13
  find(assetPath: string): Promise<boolean>;
14
+ private parentDirectory;
23
15
  }
24
16
  //# sourceMappingURL=assets.d.ts.map
@@ -1,18 +1,11 @@
1
- import { coerceBoolean, coerceString, interpretStandardResult } from '../utils/result-helpers.js';
2
- export class AssetResources {
3
- bridge;
4
- constructor(bridge) {
5
- this.bridge = bridge;
6
- }
7
- // Simple in-memory cache for asset listing
1
+ import { BaseTool } from '../tools/base-tool.js';
2
+ import { coerceString } from '../utils/result-helpers.js';
3
+ export class AssetResources extends BaseTool {
8
4
  cache = new Map();
9
5
  get ttlMs() { return Number(process.env.ASSET_LIST_TTL_MS || 10000); }
10
6
  makeKey(dir, recursive, page) {
11
7
  return page !== undefined ? `${dir}::${recursive ? 1 : 0}::${page}` : `${dir}::${recursive ? 1 : 0}`;
12
8
  }
13
- // Normalize UE content paths:
14
- // - Map '/Content' -> '/Game'
15
- // - Ensure forward slashes
16
9
  normalizeDir(dir) {
17
10
  try {
18
11
  if (!dir || typeof dir !== 'string')
@@ -23,9 +16,7 @@ export class AssetResources {
23
16
  if (d.toLowerCase().startsWith('/content')) {
24
17
  d = '/Game' + d.substring('/Content'.length);
25
18
  }
26
- // Collapse multiple slashes
27
19
  d = d.replace(/\/+/g, '/');
28
- // Remove trailing slash except root
29
20
  if (d.length > 1)
30
21
  d = d.replace(/\/$/, '');
31
22
  return d;
@@ -34,45 +25,64 @@ export class AssetResources {
34
25
  return '/Game';
35
26
  }
36
27
  }
28
+ clearCache(dir) {
29
+ if (!dir) {
30
+ this.cache.clear();
31
+ return;
32
+ }
33
+ const normalized = this.normalizeDir(dir);
34
+ for (const key of Array.from(this.cache.keys())) {
35
+ if (key.startsWith(`${normalized}::`)) {
36
+ this.cache.delete(key);
37
+ }
38
+ }
39
+ }
40
+ invalidateAssetPaths(paths) {
41
+ if (!Array.isArray(paths) || paths.length === 0) {
42
+ return;
43
+ }
44
+ const dirs = new Set();
45
+ for (const rawPath of paths) {
46
+ if (typeof rawPath !== 'string' || rawPath.trim().length === 0) {
47
+ continue;
48
+ }
49
+ const normalized = this.normalizeDir(rawPath);
50
+ dirs.add(normalized);
51
+ const parent = this.parentDirectory(normalized);
52
+ if (parent) {
53
+ dirs.add(parent);
54
+ }
55
+ }
56
+ for (const dir of dirs) {
57
+ this.clearCache(dir);
58
+ }
59
+ }
37
60
  async list(dir = '/Game', _recursive = false, limit = 50) {
38
- // ALWAYS use non-recursive listing to show only immediate children
39
- // This prevents timeouts and makes navigation clearer
40
- _recursive = false; // Force non-recursive
41
- // Normalize directory first
61
+ _recursive = false;
42
62
  dir = this.normalizeDir(dir);
43
- // Cache fast-path
44
63
  try {
45
64
  const key = this.makeKey(dir, false);
46
65
  const entry = this.cache.get(key);
47
66
  const now = Date.now();
48
67
  if (entry && (now - entry.timestamp) < this.ttlMs) {
49
- return entry.data;
68
+ return { success: true, ...entry.data };
50
69
  }
51
70
  }
52
71
  catch { }
53
- // Check if bridge is connected
54
72
  if (!this.bridge.isConnected) {
55
73
  return {
74
+ success: false,
56
75
  assets: [],
57
- warning: 'Unreal Engine is not connected. Please ensure Unreal Engine is running with Remote Control enabled.',
76
+ warning: 'Unreal Engine is not connected. Please ensure Unreal Engine is running with the MCP server enabled.',
58
77
  connectionStatus: 'disconnected'
59
78
  };
60
79
  }
61
- // Always use directory-only listing (immediate children)
62
- return this.listDirectoryOnly(dir, false, limit);
63
- // End of list method - all logic is now in listDirectoryOnly
80
+ const listed = await this.listDirectoryOnly(dir, false, limit);
81
+ return { ...listed, success: listed && listed.success === false ? false : true };
64
82
  }
65
- /**
66
- * List assets with pagination support
67
- * @param dir Directory to list assets from
68
- * @param page Page number (0-based)
69
- * @param pageSize Number of assets per page (max 50 to avoid socket failures)
70
- */
71
83
  async listPaged(dir = '/Game', page = 0, pageSize = 30, recursive = false) {
72
- // Ensure pageSize doesn't exceed safe limit
73
84
  const safePageSize = Math.min(pageSize, 50);
74
85
  const offset = page * safePageSize;
75
- // Normalize directory and check cache for this specific page
76
86
  dir = this.normalizeDir(dir);
77
87
  const cacheKey = this.makeKey(dir, recursive, page);
78
88
  const cached = this.cache.get(cacheKey);
@@ -89,10 +99,7 @@ export class AssetResources {
89
99
  };
90
100
  }
91
101
  try {
92
- // Use search API with pagination
93
- // Use the same directory listing approach but with pagination
94
102
  const allAssets = await this.listDirectoryOnly(dir, false, 1000);
95
- // Paginate the results
96
103
  const start = offset;
97
104
  const end = offset + safePageSize;
98
105
  const pagedAssets = allAssets.assets ? allAssets.assets.slice(start, end) : [];
@@ -118,136 +125,97 @@ export class AssetResources {
118
125
  error: 'Failed to fetch page'
119
126
  };
120
127
  }
121
- /**
122
- * Directory-based listing of immediate children using AssetRegistry.
123
- * Returns both subfolders and assets at the given path.
124
- */
125
128
  async listDirectoryOnly(dir, _recursive, limit) {
126
- // Always return only immediate children to avoid timeout and improve navigation
127
129
  try {
128
- const py = `
129
- import unreal
130
- import json
131
-
132
- _dir = r"${this.normalizeDir(dir)}"
133
-
134
- try:
135
- ar = unreal.AssetRegistryHelpers.get_asset_registry()
136
- # Immediate subfolders
137
- sub_paths = ar.get_sub_paths(_dir, False)
138
- folders_list = []
139
- for p in sub_paths:
140
- try:
141
- name = p.split('/')[-1]
142
- folders_list.append({'n': name, 'p': p})
143
- except Exception:
144
- pass
145
-
146
- # Immediate assets at this path
147
- assets_data = ar.get_assets_by_path(_dir, False)
148
- assets = []
149
- for a in assets_data[:${limit}]:
150
- try:
151
- assets.append({
152
- 'n': str(a.asset_name),
153
- 'p': str(a.object_path),
154
- 'c': str(a.asset_class)
155
- })
156
- except Exception:
157
- pass
158
-
159
- print("RESULT:" + json.dumps({
160
- 'success': True,
161
- 'path': _dir,
162
- 'folders': len(folders_list),
163
- 'files': len(assets),
164
- 'folders_list': folders_list,
165
- 'assets': assets
166
- }))
167
- except Exception as e:
168
- print("RESULT:" + json.dumps({'success': False, 'error': str(e), 'path': _dir}))
169
- `.trim();
170
- const resp = await this.bridge.executePython(py);
171
- const interpreted = interpretStandardResult(resp, {
172
- successMessage: 'Directory contents retrieved',
173
- failureMessage: 'Failed to list directory contents'
174
- });
175
- if (interpreted.success) {
176
- const payload = interpreted.payload;
177
- const foldersArr = Array.isArray(payload.folders_list)
178
- ? payload.folders_list.map((f) => ({
179
- Name: coerceString(f?.n) ?? '',
180
- Path: coerceString(f?.p) ?? '',
181
- Class: 'Folder',
182
- isFolder: true
183
- }))
184
- : [];
185
- const assetsArr = Array.isArray(payload.assets)
186
- ? payload.assets.map((a) => ({
187
- Name: coerceString(a?.n) ?? '',
188
- Path: coerceString(a?.p) ?? '',
189
- Class: coerceString(a?.c) ?? 'Asset',
190
- isFolder: false
191
- }))
192
- : [];
193
- const total = foldersArr.length + assetsArr.length;
194
- const summary = {
195
- total,
196
- folders: foldersArr.length,
197
- assets: assetsArr.length
198
- };
199
- const resolvedPath = coerceString(payload.path) ?? this.normalizeDir(dir);
200
- return {
201
- success: true,
202
- path: resolvedPath,
203
- summary,
204
- foldersList: foldersArr,
205
- assets: assetsArr,
206
- count: total,
207
- note: `Immediate children of ${resolvedPath}: ${foldersArr.length} folder(s), ${assetsArr.length} asset(s)`,
208
- method: 'asset_registry_listing'
209
- };
130
+ try {
131
+ const normalizedDir = this.normalizeDir(dir);
132
+ const response = await this.sendAutomationRequest('list', { directory: normalizedDir, limit, recursive: false }, { timeoutMs: 30000 });
133
+ if (response.success !== false && response.result) {
134
+ const payload = response.result;
135
+ const foldersArr = Array.isArray(payload.folders_list)
136
+ ? payload.folders_list.map((f) => ({
137
+ Name: coerceString(f?.n ?? f?.Name ?? f?.name) ?? '',
138
+ Path: coerceString(f?.p ?? f?.Path ?? f?.path) ?? '',
139
+ Class: 'Folder',
140
+ isFolder: true
141
+ }))
142
+ : [];
143
+ const assetsArr = Array.isArray(payload.assets)
144
+ ? payload.assets.map((a) => ({
145
+ Name: coerceString(a?.n ?? a?.Name ?? a?.name) ?? '',
146
+ Path: coerceString(a?.p ?? a?.Path ?? a?.path) ?? '',
147
+ Class: coerceString(a?.c ?? a?.Class ?? a?.class) ?? 'Object'
148
+ }))
149
+ : [];
150
+ const result = {
151
+ success: true,
152
+ assets: [...foldersArr, ...assetsArr],
153
+ count: foldersArr.length + assetsArr.length,
154
+ folders: foldersArr.length,
155
+ files: assetsArr.length,
156
+ path: normalizedDir,
157
+ recursive: false,
158
+ method: 'automation_bridge',
159
+ cached: false
160
+ };
161
+ const key = this.makeKey(dir, false);
162
+ this.cache.set(key, { timestamp: Date.now(), data: result });
163
+ return result;
164
+ }
210
165
  }
166
+ catch { }
211
167
  }
212
168
  catch (err) {
213
- console.warn('Engine asset listing failed:', err.message);
169
+ const errorMessage = err?.message ? String(err.message) : 'Asset registry request failed';
170
+ console.warn('Engine asset listing failed:', errorMessage);
171
+ return {
172
+ success: false,
173
+ path: this.normalizeDir(dir),
174
+ summary: { total: 0, folders: 0, assets: 0 },
175
+ foldersList: [],
176
+ assets: [],
177
+ error: errorMessage,
178
+ warning: 'AssetRegistry query failed. Ensure the MCP Automation Bridge is connected.',
179
+ transport: 'automation_bridge',
180
+ method: 'asset_registry_alternate'
181
+ };
214
182
  }
215
- // Fallback: return empty with explanation
216
183
  return {
217
- success: true,
184
+ success: false,
218
185
  path: this.normalizeDir(dir),
219
186
  summary: { total: 0, folders: 0, assets: 0 },
220
187
  foldersList: [],
221
188
  assets: [],
222
- warning: 'No items at this path or failed to query AssetRegistry.',
223
- method: 'asset_registry_fallback'
189
+ error: 'Asset registry returned no payload.',
190
+ warning: 'No items returned from AssetRegistry request.',
191
+ transport: 'automation_bridge',
192
+ method: 'asset_registry_empty'
224
193
  };
225
194
  }
226
195
  async find(assetPath) {
227
- // Guard against invalid paths (trailing slash, empty, whitespace)
228
196
  if (!assetPath || typeof assetPath !== 'string' || assetPath.trim() === '' || assetPath.endsWith('/')) {
229
197
  return false;
230
198
  }
231
- // Normalize asset path (support users passing /Content/...)
232
- const ap = this.normalizeDir(assetPath);
233
- const py = `
234
- import unreal
235
- apath = r"${ap}"
236
- try:
237
- exists = unreal.EditorAssetLibrary.does_asset_exist(apath)
238
- print("RESULT:{'success': True, 'exists': %s}" % ('True' if exists else 'False'))
239
- except Exception as e:
240
- print("RESULT:{'success': False, 'error': '" + str(e) + "'}")
241
- `.trim();
242
- const resp = await this.bridge.executePython(py);
243
- const interpreted = interpretStandardResult(resp, {
244
- successMessage: 'Asset existence verified',
245
- failureMessage: 'Failed to verify asset existence'
246
- });
247
- if (interpreted.success) {
248
- return coerceBoolean(interpreted.payload.exists, false) ?? false;
249
- }
250
- return false;
199
+ try {
200
+ const normalizedPath = this.normalizeDir(assetPath);
201
+ const response = await this.sendAutomationRequest('asset_exists', { asset_path: normalizedPath });
202
+ return response?.success !== false && response?.result?.exists === true;
203
+ }
204
+ catch {
205
+ return false;
206
+ }
207
+ }
208
+ parentDirectory(path) {
209
+ if (!path || typeof path !== 'string') {
210
+ return null;
211
+ }
212
+ const normalized = this.normalizeDir(path);
213
+ const lastSlash = normalized.lastIndexOf('/');
214
+ if (lastSlash <= 0) {
215
+ return normalized === '/' ? '/' : null;
216
+ }
217
+ const parent = normalized.substring(0, lastSlash);
218
+ return parent.length > 0 ? parent : '/';
251
219
  }
252
220
  }
253
221
  //# sourceMappingURL=assets.js.map
@@ -1,35 +1,35 @@
1
1
  import { UnrealBridge } from '../unreal-bridge.js';
2
2
  export declare class LevelResources {
3
- private bridge;
3
+ private automationBridge;
4
4
  constructor(bridge: UnrealBridge);
5
5
  getCurrentLevel(): Promise<{
6
- success: boolean;
7
- name: string;
8
- path: string;
9
- error?: undefined;
10
- } | {
11
6
  success: boolean;
12
7
  error: string;
13
8
  name?: undefined;
14
9
  path?: undefined;
15
- }>;
16
- getLevelName(): Promise<{
10
+ } | {
17
11
  success: boolean;
12
+ name: string;
18
13
  path: string;
19
14
  error?: undefined;
20
- } | {
15
+ }>;
16
+ getLevelName(): Promise<{
21
17
  success: boolean;
22
18
  error: string;
23
19
  path?: undefined;
24
- }>;
25
- saveCurrentLevel(): Promise<{
20
+ } | {
26
21
  success: boolean;
27
- message: string;
22
+ path: string;
28
23
  error?: undefined;
29
- } | {
24
+ }>;
25
+ saveCurrentLevel(): Promise<{
30
26
  success: boolean;
31
27
  error: string;
32
28
  message?: undefined;
29
+ } | {
30
+ success: boolean;
31
+ message: string;
32
+ error?: undefined;
33
33
  }>;
34
34
  }
35
35
  //# sourceMappingURL=levels.d.ts.map