unreal-engine-mcp-server 0.4.7 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (454) hide show
  1. package/.env.example +26 -0
  2. package/.env.production +38 -7
  3. package/.eslintrc.json +0 -54
  4. package/.eslintrc.override.json +8 -0
  5. package/.github/ISSUE_TEMPLATE/bug_report.yml +94 -0
  6. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  7. package/.github/ISSUE_TEMPLATE/feature_request.yml +56 -0
  8. package/.github/copilot-instructions.md +478 -45
  9. package/.github/dependabot.yml +19 -0
  10. package/.github/labeler.yml +24 -0
  11. package/.github/labels.yml +70 -0
  12. package/.github/pull_request_template.md +42 -0
  13. package/.github/release-drafter-config.yml +51 -0
  14. package/.github/workflows/auto-merge.yml +38 -0
  15. package/.github/workflows/ci.yml +38 -0
  16. package/.github/workflows/dependency-review.yml +17 -0
  17. package/.github/workflows/gemini-issue-triage.yml +172 -0
  18. package/.github/workflows/greetings.yml +27 -0
  19. package/.github/workflows/labeler.yml +17 -0
  20. package/.github/workflows/links.yml +80 -0
  21. package/.github/workflows/pr-size-labeler.yml +137 -0
  22. package/.github/workflows/publish-mcp.yml +13 -7
  23. package/.github/workflows/release-drafter.yml +23 -0
  24. package/.github/workflows/release.yml +112 -0
  25. package/.github/workflows/semantic-pull-request.yml +35 -0
  26. package/.github/workflows/smoke-test.yml +36 -0
  27. package/.github/workflows/stale.yml +28 -0
  28. package/CHANGELOG.md +338 -31
  29. package/CONTRIBUTING.md +140 -0
  30. package/GEMINI.md +115 -0
  31. package/Public/Plugin_setup_guide.mp4 +0 -0
  32. package/README.md +189 -128
  33. package/claude_desktop_config_example.json +7 -6
  34. package/dist/automation/bridge.d.ts +50 -0
  35. package/dist/automation/bridge.js +452 -0
  36. package/dist/automation/connection-manager.d.ts +23 -0
  37. package/dist/automation/connection-manager.js +107 -0
  38. package/dist/automation/handshake.d.ts +11 -0
  39. package/dist/automation/handshake.js +89 -0
  40. package/dist/automation/index.d.ts +3 -0
  41. package/dist/automation/index.js +3 -0
  42. package/dist/automation/message-handler.d.ts +12 -0
  43. package/dist/automation/message-handler.js +149 -0
  44. package/dist/automation/request-tracker.d.ts +25 -0
  45. package/dist/automation/request-tracker.js +98 -0
  46. package/dist/automation/types.d.ts +130 -0
  47. package/dist/automation/types.js +2 -0
  48. package/dist/cli.js +32 -5
  49. package/dist/config.d.ts +26 -0
  50. package/dist/config.js +59 -0
  51. package/dist/constants.d.ts +16 -0
  52. package/dist/constants.js +16 -0
  53. package/dist/graphql/loaders.d.ts +64 -0
  54. package/dist/graphql/loaders.js +117 -0
  55. package/dist/graphql/resolvers.d.ts +268 -0
  56. package/dist/graphql/resolvers.js +746 -0
  57. package/dist/graphql/schema.d.ts +5 -0
  58. package/dist/graphql/schema.js +437 -0
  59. package/dist/graphql/server.d.ts +26 -0
  60. package/dist/graphql/server.js +117 -0
  61. package/dist/graphql/types.d.ts +9 -0
  62. package/dist/graphql/types.js +2 -0
  63. package/dist/handlers/resource-handlers.d.ts +20 -0
  64. package/dist/handlers/resource-handlers.js +180 -0
  65. package/dist/index.d.ts +33 -18
  66. package/dist/index.js +130 -619
  67. package/dist/resources/actors.d.ts +17 -12
  68. package/dist/resources/actors.js +56 -76
  69. package/dist/resources/assets.d.ts +6 -14
  70. package/dist/resources/assets.js +115 -147
  71. package/dist/resources/levels.d.ts +13 -13
  72. package/dist/resources/levels.js +25 -34
  73. package/dist/server/resource-registry.d.ts +20 -0
  74. package/dist/server/resource-registry.js +37 -0
  75. package/dist/server/tool-registry.d.ts +23 -0
  76. package/dist/server/tool-registry.js +322 -0
  77. package/dist/server-setup.d.ts +20 -0
  78. package/dist/server-setup.js +71 -0
  79. package/dist/services/health-monitor.d.ts +34 -0
  80. package/dist/services/health-monitor.js +105 -0
  81. package/dist/services/metrics-server.d.ts +11 -0
  82. package/dist/services/metrics-server.js +105 -0
  83. package/dist/tools/actors.d.ts +163 -9
  84. package/dist/tools/actors.js +356 -311
  85. package/dist/tools/animation.d.ts +135 -4
  86. package/dist/tools/animation.js +510 -411
  87. package/dist/tools/assets.d.ts +75 -29
  88. package/dist/tools/assets.js +265 -284
  89. package/dist/tools/audio.d.ts +102 -42
  90. package/dist/tools/audio.js +272 -685
  91. package/dist/tools/base-tool.d.ts +17 -0
  92. package/dist/tools/base-tool.js +46 -0
  93. package/dist/tools/behavior-tree.d.ts +94 -0
  94. package/dist/tools/behavior-tree.js +39 -0
  95. package/dist/tools/blueprint.d.ts +208 -126
  96. package/dist/tools/blueprint.js +685 -832
  97. package/dist/tools/consolidated-tool-definitions.d.ts +5462 -1781
  98. package/dist/tools/consolidated-tool-definitions.js +829 -496
  99. package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
  100. package/dist/tools/consolidated-tool-handlers.js +198 -1027
  101. package/dist/tools/debug.d.ts +143 -85
  102. package/dist/tools/debug.js +234 -180
  103. package/dist/tools/dynamic-handler-registry.d.ts +13 -0
  104. package/dist/tools/dynamic-handler-registry.js +23 -0
  105. package/dist/tools/editor.d.ts +30 -83
  106. package/dist/tools/editor.js +247 -244
  107. package/dist/tools/engine.d.ts +10 -4
  108. package/dist/tools/engine.js +13 -5
  109. package/dist/tools/environment.d.ts +30 -0
  110. package/dist/tools/environment.js +267 -0
  111. package/dist/tools/foliage.d.ts +65 -99
  112. package/dist/tools/foliage.js +221 -331
  113. package/dist/tools/handlers/actor-handlers.d.ts +3 -0
  114. package/dist/tools/handlers/actor-handlers.js +227 -0
  115. package/dist/tools/handlers/animation-handlers.d.ts +3 -0
  116. package/dist/tools/handlers/animation-handlers.js +185 -0
  117. package/dist/tools/handlers/argument-helper.d.ts +16 -0
  118. package/dist/tools/handlers/argument-helper.js +80 -0
  119. package/dist/tools/handlers/asset-handlers.d.ts +3 -0
  120. package/dist/tools/handlers/asset-handlers.js +496 -0
  121. package/dist/tools/handlers/audio-handlers.d.ts +3 -0
  122. package/dist/tools/handlers/audio-handlers.js +166 -0
  123. package/dist/tools/handlers/blueprint-handlers.d.ts +4 -0
  124. package/dist/tools/handlers/blueprint-handlers.js +358 -0
  125. package/dist/tools/handlers/common-handlers.d.ts +14 -0
  126. package/dist/tools/handlers/common-handlers.js +56 -0
  127. package/dist/tools/handlers/editor-handlers.d.ts +3 -0
  128. package/dist/tools/handlers/editor-handlers.js +119 -0
  129. package/dist/tools/handlers/effect-handlers.d.ts +3 -0
  130. package/dist/tools/handlers/effect-handlers.js +171 -0
  131. package/dist/tools/handlers/environment-handlers.d.ts +3 -0
  132. package/dist/tools/handlers/environment-handlers.js +170 -0
  133. package/dist/tools/handlers/graph-handlers.d.ts +3 -0
  134. package/dist/tools/handlers/graph-handlers.js +90 -0
  135. package/dist/tools/handlers/input-handlers.d.ts +3 -0
  136. package/dist/tools/handlers/input-handlers.js +21 -0
  137. package/dist/tools/handlers/inspect-handlers.d.ts +3 -0
  138. package/dist/tools/handlers/inspect-handlers.js +383 -0
  139. package/dist/tools/handlers/level-handlers.d.ts +3 -0
  140. package/dist/tools/handlers/level-handlers.js +237 -0
  141. package/dist/tools/handlers/lighting-handlers.d.ts +3 -0
  142. package/dist/tools/handlers/lighting-handlers.js +144 -0
  143. package/dist/tools/handlers/performance-handlers.d.ts +3 -0
  144. package/dist/tools/handlers/performance-handlers.js +130 -0
  145. package/dist/tools/handlers/pipeline-handlers.d.ts +3 -0
  146. package/dist/tools/handlers/pipeline-handlers.js +110 -0
  147. package/dist/tools/handlers/sequence-handlers.d.ts +3 -0
  148. package/dist/tools/handlers/sequence-handlers.js +376 -0
  149. package/dist/tools/handlers/system-handlers.d.ts +4 -0
  150. package/dist/tools/handlers/system-handlers.js +506 -0
  151. package/dist/tools/input.d.ts +19 -0
  152. package/dist/tools/input.js +89 -0
  153. package/dist/tools/introspection.d.ts +103 -40
  154. package/dist/tools/introspection.js +425 -568
  155. package/dist/tools/landscape.d.ts +54 -93
  156. package/dist/tools/landscape.js +284 -409
  157. package/dist/tools/level.d.ts +66 -27
  158. package/dist/tools/level.js +647 -675
  159. package/dist/tools/lighting.d.ts +77 -38
  160. package/dist/tools/lighting.js +445 -943
  161. package/dist/tools/logs.d.ts +3 -3
  162. package/dist/tools/logs.js +5 -57
  163. package/dist/tools/materials.d.ts +91 -24
  164. package/dist/tools/materials.js +194 -118
  165. package/dist/tools/niagara.d.ts +149 -39
  166. package/dist/tools/niagara.js +267 -182
  167. package/dist/tools/performance.d.ts +27 -13
  168. package/dist/tools/performance.js +203 -122
  169. package/dist/tools/physics.d.ts +32 -77
  170. package/dist/tools/physics.js +175 -582
  171. package/dist/tools/property-dictionary.d.ts +13 -0
  172. package/dist/tools/property-dictionary.js +82 -0
  173. package/dist/tools/sequence.d.ts +85 -60
  174. package/dist/tools/sequence.js +208 -747
  175. package/dist/tools/tool-definition-utils.d.ts +59 -0
  176. package/dist/tools/tool-definition-utils.js +35 -0
  177. package/dist/tools/ui.d.ts +64 -34
  178. package/dist/tools/ui.js +134 -214
  179. package/dist/types/automation-responses.d.ts +115 -0
  180. package/dist/types/automation-responses.js +2 -0
  181. package/dist/types/env.d.ts +0 -3
  182. package/dist/types/env.js +0 -7
  183. package/dist/types/responses.d.ts +249 -0
  184. package/dist/types/responses.js +2 -0
  185. package/dist/types/tool-interfaces.d.ts +898 -0
  186. package/dist/types/tool-interfaces.js +2 -0
  187. package/dist/types/tool-types.d.ts +183 -19
  188. package/dist/types/tool-types.js +0 -4
  189. package/dist/unreal-bridge.d.ts +24 -131
  190. package/dist/unreal-bridge.js +364 -1506
  191. package/dist/utils/command-validator.d.ts +9 -0
  192. package/dist/utils/command-validator.js +68 -0
  193. package/dist/utils/elicitation.d.ts +1 -1
  194. package/dist/utils/elicitation.js +12 -15
  195. package/dist/utils/error-handler.d.ts +2 -51
  196. package/dist/utils/error-handler.js +11 -87
  197. package/dist/utils/ini-reader.d.ts +3 -0
  198. package/dist/utils/ini-reader.js +69 -0
  199. package/dist/utils/logger.js +9 -6
  200. package/dist/utils/normalize.d.ts +3 -0
  201. package/dist/utils/normalize.js +56 -0
  202. package/dist/utils/path-security.d.ts +2 -0
  203. package/dist/utils/path-security.js +24 -0
  204. package/dist/utils/response-factory.d.ts +7 -0
  205. package/dist/utils/response-factory.js +27 -0
  206. package/dist/utils/response-validator.d.ts +3 -24
  207. package/dist/utils/response-validator.js +130 -81
  208. package/dist/utils/result-helpers.d.ts +4 -5
  209. package/dist/utils/result-helpers.js +15 -16
  210. package/dist/utils/safe-json.js +5 -11
  211. package/dist/utils/unreal-command-queue.d.ts +24 -0
  212. package/dist/utils/unreal-command-queue.js +120 -0
  213. package/dist/utils/validation.d.ts +0 -40
  214. package/dist/utils/validation.js +1 -78
  215. package/dist/wasm/index.d.ts +70 -0
  216. package/dist/wasm/index.js +535 -0
  217. package/docs/GraphQL-API.md +888 -0
  218. package/docs/Migration-Guide-v0.5.0.md +684 -0
  219. package/docs/Roadmap.md +53 -0
  220. package/docs/WebAssembly-Integration.md +628 -0
  221. package/docs/editor-plugin-extension.md +370 -0
  222. package/docs/handler-mapping.md +242 -0
  223. package/docs/native-automation-progress.md +128 -0
  224. package/docs/testing-guide.md +423 -0
  225. package/mcp-config-example.json +6 -6
  226. package/package.json +67 -28
  227. package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +8 -0
  228. package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +64 -0
  229. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +189 -0
  230. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +22 -0
  231. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +30 -0
  232. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +1983 -0
  233. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +72 -0
  234. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +46 -0
  235. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +581 -0
  236. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +2394 -0
  237. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +300 -0
  238. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +2807 -0
  239. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +1087 -0
  240. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +488 -0
  241. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +643 -0
  242. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +31 -0
  243. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +1184 -0
  244. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +5652 -0
  245. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +152 -0
  246. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +2614 -0
  247. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +42 -0
  248. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +1237 -0
  249. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +1701 -0
  250. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +2145 -0
  251. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +954 -0
  252. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +209 -0
  253. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +41 -0
  254. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +1164 -0
  255. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +762 -0
  256. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +634 -0
  257. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +136 -0
  258. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +494 -0
  259. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +278 -0
  260. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +625 -0
  261. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +401 -0
  262. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +67 -0
  263. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +735 -0
  264. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +2634 -0
  265. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +189 -0
  266. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +917 -0
  267. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +39 -0
  268. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +2670 -0
  269. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +519 -0
  270. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +38 -0
  271. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +668 -0
  272. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +346 -0
  273. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +1330 -0
  274. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +149 -0
  275. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +783 -0
  276. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +115 -0
  277. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +796 -0
  278. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +117 -0
  279. package/scripts/check-unreal-connection.mjs +19 -0
  280. package/scripts/clean-tmp.js +23 -0
  281. package/scripts/patch-wasm.js +26 -0
  282. package/scripts/run-all-tests.mjs +136 -0
  283. package/scripts/smoke-test.ts +94 -0
  284. package/scripts/sync-mcp-plugin.js +143 -0
  285. package/scripts/test-no-plugin-alternates.mjs +113 -0
  286. package/scripts/validate-server.js +46 -0
  287. package/scripts/verify-automation-bridge.js +200 -0
  288. package/server.json +58 -21
  289. package/src/automation/bridge.ts +558 -0
  290. package/src/automation/connection-manager.ts +130 -0
  291. package/src/automation/handshake.ts +99 -0
  292. package/src/automation/index.ts +2 -0
  293. package/src/automation/message-handler.ts +167 -0
  294. package/src/automation/request-tracker.ts +123 -0
  295. package/src/automation/types.ts +107 -0
  296. package/src/cli.ts +33 -6
  297. package/src/config.ts +73 -0
  298. package/src/constants.ts +19 -0
  299. package/src/graphql/loaders.ts +244 -0
  300. package/src/graphql/resolvers.ts +1008 -0
  301. package/src/graphql/schema.ts +452 -0
  302. package/src/graphql/server.ts +156 -0
  303. package/src/graphql/types.ts +10 -0
  304. package/src/handlers/resource-handlers.ts +186 -0
  305. package/src/index.ts +166 -664
  306. package/src/resources/actors.ts +58 -76
  307. package/src/resources/assets.ts +148 -134
  308. package/src/resources/levels.ts +28 -33
  309. package/src/server/resource-registry.ts +47 -0
  310. package/src/server/tool-registry.ts +354 -0
  311. package/src/server-setup.ts +114 -0
  312. package/src/services/health-monitor.ts +132 -0
  313. package/src/services/metrics-server.ts +142 -0
  314. package/src/tools/actors.ts +426 -323
  315. package/src/tools/animation.ts +672 -461
  316. package/src/tools/assets.ts +364 -289
  317. package/src/tools/audio.ts +323 -766
  318. package/src/tools/base-tool.ts +52 -0
  319. package/src/tools/behavior-tree.ts +45 -0
  320. package/src/tools/blueprint.ts +792 -970
  321. package/src/tools/consolidated-tool-definitions.ts +993 -515
  322. package/src/tools/consolidated-tool-handlers.ts +258 -1146
  323. package/src/tools/debug.ts +292 -187
  324. package/src/tools/dynamic-handler-registry.ts +33 -0
  325. package/src/tools/editor.ts +329 -253
  326. package/src/tools/engine.ts +14 -3
  327. package/src/tools/environment.ts +281 -0
  328. package/src/tools/foliage.ts +330 -392
  329. package/src/tools/handlers/actor-handlers.ts +265 -0
  330. package/src/tools/handlers/animation-handlers.ts +237 -0
  331. package/src/tools/handlers/argument-helper.ts +142 -0
  332. package/src/tools/handlers/asset-handlers.ts +532 -0
  333. package/src/tools/handlers/audio-handlers.ts +194 -0
  334. package/src/tools/handlers/blueprint-handlers.ts +380 -0
  335. package/src/tools/handlers/common-handlers.ts +87 -0
  336. package/src/tools/handlers/editor-handlers.ts +123 -0
  337. package/src/tools/handlers/effect-handlers.ts +220 -0
  338. package/src/tools/handlers/environment-handlers.ts +183 -0
  339. package/src/tools/handlers/graph-handlers.ts +116 -0
  340. package/src/tools/handlers/input-handlers.ts +28 -0
  341. package/src/tools/handlers/inspect-handlers.ts +450 -0
  342. package/src/tools/handlers/level-handlers.ts +252 -0
  343. package/src/tools/handlers/lighting-handlers.ts +147 -0
  344. package/src/tools/handlers/performance-handlers.ts +132 -0
  345. package/src/tools/handlers/pipeline-handlers.ts +127 -0
  346. package/src/tools/handlers/sequence-handlers.ts +415 -0
  347. package/src/tools/handlers/system-handlers.ts +564 -0
  348. package/src/tools/input.ts +101 -0
  349. package/src/tools/introspection.ts +493 -584
  350. package/src/tools/landscape.ts +418 -507
  351. package/src/tools/level.ts +786 -708
  352. package/src/tools/lighting.ts +588 -984
  353. package/src/tools/logs.ts +9 -57
  354. package/src/tools/materials.ts +237 -121
  355. package/src/tools/niagara.ts +335 -168
  356. package/src/tools/performance.ts +320 -169
  357. package/src/tools/physics.ts +274 -613
  358. package/src/tools/property-dictionary.ts +98 -0
  359. package/src/tools/sequence.ts +276 -820
  360. package/src/tools/tool-definition-utils.ts +35 -0
  361. package/src/tools/ui.ts +205 -283
  362. package/src/types/automation-responses.ts +119 -0
  363. package/src/types/env.ts +0 -10
  364. package/src/types/responses.ts +355 -0
  365. package/src/types/tool-interfaces.ts +250 -0
  366. package/src/types/tool-types.ts +243 -21
  367. package/src/unreal-bridge.ts +460 -1550
  368. package/src/utils/command-validator.ts +76 -0
  369. package/src/utils/elicitation.ts +10 -7
  370. package/src/utils/error-handler.ts +14 -90
  371. package/src/utils/ini-reader.ts +86 -0
  372. package/src/utils/logger.ts +8 -3
  373. package/src/utils/normalize.test.ts +162 -0
  374. package/src/utils/normalize.ts +60 -0
  375. package/src/utils/path-security.ts +43 -0
  376. package/src/utils/response-factory.ts +44 -0
  377. package/src/utils/response-validator.ts +176 -56
  378. package/src/utils/result-helpers.ts +21 -19
  379. package/src/utils/safe-json.test.ts +90 -0
  380. package/src/utils/safe-json.ts +14 -11
  381. package/src/utils/unreal-command-queue.ts +152 -0
  382. package/src/utils/validation.test.ts +184 -0
  383. package/src/utils/validation.ts +4 -1
  384. package/src/wasm/index.ts +838 -0
  385. package/test-server.mjs +100 -0
  386. package/tests/run-unreal-tool-tests.mjs +242 -14
  387. package/tests/test-animation.mjs +369 -0
  388. package/tests/test-asset-advanced.mjs +82 -0
  389. package/tests/test-asset-errors.mjs +35 -0
  390. package/tests/test-asset-graph.mjs +311 -0
  391. package/tests/test-audio.mjs +417 -0
  392. package/tests/test-automation-timeouts.mjs +98 -0
  393. package/tests/test-behavior-tree.mjs +444 -0
  394. package/tests/test-blueprint-graph.mjs +410 -0
  395. package/tests/test-blueprint.mjs +577 -0
  396. package/tests/test-client-mode.mjs +86 -0
  397. package/tests/test-console-command.mjs +56 -0
  398. package/tests/test-control-actor.mjs +425 -0
  399. package/tests/test-control-editor.mjs +112 -0
  400. package/tests/test-graphql.mjs +372 -0
  401. package/tests/test-input.mjs +349 -0
  402. package/tests/test-inspect.mjs +302 -0
  403. package/tests/test-landscape.mjs +316 -0
  404. package/tests/test-lighting.mjs +428 -0
  405. package/tests/test-manage-asset.mjs +438 -0
  406. package/tests/test-manage-level.mjs +89 -0
  407. package/tests/test-materials.mjs +356 -0
  408. package/tests/test-niagara.mjs +185 -0
  409. package/tests/test-no-inline-python.mjs +122 -0
  410. package/tests/test-performance.mjs +539 -0
  411. package/tests/test-plugin-handshake.mjs +82 -0
  412. package/tests/test-runner.mjs +933 -0
  413. package/tests/test-sequence.mjs +104 -0
  414. package/tests/test-system.mjs +96 -0
  415. package/tests/test-wasm.mjs +283 -0
  416. package/tests/test-world-partition.mjs +215 -0
  417. package/tsconfig.json +3 -3
  418. package/vitest.config.ts +35 -0
  419. package/wasm/Cargo.lock +363 -0
  420. package/wasm/Cargo.toml +42 -0
  421. package/wasm/LICENSE +21 -0
  422. package/wasm/README.md +253 -0
  423. package/wasm/src/dependency_resolver.rs +377 -0
  424. package/wasm/src/lib.rs +153 -0
  425. package/wasm/src/property_parser.rs +271 -0
  426. package/wasm/src/transform_math.rs +396 -0
  427. package/wasm/tests/integration.rs +109 -0
  428. package/.github/workflows/smithery-build.yml +0 -29
  429. package/dist/prompts/index.d.ts +0 -21
  430. package/dist/prompts/index.js +0 -217
  431. package/dist/tools/build_environment_advanced.d.ts +0 -65
  432. package/dist/tools/build_environment_advanced.js +0 -633
  433. package/dist/tools/rc.d.ts +0 -110
  434. package/dist/tools/rc.js +0 -437
  435. package/dist/tools/visual.d.ts +0 -40
  436. package/dist/tools/visual.js +0 -282
  437. package/dist/utils/http.d.ts +0 -6
  438. package/dist/utils/http.js +0 -151
  439. package/dist/utils/python-output.d.ts +0 -18
  440. package/dist/utils/python-output.js +0 -290
  441. package/dist/utils/python.d.ts +0 -2
  442. package/dist/utils/python.js +0 -4
  443. package/dist/utils/stdio-redirect.d.ts +0 -2
  444. package/dist/utils/stdio-redirect.js +0 -20
  445. package/docs/unreal-tool-test-cases.md +0 -574
  446. package/smithery.yaml +0 -29
  447. package/src/prompts/index.ts +0 -249
  448. package/src/tools/build_environment_advanced.ts +0 -732
  449. package/src/tools/rc.ts +0 -515
  450. package/src/tools/visual.ts +0 -281
  451. package/src/utils/http.ts +0 -187
  452. package/src/utils/python-output.ts +0 -351
  453. package/src/utils/python.ts +0 -3
  454. package/src/utils/stdio-redirect.ts +0 -18
@@ -0,0 +1,735 @@
1
+ #include "Async/Async.h"
2
+ #include "HAL/PlatformTime.h"
3
+ #include "McpAutomationBridgeGlobals.h"
4
+ #include "McpAutomationBridgeHelpers.h"
5
+ #include "McpAutomationBridgeSubsystem.h"
6
+ #include "McpConnectionManager.h"
7
+ #include "Misc/ScopeExit.h"
8
+ #include "Misc/ScopeLock.h"
9
+
10
+ void UMcpAutomationBridgeSubsystem::ProcessAutomationRequest(
11
+ const FString &RequestId, const FString &Action,
12
+ const TSharedPtr<FJsonObject> &Payload,
13
+ TSharedPtr<FMcpBridgeWebSocket> RequestingSocket) {
14
+ // This large implementation was extracted from the original subsystem
15
+ // translation unit to keep the core file smaller and focused. It
16
+ // contains the main dispatcher that delegates to specialized handler
17
+ // functions (property/blueprint/sequence/asset handlers) and retains
18
+ // the queuing/scope-exit safety logic expected by callers.
19
+
20
+ // Ensure automation processing happens on the game thread
21
+ // This trace is intentionally verbose — routine requests can be high
22
+ // frequency and will otherwise flood the logs. Developers can enable
23
+ // Verbose logging to see these messages when required.
24
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
25
+ TEXT(">>> ProcessAutomationRequest ENTRY: RequestId=%s action='%s' "
26
+ "(thread=%s)"),
27
+ *RequestId, *Action,
28
+ IsInGameThread() ? TEXT("GameThread") : TEXT("SocketThread"));
29
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
30
+ TEXT("ProcessAutomationRequest invoked (thread=%s) RequestId=%s "
31
+ "action=%s activeSockets=%d pendingQueue=%d"),
32
+ IsInGameThread() ? TEXT("GameThread") : TEXT("SocketThread"),
33
+ *RequestId, *Action,
34
+ ConnectionManager.IsValid() ? ConnectionManager->GetActiveSocketCount()
35
+ : 0,
36
+ PendingAutomationRequests.Num());
37
+ if (!IsInGameThread()) {
38
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
39
+ TEXT("Scheduling ProcessAutomationRequest on GameThread: "
40
+ "RequestId=%s action=%s"),
41
+ *RequestId, *Action);
42
+ AsyncTask(ENamedThreads::GameThread,
43
+ [WeakThis = TWeakObjectPtr<UMcpAutomationBridgeSubsystem>(this),
44
+ RequestId, Action, Payload, RequestingSocket]() {
45
+ if (UMcpAutomationBridgeSubsystem *Pinned = WeakThis.Get()) {
46
+ Pinned->ProcessAutomationRequest(RequestId, Action, Payload,
47
+ RequestingSocket);
48
+ }
49
+ });
50
+ return;
51
+ }
52
+
53
+ // Guard against unsafe engine states (Saving, GC, Async Loading)
54
+ // Calling StaticFindObject (via ResolveClassByName) during these states can
55
+ // cause crashes.
56
+ if (GIsSavingPackage || IsGarbageCollecting() || IsAsyncLoading()) {
57
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
58
+ TEXT("Deferring ProcessAutomationRequest due to active "
59
+ "Serialization/GC/Loading: RequestId=%s Action=%s"),
60
+ *RequestId, *Action);
61
+
62
+ FPendingAutomationRequest P;
63
+ P.RequestId = RequestId;
64
+ P.Action = Action;
65
+ P.Payload = Payload;
66
+ P.RequestingSocket = RequestingSocket;
67
+ {
68
+ FScopeLock Lock(&PendingAutomationRequestsMutex);
69
+ PendingAutomationRequests.Add(MoveTemp(P));
70
+ bPendingRequestsScheduled = true;
71
+ }
72
+ return;
73
+ }
74
+
75
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
76
+ TEXT("Starting ProcessAutomationRequest on GameThread: RequestId=%s "
77
+ "action=%s bProcessingAutomationRequest=%s"),
78
+ *RequestId, *Action,
79
+ bProcessingAutomationRequest ? TEXT("true") : TEXT("false"));
80
+
81
+ const FString LowerAction = Action.ToLower();
82
+
83
+ if (ConnectionManager.IsValid()) {
84
+ ConnectionManager->StartRequestTelemetry(RequestId, Action);
85
+ }
86
+
87
+ // Reentrancy guard / enqueue
88
+ if (bProcessingAutomationRequest) {
89
+ FPendingAutomationRequest P;
90
+ P.RequestId = RequestId;
91
+ P.Action = Action;
92
+ P.Payload = Payload;
93
+ P.RequestingSocket = RequestingSocket;
94
+ {
95
+ FScopeLock Lock(&PendingAutomationRequestsMutex);
96
+ PendingAutomationRequests.Add(MoveTemp(P));
97
+ bPendingRequestsScheduled = true;
98
+ }
99
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
100
+ TEXT("Enqueued automation request %s for action %s (processing in "
101
+ "progress)."),
102
+ *RequestId, *Action);
103
+ return;
104
+ }
105
+
106
+ bProcessingAutomationRequest = true;
107
+ bool bDispatchHandled = false;
108
+ FString ConsumedHandlerLabel = TEXT("unknown-handler");
109
+ const double DispatchStartSeconds = FPlatformTime::Seconds();
110
+
111
+ auto HandleAndLog = [&](const TCHAR *HandlerLabel, auto &&Callable) -> bool {
112
+ const bool bResult = Callable();
113
+ if (bResult) {
114
+ bDispatchHandled = true;
115
+ ConsumedHandlerLabel = HandlerLabel;
116
+ }
117
+ return bResult;
118
+ };
119
+
120
+ {
121
+ ON_SCOPE_EXIT {
122
+ bProcessingAutomationRequest = false;
123
+ const double DispatchEndSeconds = FPlatformTime::Seconds();
124
+ const double DurationMs =
125
+ (DispatchEndSeconds - DispatchStartSeconds) * 1000.0;
126
+ if (bDispatchHandled) {
127
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
128
+ TEXT("ProcessAutomationRequest: Completed handler='%s' "
129
+ "RequestId=%s action='%s' (%.3f ms)"),
130
+ *ConsumedHandlerLabel, *RequestId, *Action, DurationMs);
131
+ } else {
132
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Warning,
133
+ TEXT("ProcessAutomationRequest: No handler consumed "
134
+ "RequestId=%s action='%s' (%.3f ms)"),
135
+ *RequestId, *Action, DurationMs);
136
+ }
137
+
138
+ if (bPendingRequestsScheduled) {
139
+ bPendingRequestsScheduled = false;
140
+ ProcessPendingAutomationRequests();
141
+ }
142
+ };
143
+
144
+ try {
145
+ // Map this requestId to the requesting socket so responses can be
146
+ // delivered reliably
147
+ if (!RequestId.IsEmpty() && RequestingSocket.IsValid() &&
148
+ ConnectionManager.IsValid()) {
149
+ ConnectionManager->RegisterRequestSocket(RequestId, RequestingSocket);
150
+ }
151
+
152
+ // ---------------------------------------------------------
153
+ // Check Handler Registry (O(1) dispatch)
154
+ // ---------------------------------------------------------
155
+ if (const FAutomationHandler *Handler = AutomationHandlers.Find(Action)) {
156
+ if (HandleAndLog(*Action, [&]() {
157
+ return (*Handler)(RequestId, Action, Payload, RequestingSocket);
158
+ })) {
159
+ return;
160
+ }
161
+ }
162
+
163
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
164
+ TEXT("ProcessAutomationRequest: Starting handler dispatch for "
165
+ "action='%s'"),
166
+ *Action);
167
+
168
+ // Prioritize blueprint actions early only for blueprint-like actions to
169
+ // avoid noisy prefix logs
170
+ {
171
+ FString LowerNormalized = LowerAction;
172
+ LowerNormalized.ReplaceInline(TEXT("-"), TEXT("_"));
173
+ LowerNormalized.ReplaceInline(TEXT(" "), TEXT("_"));
174
+ const bool bLooksBlueprint =
175
+ (LowerNormalized.StartsWith(TEXT("blueprint_")) ||
176
+ LowerNormalized.StartsWith(TEXT("manage_blueprint")) ||
177
+ LowerNormalized.Contains(TEXT("_scs")) ||
178
+ LowerNormalized.Contains(TEXT("scs_")) ||
179
+ LowerNormalized.Contains(TEXT("scs")));
180
+ if (bLooksBlueprint) {
181
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
182
+ TEXT("ProcessAutomationRequest: Checking "
183
+ "HandleBlueprintAction (early)"));
184
+ if (HandleAndLog(TEXT("HandleBlueprintAction (early)"), [&]() {
185
+ return HandleBlueprintAction(RequestId, Action, Payload,
186
+ RequestingSocket);
187
+ })) {
188
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
189
+ TEXT("HandleBlueprintAction (early) consumed request"));
190
+ return;
191
+ }
192
+ }
193
+ }
194
+
195
+ // Allow small handlers to short-circuit fast (property/function)
196
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
197
+ TEXT("ProcessAutomationRequest: About to call "
198
+ "HandleExecuteEditorFunction"));
199
+ if (HandleAndLog(TEXT("HandleExecuteEditorFunction"), [&]() {
200
+ return HandleExecuteEditorFunction(RequestId, Action, Payload,
201
+ RequestingSocket);
202
+ })) {
203
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
204
+ TEXT("HandleExecuteEditorFunction consumed request"));
205
+ return;
206
+ }
207
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
208
+ TEXT("ProcessAutomationRequest: HandleExecuteEditorFunction "
209
+ "returned false"));
210
+
211
+ // Level utilities (top-level aliases)
212
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
213
+ TEXT("ProcessAutomationRequest: Checking HandleLevelAction"));
214
+ if (HandleAndLog(TEXT("HandleLevelAction"), [&]() {
215
+ return HandleLevelAction(RequestId, Action, Payload,
216
+ RequestingSocket);
217
+ })) {
218
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
219
+ TEXT("HandleLevelAction consumed request"));
220
+ return;
221
+ }
222
+
223
+ // Try asset actions early (materials, import, list, rename, etc.)
224
+ UE_LOG(
225
+ LogMcpAutomationBridgeSubsystem, Verbose,
226
+ TEXT("ProcessAutomationRequest: Checking HandleAssetAction (early)"));
227
+ if (HandleAndLog(TEXT("HandleAssetAction (early)"), [&]() {
228
+ return HandleAssetAction(RequestId, Action, Payload,
229
+ RequestingSocket);
230
+ })) {
231
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
232
+ TEXT("HandleAssetAction (early) consumed request"));
233
+ return;
234
+ }
235
+ if (HandleAndLog(TEXT("HandleSetObjectProperty"), [&]() {
236
+ return HandleSetObjectProperty(RequestId, Action, Payload,
237
+ RequestingSocket);
238
+ }))
239
+ return;
240
+ if (HandleAndLog(TEXT("HandleGetObjectProperty"), [&]() {
241
+ return HandleGetObjectProperty(RequestId, Action, Payload,
242
+ RequestingSocket);
243
+ }))
244
+ return;
245
+ // Array manipulation operations
246
+ if (HandleAndLog(TEXT("HandleArrayAppend"), [&]() {
247
+ return HandleArrayAppend(RequestId, Action, Payload,
248
+ RequestingSocket);
249
+ }))
250
+ return;
251
+ if (HandleAndLog(TEXT("HandleArrayRemove"), [&]() {
252
+ return HandleArrayRemove(RequestId, Action, Payload,
253
+ RequestingSocket);
254
+ }))
255
+ return;
256
+ if (HandleAndLog(TEXT("HandleArrayInsert"), [&]() {
257
+ return HandleArrayInsert(RequestId, Action, Payload,
258
+ RequestingSocket);
259
+ }))
260
+ return;
261
+ if (HandleAndLog(TEXT("HandleArrayGetElement"), [&]() {
262
+ return HandleArrayGetElement(RequestId, Action, Payload,
263
+ RequestingSocket);
264
+ }))
265
+ return;
266
+ if (HandleAndLog(TEXT("HandleArraySetElement"), [&]() {
267
+ return HandleArraySetElement(RequestId, Action, Payload,
268
+ RequestingSocket);
269
+ }))
270
+ return;
271
+ if (HandleAndLog(TEXT("HandleArrayClear"), [&]() {
272
+ return HandleArrayClear(RequestId, Action, Payload,
273
+ RequestingSocket);
274
+ }))
275
+ return;
276
+ // Map manipulation operations
277
+ if (HandleAndLog(TEXT("HandleMapSetValue"), [&]() {
278
+ return HandleMapSetValue(RequestId, Action, Payload,
279
+ RequestingSocket);
280
+ }))
281
+ return;
282
+ if (HandleAndLog(TEXT("HandleMapGetValue"), [&]() {
283
+ return HandleMapGetValue(RequestId, Action, Payload,
284
+ RequestingSocket);
285
+ }))
286
+ return;
287
+ if (HandleAndLog(TEXT("HandleMapRemoveKey"), [&]() {
288
+ return HandleMapRemoveKey(RequestId, Action, Payload,
289
+ RequestingSocket);
290
+ }))
291
+ return;
292
+ if (HandleAndLog(TEXT("HandleMapHasKey"), [&]() {
293
+ return HandleMapHasKey(RequestId, Action, Payload,
294
+ RequestingSocket);
295
+ }))
296
+ return;
297
+ if (HandleAndLog(TEXT("HandleMapGetKeys"), [&]() {
298
+ return HandleMapGetKeys(RequestId, Action, Payload,
299
+ RequestingSocket);
300
+ }))
301
+ return;
302
+ if (HandleAndLog(TEXT("HandleMapClear"), [&]() {
303
+ return HandleMapClear(RequestId, Action, Payload, RequestingSocket);
304
+ }))
305
+ return;
306
+ // Set manipulation operations
307
+ if (HandleAndLog(TEXT("HandleSetAdd"), [&]() {
308
+ return HandleSetAdd(RequestId, Action, Payload, RequestingSocket);
309
+ }))
310
+ return;
311
+ if (HandleAndLog(TEXT("HandleSetRemove"), [&]() {
312
+ return HandleSetRemove(RequestId, Action, Payload,
313
+ RequestingSocket);
314
+ }))
315
+ return;
316
+ if (HandleAndLog(TEXT("HandleSetContains"), [&]() {
317
+ return HandleSetContains(RequestId, Action, Payload,
318
+ RequestingSocket);
319
+ }))
320
+ return;
321
+ if (HandleAndLog(TEXT("HandleSetClear"), [&]() {
322
+ return HandleSetClear(RequestId, Action, Payload, RequestingSocket);
323
+ }))
324
+ return;
325
+ // Asset dependency graph traversal
326
+ if (HandleAndLog(TEXT("HandleGetAssetReferences"), [&]() {
327
+ return HandleGetAssetReferences(RequestId, Action, Payload,
328
+ RequestingSocket);
329
+ }))
330
+ return;
331
+ if (HandleAndLog(TEXT("HandleGetAssetDependencies"), [&]() {
332
+ return HandleGetAssetDependencies(RequestId, Action, Payload,
333
+ RequestingSocket);
334
+ }))
335
+ return;
336
+ // Asset workflow handlers
337
+ if (HandleAndLog(TEXT("HandleFixupRedirectors"), [&]() {
338
+ return HandleFixupRedirectors(RequestId, Action, Payload,
339
+ RequestingSocket);
340
+ }))
341
+ return;
342
+ if (HandleAndLog(TEXT("HandleSourceControlCheckout"), [&]() {
343
+ return HandleSourceControlCheckout(RequestId, Action, Payload,
344
+ RequestingSocket);
345
+ }))
346
+ return;
347
+ if (HandleAndLog(TEXT("HandleSourceControlSubmit"), [&]() {
348
+ return HandleSourceControlSubmit(RequestId, Action, Payload,
349
+ RequestingSocket);
350
+ }))
351
+ return;
352
+ if (HandleAndLog(TEXT("HandleBulkRenameAssets"), [&]() {
353
+ return HandleBulkRenameAssets(RequestId, Action, Payload,
354
+ RequestingSocket);
355
+ }))
356
+ return;
357
+ if (HandleAndLog(TEXT("HandleBulkDeleteAssets"), [&]() {
358
+ return HandleBulkDeleteAssets(RequestId, Action, Payload,
359
+ RequestingSocket);
360
+ }))
361
+ return;
362
+ if (HandleAndLog(TEXT("HandleGenerateThumbnail"), [&]() {
363
+ return HandleGenerateThumbnail(RequestId, Action, Payload,
364
+ RequestingSocket);
365
+ }))
366
+ return;
367
+ // Landscape operations
368
+ if (HandleAndLog(TEXT("HandleCreateLandscape"), [&]() {
369
+ return HandleCreateLandscape(RequestId, Action, Payload,
370
+ RequestingSocket);
371
+ }))
372
+ return;
373
+ if (HandleAndLog(TEXT("HandleCreateProceduralTerrain"), [&]() {
374
+ return HandleCreateProceduralTerrain(RequestId, Action, Payload,
375
+ RequestingSocket);
376
+ }))
377
+ return;
378
+ if (HandleAndLog(TEXT("HandleCreateLandscapeGrassType"), [&]() {
379
+ return HandleCreateLandscapeGrassType(RequestId, Action, Payload,
380
+ RequestingSocket);
381
+ }))
382
+ return;
383
+ if (HandleAndLog(TEXT("HandleSculptLandscape"), [&]() {
384
+ return HandleSculptLandscape(RequestId, Action, Payload,
385
+ RequestingSocket);
386
+ }))
387
+ return;
388
+ if (HandleAndLog(TEXT("HandleSetLandscapeMaterial"), [&]() {
389
+ return HandleSetLandscapeMaterial(RequestId, Action, Payload,
390
+ RequestingSocket);
391
+ }))
392
+ return;
393
+ if (HandleAndLog(TEXT("HandleEditLandscape"), [&]() {
394
+ return HandleEditLandscape(RequestId, Action, Payload,
395
+ RequestingSocket);
396
+ }))
397
+ return;
398
+ // Foliage operations
399
+ if (HandleAndLog(TEXT("HandleAddFoliageType"), [&]() {
400
+ return HandleAddFoliageType(RequestId, Action, Payload,
401
+ RequestingSocket);
402
+ }))
403
+ return;
404
+ if (HandleAndLog(TEXT("HandleCreateProceduralFoliage"), [&]() {
405
+ return HandleCreateProceduralFoliage(RequestId, Action, Payload,
406
+ RequestingSocket);
407
+ }))
408
+ return;
409
+ if (HandleAndLog(TEXT("HandlePaintFoliage"), [&]() {
410
+ return HandlePaintFoliage(RequestId, Action, Payload,
411
+ RequestingSocket);
412
+ }))
413
+ return;
414
+ if (HandleAndLog(TEXT("HandleAddFoliageInstances"), [&]() {
415
+ return HandleAddFoliageInstances(RequestId, Action, Payload,
416
+ RequestingSocket);
417
+ }))
418
+ return;
419
+ if (HandleAndLog(TEXT("HandleRemoveFoliage"), [&]() {
420
+ return HandleRemoveFoliage(RequestId, Action, Payload,
421
+ RequestingSocket);
422
+ }))
423
+ return;
424
+ if (HandleAndLog(TEXT("HandleGetFoliageInstances"), [&]() {
425
+ return HandleGetFoliageInstances(RequestId, Action, Payload,
426
+ RequestingSocket);
427
+ }))
428
+ return;
429
+ // Niagara operations
430
+ if (HandleAndLog(TEXT("HandleCreateNiagaraSystem"), [&]() {
431
+ return HandleCreateNiagaraSystem(RequestId, Action, Payload,
432
+ RequestingSocket);
433
+ }))
434
+ return;
435
+ if (HandleAndLog(TEXT("HandleCreateNiagaraRibbon"), [&]() {
436
+ return HandleCreateNiagaraRibbon(RequestId, Action, Payload,
437
+ RequestingSocket);
438
+ }))
439
+ return;
440
+ if (HandleAndLog(TEXT("HandleCreateNiagaraEmitter"), [&]() {
441
+ return HandleCreateNiagaraEmitter(RequestId, Action, Payload,
442
+ RequestingSocket);
443
+ }))
444
+ return;
445
+ if (HandleAndLog(TEXT("HandleSpawnNiagaraActor"), [&]() {
446
+ return HandleSpawnNiagaraActor(RequestId, Action, Payload,
447
+ RequestingSocket);
448
+ }))
449
+ return;
450
+ if (HandleAndLog(TEXT("HandleModifyNiagaraParameter"), [&]() {
451
+ return HandleModifyNiagaraParameter(RequestId, Action, Payload,
452
+ RequestingSocket);
453
+ }))
454
+ return;
455
+ // Animation blueprint operations
456
+ if (HandleAndLog(TEXT("HandleCreateAnimBlueprint"), [&]() {
457
+ return HandleCreateAnimBlueprint(RequestId, Action, Payload,
458
+ RequestingSocket);
459
+ }))
460
+ return;
461
+ if (HandleAndLog(TEXT("HandlePlayAnimMontage"), [&]() {
462
+ return HandlePlayAnimMontage(RequestId, Action, Payload,
463
+ RequestingSocket);
464
+ }))
465
+ return;
466
+ if (HandleAndLog(TEXT("HandleSetupRagdoll"), [&]() {
467
+ return HandleSetupRagdoll(RequestId, Action, Payload,
468
+ RequestingSocket);
469
+ }))
470
+ return;
471
+ // Material graph operations
472
+ if (HandleAndLog(TEXT("HandleAddMaterialTextureSample"), [&]() {
473
+ return HandleAddMaterialTextureSample(RequestId, Action, Payload,
474
+ RequestingSocket);
475
+ }))
476
+ return;
477
+ if (HandleAndLog(TEXT("HandleAddMaterialExpression"), [&]() {
478
+ return HandleAddMaterialExpression(RequestId, Action, Payload,
479
+ RequestingSocket);
480
+ }))
481
+ return;
482
+ if (HandleAndLog(TEXT("HandleCreateMaterialNodes"), [&]() {
483
+ return HandleCreateMaterialNodes(RequestId, Action, Payload,
484
+ RequestingSocket);
485
+ }))
486
+ return;
487
+ // Sequencer operations
488
+ if (HandleAndLog(TEXT("HandleAddSequencerKeyframe"), [&]() {
489
+ return HandleAddSequencerKeyframe(RequestId, Action, Payload,
490
+ RequestingSocket);
491
+ }))
492
+ return;
493
+ if (HandleAndLog(TEXT("HandleManageSequencerTrack"), [&]() {
494
+ return HandleManageSequencerTrack(RequestId, Action, Payload,
495
+ RequestingSocket);
496
+ }))
497
+ return;
498
+ if (HandleAndLog(TEXT("HandleAddCameraTrack"), [&]() {
499
+ return HandleAddCameraTrack(RequestId, Action, Payload,
500
+ RequestingSocket);
501
+ }))
502
+ return;
503
+ if (HandleAndLog(TEXT("HandleAddAnimationTrack"), [&]() {
504
+ return HandleAddAnimationTrack(RequestId, Action, Payload,
505
+ RequestingSocket);
506
+ }))
507
+ return;
508
+ if (HandleAndLog(TEXT("HandleAddTransformTrack"), [&]() {
509
+ return HandleAddTransformTrack(RequestId, Action, Payload,
510
+ RequestingSocket);
511
+ }))
512
+ return;
513
+
514
+ // Delegate asset/control/blueprint/sequence actions to their handlers
515
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
516
+ TEXT("ProcessAutomationRequest: Checking HandleAssetAction"));
517
+ if (HandleAndLog(TEXT("HandleAssetAction"), [&]() {
518
+ return HandleAssetAction(RequestId, Action, Payload,
519
+ RequestingSocket);
520
+ })) {
521
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
522
+ TEXT("HandleAssetAction consumed request"));
523
+ return;
524
+ }
525
+ UE_LOG(
526
+ LogMcpAutomationBridgeSubsystem, Verbose,
527
+ TEXT("ProcessAutomationRequest: Checking HandleControlActorAction"));
528
+ if (HandleAndLog(TEXT("HandleControlActorAction"), [&]() {
529
+ return HandleControlActorAction(RequestId, Action, Payload,
530
+ RequestingSocket);
531
+ })) {
532
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
533
+ TEXT("HandleControlActorAction consumed request"));
534
+ return;
535
+ }
536
+ UE_LOG(
537
+ LogMcpAutomationBridgeSubsystem, Verbose,
538
+ TEXT("ProcessAutomationRequest: Checking HandleControlEditorAction"));
539
+ if (HandleAndLog(TEXT("HandleControlEditorAction"), [&]() {
540
+ return HandleControlEditorAction(RequestId, Action, Payload,
541
+ RequestingSocket);
542
+ })) {
543
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
544
+ TEXT("HandleControlEditorAction consumed request"));
545
+ return;
546
+ }
547
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
548
+ TEXT("ProcessAutomationRequest: Checking HandleUiAction"));
549
+ if (HandleAndLog(TEXT("HandleUiAction"), [&]() {
550
+ return HandleUiAction(RequestId, Action, Payload, RequestingSocket);
551
+ })) {
552
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
553
+ TEXT("HandleUiAction consumed request"));
554
+ return;
555
+ }
556
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
557
+ TEXT("ProcessAutomationRequest: Checking HandleBlueprintAction "
558
+ "(late)"));
559
+ if (HandleAndLog(TEXT("HandleBlueprintAction (late)"), [&]() {
560
+ return HandleBlueprintAction(RequestId, Action, Payload,
561
+ RequestingSocket);
562
+ })) {
563
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
564
+ TEXT("HandleBlueprintAction (late) consumed request"));
565
+ return;
566
+ }
567
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
568
+ TEXT("ProcessAutomationRequest: Checking HandleSequenceAction"));
569
+ if (HandleAndLog(TEXT("HandleSequenceAction"), [&]() {
570
+ return HandleSequenceAction(RequestId, Action, Payload,
571
+ RequestingSocket);
572
+ })) {
573
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
574
+ TEXT("HandleSequenceAction consumed request"));
575
+ return;
576
+ }
577
+ if (HandleAndLog(TEXT("HandleEffectAction"), [&]() {
578
+ return HandleEffectAction(RequestId, Action, Payload,
579
+ RequestingSocket);
580
+ }))
581
+ return;
582
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
583
+ TEXT("ProcessAutomationRequest: Checking "
584
+ "HandleAnimationPhysicsAction"));
585
+ if (HandleAndLog(TEXT("HandleAnimationPhysicsAction"), [&]() {
586
+ return HandleAnimationPhysicsAction(RequestId, Action, Payload,
587
+ RequestingSocket);
588
+ })) {
589
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
590
+ TEXT("HandleAnimationPhysicsAction consumed request"));
591
+ return;
592
+ }
593
+ if (HandleAndLog(TEXT("HandleAudioAction"), [&]() {
594
+ return HandleAudioAction(RequestId, Action, Payload,
595
+ RequestingSocket);
596
+ }))
597
+ return;
598
+ if (HandleAndLog(TEXT("HandleLightingAction"), [&]() {
599
+ return HandleLightingAction(RequestId, Action, Payload,
600
+ RequestingSocket);
601
+ }))
602
+ return;
603
+ if (HandleAndLog(TEXT("HandlePerformanceAction"), [&]() {
604
+ return HandlePerformanceAction(RequestId, Action, Payload,
605
+ RequestingSocket);
606
+ }))
607
+ return;
608
+ if (HandleAndLog(TEXT("HandleBuildEnvironmentAction"), [&]() {
609
+ return HandleBuildEnvironmentAction(RequestId, Action, Payload,
610
+ RequestingSocket);
611
+ }))
612
+ return;
613
+ if (HandleAndLog(TEXT("HandleControlEnvironmentAction"), [&]() {
614
+ return HandleControlEnvironmentAction(RequestId, Action, Payload,
615
+ RequestingSocket);
616
+ }))
617
+ return;
618
+
619
+ // Additional consolidated tool handlers
620
+ if (HandleAndLog(TEXT("HandleSystemControlAction"), [&]() {
621
+ return HandleSystemControlAction(RequestId, Action, Payload,
622
+ RequestingSocket);
623
+ }))
624
+ return;
625
+ if (HandleAndLog(TEXT("HandleConsoleCommandAction"), [&]() {
626
+ return HandleConsoleCommandAction(RequestId, Action, Payload,
627
+ RequestingSocket);
628
+ }))
629
+ return;
630
+ if (HandleAndLog(TEXT("HandleInspectAction"), [&]() {
631
+ return HandleInspectAction(RequestId, Action, Payload,
632
+ RequestingSocket);
633
+ }))
634
+ return;
635
+
636
+ // 1. Editor Authoring & Graph Editing
637
+ if (HandleAndLog(TEXT("HandleBlueprintGraphAction"), [&]() {
638
+ return HandleBlueprintGraphAction(RequestId, Action, Payload,
639
+ RequestingSocket);
640
+ }))
641
+ return;
642
+ if (HandleAndLog(TEXT("HandleNiagaraGraphAction"), [&]() {
643
+ return HandleNiagaraGraphAction(RequestId, Action, Payload,
644
+ RequestingSocket);
645
+ }))
646
+ return;
647
+ if (HandleAndLog(TEXT("HandleMaterialGraphAction"), [&]() {
648
+ return HandleMaterialGraphAction(RequestId, Action, Payload,
649
+ RequestingSocket);
650
+ }))
651
+ return;
652
+ if (HandleAndLog(TEXT("HandleBehaviorTreeAction"), [&]() {
653
+ return HandleBehaviorTreeAction(RequestId, Action, Payload,
654
+ RequestingSocket);
655
+ }))
656
+ return;
657
+ if (HandleAndLog(TEXT("HandleWorldPartitionAction"), [&]() {
658
+ return HandleWorldPartitionAction(RequestId, Action, Payload,
659
+ RequestingSocket);
660
+ }))
661
+ return;
662
+ if (HandleAndLog(TEXT("HandleRenderAction"), [&]() {
663
+ return HandleRenderAction(RequestId, Action, Payload,
664
+ RequestingSocket);
665
+ }))
666
+ return;
667
+
668
+ // 2. Execution & Build / Test Pipeline
669
+ if (HandleAndLog(TEXT("HandlePipelineAction"), [&]() {
670
+ return HandlePipelineAction(RequestId, Action, Payload,
671
+ RequestingSocket);
672
+ }))
673
+ return;
674
+ if (HandleAndLog(TEXT("HandleTestAction"), [&]() {
675
+ return HandleTestAction(RequestId, Action, Payload,
676
+ RequestingSocket);
677
+ }))
678
+ return;
679
+
680
+ // 3. Observability, Logs, Debugging & History
681
+ if (HandleAndLog(TEXT("HandleLogAction"), [&]() {
682
+ return HandleLogAction(RequestId, Action, Payload,
683
+ RequestingSocket);
684
+ }))
685
+ return;
686
+ if (HandleAndLog(TEXT("HandleDebugAction"), [&]() {
687
+ return HandleDebugAction(RequestId, Action, Payload,
688
+ RequestingSocket);
689
+ }))
690
+ return;
691
+ if (HandleAndLog(TEXT("HandleAssetQueryAction"), [&]() {
692
+ return HandleAssetQueryAction(RequestId, Action, Payload,
693
+ RequestingSocket);
694
+ }))
695
+ return;
696
+ if (HandleAndLog(TEXT("HandleInsightsAction"), [&]() {
697
+ return HandleInsightsAction(RequestId, Action, Payload,
698
+ RequestingSocket);
699
+ }))
700
+ return;
701
+
702
+ // Unhandled action
703
+ bDispatchHandled = true;
704
+ ConsumedHandlerLabel = TEXT("SendAutomationError (unknown action)");
705
+ SendAutomationError(
706
+ RequestingSocket, RequestId,
707
+ FString::Printf(TEXT("Unknown automation action: %s"), *Action),
708
+ TEXT("UNKNOWN_ACTION"));
709
+ } catch (const std::exception &E) {
710
+ UE_LOG(LogMcpAutomationBridgeSubsystem, Error,
711
+ TEXT("Unhandled exception processing automation request %s: %s"),
712
+ *RequestId, ANSI_TO_TCHAR(E.what()));
713
+ bDispatchHandled = true;
714
+ ConsumedHandlerLabel = TEXT("Exception handler");
715
+ SendAutomationError(
716
+ RequestingSocket, RequestId,
717
+ FString::Printf(TEXT("Internal error: %s"), ANSI_TO_TCHAR(E.what())),
718
+ TEXT("INTERNAL_ERROR"));
719
+ } catch (...) {
720
+ UE_LOG(
721
+ LogMcpAutomationBridgeSubsystem, Error,
722
+ TEXT("Unhandled unknown exception processing automation request %s"),
723
+ *RequestId);
724
+ bDispatchHandled = true;
725
+ ConsumedHandlerLabel = TEXT("Exception handler (unknown)");
726
+ SendAutomationError(RequestingSocket, RequestId,
727
+ TEXT("Internal error (unknown)."),
728
+ TEXT("INTERNAL_ERROR"));
729
+ }
730
+ }
731
+ }
732
+
733
+ // ProcessPendingAutomationRequests() intentionally implemented in the
734
+ // primary subsystem translation unit (McpAutomationBridgeSubsystem.cpp)
735
+ // to ensure the linker emits the symbol into the module's object file.