ultimate-unreal-engine-mcp 0.1.3 → 0.1.4

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 (32) hide show
  1. package/package.json +1 -1
  2. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAICommands.cpp.disabled → MCPAICommands.cpp} +48 -56
  3. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAICommands.h.disabled → MCPAICommands.h} +7 -1
  4. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAnimationCommands.cpp.disabled → MCPAnimationCommands.cpp} +193 -80
  5. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAnimationCommands.h.disabled → MCPAnimationCommands.h} +4 -1
  6. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAudioCommands.cpp.disabled → MCPAudioCommands.cpp} +824 -624
  7. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAudioCommands.h.disabled → MCPAudioCommands.h} +26 -22
  8. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPBridgeSubsystem.cpp +29 -32
  9. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPChaosCommands.cpp.disabled → MCPChaosCommands.cpp} +797 -771
  10. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPChaosCommands.h.disabled → MCPChaosCommands.h} +28 -22
  11. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPGASCommands.cpp.disabled → MCPGASCommands.cpp} +303 -133
  12. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPGASCommands.h.disabled → MCPGASCommands.h} +7 -1
  13. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPImportExportCommands.cpp.disabled → MCPImportExportCommands.cpp} +279 -115
  14. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPImportExportCommands.h.disabled → MCPImportExportCommands.h} +1 -1
  15. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPLiveLinkCommands.cpp +1126 -0
  16. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPLiveLinkCommands.h.disabled → MCPLiveLinkCommands.h} +22 -22
  17. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMaterialCommands.cpp.disabled → MCPMaterialCommands.cpp} +528 -520
  18. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMaterialCommands.h.disabled → MCPMaterialCommands.h} +24 -22
  19. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMotionDesignCommands.cpp.disabled → MCPMotionDesignCommands.cpp} +357 -229
  20. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMotionDesignCommands.h.disabled → MCPMotionDesignCommands.h} +11 -3
  21. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPMovieRenderCommands.cpp +1136 -0
  22. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMovieRenderCommands.h.disabled → MCPMovieRenderCommands.h} +16 -16
  23. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPNetworkingCommands.cpp.disabled → MCPNetworkingCommands.cpp} +574 -482
  24. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPNetworkingCommands.h.disabled → MCPNetworkingCommands.h} +20 -16
  25. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPValidationCommands.cpp +640 -0
  26. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPValidationCommands.h.disabled → MCPValidationCommands.h} +26 -22
  27. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPWorldPartitionCommands.cpp.disabled → MCPWorldPartitionCommands.cpp} +154 -28
  28. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPWorldPartitionCommands.h.disabled → MCPWorldPartitionCommands.h} +5 -1
  29. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/ReflectionHelpers.h +302 -0
  30. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/Optional/MCPLiveLinkCommands.cpp.disabled +0 -504
  31. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/Optional/MCPMovieRenderCommands.cpp.disabled +0 -585
  32. package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/Optional/MCPValidationCommands.cpp.disabled +0 -368
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-unreal-engine-mcp",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "MCP server giving AI assistants full access to Unreal Engine 5.7 projects",
5
5
  "type": "module",
6
6
  "engines": {
@@ -1,4 +1,4 @@
1
- // MCPAICommands.cpp (Plan 22-01)
1
+ // MCPAICommands.cpp (Plan 33-04)
2
2
  // Implements five AI system inspection command handlers for the MCP bridge:
3
3
  // ai.behaviorTree -- inspect Behavior Tree node hierarchy, decorators, services (AI-01)
4
4
  // ai.stateTree -- read State Tree states, transitions, and tasks (AI-02)
@@ -11,31 +11,31 @@
11
11
  // asset_path is validated to start with "/Game/" or "/Engine/" before any
12
12
  // StaticLoadObject call to prevent path traversal (T-22-01).
13
13
  // Behavior Tree recursion is capped at 100 levels to prevent DoS (T-22-02).
14
+ //
15
+ // Reflection-based: only ai.stateTree removes StateTree.h and StateTreeTypes.h.
16
+ // BehaviorTree/Blackboard/EQS/NavMesh handlers KEEP their direct core module includes.
14
17
 
15
18
  #include "MCPAICommands.h"
19
+ #include "ReflectionHelpers.h"
16
20
 
17
- // Behavior Tree headers
21
+ // Behavior Tree headers (AIModule -- in Build.cs, always available)
18
22
  #include "BehaviorTree/BehaviorTree.h"
19
23
  #include "BehaviorTree/BTCompositeNode.h"
20
24
  #include "BehaviorTree/BTDecorator.h"
21
25
  #include "BehaviorTree/BTService.h"
22
26
  #include "BehaviorTree/BTTaskNode.h"
23
27
 
24
- // Blackboard headers
28
+ // Blackboard headers (AIModule -- in Build.cs)
25
29
  #include "BehaviorTree/BlackboardData.h"
26
30
  #include "BehaviorTree/Blackboard/BlackboardKeyType.h"
27
31
 
28
- // State Tree headers
29
- #include "StateTree.h"
30
- #include "StateTreeTypes.h"
31
-
32
- // EQS headers
32
+ // EQS headers (AIModule -- in Build.cs)
33
33
  #include "EnvironmentQuery/EnvQuery.h"
34
34
  #include "EnvironmentQuery/EnvQueryOption.h"
35
35
  #include "EnvironmentQuery/EnvQueryGenerator.h"
36
36
  #include "EnvironmentQuery/EnvQueryTest.h"
37
37
 
38
- // Navigation System headers
38
+ // Navigation System headers (NavigationSystem -- in Build.cs)
39
39
  #include "NavigationSystem.h"
40
40
  #include "NavigationData.h"
41
41
  #include "NavMesh/RecastNavMesh.h"
@@ -90,7 +90,7 @@ static FString BuildAIErrorResponse(const FString& CorrId, const FString& Error)
90
90
  * Validate that asset_path starts with "/Game/" or "/Engine/" to prevent
91
91
  * path traversal attacks (T-22-01).
92
92
  */
93
- static bool IsValidAssetPath(const FString& AssetPath)
93
+ static bool IsValidAIAssetPath(const FString& AssetPath)
94
94
  {
95
95
  return AssetPath.StartsWith(TEXT("/Game/")) || AssetPath.StartsWith(TEXT("/Engine/"));
96
96
  }
@@ -164,20 +164,6 @@ static TSharedPtr<FJsonObject> BuildBTCompositeNodeJson(UBTCompositeNode* Compos
164
164
  ChildrenArray.Add(MakeShared<FJsonValueObject>(ChildJson));
165
165
  }
166
166
  }
167
-
168
- // Each child slot may also have decorators attached to the child edge.
169
- for (UBTDecorator* ChildDecorator : ChildInfo.Decorators)
170
- {
171
- if (!ChildDecorator)
172
- {
173
- continue;
174
- }
175
- TSharedPtr<FJsonObject> DecObj = MakeShared<FJsonObject>();
176
- DecObj->SetStringField(TEXT("node_name"), ChildDecorator->GetNodeName());
177
- DecObj->SetStringField(TEXT("node_class"), ChildDecorator->GetClass()->GetName());
178
- DecObj->SetStringField(TEXT("node_type"), TEXT("Decorator"));
179
- // Edge decorators are reported as children of the composite for context.
180
- }
181
167
  }
182
168
  }
183
169
  else
@@ -250,6 +236,7 @@ void RegisterAICommands(FMCPCommandRouter& Router)
250
236
  // Returns: asset_path, root_node (recursive tree with node_name, node_class,
251
237
  // node_type, decorators[], services[], children[]).
252
238
  // Recursion limited to 100 levels (T-22-02).
239
+ // Uses core AIModule types -- direct includes (in Build.cs).
253
240
  // -----------------------------------------------------------------------
254
241
  Router.RegisterHandler(TEXT("ai.behaviorTree"), [](TSharedPtr<FJsonObject> Cmd, FMCPResponseSender SendResponse)
255
242
  {
@@ -271,7 +258,7 @@ void RegisterAICommands(FMCPCommandRouter& Router)
271
258
  }
272
259
 
273
260
  // Validate path prefix (T-22-01).
274
- if (!IsValidAssetPath(AssetPath))
261
+ if (!IsValidAIAssetPath(AssetPath))
275
262
  {
276
263
  SendResponse(BuildAIErrorResponse(CorrId, TEXT("invalid_asset_path")) + TEXT("\n"));
277
264
  return;
@@ -316,15 +303,29 @@ void RegisterAICommands(FMCPCommandRouter& Router)
316
303
  // Required payload field: asset_path (must start with /Game/ or /Engine/).
317
304
  // Returns: asset_path, states[] (name, type, parent_state, tasks[], transitions[]).
318
305
  //
319
- // UE 5.7 API Note: UStateTree stores its states in FStateTreeEditorData
320
- // (accessible via StateTree->EditorData when WITH_EDITORONLY_DATA is defined).
321
- // In compiled/cooked form the states are baked into FStateTreeStateHandle arrays.
322
- // We use EditorData here since this handler runs in the editor context only.
306
+ // REFLECTION-BASED: StateTree.h and StateTreeTypes.h are NOT included.
307
+ // UStateTree is located at runtime via FindObject<UClass>.
308
+ // Returns module_not_available when StateTreeModule is not loaded.
323
309
  // -----------------------------------------------------------------------
324
310
  Router.RegisterHandler(TEXT("ai.stateTree"), [](TSharedPtr<FJsonObject> Cmd, FMCPResponseSender SendResponse)
325
311
  {
326
312
  const FString CorrId = Cmd->GetStringField(TEXT("correlationId"));
327
313
 
314
+ // Runtime check: StateTreeModule must be loaded.
315
+ if (!MCPReflect::CheckModuleLoaded(TEXT("StateTreeModule")))
316
+ {
317
+ MCPReflect::SendModuleNotAvailable(SendResponse, CorrId, TEXT("StateTreeModule"));
318
+ return;
319
+ }
320
+
321
+ // Find UStateTree class via reflection.
322
+ UClass* StateTreeClass = FindObject<UClass>(nullptr, TEXT("/Script/StateTreeModule.StateTree"));
323
+ if (!StateTreeClass)
324
+ {
325
+ SendResponse(BuildAIErrorResponse(CorrId, TEXT("StateTree_class_not_found")) + TEXT("\n"));
326
+ return;
327
+ }
328
+
328
329
  // Extract payload.
329
330
  TSharedPtr<FJsonObject> Payload;
330
331
  const TSharedPtr<FJsonValue>* PayloadVal = Cmd->Values.Find(TEXT("payload"));
@@ -341,14 +342,14 @@ void RegisterAICommands(FMCPCommandRouter& Router)
341
342
  }
342
343
 
343
344
  // Validate path prefix (T-22-01).
344
- if (!IsValidAssetPath(AssetPath))
345
+ if (!IsValidAIAssetPath(AssetPath))
345
346
  {
346
347
  SendResponse(BuildAIErrorResponse(CorrId, TEXT("invalid_asset_path")) + TEXT("\n"));
347
348
  return;
348
349
  }
349
350
 
350
- // Load the StateTree asset.
351
- UStateTree* StateTree = Cast<UStateTree>(StaticLoadObject(UStateTree::StaticClass(), nullptr, *AssetPath));
351
+ // Load the StateTree asset as UObject (no direct class cast needed).
352
+ UObject* StateTree = StaticLoadObject(StateTreeClass, nullptr, *AssetPath);
352
353
  if (!StateTree)
353
354
  {
354
355
  SendResponse(BuildAIErrorResponse(CorrId, TEXT("state_tree_not_found")) + TEXT("\n"));
@@ -356,19 +357,16 @@ void RegisterAICommands(FMCPCommandRouter& Router)
356
357
  }
357
358
 
358
359
  // Access states via EditorData (editor-only property, available in editor context).
359
- // UStateTree exposes EditorData as a UObject* property; cast to UStateTreeEditorData
360
- // to get the States array. If EditorData is not available (cooked build), fall back
361
- // to reporting only the asset name and state count from the baked structure.
360
+ // UStateTree exposes EditorData as a UObject* property.
362
361
  TArray<TSharedPtr<FJsonValue>> StatesArray;
363
362
 
364
363
  #if WITH_EDITORONLY_DATA
365
- if (StateTree->EditorData)
366
- {
367
- // UStateTreeEditorData stores states in a TArray<FStateTreeStateBase*> or
368
- // TArray<FStateTreeEditorState>. Access via reflection to remain resilient
369
- // to minor API changes across UE 5.x point releases.
370
- UObject* EditorDataObj = StateTree->EditorData;
364
+ // Access EditorData via FProperty reflection.
365
+ FObjectProperty* EditorDataProp = CastField<FObjectProperty>(StateTree->GetClass()->FindPropertyByName(TEXT("EditorData")));
366
+ UObject* EditorDataObj = EditorDataProp ? EditorDataProp->GetObjectPropertyValue_InContainer(StateTree) : nullptr;
371
367
 
368
+ if (EditorDataObj)
369
+ {
372
370
  // Walk the states using the property system to remain compatible with
373
371
  // UE 5.7 API changes. Look for an array property named "States" on EditorData.
374
372
  FArrayProperty* StatesProp = nullptr;
@@ -455,15 +453,14 @@ void RegisterAICommands(FMCPCommandRouter& Router)
455
453
  FStructProperty* TaskElemProp = CastField<FStructProperty>(TasksProp->Inner);
456
454
  for (int32 j = 0; j < TasksHelper.Num(); ++j)
457
455
  {
458
- void* TaskPtr = TasksHelper.GetRawPtr(j);
459
456
  FString TaskClass = TEXT("UnknownTask");
460
457
  if (TaskElemProp)
461
458
  {
462
- // Try to get the task class name from the Instance property.
463
- FStructProperty* InstanceProp = CastField<FStructProperty>(TaskElemProp->Struct->FindPropertyByName(TEXT("Node")));
464
- if (InstanceProp)
459
+ // Try to get the task class name from the Node property.
460
+ FStructProperty* NodeProp = CastField<FStructProperty>(TaskElemProp->Struct->FindPropertyByName(TEXT("Node")));
461
+ if (NodeProp)
465
462
  {
466
- TaskClass = InstanceProp->Struct->GetName();
463
+ TaskClass = NodeProp->Struct->GetName();
467
464
  }
468
465
  else
469
466
  {
@@ -541,12 +538,6 @@ void RegisterAICommands(FMCPCommandRouter& Router)
541
538
  // If we couldn't extract states via EditorData, report what we can.
542
539
  if (StatesArray.IsEmpty())
543
540
  {
544
- // UStateTree baked data: StateTree->NumStates (available at runtime).
545
- // Report state count as the only available info without editor data.
546
- int32 NumStates = 0;
547
- #if WITH_EDITORONLY_DATA
548
- // Already attempted above; fall through.
549
- #endif
550
541
  UE_LOG(LogTemp, Warning, TEXT("[MCPBridge] ai.stateTree: No editor state data available for '%s'."), *AssetPath);
551
542
  }
552
543
 
@@ -562,6 +553,7 @@ void RegisterAICommands(FMCPCommandRouter& Router)
562
553
  // Lists Blackboard keys with their types and instance-sync flags.
563
554
  // Required payload field: asset_path (must start with /Game/ or /Engine/).
564
555
  // Returns: asset_path, keys[] (key_name, key_type, instance_synced), parent_asset.
556
+ // Uses core AIModule types -- direct includes (in Build.cs).
565
557
  // -----------------------------------------------------------------------
566
558
  Router.RegisterHandler(TEXT("ai.blackboard"), [](TSharedPtr<FJsonObject> Cmd, FMCPResponseSender SendResponse)
567
559
  {
@@ -583,7 +575,7 @@ void RegisterAICommands(FMCPCommandRouter& Router)
583
575
  }
584
576
 
585
577
  // Validate path prefix (T-22-01).
586
- if (!IsValidAssetPath(AssetPath))
578
+ if (!IsValidAIAssetPath(AssetPath))
587
579
  {
588
580
  SendResponse(BuildAIErrorResponse(CorrId, TEXT("invalid_asset_path")) + TEXT("\n"));
589
581
  return;
@@ -646,6 +638,7 @@ void RegisterAICommands(FMCPCommandRouter& Router)
646
638
  // Inspects an EQS query template: options, generators, tests, scoring.
647
639
  // Required payload field: asset_path (must start with /Game/ or /Engine/).
648
640
  // Returns: asset_path, options[] (generator_class, generator_name, tests[]).
641
+ // Uses core AIModule types -- direct includes (in Build.cs).
649
642
  // -----------------------------------------------------------------------
650
643
  Router.RegisterHandler(TEXT("ai.eqs"), [](TSharedPtr<FJsonObject> Cmd, FMCPResponseSender SendResponse)
651
644
  {
@@ -667,7 +660,7 @@ void RegisterAICommands(FMCPCommandRouter& Router)
667
660
  }
668
661
 
669
662
  // Validate path prefix (T-22-01).
670
- if (!IsValidAssetPath(AssetPath))
663
+ if (!IsValidAIAssetPath(AssetPath))
671
664
  {
672
665
  SendResponse(BuildAIErrorResponse(CorrId, TEXT("invalid_asset_path")) + TEXT("\n"));
673
666
  return;
@@ -754,7 +747,7 @@ void RegisterAICommands(FMCPCommandRouter& Router)
754
747
  // Returns: build_status, bounds {min, max}, nav_data_class, agent_radius,
755
748
  // agent_height, and optionally reachability {is_reachable, path_length, path_cost}.
756
749
  // Single synchronous path query only (T-22-03); no batch queries.
757
- // NavMesh data is editor-only and not sensitive (T-22-04, accepted).
750
+ // Uses core NavigationSystem types -- direct includes (in Build.cs).
758
751
  // -----------------------------------------------------------------------
759
752
  Router.RegisterHandler(TEXT("ai.navmesh"), [](TSharedPtr<FJsonObject> Cmd, FMCPResponseSender SendResponse)
760
753
  {
@@ -838,7 +831,6 @@ void RegisterAICommands(FMCPCommandRouter& Router)
838
831
  NavDataClass = NavData->GetClass()->GetName();
839
832
 
840
833
  // Determine build status from the nav data.
841
- // UNavigationSystemV1 tracks build status per data actor.
842
834
  BuildStatus = NavData->IsRegistered() ? TEXT("built") : TEXT("not_built");
843
835
 
844
836
  // Get bounds from the nav data's runtime bounding box.
@@ -1,9 +1,15 @@
1
- // MCPAICommands.h (Plan 22-01)
1
+ // MCPAICommands.h (Plan 33-04)
2
2
  // Declares the registration function for all AI system inspection MCP command handlers.
3
3
  // Handlers: ai.behaviorTree, ai.stateTree, ai.blackboard, ai.eqs, ai.navmesh
4
4
  //
5
5
  // Call RegisterAICommands(*Router) in MCPBridgeSubsystem::Initialize()
6
6
  // BEFORE the TCP server starts accepting connections.
7
+ //
8
+ // All handlers compile without optional plugin headers.
9
+ // ai.behaviorTree, ai.blackboard, ai.eqs, ai.navmesh use direct includes
10
+ // from the core AIModule and NavigationSystem modules (in Build.cs).
11
+ // ai.stateTree uses runtime reflection to locate StateTree types and returns
12
+ // "module_not_available" when the StateTreeModule is not loaded.
7
13
 
8
14
  #pragma once
9
15