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
@@ -0,0 +1,496 @@
1
+ import { cleanObject } from '../../utils/safe-json.js';
2
+ import { executeAutomationRequest } from './common-handlers.js';
3
+ import { normalizeArgs } from './argument-helper.js';
4
+ export async function handleAssetTools(action, args, tools) {
5
+ switch (action) {
6
+ case 'list': {
7
+ const params = normalizeArgs(args, [
8
+ { key: 'path', aliases: ['directory', 'assetPath'], default: '/Game' },
9
+ { key: 'limit', default: 50 },
10
+ { key: 'recursive', default: false },
11
+ { key: 'depth', default: undefined }
12
+ ]);
13
+ const recursive = params.recursive === true || (params.depth !== undefined && params.depth > 0);
14
+ const res = await executeAutomationRequest(tools, 'list', {
15
+ path: params.path,
16
+ recursive,
17
+ depth: params.depth
18
+ });
19
+ const response = res;
20
+ const assets = (Array.isArray(response.assets) ? response.assets :
21
+ (Array.isArray(response.result) ? response.result : (response.result?.assets || [])));
22
+ const folders = Array.isArray(response.folders) ? response.folders : (response.result?.folders || []);
23
+ const totalCount = assets.length;
24
+ const limitedAssets = assets.slice(0, params.limit);
25
+ const remaining = Math.max(0, totalCount - params.limit);
26
+ let message = `Found ${totalCount} assets`;
27
+ if (folders.length > 0) {
28
+ message += ` and ${folders.length} folders`;
29
+ }
30
+ message += `: ${limitedAssets.map((a) => a.path || a.package || a.name).join(', ')}`;
31
+ if (folders.length > 0 && limitedAssets.length < params.limit) {
32
+ const remainingLimit = params.limit - limitedAssets.length;
33
+ if (remainingLimit > 0) {
34
+ const limitedFolders = folders.slice(0, remainingLimit);
35
+ if (limitedAssets.length > 0)
36
+ message += ', ';
37
+ message += `Folders: [${limitedFolders.join(', ')}]`;
38
+ if (folders.length > remainingLimit)
39
+ message += '...';
40
+ }
41
+ }
42
+ if (remaining > 0) {
43
+ message += `... and ${remaining} others`;
44
+ }
45
+ return {
46
+ message: message,
47
+ assets: limitedAssets,
48
+ folders: folders,
49
+ totalCount: totalCount,
50
+ count: limitedAssets.length
51
+ };
52
+ }
53
+ case 'create_folder': {
54
+ const params = normalizeArgs(args, [
55
+ { key: 'path', aliases: ['directoryPath'], required: true }
56
+ ]);
57
+ const res = await tools.assetTools.createFolder(params.path);
58
+ return cleanObject(res);
59
+ }
60
+ case 'import': {
61
+ const params = normalizeArgs(args, [
62
+ { key: 'sourcePath', required: true },
63
+ { key: 'destinationPath', required: true },
64
+ { key: 'overwrite', default: false },
65
+ { key: 'save', default: true }
66
+ ]);
67
+ const res = await tools.assetTools.importAsset({
68
+ sourcePath: params.sourcePath,
69
+ destinationPath: params.destinationPath,
70
+ overwrite: params.overwrite,
71
+ save: params.save
72
+ });
73
+ return cleanObject(res);
74
+ }
75
+ case 'duplicate': {
76
+ const params = normalizeArgs(args, [
77
+ { key: 'sourcePath', aliases: ['assetPath'], required: true },
78
+ { key: 'destinationPath' },
79
+ { key: 'newName' }
80
+ ]);
81
+ let destinationPath = params.destinationPath;
82
+ if (params.newName) {
83
+ if (!destinationPath) {
84
+ const lastSlash = params.sourcePath.lastIndexOf('/');
85
+ const parentDir = lastSlash > 0 ? params.sourcePath.substring(0, lastSlash) : '/Game';
86
+ destinationPath = `${parentDir}/${params.newName}`;
87
+ }
88
+ else if (!destinationPath.endsWith(params.newName)) {
89
+ if (destinationPath.endsWith('/')) {
90
+ destinationPath = `${destinationPath}${params.newName}`;
91
+ }
92
+ }
93
+ }
94
+ if (!destinationPath) {
95
+ throw new Error('destinationPath or newName is required for duplicate action');
96
+ }
97
+ const res = await tools.assetTools.duplicateAsset({
98
+ sourcePath: params.sourcePath,
99
+ destinationPath
100
+ });
101
+ return cleanObject(res);
102
+ }
103
+ case 'rename': {
104
+ const params = normalizeArgs(args, [
105
+ { key: 'sourcePath', aliases: ['assetPath'], required: true },
106
+ { key: 'destinationPath' },
107
+ { key: 'newName' }
108
+ ]);
109
+ let destinationPath = params.destinationPath;
110
+ if (!destinationPath && params.newName) {
111
+ const lastSlash = params.sourcePath.lastIndexOf('/');
112
+ const parentDir = lastSlash > 0 ? params.sourcePath.substring(0, lastSlash) : '/Game';
113
+ destinationPath = `${parentDir}/${params.newName}`;
114
+ }
115
+ if (!destinationPath)
116
+ throw new Error('Missing destinationPath or newName');
117
+ const res = await tools.assetTools.renameAsset({
118
+ sourcePath: params.sourcePath,
119
+ destinationPath
120
+ });
121
+ if (res && res.success === false) {
122
+ const msg = (res.message || '').toLowerCase();
123
+ if (msg.includes('already exists') || msg.includes('exists')) {
124
+ return cleanObject({
125
+ success: false,
126
+ error: 'ASSET_ALREADY_EXISTS',
127
+ message: res.message || 'Asset already exists at destination',
128
+ sourcePath: params.sourcePath,
129
+ destinationPath
130
+ });
131
+ }
132
+ }
133
+ return cleanObject(res);
134
+ }
135
+ case 'move': {
136
+ const params = normalizeArgs(args, [
137
+ { key: 'sourcePath', aliases: ['assetPath'], required: true },
138
+ { key: 'destinationPath' }
139
+ ]);
140
+ let destinationPath = params.destinationPath;
141
+ const assetName = params.sourcePath.split('/').pop();
142
+ if (assetName && destinationPath && !destinationPath.endsWith(assetName)) {
143
+ destinationPath = `${destinationPath.replace(/\/$/, '')}/${assetName}`;
144
+ }
145
+ const res = await tools.assetTools.moveAsset({
146
+ sourcePath: params.sourcePath,
147
+ destinationPath
148
+ });
149
+ return cleanObject(res);
150
+ }
151
+ case 'delete_assets':
152
+ case 'delete_asset':
153
+ case 'delete': {
154
+ let paths = [];
155
+ if (Array.isArray(args.paths)) {
156
+ paths = args.paths;
157
+ }
158
+ else if (Array.isArray(args.assetPaths)) {
159
+ paths = args.assetPaths;
160
+ }
161
+ else {
162
+ const single = args.assetPath || args.path;
163
+ if (typeof single === 'string' && single.trim()) {
164
+ paths = [single.trim()];
165
+ }
166
+ }
167
+ if (paths.length === 0) {
168
+ throw new Error('No paths provided for delete action');
169
+ }
170
+ const res = await tools.assetTools.deleteAssets({ paths });
171
+ return cleanObject(res);
172
+ }
173
+ case 'generate_lods': {
174
+ const params = normalizeArgs(args, [
175
+ { key: 'assetPath', required: true },
176
+ { key: 'lodCount', required: true }
177
+ ]);
178
+ return cleanObject(await tools.assetTools.generateLODs({
179
+ assetPath: params.assetPath,
180
+ lodCount: params.lodCount
181
+ }));
182
+ }
183
+ case 'create_thumbnail': {
184
+ const params = normalizeArgs(args, [
185
+ { key: 'assetPath', required: true },
186
+ { key: 'width' },
187
+ { key: 'height' }
188
+ ]);
189
+ const res = await tools.assetTools.createThumbnail({
190
+ assetPath: params.assetPath,
191
+ width: params.width,
192
+ height: params.height
193
+ });
194
+ return cleanObject(res);
195
+ }
196
+ case 'set_tags': {
197
+ try {
198
+ const params = normalizeArgs(args, [
199
+ { key: 'assetPath', required: true },
200
+ { key: 'tags', required: true }
201
+ ]);
202
+ const res = await tools.assetTools.setTags({ assetPath: params.assetPath, tags: params.tags });
203
+ return cleanObject(res);
204
+ }
205
+ catch (err) {
206
+ const message = String(err?.message || err || '').toLowerCase();
207
+ if (message.includes('not_implemented') ||
208
+ message.includes('not implemented') ||
209
+ message.includes('unknown action') ||
210
+ message.includes('unknown subaction')) {
211
+ return cleanObject({
212
+ success: false,
213
+ error: 'NOT_IMPLEMENTED',
214
+ message: 'Asset tag writes are not implemented by the automation plugin.',
215
+ action: 'set_tags',
216
+ assetPath: args.assetPath,
217
+ tags: args.tags
218
+ });
219
+ }
220
+ throw err;
221
+ }
222
+ }
223
+ case 'get_metadata': {
224
+ const params = normalizeArgs(args, [
225
+ { key: 'assetPath', required: true }
226
+ ]);
227
+ const res = await tools.assetTools.getMetadata({ assetPath: params.assetPath });
228
+ const tags = res.tags || {};
229
+ const metadata = res.metadata || {};
230
+ const merged = { ...tags, ...metadata };
231
+ const tagCount = Object.keys(merged).length;
232
+ const cleanRes = cleanObject(res);
233
+ cleanRes.message = `Metadata retrieved (${tagCount} items)`;
234
+ cleanRes.tags = tags;
235
+ if (Object.keys(metadata).length > 0) {
236
+ cleanRes.metadata = metadata;
237
+ }
238
+ return cleanRes;
239
+ }
240
+ case 'set_metadata': {
241
+ const res = await executeAutomationRequest(tools, 'set_metadata', args);
242
+ return cleanObject(res);
243
+ }
244
+ case 'validate':
245
+ case 'validate_asset': {
246
+ const params = normalizeArgs(args, [
247
+ { key: 'assetPath', required: true }
248
+ ]);
249
+ const res = await tools.assetTools.validate({ assetPath: params.assetPath });
250
+ return cleanObject(res);
251
+ }
252
+ case 'generate_report': {
253
+ const params = normalizeArgs(args, [
254
+ { key: 'directory' },
255
+ { key: 'reportType' },
256
+ { key: 'outputPath' }
257
+ ]);
258
+ const res = await tools.assetTools.generateReport({
259
+ directory: params.directory,
260
+ reportType: params.reportType,
261
+ outputPath: params.outputPath
262
+ });
263
+ return cleanObject(res);
264
+ }
265
+ case 'create_material_instance': {
266
+ const res = await executeAutomationRequest(tools, 'create_material_instance', args, 'Automation bridge not available for create_material_instance');
267
+ const result = res?.result ?? res ?? {};
268
+ const errorCode = typeof result.error === 'string' ? result.error.toUpperCase() : '';
269
+ const message = typeof result.message === 'string' ? result.message : '';
270
+ if (errorCode === 'PARENT_NOT_FOUND' || message.toLowerCase().includes('parent material not found')) {
271
+ return cleanObject({
272
+ success: false,
273
+ error: 'PARENT_NOT_FOUND',
274
+ message: message || 'Parent material not found',
275
+ path: result.path,
276
+ parentMaterial: args.parentMaterial
277
+ });
278
+ }
279
+ return cleanObject(res);
280
+ }
281
+ case 'search_assets': {
282
+ const params = normalizeArgs(args, [
283
+ { key: 'classNames' },
284
+ { key: 'packagePaths' },
285
+ { key: 'recursivePaths' },
286
+ { key: 'recursiveClasses' },
287
+ { key: 'limit' }
288
+ ]);
289
+ const res = await tools.assetTools.searchAssets({
290
+ classNames: params.classNames,
291
+ packagePaths: params.packagePaths,
292
+ recursivePaths: params.recursivePaths,
293
+ recursiveClasses: params.recursiveClasses,
294
+ limit: params.limit
295
+ });
296
+ return cleanObject(res);
297
+ }
298
+ case 'find_by_tag': {
299
+ const params = normalizeArgs(args, [
300
+ { key: 'tag', required: true },
301
+ { key: 'value' }
302
+ ]);
303
+ return tools.assetTools.findByTag({ tag: params.tag, value: params.value });
304
+ }
305
+ case 'get_dependencies': {
306
+ const params = normalizeArgs(args, [
307
+ { key: 'assetPath', required: true },
308
+ { key: 'recursive' }
309
+ ]);
310
+ const res = await tools.assetTools.getDependencies({ assetPath: params.assetPath, recursive: params.recursive });
311
+ return cleanObject(res);
312
+ }
313
+ case 'get_source_control_state': {
314
+ const params = normalizeArgs(args, [
315
+ { key: 'assetPath', required: true }
316
+ ]);
317
+ const res = await tools.assetTools.getSourceControlState({ assetPath: params.assetPath });
318
+ return cleanObject(res);
319
+ }
320
+ case 'analyze_graph': {
321
+ const params = normalizeArgs(args, [
322
+ { key: 'assetPath', required: true },
323
+ { key: 'maxDepth' }
324
+ ]);
325
+ const res = await executeAutomationRequest(tools, 'get_asset_graph', {
326
+ assetPath: params.assetPath,
327
+ maxDepth: params.maxDepth
328
+ });
329
+ return cleanObject(res);
330
+ }
331
+ case 'create_render_target': {
332
+ const params = normalizeArgs(args, [
333
+ { key: 'name', required: true },
334
+ { key: 'packagePath', aliases: ['path'], default: '/Game' },
335
+ { key: 'width' },
336
+ { key: 'height' },
337
+ { key: 'format' }
338
+ ]);
339
+ const res = await executeAutomationRequest(tools, 'manage_render', {
340
+ subAction: 'create_render_target',
341
+ name: params.name,
342
+ packagePath: params.packagePath,
343
+ width: params.width,
344
+ height: params.height,
345
+ format: params.format,
346
+ save: true
347
+ });
348
+ return cleanObject(res);
349
+ }
350
+ case 'nanite_rebuild_mesh': {
351
+ const params = normalizeArgs(args, [
352
+ { key: 'assetPath', aliases: ['meshPath'], required: true }
353
+ ]);
354
+ const res = await executeAutomationRequest(tools, 'manage_render', {
355
+ subAction: 'nanite_rebuild_mesh',
356
+ assetPath: params.assetPath
357
+ });
358
+ return cleanObject(res);
359
+ }
360
+ case 'fixup_redirectors': {
361
+ const directoryRaw = typeof args.directory === 'string' && args.directory.trim().length > 0
362
+ ? args.directory.trim()
363
+ : (typeof args.directoryPath === 'string' && args.directoryPath.trim().length > 0
364
+ ? args.directoryPath.trim()
365
+ : '');
366
+ const payload = {};
367
+ if (directoryRaw) {
368
+ payload.directoryPath = directoryRaw;
369
+ }
370
+ if (typeof args.checkoutFiles === 'boolean') {
371
+ payload.checkoutFiles = args.checkoutFiles;
372
+ }
373
+ const res = await executeAutomationRequest(tools, 'fixup_redirectors', payload);
374
+ return cleanObject(res);
375
+ }
376
+ case 'add_material_parameter': {
377
+ const params = normalizeArgs(args, [
378
+ { key: 'assetPath', required: true },
379
+ { key: 'parameterName', aliases: ['name'], required: true },
380
+ { key: 'parameterType', aliases: ['type'] },
381
+ { key: 'value', aliases: ['defaultValue'] }
382
+ ]);
383
+ const res = await executeAutomationRequest(tools, 'add_material_parameter', {
384
+ assetPath: params.assetPath,
385
+ name: params.parameterName,
386
+ type: params.parameterType,
387
+ value: params.value
388
+ });
389
+ return cleanObject(res);
390
+ }
391
+ case 'list_instances': {
392
+ const params = normalizeArgs(args, [
393
+ { key: 'assetPath', required: true }
394
+ ]);
395
+ const res = await executeAutomationRequest(tools, 'list_instances', {
396
+ assetPath: params.assetPath
397
+ });
398
+ return cleanObject(res);
399
+ }
400
+ case 'reset_instance_parameters': {
401
+ const params = normalizeArgs(args, [
402
+ { key: 'assetPath', required: true }
403
+ ]);
404
+ const res = await executeAutomationRequest(tools, 'reset_instance_parameters', {
405
+ assetPath: params.assetPath
406
+ });
407
+ return cleanObject(res);
408
+ }
409
+ case 'exists': {
410
+ const params = normalizeArgs(args, [
411
+ { key: 'assetPath', required: true }
412
+ ]);
413
+ const res = await executeAutomationRequest(tools, 'exists', {
414
+ assetPath: params.assetPath
415
+ });
416
+ return cleanObject(res);
417
+ }
418
+ case 'get_material_stats': {
419
+ const params = normalizeArgs(args, [
420
+ { key: 'assetPath', required: true }
421
+ ]);
422
+ const res = await executeAutomationRequest(tools, 'get_material_stats', {
423
+ assetPath: params.assetPath
424
+ });
425
+ return cleanObject(res);
426
+ }
427
+ case 'rebuild_material': {
428
+ const params = normalizeArgs(args, [
429
+ { key: 'assetPath', required: true }
430
+ ]);
431
+ const res = await executeAutomationRequest(tools, 'rebuild_material', {
432
+ assetPath: params.assetPath
433
+ });
434
+ return cleanObject(res);
435
+ }
436
+ case 'add_material_node': {
437
+ const materialNodeAliases = {
438
+ 'Multiply': 'MaterialExpressionMultiply',
439
+ 'Add': 'MaterialExpressionAdd',
440
+ 'Subtract': 'MaterialExpressionSubtract',
441
+ 'Divide': 'MaterialExpressionDivide',
442
+ 'Power': 'MaterialExpressionPower',
443
+ 'Clamp': 'MaterialExpressionClamp',
444
+ 'Constant': 'MaterialExpressionConstant',
445
+ 'Constant2Vector': 'MaterialExpressionConstant2Vector',
446
+ 'Constant3Vector': 'MaterialExpressionConstant3Vector',
447
+ 'Constant4Vector': 'MaterialExpressionConstant4Vector',
448
+ 'TextureSample': 'MaterialExpressionTextureSample',
449
+ 'TextureCoordinate': 'MaterialExpressionTextureCoordinate',
450
+ 'Panner': 'MaterialExpressionPanner',
451
+ 'Rotator': 'MaterialExpressionRotator',
452
+ 'Lerp': 'MaterialExpressionLinearInterpolate',
453
+ 'LinearInterpolate': 'MaterialExpressionLinearInterpolate',
454
+ 'Sine': 'MaterialExpressionSine',
455
+ 'Cosine': 'MaterialExpressionCosine',
456
+ 'Append': 'MaterialExpressionAppendVector',
457
+ 'AppendVector': 'MaterialExpressionAppendVector',
458
+ 'ComponentMask': 'MaterialExpressionComponentMask',
459
+ 'Fresnel': 'MaterialExpressionFresnel',
460
+ 'Time': 'MaterialExpressionTime',
461
+ 'ScalarParameter': 'MaterialExpressionScalarParameter',
462
+ 'VectorParameter': 'MaterialExpressionVectorParameter',
463
+ 'StaticSwitchParameter': 'MaterialExpressionStaticSwitchParameter'
464
+ };
465
+ const params = normalizeArgs(args, [
466
+ { key: 'assetPath', required: true },
467
+ { key: 'nodeType', aliases: ['type'], required: true, map: materialNodeAliases },
468
+ { key: 'posX' },
469
+ { key: 'posY' }
470
+ ]);
471
+ const res = await executeAutomationRequest(tools, 'add_material_node', {
472
+ assetPath: params.assetPath,
473
+ nodeType: params.nodeType,
474
+ posX: params.posX,
475
+ posY: params.posY
476
+ });
477
+ return cleanObject(res);
478
+ }
479
+ default:
480
+ const res = await executeAutomationRequest(tools, action || 'manage_asset', args);
481
+ const result = res?.result ?? res ?? {};
482
+ const errorCode = typeof result.error === 'string' ? result.error.toUpperCase() : '';
483
+ const message = typeof result.message === 'string' ? result.message : '';
484
+ if (errorCode === 'INVALID_SUBACTION' || message.toLowerCase().includes('unknown subaction')) {
485
+ return cleanObject({
486
+ success: false,
487
+ error: 'INVALID_SUBACTION',
488
+ message: 'Asset action not recognized by the automation plugin.',
489
+ action: action || 'manage_asset',
490
+ assetPath: args.assetPath ?? args.path
491
+ });
492
+ }
493
+ return cleanObject(res);
494
+ }
495
+ }
496
+ //# sourceMappingURL=asset-handlers.js.map
@@ -0,0 +1,3 @@
1
+ import { ITools } from '../../types/tool-interfaces.js';
2
+ export declare function handleAudioTools(action: string, args: any, tools: ITools): Promise<any>;
3
+ //# sourceMappingURL=audio-handlers.d.ts.map
@@ -0,0 +1,166 @@
1
+ import { cleanObject } from '../../utils/safe-json.js';
2
+ import { requireNonEmptyString } from './common-handlers.js';
3
+ function toVec3Array(v) {
4
+ if (!v || typeof v !== 'object')
5
+ return undefined;
6
+ const x = Number(v.x);
7
+ const y = Number(v.y);
8
+ const z = Number(v.z);
9
+ if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z))
10
+ return undefined;
11
+ return [x, y, z];
12
+ }
13
+ function toRotArray(r) {
14
+ if (!r || typeof r !== 'object')
15
+ return undefined;
16
+ const pitch = Number(r.pitch);
17
+ const yaw = Number(r.yaw);
18
+ const roll = Number(r.roll);
19
+ if (!Number.isFinite(pitch) || !Number.isFinite(yaw) || !Number.isFinite(roll))
20
+ return undefined;
21
+ return [pitch, yaw, roll];
22
+ }
23
+ function getTimeoutMs() {
24
+ const envDefault = Number(process.env.MCP_AUTOMATION_REQUEST_TIMEOUT_MS ?? '120000');
25
+ return Number.isFinite(envDefault) && envDefault > 0 ? envDefault : 120000;
26
+ }
27
+ export async function handleAudioTools(action, args, tools) {
28
+ switch (action) {
29
+ case 'create_sound_cue':
30
+ requireNonEmptyString(args?.name, 'name', 'Missing required parameter: name');
31
+ requireNonEmptyString(args?.wavePath ?? args?.soundPath, 'soundPath', 'Missing required parameter: soundPath (or wavePath)');
32
+ return cleanObject(await tools.audioTools.createSoundCue({
33
+ name: args.name,
34
+ wavePath: args.wavePath ?? args.soundPath,
35
+ savePath: args.savePath,
36
+ settings: args.settings
37
+ }));
38
+ case 'play_sound_at_location':
39
+ requireNonEmptyString(args?.soundPath, 'soundPath', 'Missing required parameter: soundPath');
40
+ return cleanObject(await tools.audioTools.playSoundAtLocation({
41
+ soundPath: args.soundPath,
42
+ location: toVec3Array(args.location) ?? [0, 0, 0],
43
+ rotation: toRotArray(args.rotation),
44
+ volume: args.volume,
45
+ pitch: args.pitch,
46
+ startTime: args.startTime,
47
+ attenuationPath: args.attenuationPath,
48
+ concurrencyPath: args.concurrencyPath
49
+ }));
50
+ case 'play_sound_2d':
51
+ requireNonEmptyString(args?.soundPath, 'soundPath', 'Missing required parameter: soundPath');
52
+ return cleanObject(await tools.audioTools.playSound2D({
53
+ soundPath: args.soundPath,
54
+ volume: args.volume,
55
+ pitch: args.pitch,
56
+ startTime: args.startTime
57
+ }));
58
+ case 'create_audio_component':
59
+ requireNonEmptyString(args?.actorName, 'actorName', 'Missing required parameter: actorName');
60
+ requireNonEmptyString(args?.componentName, 'componentName', 'Missing required parameter: componentName');
61
+ requireNonEmptyString(args?.soundPath, 'soundPath', 'Missing required parameter: soundPath');
62
+ return cleanObject(await tools.audioTools.createAudioComponent({
63
+ actorName: args.actorName,
64
+ componentName: args.componentName,
65
+ soundPath: args.soundPath,
66
+ autoPlay: args.autoPlay,
67
+ is3D: args.is3D
68
+ }));
69
+ case 'set_sound_attenuation':
70
+ requireNonEmptyString(args?.name, 'name', 'Missing required parameter: name');
71
+ return cleanObject(await tools.audioTools.setSoundAttenuation({
72
+ name: args.name,
73
+ innerRadius: args.innerRadius,
74
+ falloffDistance: args.falloffDistance,
75
+ attenuationShape: args.attenuationShape,
76
+ falloffMode: args.falloffMode
77
+ }));
78
+ case 'create_sound_class':
79
+ requireNonEmptyString(args?.name, 'name', 'Missing required parameter: name');
80
+ return cleanObject(await tools.audioTools.createSoundClass({
81
+ name: args.name,
82
+ parentClass: args.parentClass,
83
+ properties: args.properties
84
+ }));
85
+ case 'create_sound_mix':
86
+ requireNonEmptyString(args?.name, 'name', 'Missing required parameter: name');
87
+ return cleanObject(await tools.audioTools.createSoundMix({
88
+ name: args.name,
89
+ classAdjusters: args.classAdjusters
90
+ }));
91
+ case 'push_sound_mix':
92
+ requireNonEmptyString(args?.mixName ?? args?.name, 'mixName', 'Missing required parameter: mixName (or name)');
93
+ return cleanObject(await tools.audioTools.pushSoundMix({
94
+ mixName: args.mixName ?? args.name
95
+ }));
96
+ case 'pop_sound_mix':
97
+ requireNonEmptyString(args?.mixName ?? args?.name, 'mixName', 'Missing required parameter: mixName (or name)');
98
+ return cleanObject(await tools.audioTools.popSoundMix({
99
+ mixName: args.mixName ?? args.name
100
+ }));
101
+ case 'create_ambient_sound':
102
+ requireNonEmptyString(args?.soundPath, 'soundPath', 'Missing required parameter: soundPath');
103
+ return cleanObject(await tools.audioTools.createAmbientSound({
104
+ soundPath: args.soundPath,
105
+ location: toVec3Array(args.location) ?? [0, 0, 0],
106
+ volume: args.volume,
107
+ pitch: args.pitch,
108
+ startTime: args.startTime,
109
+ attenuationPath: args.attenuationPath,
110
+ concurrencyPath: args.concurrencyPath
111
+ }));
112
+ case 'create_reverb_zone':
113
+ requireNonEmptyString(args?.name, 'name', 'Missing required parameter: name');
114
+ return cleanObject(await tools.audioTools.createReverbZone({
115
+ name: args.name,
116
+ location: toVec3Array(args.location) ?? [0, 0, 0],
117
+ size: toVec3Array(args.size) ?? [0, 0, 0],
118
+ reverbEffect: args.reverbEffect,
119
+ volume: args.volume,
120
+ fadeTime: args.fadeTime
121
+ }));
122
+ case 'enable_audio_analysis':
123
+ return cleanObject(await tools.audioTools.enableAudioAnalysis({
124
+ enabled: args.enabled,
125
+ fftSize: args.fftSize,
126
+ outputType: args.outputType
127
+ }));
128
+ case 'fade_sound':
129
+ requireNonEmptyString(args?.soundName, 'soundName', 'Missing required parameter: soundName');
130
+ return cleanObject(await tools.audioTools.fadeSound({
131
+ soundName: args.soundName,
132
+ targetVolume: args.targetVolume,
133
+ fadeTime: args.fadeTime,
134
+ fadeType: args.fadeType
135
+ }));
136
+ case 'set_doppler_effect':
137
+ return cleanObject(await tools.audioTools.setDopplerEffect({
138
+ enabled: args.enabled,
139
+ scale: args.scale
140
+ }));
141
+ case 'set_audio_occlusion':
142
+ return cleanObject(await tools.audioTools.setAudioOcclusion({
143
+ enabled: args.enabled,
144
+ lowPassFilterFrequency: args.lowPassFilterFrequency,
145
+ volumeAttenuation: args.volumeAttenuation
146
+ }));
147
+ case 'spawn_sound_at_location':
148
+ return cleanObject(await tools.automationBridge?.sendAutomationRequest('spawn_sound_at_location', args, { timeoutMs: getTimeoutMs() }));
149
+ case 'play_sound_attached':
150
+ return cleanObject(await tools.automationBridge?.sendAutomationRequest('play_sound_attached', args, { timeoutMs: getTimeoutMs() }));
151
+ case 'set_sound_mix_class_override':
152
+ return cleanObject(await tools.automationBridge?.sendAutomationRequest('set_sound_mix_class_override', args, { timeoutMs: getTimeoutMs() }));
153
+ case 'clear_sound_mix_class_override':
154
+ return cleanObject(await tools.automationBridge?.sendAutomationRequest('clear_sound_mix_class_override', args, { timeoutMs: getTimeoutMs() }));
155
+ case 'set_base_sound_mix':
156
+ return cleanObject(await tools.automationBridge?.sendAutomationRequest('set_base_sound_mix', args, { timeoutMs: getTimeoutMs() }));
157
+ case 'prime_sound':
158
+ return cleanObject(await tools.automationBridge?.sendAutomationRequest('prime_sound', args, { timeoutMs: getTimeoutMs() }));
159
+ case 'fade_sound_in':
160
+ case 'fade_sound_out':
161
+ return cleanObject(await tools.automationBridge?.sendAutomationRequest(action, args, { timeoutMs: getTimeoutMs() }));
162
+ default:
163
+ return cleanObject({ success: false, error: 'UNKNOWN_ACTION', message: `Unknown audio action: ${action}` });
164
+ }
165
+ }
166
+ //# sourceMappingURL=audio-handlers.js.map
@@ -0,0 +1,4 @@
1
+ import { ITools } from '../../types/tool-interfaces.js';
2
+ export declare function handleBlueprintTools(action: string, args: any, tools: ITools): Promise<any>;
3
+ export declare function handleBlueprintGet(args: any, tools: ITools): Promise<any>;
4
+ //# sourceMappingURL=blueprint-handlers.d.ts.map