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.
- package/package.json +1 -1
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAICommands.cpp.disabled → MCPAICommands.cpp} +48 -56
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAICommands.h.disabled → MCPAICommands.h} +7 -1
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAnimationCommands.cpp.disabled → MCPAnimationCommands.cpp} +193 -80
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAnimationCommands.h.disabled → MCPAnimationCommands.h} +4 -1
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAudioCommands.cpp.disabled → MCPAudioCommands.cpp} +824 -624
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPAudioCommands.h.disabled → MCPAudioCommands.h} +26 -22
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPBridgeSubsystem.cpp +29 -32
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPChaosCommands.cpp.disabled → MCPChaosCommands.cpp} +797 -771
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPChaosCommands.h.disabled → MCPChaosCommands.h} +28 -22
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPGASCommands.cpp.disabled → MCPGASCommands.cpp} +303 -133
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPGASCommands.h.disabled → MCPGASCommands.h} +7 -1
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPImportExportCommands.cpp.disabled → MCPImportExportCommands.cpp} +279 -115
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPImportExportCommands.h.disabled → MCPImportExportCommands.h} +1 -1
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPLiveLinkCommands.cpp +1126 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPLiveLinkCommands.h.disabled → MCPLiveLinkCommands.h} +22 -22
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMaterialCommands.cpp.disabled → MCPMaterialCommands.cpp} +528 -520
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMaterialCommands.h.disabled → MCPMaterialCommands.h} +24 -22
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMotionDesignCommands.cpp.disabled → MCPMotionDesignCommands.cpp} +357 -229
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMotionDesignCommands.h.disabled → MCPMotionDesignCommands.h} +11 -3
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPMovieRenderCommands.cpp +1136 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPMovieRenderCommands.h.disabled → MCPMovieRenderCommands.h} +16 -16
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPNetworkingCommands.cpp.disabled → MCPNetworkingCommands.cpp} +574 -482
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPNetworkingCommands.h.disabled → MCPNetworkingCommands.h} +20 -16
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPValidationCommands.cpp +640 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPValidationCommands.h.disabled → MCPValidationCommands.h} +26 -22
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPWorldPartitionCommands.cpp.disabled → MCPWorldPartitionCommands.cpp} +154 -28
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/{Optional/MCPWorldPartitionCommands.h.disabled → MCPWorldPartitionCommands.h} +5 -1
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/ReflectionHelpers.h +302 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/Optional/MCPLiveLinkCommands.cpp.disabled +0 -504
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/Optional/MCPMovieRenderCommands.cpp.disabled +0 -585
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/Optional/MCPValidationCommands.cpp.disabled +0 -368
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// MCPAICommands.cpp (Plan
|
|
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
|
-
//
|
|
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
|
|
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 (!
|
|
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
|
-
//
|
|
320
|
-
//
|
|
321
|
-
//
|
|
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 (!
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
|
463
|
-
FStructProperty*
|
|
464
|
-
if (
|
|
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 =
|
|
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 (!
|
|
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 (!
|
|
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
|
-
//
|
|
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
|
|
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
|
|