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