Refactor MCPHandler to be a UINTERFACE
This commit is contained in:
@@ -862,8 +862,9 @@ bool FBlueprintMCPServer::ProcessOneRequest()
|
|||||||
GEditor->BeginTransaction(FText::FromString(FString::Printf(TEXT("BlueprintMCP: %s"), *Req->Endpoint)));
|
GEditor->BeginTransaction(FText::FromString(FString::Printf(TEXT("BlueprintMCP: %s"), *Req->Endpoint)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TStrongObjectPtr<UMCPHandler> Handler(NewObject<UMCPHandler>(GetTransientPackage(), *HandlerClass));
|
TStrongObjectPtr<UObject> HandlerObj(NewObject<UObject>(GetTransientPackage(), *HandlerClass));
|
||||||
FString PopulateError = PopulateFromJson(Handler->GetClass(), Handler.Get(), Params.Get());
|
IMCPHandler* Handler = Cast<IMCPHandler>(HandlerObj.Get());
|
||||||
|
FString PopulateError = PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), Params.Get());
|
||||||
if (PopulateError.IsEmpty())
|
if (PopulateError.IsEmpty())
|
||||||
{
|
{
|
||||||
Handler->Handle(Params.Get(), &*Result);
|
Handler->Handle(Params.Get(), &*Result);
|
||||||
@@ -1057,11 +1058,13 @@ void FBlueprintMCPServer::RegisterHandlers()
|
|||||||
|
|
||||||
void FBlueprintMCPServer::BuildMCPHandlerRegistry()
|
void FBlueprintMCPServer::BuildMCPHandlerRegistry()
|
||||||
{
|
{
|
||||||
TArray<UClass*> HandlerClasses;
|
for (TObjectIterator<UClass> It; It; ++It)
|
||||||
GetDerivedClasses(UMCPHandler::StaticClass(), HandlerClasses);
|
|
||||||
|
|
||||||
for (UClass* Class : HandlerClasses)
|
|
||||||
{
|
{
|
||||||
|
UClass* Class = *It;
|
||||||
|
if (!Class->ImplementsInterface(UMCPHandler::StaticClass()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (Class->HasAnyClassFlags(CLASS_Abstract))
|
if (Class->HasAnyClassFlags(CLASS_Abstract))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "BlueprintMCPHandlers_DiffBlueprints.generated.h"
|
#include "BlueprintMCPHandlers_DiffBlueprints.generated.h"
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="diff_blueprints"))
|
UCLASS(meta=(ToolName="diff_blueprints"))
|
||||||
class UMCPHandler_DiffBlueprints : public UMCPHandler
|
class UMCPHandler_DiffBlueprints : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "BlueprintMCPHandlers_Interfaces.generated.h"
|
#include "BlueprintMCPHandlers_Interfaces.generated.h"
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="list_interfaces"))
|
UCLASS(meta=(ToolName="list_interfaces"))
|
||||||
class UMCPHandler_ListInterfaces : public UMCPHandler
|
class UMCPHandler_ListInterfaces : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="add_interface"))
|
UCLASS(meta=(ToolName="add_interface"))
|
||||||
class UMCPHandler_AddInterface : public UMCPHandler
|
class UMCPHandler_AddInterface : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="remove_interface"))
|
UCLASS(meta=(ToolName="remove_interface"))
|
||||||
class UMCPHandler_RemoveInterface : public UMCPHandler
|
class UMCPHandler_RemoveInterface : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ struct FSetPinDefaultEntry
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="set_pin_default"))
|
UCLASS(meta=(ToolName="set_pin_default"))
|
||||||
class UMCPHandler_SetPinDefault : public UMCPHandler
|
class UMCPHandler_SetPinDefault : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ struct FMoveNodeEntry
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="move_node"))
|
UCLASS(meta=(ToolName="move_node"))
|
||||||
class UMCPHandler_MoveNode : public UMCPHandler
|
class UMCPHandler_MoveNode : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="duplicate_nodes"))
|
UCLASS(meta=(ToolName="duplicate_nodes"))
|
||||||
class UMCPHandler_DuplicateNodes : public UMCPHandler
|
class UMCPHandler_DuplicateNodes : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ struct FSpawnNodeEntry
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="spawn_node"))
|
UCLASS(meta=(ToolName="spawn_node"))
|
||||||
class UMCPHandler_SpawnNode : public UMCPHandler
|
class UMCPHandler_SpawnNode : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="get_node_comment"))
|
UCLASS(meta=(ToolName="get_node_comment"))
|
||||||
class UMCPHandler_GetNodeComment : public UMCPHandler
|
class UMCPHandler_GetNodeComment : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="set_node_comment"))
|
UCLASS(meta=(ToolName="set_node_comment"))
|
||||||
class UMCPHandler_SetNodeComment : public UMCPHandler
|
class UMCPHandler_SetNodeComment : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="delete_node"))
|
UCLASS(meta=(ToolName="delete_node"))
|
||||||
class UMCPHandler_DeleteNode : public UMCPHandler
|
class UMCPHandler_DeleteNode : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ struct FConnectPinsEntry
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="connect_pins"))
|
UCLASS(meta=(ToolName="connect_pins"))
|
||||||
class UMCPHandler_ConnectPins : public UMCPHandler
|
class UMCPHandler_ConnectPins : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ struct FDisconnectPinEntry
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="disconnect_pin"))
|
UCLASS(meta=(ToolName="disconnect_pin"))
|
||||||
class UMCPHandler_DisconnectPin : public UMCPHandler
|
class UMCPHandler_DisconnectPin : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="replace_function_calls"))
|
UCLASS(meta=(ToolName="replace_function_calls"))
|
||||||
class UMCPHandler_ReplaceFunctionCalls : public UMCPHandler
|
class UMCPHandler_ReplaceFunctionCalls : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -314,7 +314,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="delete_asset"))
|
UCLASS(meta=(ToolName="delete_asset"))
|
||||||
class UMCPHandler_DeleteAsset : public UMCPHandler
|
class UMCPHandler_DeleteAsset : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -335,7 +335,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="refresh_all_nodes"))
|
UCLASS(meta=(ToolName="refresh_all_nodes"))
|
||||||
class UMCPHandler_RefreshAllNodes : public UMCPHandler
|
class UMCPHandler_RefreshAllNodes : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -353,7 +353,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="change_struct_node_type"))
|
UCLASS(meta=(ToolName="change_struct_node_type"))
|
||||||
class UMCPHandler_ChangeStructNodeType : public UMCPHandler
|
class UMCPHandler_ChangeStructNodeType : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -377,7 +377,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="rename_asset"))
|
UCLASS(meta=(ToolName="rename_asset"))
|
||||||
class UMCPHandler_RenameAsset : public UMCPHandler
|
class UMCPHandler_RenameAsset : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -397,7 +397,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="set_blueprint_default"))
|
UCLASS(meta=(ToolName="set_blueprint_default"))
|
||||||
class UMCPHandler_SetBlueprintDefault : public UMCPHandler
|
class UMCPHandler_SetBlueprintDefault : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -421,7 +421,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(meta=(ToolName="search_node_types"))
|
UCLASS(meta=(ToolName="search_node_types"))
|
||||||
class UMCPHandler_SearchNodeTypes : public UMCPHandler
|
class UMCPHandler_SearchNodeTypes : public UObject, public IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class UMaterial;
|
|||||||
class UMaterialInstanceConstant;
|
class UMaterialInstanceConstant;
|
||||||
class UMaterialFunction;
|
class UMaterialFunction;
|
||||||
class UMaterialExpression;
|
class UMaterialExpression;
|
||||||
class UMCPHandler;
|
class IMCPHandler;
|
||||||
|
|
||||||
// ----- Snapshot data structures -----
|
// ----- Snapshot data structures -----
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ struct FMCPJsonArray
|
|||||||
TArray<TSharedPtr<FJsonValue>> Array;
|
TArray<TSharedPtr<FJsonValue>> Array;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for self-registering MCP tool handlers.
|
// Interface for self-registering MCP tool handlers.
|
||||||
//
|
//
|
||||||
// Subclasses declare their parameters as UPROPERTY fields, which are
|
// Implementing classes declare their parameters as UPROPERTY fields, which are
|
||||||
// automatically populated from the incoming JSON request and used to
|
// automatically populated from the incoming JSON request and used to
|
||||||
// generate the tool's JSON Schema for MCP tools/list.
|
// generate the tool's JSON Schema for MCP tools/list.
|
||||||
//
|
//
|
||||||
@@ -35,17 +35,20 @@ struct FMCPJsonArray
|
|||||||
// Property metadata:
|
// Property metadata:
|
||||||
// Optional - marks a parameter as not required
|
// Optional - marks a parameter as not required
|
||||||
//
|
//
|
||||||
UCLASS(Abstract)
|
UINTERFACE(MinimalAPI, meta=(CannotImplementInterfaceInBlueprint))
|
||||||
class BLUEPRINTMCP_API UMCPHandler : public UObject
|
class UMCPHandler : public UInterface
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
};
|
||||||
|
|
||||||
|
class BLUEPRINTMCP_API IMCPHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Human-readable tool description for MCP tools/list.
|
// Human-readable tool description for MCP tools/list.
|
||||||
// Override in each subclass.
|
virtual FString GetDescription() const = 0;
|
||||||
virtual FString GetDescription() const PURE_VIRTUAL(UMCPHandler::GetDescription, return FString(););
|
|
||||||
|
|
||||||
// Called after parameter fields have been populated from JSON.
|
// Called after parameter fields have been populated from JSON.
|
||||||
// Override in each subclass.
|
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) = 0;
|
||||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) PURE_VIRTUAL(UMCPHandler::Handle, );
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user