unreal-engine-mcp-server 0.4.6 → 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 +269 -22
  29. package/CONTRIBUTING.md +140 -0
  30. package/README.md +166 -72
  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 -604
  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 +5475 -1627
  97. package/dist/tools/consolidated-tool-definitions.js +829 -482
  98. package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
  99. package/dist/tools/consolidated-tool-handlers.js +211 -1009
  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 +45 -0
  161. package/dist/tools/logs.js +210 -0
  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 +195 -11
  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 -649
  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 -500
  316. package/src/tools/consolidated-tool-handlers.ts +272 -1122
  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 +219 -0
  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 +250 -13
  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 -572
  431. package/smithery.yaml +0 -29
  432. package/src/tools/build_environment_advanced.ts +0 -732
  433. package/src/tools/rc.ts +0 -515
  434. package/src/tools/visual.ts +0 -281
  435. package/src/utils/http.ts +0 -187
  436. package/src/utils/python-output.ts +0 -351
  437. package/src/utils/python.ts +0 -3
  438. package/src/utils/stdio-redirect.ts +0 -18
@@ -1,281 +0,0 @@
1
- import { UnrealBridge } from '../unreal-bridge.js';
2
- import { loadEnv } from '../types/env.js';
3
- import { Logger } from '../utils/logger.js';
4
- import { coerceStringArray, interpretStandardResult } from '../utils/result-helpers.js';
5
- import { promises as fs } from 'fs';
6
- import path from 'path';
7
-
8
- export class VisualTools {
9
- private env = loadEnv();
10
- private log = new Logger('VisualTools');
11
- constructor(private bridge: UnrealBridge) {}
12
-
13
- // Take a screenshot of viewport (high res or standard). Returns path and base64 (truncated)
14
- async takeScreenshot(params: { resolution?: string }) {
15
- const res = params.resolution && /^\d+x\d+$/i.test(params.resolution) ? params.resolution : '';
16
- const primaryCommand = res ? `HighResShot ${res}` : 'Shot';
17
- const captureStartedAt = Date.now();
18
- try {
19
- const firstAttempt = await this.bridge.executeConsoleCommand(primaryCommand);
20
- const firstSummary = this.bridge.summarizeConsoleCommand(primaryCommand, firstAttempt);
21
-
22
- if (!res) {
23
- const output = (firstSummary.output || '').toLowerCase();
24
- const badInput = output.includes('bad input') || output.includes('unrecognized command');
25
- const hasErrorLine = firstSummary.logLines?.some(line => /error:/i.test(line));
26
- if (badInput || hasErrorLine) {
27
- this.log.debug(`Screenshot primary command reported an error (${firstSummary.output || 'no output'})`);
28
- }
29
- }
30
- // Give the engine a moment to write the file (UE can flush asynchronously)
31
- await new Promise(r => setTimeout(r, 1200));
32
- const p = await this.findLatestScreenshot(captureStartedAt);
33
- if (!p) {
34
- this.log.warn('Screenshot captured but output file was not found');
35
- return { success: true, message: 'Screenshot triggered, but could not locate output file' };
36
- }
37
- let b64: string | undefined;
38
- let truncated = false;
39
- let sizeBytes: number | undefined;
40
- let mime: string | undefined;
41
- try {
42
- const stat = await fs.stat(p);
43
- sizeBytes = stat.size;
44
- const max = 1024 * 1024; // 1 MiB cap for inline payloads
45
- if (stat.size <= max) {
46
- const buf = await fs.readFile(p);
47
- b64 = buf.toString('base64');
48
- } else {
49
- truncated = true;
50
- }
51
- const ext = path.extname(p).toLowerCase();
52
- if (ext === '.png') mime = 'image/png';
53
- else if (ext === '.jpg' || ext === '.jpeg') mime = 'image/jpeg';
54
- else if (ext === '.bmp') mime = 'image/bmp';
55
- } catch {}
56
- return {
57
- success: true,
58
- imagePath: p.replace(/\\/g, '/'),
59
- imageMimeType: mime,
60
- imageSizeBytes: sizeBytes,
61
- imageBase64: b64,
62
- imageBase64Truncated: truncated
63
- };
64
- } catch (err: any) {
65
- return { success: false, error: String(err?.message || err) };
66
- }
67
- }
68
-
69
- private async getEngineScreenshotDirectories(): Promise<string[]> {
70
- const python = `
71
- import unreal
72
- import json
73
- import os
74
-
75
- result = {
76
- "success": True,
77
- "message": "",
78
- "error": "",
79
- "directories": [],
80
- "warnings": [],
81
- "details": []
82
- }
83
-
84
- def finalize():
85
- data = dict(result)
86
- if data.get("success"):
87
- if not data.get("message"):
88
- data["message"] = "Collected screenshot directories"
89
- data.pop("error", None)
90
- else:
91
- if not data.get("error"):
92
- data["error"] = data.get("message") or "Failed to collect screenshot directories"
93
- if not data.get("message"):
94
- data["message"] = data["error"]
95
- if not data.get("warnings"):
96
- data.pop("warnings", None)
97
- if not data.get("details"):
98
- data.pop("details", None)
99
- if not data.get("directories"):
100
- data.pop("directories", None)
101
- return data
102
-
103
- def add_path(candidate, note=None):
104
- if not candidate:
105
- return
106
- try:
107
- abs_path = os.path.abspath(os.path.normpath(candidate))
108
- except Exception as normalize_error:
109
- result["warnings"].append(f"Failed to normalize path {candidate}: {normalize_error}")
110
- return
111
- if abs_path not in result["directories"]:
112
- result["directories"].append(abs_path)
113
- if note:
114
- result["details"].append(f"{note}: {abs_path}")
115
- else:
116
- result["details"].append(f"Discovered screenshot directory: {abs_path}")
117
-
118
- try:
119
- automation_dir = unreal.AutomationLibrary.get_screenshot_directory()
120
- add_path(automation_dir, "Automation screenshot directory")
121
- except Exception as automation_error:
122
- result["warnings"].append(f"Automation screenshot directory unavailable: {automation_error}")
123
-
124
- try:
125
- project_saved = unreal.Paths.project_saved_dir()
126
- add_path(project_saved, "Project Saved directory")
127
- if project_saved:
128
- add_path(os.path.join(project_saved, 'Screenshots'), "Project Saved screenshots")
129
- add_path(os.path.join(project_saved, 'Screenshots', 'Windows'), "Project Saved Windows screenshots")
130
- add_path(os.path.join(project_saved, 'Screenshots', 'WindowsEditor'), "Project Saved WindowsEditor screenshots")
131
- try:
132
- platform_name = unreal.SystemLibrary.get_platform_user_name()
133
- if platform_name:
134
- add_path(os.path.join(project_saved, 'Screenshots', platform_name), f"Project Saved screenshots for {platform_name}")
135
- add_path(os.path.join(project_saved, 'Screenshots', f"{platform_name}Editor"), f"Project Saved editor screenshots for {platform_name}")
136
- except Exception as platform_error:
137
- result["warnings"].append(f"Failed to resolve platform-specific screenshot directories: {platform_error}")
138
- except Exception as saved_error:
139
- result["warnings"].append(f"Project Saved directory unavailable: {saved_error}")
140
-
141
- try:
142
- project_file = unreal.Paths.get_project_file_path()
143
- if project_file:
144
- project_dir = os.path.dirname(project_file)
145
- add_path(os.path.join(project_dir, 'Saved', 'Screenshots'), "Project directory screenshots")
146
- add_path(os.path.join(project_dir, 'Saved', 'Screenshots', 'Windows'), "Project directory Windows screenshots")
147
- add_path(os.path.join(project_dir, 'Saved', 'Screenshots', 'WindowsEditor'), "Project directory WindowsEditor screenshots")
148
- except Exception as project_error:
149
- result["warnings"].append(f"Project directory screenshots unavailable: {project_error}")
150
-
151
- if not result["directories"]:
152
- result["warnings"].append("No screenshot directories discovered")
153
-
154
- print('RESULT:' + json.dumps(finalize()))
155
- `.trim()
156
- .replace(/\r?\n/g, '\n');
157
-
158
- try {
159
- const response = await this.bridge.executePython(python);
160
- const interpreted = interpretStandardResult(response, {
161
- successMessage: 'Collected screenshot directories',
162
- failureMessage: 'Failed to collect screenshot directories'
163
- });
164
-
165
- if (interpreted.details) {
166
- for (const entry of interpreted.details) {
167
- this.log.debug(entry);
168
- }
169
- }
170
-
171
- if (interpreted.warnings) {
172
- for (const warning of interpreted.warnings) {
173
- this.log.debug(`Screenshot directory warning: ${warning}`);
174
- }
175
- }
176
-
177
- const directories = coerceStringArray(interpreted.payload.directories);
178
- if (directories?.length) {
179
- return directories;
180
- }
181
-
182
- if (!interpreted.success && interpreted.error) {
183
- this.log.warn(`Screenshot path probe failed: ${interpreted.error}`);
184
- }
185
-
186
- if (interpreted.rawText) {
187
- try {
188
- const fallback = JSON.parse(interpreted.rawText);
189
- const fallbackDirs = coerceStringArray(fallback);
190
- if (fallbackDirs?.length) {
191
- return fallbackDirs;
192
- }
193
- } catch {}
194
- }
195
- } catch (err) {
196
- this.log.debug('Screenshot path probe failed', err);
197
- }
198
- return [];
199
- }
200
-
201
- private async findLatestScreenshot(since?: number): Promise<string | null> {
202
- // Try env override, otherwise look in common UE Saved/Screenshots folder under project
203
- const candidates: string[] = [];
204
- const seen = new Set<string>();
205
- const addCandidate = (candidate?: string | null) => {
206
- if (!candidate) return;
207
- const normalized = path.isAbsolute(candidate)
208
- ? path.normalize(candidate)
209
- : path.resolve(candidate);
210
- if (!seen.has(normalized)) {
211
- seen.add(normalized);
212
- candidates.push(normalized);
213
- }
214
- };
215
-
216
- if (this.env.UE_SCREENSHOT_DIR) addCandidate(this.env.UE_SCREENSHOT_DIR);
217
- if (this.env.UE_PROJECT_PATH) {
218
- const projectDir = path.dirname(this.env.UE_PROJECT_PATH);
219
- addCandidate(path.join(projectDir, 'Saved', 'Screenshots'));
220
- addCandidate(path.join(projectDir, 'Saved', 'Screenshots', 'Windows'));
221
- addCandidate(path.join(projectDir, 'Saved', 'Screenshots', 'WindowsEditor'));
222
- }
223
-
224
- const engineDirs = await this.getEngineScreenshotDirectories();
225
- for (const dir of engineDirs) {
226
- addCandidate(dir);
227
- }
228
-
229
- // Fallback: common locations relative to current working directory
230
- addCandidate(path.join(process.cwd(), 'Saved', 'Screenshots'));
231
- addCandidate(path.join(process.cwd(), 'Saved', 'Screenshots', 'Windows'));
232
- addCandidate(path.join(process.cwd(), 'Saved', 'Screenshots', 'WindowsEditor'));
233
-
234
- const searchDirs = new Set<string>();
235
- const queue: string[] = [...candidates];
236
- while (queue.length) {
237
- const candidate = queue.pop();
238
- if (!candidate || searchDirs.has(candidate)) continue;
239
- searchDirs.add(candidate);
240
- try {
241
- const entries = await fs.readdir(candidate, { withFileTypes: true });
242
- for (const entry of entries) {
243
- if (entry.isDirectory()) {
244
- queue.push(path.join(candidate, entry.name));
245
- }
246
- }
247
- } catch {}
248
- }
249
-
250
- let latest: { path: string; mtime: number } | null = null;
251
- let latestSince: { path: string; mtime: number } | null = null;
252
- const cutoff = since ? since - 2000 : undefined; // allow slight clock drift
253
-
254
- for (const dirPath of searchDirs) {
255
- let entries: string[];
256
- try {
257
- entries = await fs.readdir(dirPath);
258
- } catch {
259
- continue;
260
- }
261
- for (const entry of entries) {
262
- const fp = path.join(dirPath, entry);
263
- if (!/\.(png|jpg|jpeg|bmp)$/i.test(fp)) continue;
264
- try {
265
- const st = await fs.stat(fp);
266
- const info = { path: fp, mtime: st.mtimeMs };
267
- if (!latest || info.mtime > latest.mtime) {
268
- latest = info;
269
- }
270
- if (cutoff !== undefined && st.mtimeMs >= cutoff) {
271
- if (!latestSince || info.mtime > latestSince.mtime) {
272
- latestSince = info;
273
- }
274
- }
275
- } catch {}
276
- }
277
- }
278
- const chosen = latestSince || latest;
279
- return chosen?.path || null;
280
- }
281
- }
package/src/utils/http.ts DELETED
@@ -1,187 +0,0 @@
1
- import axios, { AxiosInstance } from 'axios';
2
- import http from 'http';
3
- import https from 'https';
4
- import { Logger } from './logger.js';
5
-
6
- /**
7
- * Simple in-memory cache for HTTP responses
8
- * Based on best practices from Axios optimization guides
9
- */
10
- interface CacheEntry {
11
- data: any;
12
- timestamp: number;
13
- ttl: number;
14
- }
15
-
16
- class SimpleCache {
17
- private cache = new Map<string, CacheEntry>();
18
- private readonly maxSize = 100;
19
-
20
- set(key: string, data: any, ttl: number = 60000): void {
21
- // Prevent unbounded growth
22
- if (this.cache.size >= this.maxSize) {
23
- const firstKey = this.cache.keys().next().value;
24
- if (firstKey !== undefined) {
25
- this.cache.delete(firstKey);
26
- }
27
- }
28
-
29
- this.cache.set(key, {
30
- data,
31
- timestamp: Date.now(),
32
- ttl
33
- });
34
- }
35
-
36
- get(key: string): any | null {
37
- const entry = this.cache.get(key);
38
- if (!entry) return null;
39
-
40
- // Check if expired
41
- if (Date.now() - entry.timestamp > entry.ttl) {
42
- this.cache.delete(key);
43
- return null;
44
- }
45
-
46
- return entry.data;
47
- }
48
-
49
- clear(): void {
50
- this.cache.clear();
51
- }
52
-
53
- getStats(): { size: number; maxSize: number } {
54
- return { size: this.cache.size, maxSize: this.maxSize };
55
- }
56
- }
57
-
58
- const responseCache = new SimpleCache();
59
-
60
- // Enhanced connection pooling configuration to prevent socket failures
61
- const httpAgent = new http.Agent({
62
- keepAlive: true,
63
- keepAliveMsecs: 60000, // Increased keep-alive time
64
- maxSockets: 20, // Increased socket pool
65
- maxFreeSockets: 10, // More free sockets
66
- timeout: 60000, // Longer timeout
67
- });
68
-
69
- const httpsAgent = new https.Agent({
70
- keepAlive: true,
71
- keepAliveMsecs: 60000, // Increased keep-alive time
72
- maxSockets: 20, // Increased socket pool
73
- maxFreeSockets: 10, // More free sockets
74
- timeout: 60000, // Longer timeout
75
- });
76
-
77
- const log = new Logger('HTTP');
78
-
79
- /**
80
- * Enhanced HTTP client factory with connection pooling and request timing
81
- */
82
- export function createHttpClient(baseURL: string): AxiosInstance {
83
- const client = axios.create({
84
- baseURL,
85
- headers: {
86
- 'Content-Type': 'application/json',
87
- 'Accept': 'application/json'
88
- },
89
- timeout: 15000,
90
- httpAgent,
91
- httpsAgent,
92
- // Ensure proper handling of request body transformation
93
- transformRequest: [(data, headers) => {
94
- // Remove Content-Length if it's set incorrectly
95
- delete headers['Content-Length'];
96
- delete headers['content-length'];
97
-
98
- // Properly stringify JSON data
99
- if (data && typeof data === 'object') {
100
- const jsonStr = JSON.stringify(data);
101
- // Let axios set Content-Length automatically
102
- return jsonStr;
103
- }
104
- return data;
105
- }],
106
- // Optimize response handling
107
- maxContentLength: 50 * 1024 * 1024, // 50MB
108
- maxBodyLength: 50 * 1024 * 1024,
109
- decompress: true
110
- });
111
-
112
- // Request interceptor: timing, caching check, and logging
113
- client.interceptors.request.use(
114
- (config) => {
115
- // Add metadata for performance tracking
116
- (config as any).metadata = { startTime: Date.now() };
117
-
118
- // Check cache for GET requests
119
- if (config.method?.toLowerCase() === 'get' && config.url) {
120
- const cacheKey = `${config.url}:${JSON.stringify(config.params || {})}`;
121
- const cached = responseCache.get(cacheKey);
122
- if (cached) {
123
- log.debug(`[HTTP Cache Hit] ${config.url}`);
124
- // Return cached response
125
- (config as any).cached = cached;
126
- }
127
- }
128
-
129
- return config;
130
- },
131
- (error) => {
132
- log.error('[HTTP Request Error]', error);
133
- return Promise.reject(error);
134
- }
135
- );
136
-
137
- // Response interceptor: timing, caching, and error handling
138
- client.interceptors.response.use(
139
- (response) => {
140
- // Check if we used cached response
141
- if ((response.config as any).cached) {
142
- return Promise.resolve({
143
- ...response,
144
- data: (response.config as any).cached,
145
- status: 200,
146
- statusText: 'OK (Cached)',
147
- headers: {},
148
- config: response.config
149
- });
150
- }
151
-
152
- // Performance tracking
153
- const duration = Date.now() - ((response.config as any).metadata?.startTime || 0);
154
- if (duration > 5000) {
155
- log.warn(`[HTTP Slow] ${response.config.url} took ${duration}ms`);
156
- } else if (duration > 1000) {
157
- log.debug(`[HTTP] ${response.config.url} took ${duration}ms`);
158
- }
159
-
160
- // Cache successful GET responses
161
- if (response.config.method?.toLowerCase() === 'get' &&
162
- response.status === 200 &&
163
- response.config.url) {
164
- const cacheKey = `${response.config.url}:${JSON.stringify(response.config.params || {})}`;
165
- // Cache for 30 seconds by default
166
- responseCache.set(cacheKey, response.data, 30000);
167
- }
168
-
169
- return response;
170
- },
171
- (error) => {
172
- // Enhanced error logging
173
- const duration = Date.now() - ((error.config as any)?.metadata?.startTime || 0);
174
- log.error(`[HTTP Error] ${error.config?.url} failed after ${duration}ms:`, {
175
- status: error.response?.status,
176
- message: error.message,
177
- code: error.code
178
- });
179
- return Promise.reject(error);
180
- }
181
- );
182
-
183
- return client;
184
- }
185
-
186
- // No retry helpers are exported; consolidated command flows rely on
187
- // Unreal's own retry/backoff semantics to avoid duplicate side effects.