unreal-engine-mcp-server 0.4.7 → 0.5.0

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 (438) 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.yml +148 -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 +23 -0
  19. package/.github/workflows/labeler.yml +16 -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 +12 -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 +267 -31
  29. package/CONTRIBUTING.md +140 -0
  30. package/README.md +166 -71
  31. package/claude_desktop_config_example.json +7 -6
  32. package/dist/automation/bridge.d.ts +50 -0
  33. package/dist/automation/bridge.js +452 -0
  34. package/dist/automation/connection-manager.d.ts +23 -0
  35. package/dist/automation/connection-manager.js +107 -0
  36. package/dist/automation/handshake.d.ts +11 -0
  37. package/dist/automation/handshake.js +89 -0
  38. package/dist/automation/index.d.ts +3 -0
  39. package/dist/automation/index.js +3 -0
  40. package/dist/automation/message-handler.d.ts +12 -0
  41. package/dist/automation/message-handler.js +149 -0
  42. package/dist/automation/request-tracker.d.ts +25 -0
  43. package/dist/automation/request-tracker.js +98 -0
  44. package/dist/automation/types.d.ts +130 -0
  45. package/dist/automation/types.js +2 -0
  46. package/dist/cli.js +32 -5
  47. package/dist/config.d.ts +27 -0
  48. package/dist/config.js +60 -0
  49. package/dist/constants.d.ts +12 -0
  50. package/dist/constants.js +12 -0
  51. package/dist/graphql/resolvers.d.ts +268 -0
  52. package/dist/graphql/resolvers.js +743 -0
  53. package/dist/graphql/schema.d.ts +5 -0
  54. package/dist/graphql/schema.js +437 -0
  55. package/dist/graphql/server.d.ts +26 -0
  56. package/dist/graphql/server.js +115 -0
  57. package/dist/graphql/types.d.ts +7 -0
  58. package/dist/graphql/types.js +2 -0
  59. package/dist/handlers/resource-handlers.d.ts +20 -0
  60. package/dist/handlers/resource-handlers.js +180 -0
  61. package/dist/index.d.ts +31 -18
  62. package/dist/index.js +119 -619
  63. package/dist/prompts/index.js +4 -4
  64. package/dist/resources/actors.d.ts +17 -12
  65. package/dist/resources/actors.js +56 -76
  66. package/dist/resources/assets.d.ts +6 -14
  67. package/dist/resources/assets.js +115 -147
  68. package/dist/resources/levels.d.ts +13 -13
  69. package/dist/resources/levels.js +25 -34
  70. package/dist/server/resource-registry.d.ts +20 -0
  71. package/dist/server/resource-registry.js +37 -0
  72. package/dist/server/tool-registry.d.ts +23 -0
  73. package/dist/server/tool-registry.js +322 -0
  74. package/dist/server-setup.d.ts +21 -0
  75. package/dist/server-setup.js +111 -0
  76. package/dist/services/health-monitor.d.ts +34 -0
  77. package/dist/services/health-monitor.js +105 -0
  78. package/dist/services/metrics-server.d.ts +11 -0
  79. package/dist/services/metrics-server.js +105 -0
  80. package/dist/tools/actors.d.ts +147 -9
  81. package/dist/tools/actors.js +350 -311
  82. package/dist/tools/animation.d.ts +135 -4
  83. package/dist/tools/animation.js +510 -411
  84. package/dist/tools/assets.d.ts +117 -19
  85. package/dist/tools/assets.js +259 -284
  86. package/dist/tools/audio.d.ts +102 -42
  87. package/dist/tools/audio.js +272 -685
  88. package/dist/tools/base-tool.d.ts +17 -0
  89. package/dist/tools/base-tool.js +46 -0
  90. package/dist/tools/behavior-tree.d.ts +94 -0
  91. package/dist/tools/behavior-tree.js +39 -0
  92. package/dist/tools/blueprint/helpers.d.ts +29 -0
  93. package/dist/tools/blueprint/helpers.js +182 -0
  94. package/dist/tools/blueprint.d.ts +228 -118
  95. package/dist/tools/blueprint.js +685 -832
  96. package/dist/tools/consolidated-tool-definitions.d.ts +5462 -1781
  97. package/dist/tools/consolidated-tool-definitions.js +829 -496
  98. package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
  99. package/dist/tools/consolidated-tool-handlers.js +211 -1026
  100. package/dist/tools/debug.d.ts +143 -85
  101. package/dist/tools/debug.js +234 -180
  102. package/dist/tools/dynamic-handler-registry.d.ts +11 -0
  103. package/dist/tools/dynamic-handler-registry.js +101 -0
  104. package/dist/tools/editor.d.ts +139 -18
  105. package/dist/tools/editor.js +239 -244
  106. package/dist/tools/engine.d.ts +10 -4
  107. package/dist/tools/engine.js +13 -5
  108. package/dist/tools/environment.d.ts +36 -0
  109. package/dist/tools/environment.js +267 -0
  110. package/dist/tools/foliage.d.ts +105 -14
  111. package/dist/tools/foliage.js +219 -331
  112. package/dist/tools/handlers/actor-handlers.d.ts +3 -0
  113. package/dist/tools/handlers/actor-handlers.js +232 -0
  114. package/dist/tools/handlers/animation-handlers.d.ts +3 -0
  115. package/dist/tools/handlers/animation-handlers.js +185 -0
  116. package/dist/tools/handlers/argument-helper.d.ts +16 -0
  117. package/dist/tools/handlers/argument-helper.js +80 -0
  118. package/dist/tools/handlers/asset-handlers.d.ts +3 -0
  119. package/dist/tools/handlers/asset-handlers.js +496 -0
  120. package/dist/tools/handlers/audio-handlers.d.ts +3 -0
  121. package/dist/tools/handlers/audio-handlers.js +166 -0
  122. package/dist/tools/handlers/blueprint-handlers.d.ts +4 -0
  123. package/dist/tools/handlers/blueprint-handlers.js +358 -0
  124. package/dist/tools/handlers/common-handlers.d.ts +14 -0
  125. package/dist/tools/handlers/common-handlers.js +56 -0
  126. package/dist/tools/handlers/editor-handlers.d.ts +3 -0
  127. package/dist/tools/handlers/editor-handlers.js +119 -0
  128. package/dist/tools/handlers/effect-handlers.d.ts +3 -0
  129. package/dist/tools/handlers/effect-handlers.js +171 -0
  130. package/dist/tools/handlers/environment-handlers.d.ts +3 -0
  131. package/dist/tools/handlers/environment-handlers.js +170 -0
  132. package/dist/tools/handlers/graph-handlers.d.ts +3 -0
  133. package/dist/tools/handlers/graph-handlers.js +90 -0
  134. package/dist/tools/handlers/input-handlers.d.ts +3 -0
  135. package/dist/tools/handlers/input-handlers.js +21 -0
  136. package/dist/tools/handlers/inspect-handlers.d.ts +3 -0
  137. package/dist/tools/handlers/inspect-handlers.js +383 -0
  138. package/dist/tools/handlers/level-handlers.d.ts +3 -0
  139. package/dist/tools/handlers/level-handlers.js +237 -0
  140. package/dist/tools/handlers/lighting-handlers.d.ts +3 -0
  141. package/dist/tools/handlers/lighting-handlers.js +144 -0
  142. package/dist/tools/handlers/performance-handlers.d.ts +3 -0
  143. package/dist/tools/handlers/performance-handlers.js +130 -0
  144. package/dist/tools/handlers/pipeline-handlers.d.ts +3 -0
  145. package/dist/tools/handlers/pipeline-handlers.js +110 -0
  146. package/dist/tools/handlers/sequence-handlers.d.ts +3 -0
  147. package/dist/tools/handlers/sequence-handlers.js +376 -0
  148. package/dist/tools/handlers/system-handlers.d.ts +4 -0
  149. package/dist/tools/handlers/system-handlers.js +506 -0
  150. package/dist/tools/input.d.ts +19 -0
  151. package/dist/tools/input.js +89 -0
  152. package/dist/tools/introspection.d.ts +103 -40
  153. package/dist/tools/introspection.js +425 -568
  154. package/dist/tools/landscape.d.ts +97 -36
  155. package/dist/tools/landscape.js +280 -409
  156. package/dist/tools/level.d.ts +130 -10
  157. package/dist/tools/level.js +639 -675
  158. package/dist/tools/lighting.d.ts +77 -38
  159. package/dist/tools/lighting.js +441 -943
  160. package/dist/tools/logs.d.ts +3 -3
  161. package/dist/tools/logs.js +5 -57
  162. package/dist/tools/materials.d.ts +91 -24
  163. package/dist/tools/materials.js +190 -118
  164. package/dist/tools/niagara.d.ts +149 -39
  165. package/dist/tools/niagara.js +232 -182
  166. package/dist/tools/performance.d.ts +27 -12
  167. package/dist/tools/performance.js +204 -122
  168. package/dist/tools/physics.d.ts +32 -77
  169. package/dist/tools/physics.js +171 -582
  170. package/dist/tools/property-dictionary.d.ts +13 -0
  171. package/dist/tools/property-dictionary.js +82 -0
  172. package/dist/tools/sequence.d.ts +73 -48
  173. package/dist/tools/sequence.js +196 -748
  174. package/dist/tools/tool-definition-utils.d.ts +59 -0
  175. package/dist/tools/tool-definition-utils.js +35 -0
  176. package/dist/tools/ui.d.ts +66 -34
  177. package/dist/tools/ui.js +134 -214
  178. package/dist/types/env.d.ts +0 -3
  179. package/dist/types/env.js +0 -7
  180. package/dist/types/tool-interfaces.d.ts +898 -0
  181. package/dist/types/tool-interfaces.js +2 -0
  182. package/dist/types/tool-types.d.ts +183 -19
  183. package/dist/types/tool-types.js +0 -4
  184. package/dist/unreal-bridge.d.ts +24 -131
  185. package/dist/unreal-bridge.js +364 -1506
  186. package/dist/utils/command-validator.d.ts +9 -0
  187. package/dist/utils/command-validator.js +67 -0
  188. package/dist/utils/elicitation.d.ts +1 -1
  189. package/dist/utils/elicitation.js +12 -15
  190. package/dist/utils/error-handler.d.ts +2 -51
  191. package/dist/utils/error-handler.js +11 -87
  192. package/dist/utils/ini-reader.d.ts +3 -0
  193. package/dist/utils/ini-reader.js +69 -0
  194. package/dist/utils/logger.js +9 -6
  195. package/dist/utils/normalize.d.ts +3 -0
  196. package/dist/utils/normalize.js +56 -0
  197. package/dist/utils/response-factory.d.ts +7 -0
  198. package/dist/utils/response-factory.js +33 -0
  199. package/dist/utils/response-validator.d.ts +3 -24
  200. package/dist/utils/response-validator.js +130 -81
  201. package/dist/utils/result-helpers.d.ts +4 -5
  202. package/dist/utils/result-helpers.js +15 -16
  203. package/dist/utils/safe-json.js +5 -11
  204. package/dist/utils/unreal-command-queue.d.ts +24 -0
  205. package/dist/utils/unreal-command-queue.js +120 -0
  206. package/dist/utils/validation.d.ts +0 -40
  207. package/dist/utils/validation.js +1 -78
  208. package/dist/wasm/index.d.ts +70 -0
  209. package/dist/wasm/index.js +535 -0
  210. package/docs/GraphQL-API.md +888 -0
  211. package/docs/Migration-Guide-v0.5.0.md +692 -0
  212. package/docs/Roadmap.md +53 -0
  213. package/docs/WebAssembly-Integration.md +628 -0
  214. package/docs/editor-plugin-extension.md +370 -0
  215. package/docs/handler-mapping.md +242 -0
  216. package/docs/native-automation-progress.md +128 -0
  217. package/docs/testing-guide.md +423 -0
  218. package/mcp-config-example.json +6 -6
  219. package/package.json +60 -27
  220. package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +8 -0
  221. package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +64 -0
  222. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +189 -0
  223. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +22 -0
  224. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +30 -0
  225. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +1983 -0
  226. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +72 -0
  227. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +46 -0
  228. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +581 -0
  229. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +2394 -0
  230. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +300 -0
  231. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +2807 -0
  232. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +1087 -0
  233. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +488 -0
  234. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +643 -0
  235. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +31 -0
  236. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +1184 -0
  237. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +5652 -0
  238. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +152 -0
  239. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +2614 -0
  240. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +42 -0
  241. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +1237 -0
  242. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +1701 -0
  243. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +2145 -0
  244. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +954 -0
  245. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +209 -0
  246. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +41 -0
  247. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +1164 -0
  248. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +762 -0
  249. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +634 -0
  250. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +136 -0
  251. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +494 -0
  252. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +278 -0
  253. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +625 -0
  254. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +401 -0
  255. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +67 -0
  256. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +735 -0
  257. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +2634 -0
  258. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +189 -0
  259. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +917 -0
  260. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +39 -0
  261. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +2670 -0
  262. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +519 -0
  263. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +38 -0
  264. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +668 -0
  265. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +346 -0
  266. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +1330 -0
  267. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +149 -0
  268. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +783 -0
  269. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +115 -0
  270. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +796 -0
  271. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +117 -0
  272. package/scripts/check-unreal-connection.mjs +19 -0
  273. package/scripts/clean-tmp.js +23 -0
  274. package/scripts/patch-wasm.js +26 -0
  275. package/scripts/run-all-tests.mjs +131 -0
  276. package/scripts/smoke-test.ts +94 -0
  277. package/scripts/sync-mcp-plugin.js +143 -0
  278. package/scripts/test-no-plugin-alternates.mjs +113 -0
  279. package/scripts/validate-server.js +46 -0
  280. package/scripts/verify-automation-bridge.js +200 -0
  281. package/server.json +57 -21
  282. package/src/automation/bridge.ts +558 -0
  283. package/src/automation/connection-manager.ts +130 -0
  284. package/src/automation/handshake.ts +99 -0
  285. package/src/automation/index.ts +2 -0
  286. package/src/automation/message-handler.ts +167 -0
  287. package/src/automation/request-tracker.ts +123 -0
  288. package/src/automation/types.ts +107 -0
  289. package/src/cli.ts +33 -6
  290. package/src/config.ts +73 -0
  291. package/src/constants.ts +12 -0
  292. package/src/graphql/resolvers.ts +1010 -0
  293. package/src/graphql/schema.ts +452 -0
  294. package/src/graphql/server.ts +154 -0
  295. package/src/graphql/types.ts +7 -0
  296. package/src/handlers/resource-handlers.ts +186 -0
  297. package/src/index.ts +152 -663
  298. package/src/prompts/index.ts +4 -4
  299. package/src/resources/actors.ts +58 -76
  300. package/src/resources/assets.ts +147 -134
  301. package/src/resources/levels.ts +28 -33
  302. package/src/server/resource-registry.ts +47 -0
  303. package/src/server/tool-registry.ts +354 -0
  304. package/src/server-setup.ts +148 -0
  305. package/src/services/health-monitor.ts +132 -0
  306. package/src/services/metrics-server.ts +142 -0
  307. package/src/tools/actors.ts +417 -322
  308. package/src/tools/animation.ts +671 -461
  309. package/src/tools/assets.ts +353 -289
  310. package/src/tools/audio.ts +323 -766
  311. package/src/tools/base-tool.ts +52 -0
  312. package/src/tools/behavior-tree.ts +45 -0
  313. package/src/tools/blueprint/helpers.ts +189 -0
  314. package/src/tools/blueprint.ts +787 -965
  315. package/src/tools/consolidated-tool-definitions.ts +993 -515
  316. package/src/tools/consolidated-tool-handlers.ts +272 -1139
  317. package/src/tools/debug.ts +292 -187
  318. package/src/tools/dynamic-handler-registry.ts +151 -0
  319. package/src/tools/editor.ts +309 -246
  320. package/src/tools/engine.ts +14 -3
  321. package/src/tools/environment.ts +287 -0
  322. package/src/tools/foliage.ts +314 -379
  323. package/src/tools/handlers/actor-handlers.ts +271 -0
  324. package/src/tools/handlers/animation-handlers.ts +237 -0
  325. package/src/tools/handlers/argument-helper.ts +142 -0
  326. package/src/tools/handlers/asset-handlers.ts +532 -0
  327. package/src/tools/handlers/audio-handlers.ts +194 -0
  328. package/src/tools/handlers/blueprint-handlers.ts +380 -0
  329. package/src/tools/handlers/common-handlers.ts +87 -0
  330. package/src/tools/handlers/editor-handlers.ts +123 -0
  331. package/src/tools/handlers/effect-handlers.ts +220 -0
  332. package/src/tools/handlers/environment-handlers.ts +183 -0
  333. package/src/tools/handlers/graph-handlers.ts +116 -0
  334. package/src/tools/handlers/input-handlers.ts +28 -0
  335. package/src/tools/handlers/inspect-handlers.ts +450 -0
  336. package/src/tools/handlers/level-handlers.ts +252 -0
  337. package/src/tools/handlers/lighting-handlers.ts +147 -0
  338. package/src/tools/handlers/performance-handlers.ts +132 -0
  339. package/src/tools/handlers/pipeline-handlers.ts +127 -0
  340. package/src/tools/handlers/sequence-handlers.ts +415 -0
  341. package/src/tools/handlers/system-handlers.ts +564 -0
  342. package/src/tools/input.ts +101 -0
  343. package/src/tools/introspection.ts +493 -584
  344. package/src/tools/landscape.ts +394 -489
  345. package/src/tools/level.ts +752 -694
  346. package/src/tools/lighting.ts +583 -984
  347. package/src/tools/logs.ts +9 -57
  348. package/src/tools/materials.ts +231 -121
  349. package/src/tools/niagara.ts +293 -168
  350. package/src/tools/performance.ts +320 -168
  351. package/src/tools/physics.ts +268 -613
  352. package/src/tools/property-dictionary.ts +98 -0
  353. package/src/tools/sequence.ts +255 -815
  354. package/src/tools/tool-definition-utils.ts +35 -0
  355. package/src/tools/ui.ts +207 -283
  356. package/src/types/env.ts +0 -10
  357. package/src/types/tool-interfaces.ts +250 -0
  358. package/src/types/tool-types.ts +243 -21
  359. package/src/unreal-bridge.ts +460 -1550
  360. package/src/utils/command-validator.ts +75 -0
  361. package/src/utils/elicitation.ts +10 -7
  362. package/src/utils/error-handler.ts +14 -90
  363. package/src/utils/ini-reader.ts +86 -0
  364. package/src/utils/logger.ts +8 -3
  365. package/src/utils/normalize.ts +60 -0
  366. package/src/utils/response-factory.ts +39 -0
  367. package/src/utils/response-validator.ts +176 -56
  368. package/src/utils/result-helpers.ts +21 -19
  369. package/src/utils/safe-json.ts +14 -11
  370. package/src/utils/unreal-command-queue.ts +152 -0
  371. package/src/utils/validation.ts +4 -1
  372. package/src/wasm/index.ts +838 -0
  373. package/test-server.mjs +100 -0
  374. package/tests/run-unreal-tool-tests.mjs +242 -14
  375. package/tests/test-animation.mjs +44 -0
  376. package/tests/test-asset-advanced.mjs +82 -0
  377. package/tests/test-asset-errors.mjs +35 -0
  378. package/tests/test-audio.mjs +219 -0
  379. package/tests/test-automation-timeouts.mjs +98 -0
  380. package/tests/test-behavior-tree.mjs +261 -0
  381. package/tests/test-blueprint-events.mjs +35 -0
  382. package/tests/test-blueprint-graph.mjs +79 -0
  383. package/tests/test-blueprint.mjs +577 -0
  384. package/tests/test-client-mode.mjs +86 -0
  385. package/tests/test-console-command.mjs +56 -0
  386. package/tests/test-control-actor.mjs +425 -0
  387. package/tests/test-control-editor.mjs +80 -0
  388. package/tests/test-extra-tools.mjs +38 -0
  389. package/tests/test-graphql.mjs +322 -0
  390. package/tests/test-inspect.mjs +72 -0
  391. package/tests/test-landscape.mjs +60 -0
  392. package/tests/test-manage-asset.mjs +438 -0
  393. package/tests/test-manage-level.mjs +70 -0
  394. package/tests/test-materials.mjs +356 -0
  395. package/tests/test-niagara.mjs +185 -0
  396. package/tests/test-no-inline-python.mjs +122 -0
  397. package/tests/test-plugin-handshake.mjs +82 -0
  398. package/tests/test-render.mjs +33 -0
  399. package/tests/test-runner.mjs +933 -0
  400. package/tests/test-search-assets.mjs +66 -0
  401. package/tests/test-sequence.mjs +68 -0
  402. package/tests/test-system.mjs +57 -0
  403. package/tests/test-wasm.mjs +193 -0
  404. package/tests/test-world-partition.mjs +215 -0
  405. package/tsconfig.json +3 -3
  406. package/wasm/Cargo.lock +363 -0
  407. package/wasm/Cargo.toml +42 -0
  408. package/wasm/LICENSE +21 -0
  409. package/wasm/README.md +253 -0
  410. package/wasm/src/dependency_resolver.rs +377 -0
  411. package/wasm/src/lib.rs +153 -0
  412. package/wasm/src/property_parser.rs +271 -0
  413. package/wasm/src/transform_math.rs +396 -0
  414. package/wasm/tests/integration.rs +109 -0
  415. package/.github/workflows/smithery-build.yml +0 -29
  416. package/dist/tools/build_environment_advanced.d.ts +0 -65
  417. package/dist/tools/build_environment_advanced.js +0 -633
  418. package/dist/tools/rc.d.ts +0 -110
  419. package/dist/tools/rc.js +0 -437
  420. package/dist/tools/visual.d.ts +0 -40
  421. package/dist/tools/visual.js +0 -282
  422. package/dist/utils/http.d.ts +0 -6
  423. package/dist/utils/http.js +0 -151
  424. package/dist/utils/python-output.d.ts +0 -18
  425. package/dist/utils/python-output.js +0 -290
  426. package/dist/utils/python.d.ts +0 -2
  427. package/dist/utils/python.js +0 -4
  428. package/dist/utils/stdio-redirect.d.ts +0 -2
  429. package/dist/utils/stdio-redirect.js +0 -20
  430. package/docs/unreal-tool-test-cases.md +0 -574
  431. package/smithery.yaml +0 -29
  432. package/src/tools/build_environment_advanced.ts +0 -732
  433. package/src/tools/rc.ts +0 -515
  434. package/src/tools/visual.ts +0 -281
  435. package/src/utils/http.ts +0 -187
  436. package/src/utils/python-output.ts +0 -351
  437. package/src/utils/python.ts +0 -3
  438. package/src/utils/stdio-redirect.ts +0 -18
@@ -1,16 +1,16 @@
1
- function clampChoice(value, choices, fallback) {
1
+ function clampChoice(value, choices, defaultChoice) {
2
2
  if (typeof value === 'string') {
3
3
  const normalized = value.toLowerCase();
4
4
  if (choices.includes(normalized)) {
5
5
  return normalized;
6
6
  }
7
7
  }
8
- return fallback;
8
+ return defaultChoice;
9
9
  }
10
- function coerceNumber(value, fallback, min, max) {
10
+ function coerceNumber(value, defaultValue, min, max) {
11
11
  const num = typeof value === 'number' ? value : Number(value);
12
12
  if (!Number.isFinite(num)) {
13
- return fallback;
13
+ return defaultValue;
14
14
  }
15
15
  if (min !== undefined && num < min) {
16
16
  return min;
@@ -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