More work on MCP endpoints
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -367,23 +367,6 @@ static int32 TrySavePackageSEH(
|
||||
}
|
||||
}
|
||||
|
||||
static void RefreshAllNodesInner(UBlueprint* BP)
|
||||
{
|
||||
FBlueprintEditorUtils::RefreshAllNodes(BP);
|
||||
}
|
||||
|
||||
int32 TryRefreshAllNodesSEH(UBlueprint* BP)
|
||||
{
|
||||
__try
|
||||
{
|
||||
RefreshAllNodesInner(BP);
|
||||
return 0;
|
||||
}
|
||||
__except (1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Inner: create expression, register in material, and trigger PostEditChange.
|
||||
// All of this may crash for classes that are effectively abstract.
|
||||
@@ -601,13 +584,13 @@ bool FBlueprintMCPServer::Start(int32 InPort, bool bEditorMode)
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/references")), EHttpServerRequestVerbs::VERB_GET,
|
||||
QueuedHandler(TEXT("references")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/replace-function-calls")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("replaceFunctionCalls")));
|
||||
QueuedHandler(TEXT("replace_function_calls")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/change-variable-type")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("changeVariableType")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/change-function-param-type")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("changeFunctionParamType")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/delete-asset")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("deleteAsset")));
|
||||
QueuedHandler(TEXT("delete_asset")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/test-save")), EHttpServerRequestVerbs::VERB_GET,
|
||||
QueuedHandler(TEXT("testSave")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/connect-pins")), EHttpServerRequestVerbs::VERB_POST,
|
||||
@@ -615,7 +598,7 @@ bool FBlueprintMCPServer::Start(int32 InPort, bool bEditorMode)
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/disconnect-pin")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("disconnect_pin")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/refresh-all-nodes")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("refreshAllNodes")));
|
||||
QueuedHandler(TEXT("refresh_all_nodes")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/set-pin-default")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("set_pin_default")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/move-node")), EHttpServerRequestVerbs::VERB_POST,
|
||||
@@ -635,7 +618,7 @@ bool FBlueprintMCPServer::Start(int32 InPort, bool bEditorMode)
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/list-properties")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("listProperties")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/change-struct-node-type")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("changeStructNodeType")));
|
||||
QueuedHandler(TEXT("change_struct_node_type")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/remove-function-parameter")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("removeFunctionParameter")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/delete-node")), EHttpServerRequestVerbs::VERB_POST,
|
||||
@@ -648,18 +631,16 @@ bool FBlueprintMCPServer::Start(int32 InPort, bool bEditorMode)
|
||||
QueuedHandler(TEXT("validateBlueprint")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/validate-all-blueprints")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("validateAllBlueprints")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/add-node")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("addNode")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/search-node-actions")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("searchNodeActions")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/search-node-actions")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("search_node_actions")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/spawn-node")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("spawn_node")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/rename-asset")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("renameAsset")));
|
||||
QueuedHandler(TEXT("rename_asset")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/reparent-blueprint")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("reparentBlueprint")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/set-blueprint-default")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("setBlueprintDefault")));
|
||||
QueuedHandler(TEXT("set_blueprint_default")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/create-blueprint")), EHttpServerRequestVerbs::VERB_POST,
|
||||
QueuedHandler(TEXT("createBlueprint")));
|
||||
Router->BindRoute(FHttpPath(TEXT("/api/create-graph")), EHttpServerRequestVerbs::VERB_POST,
|
||||
@@ -977,25 +958,24 @@ void FBlueprintMCPServer::RegisterHandlers()
|
||||
{
|
||||
// Mutation endpoints — wrapped in undo transactions by ProcessOneRequest()
|
||||
MutationEndpoints = {
|
||||
TEXT("replaceFunctionCalls"),
|
||||
TEXT("replace_function_calls"),
|
||||
TEXT("changeVariableType"),
|
||||
TEXT("changeFunctionParamType"),
|
||||
TEXT("removeFunctionParameter"),
|
||||
TEXT("deleteAsset"),
|
||||
TEXT("delete_asset"),
|
||||
TEXT("connect_pins"),
|
||||
TEXT("disconnect_pin"),
|
||||
TEXT("refreshAllNodes"),
|
||||
TEXT("refresh_all_nodes"),
|
||||
TEXT("set_pin_default"),
|
||||
TEXT("move_node"),
|
||||
TEXT("changeStructNodeType"),
|
||||
TEXT("change_struct_node_type"),
|
||||
TEXT("delete_node"),
|
||||
TEXT("duplicate_nodes"),
|
||||
TEXT("addNode"),
|
||||
TEXT("spawn_node"),
|
||||
TEXT("set_node_comment"),
|
||||
TEXT("renameAsset"),
|
||||
TEXT("rename_asset"),
|
||||
TEXT("reparentBlueprint"),
|
||||
TEXT("setBlueprintDefault"),
|
||||
TEXT("set_blueprint_default"),
|
||||
TEXT("createBlueprint"),
|
||||
TEXT("createGraph"),
|
||||
TEXT("deleteGraph"),
|
||||
@@ -1050,14 +1030,14 @@ void FBlueprintMCPServer::RegisterHandlers()
|
||||
H(TEXT("references"), &FBlueprintMCPServer::HandleFindReferences);
|
||||
H(TEXT("testSave"), &FBlueprintMCPServer::HandleTestSave);
|
||||
H(TEXT("searchByType"), &FBlueprintMCPServer::HandleSearchByType);
|
||||
H(TEXT("replaceFunctionCalls"), &FBlueprintMCPServer::HandleReplaceFunctionCalls);
|
||||
// replace_function_calls is now handled by UMCPHandler_ReplaceFunctionCalls (new-style registry)
|
||||
H(TEXT("changeVariableType"), &FBlueprintMCPServer::HandleChangeVariableType);
|
||||
H(TEXT("changeFunctionParamType"), &FBlueprintMCPServer::HandleChangeFunctionParamType);
|
||||
H(TEXT("removeFunctionParameter"), &FBlueprintMCPServer::HandleRemoveFunctionParameter);
|
||||
H(TEXT("deleteAsset"), &FBlueprintMCPServer::HandleDeleteAsset);
|
||||
// delete_asset is now handled by UMCPHandler_DeleteAsset (new-style registry)
|
||||
// connect_pins is now handled by UMCPHandler_ConnectPins (new-style registry)
|
||||
// disconnect_pin is now handled by UMCPHandler_DisconnectPin (new-style registry)
|
||||
H(TEXT("refreshAllNodes"), &FBlueprintMCPServer::HandleRefreshAllNodes);
|
||||
// refresh_all_nodes is now handled by UMCPHandler_RefreshAllNodes (new-style registry)
|
||||
// set_pin_default is now handled by UMCPHandler_SetPinDefault (new-style registry)
|
||||
// move_node is now handled by UMCPHandler_MoveNode (new-style registry)
|
||||
// get_node_comment is now handled by UMCPHandler_GetNodeComment (new-style registry)
|
||||
@@ -1067,17 +1047,16 @@ void FBlueprintMCPServer::RegisterHandlers()
|
||||
H(TEXT("listClasses"), &FBlueprintMCPServer::HandleListClasses);
|
||||
H(TEXT("listFunctions"), &FBlueprintMCPServer::HandleListFunctions);
|
||||
H(TEXT("listProperties"), &FBlueprintMCPServer::HandleListProperties);
|
||||
H(TEXT("changeStructNodeType"), &FBlueprintMCPServer::HandleChangeStructNodeType);
|
||||
// change_struct_node_type is now handled by UMCPHandler_ChangeStructNodeType (new-style registry)
|
||||
// delete_node is now handled by UMCPHandler_DeleteNode (new-style registry)
|
||||
// duplicate_nodes is now handled by UMCPHandler_DuplicateNodes (new-style registry)
|
||||
H(TEXT("validateBlueprint"), &FBlueprintMCPServer::HandleValidateBlueprint);
|
||||
H(TEXT("validateAllBlueprints"), &FBlueprintMCPServer::HandleValidateAllBlueprints);
|
||||
H(TEXT("addNode"), &FBlueprintMCPServer::HandleAddNode);
|
||||
H(TEXT("searchNodeActions"), &FBlueprintMCPServer::HandleSearchNodeActions);
|
||||
// search_node_actions is now handled by UMCPHandler_SearchNodeActions (new-style registry)
|
||||
// spawn_node is now handled by UMCPHandler_SpawnNode (new-style registry)
|
||||
H(TEXT("renameAsset"), &FBlueprintMCPServer::HandleRenameAsset);
|
||||
// rename_asset is now handled by UMCPHandler_RenameAsset (new-style registry)
|
||||
H(TEXT("reparentBlueprint"), &FBlueprintMCPServer::HandleReparentBlueprint);
|
||||
H(TEXT("setBlueprintDefault"), &FBlueprintMCPServer::HandleSetBlueprintDefault);
|
||||
// set_blueprint_default is now handled by UMCPHandler_SetBlueprintDefault (new-style registry)
|
||||
H(TEXT("createBlueprint"), &FBlueprintMCPServer::HandleCreateBlueprint);
|
||||
H(TEXT("createGraph"), &FBlueprintMCPServer::HandleCreateGraph);
|
||||
H(TEXT("deleteGraph"), &FBlueprintMCPServer::HandleDeleteGraph);
|
||||
|
||||
@@ -285,3 +285,158 @@ public:
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override;
|
||||
};
|
||||
|
||||
UCLASS(meta=(ToolName="replace_function_calls"))
|
||||
class UMCPHandler_ReplaceFunctionCalls : public UMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
||||
FString Blueprint;
|
||||
|
||||
UPROPERTY(meta=(Description="Old class name to match"))
|
||||
FString OldClass;
|
||||
|
||||
UPROPERTY(meta=(Description="New class name to redirect to"))
|
||||
FString NewClass;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="If true, report what would change without modifying"))
|
||||
bool DryRun = false;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Redirect function call nodes from one class to another. "
|
||||
"Supports dry-run to preview impact before applying.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override;
|
||||
};
|
||||
|
||||
UCLASS(meta=(ToolName="delete_asset"))
|
||||
class UMCPHandler_DeleteAsset : public UMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Package path of the asset to delete"))
|
||||
FString AssetPath;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="If true, skip reference check and force delete"))
|
||||
bool Force = false;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Delete a .uasset after verifying no references. "
|
||||
"Use force=true to skip the reference check.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override;
|
||||
};
|
||||
|
||||
UCLASS(meta=(ToolName="refresh_all_nodes"))
|
||||
class UMCPHandler_RefreshAllNodes : public UMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
||||
FString Blueprint;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Refresh all nodes in a Blueprint, removing orphaned pins. "
|
||||
"Reports compiler warnings and errors.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override;
|
||||
};
|
||||
|
||||
UCLASS(meta=(ToolName="change_struct_node_type"))
|
||||
class UMCPHandler_ChangeStructNodeType : public UMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
||||
FString Blueprint;
|
||||
|
||||
UPROPERTY(meta=(Description="Node GUID of the BreakStruct or MakeStruct node"))
|
||||
FString NodeId;
|
||||
|
||||
UPROPERTY(meta=(Description="New struct type name (e.g. 'FVector', 'Vector')"))
|
||||
FString NewType;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Change the struct type on a BreakStruct or MakeStruct node. "
|
||||
"Attempts to reconnect matching pins after the type change.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override;
|
||||
};
|
||||
|
||||
UCLASS(meta=(ToolName="rename_asset"))
|
||||
class UMCPHandler_RenameAsset : public UMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Current package path of the asset"))
|
||||
FString AssetPath;
|
||||
|
||||
UPROPERTY(meta=(Description="New package path or new asset name"))
|
||||
FString NewPath;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Rename or move an asset with reference fixup.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override;
|
||||
};
|
||||
|
||||
UCLASS(meta=(ToolName="set_blueprint_default"))
|
||||
class UMCPHandler_SetBlueprintDefault : public UMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
||||
FString Blueprint;
|
||||
|
||||
UPROPERTY(meta=(Description="Property name on the Class Default Object"))
|
||||
FString Property;
|
||||
|
||||
UPROPERTY(meta=(Description="New value (parsed according to property type)"))
|
||||
FString Value;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Set a default property value on a Blueprint's Class Default Object. "
|
||||
"Handles class references, object references, and simple types.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override;
|
||||
};
|
||||
|
||||
UCLASS(meta=(ToolName="search_node_actions"))
|
||||
class UMCPHandler_SearchNodeActions : public UMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Search query string"))
|
||||
FString Query;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="Maximum number of results (default 50, max 500)"))
|
||||
int32 MaxResults = 50;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Search the Blueprint action database for node spawners matching a query. "
|
||||
"Returns full action names for use with spawn_node.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override;
|
||||
};
|
||||
|
||||
@@ -97,6 +97,13 @@ public:
|
||||
/** Number of indexed Material Instance assets. */
|
||||
int32 GetMaterialInstanceCount() const { return AllMaterialInstanceAssets.Num(); }
|
||||
|
||||
// ----- Cached asset lists (accessed by handlers) -----
|
||||
TArray<FAssetData> AllBlueprintAssets;
|
||||
TArray<FAssetData> AllMapAssets;
|
||||
TArray<FAssetData> AllMaterialAssets;
|
||||
TArray<FAssetData> AllMaterialInstanceAssets;
|
||||
TArray<FAssetData> AllMaterialFunctionAssets;
|
||||
|
||||
private:
|
||||
// ----- Request dispatch -----
|
||||
using FRequestHandler = TFunction<void(const FJsonObject* Json, FJsonObject* Result)>;
|
||||
@@ -115,11 +122,6 @@ private:
|
||||
};
|
||||
|
||||
TQueue<TSharedPtr<FPendingRequest>> RequestQueue;
|
||||
TArray<FAssetData> AllBlueprintAssets;
|
||||
TArray<FAssetData> AllMapAssets;
|
||||
TArray<FAssetData> AllMaterialAssets;
|
||||
TArray<FAssetData> AllMaterialInstanceAssets;
|
||||
TArray<FAssetData> AllMaterialFunctionAssets;
|
||||
int32 Port = 9847;
|
||||
bool bRunning = false;
|
||||
bool bIsEditor = false;
|
||||
@@ -136,21 +138,14 @@ private:
|
||||
void HandleSearchByType(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
// ----- Request handlers (write) -----
|
||||
void HandleReplaceFunctionCalls(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleChangeVariableType(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleChangeFunctionParamType(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleRemoveFunctionParameter(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleDeleteAsset(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleAddNode(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleRenameAsset(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
// ----- Validation (read-only, no save) -----
|
||||
void HandleValidateBlueprint(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleValidateAllBlueprints(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
// ----- Pin manipulation (write) -----
|
||||
void HandleRefreshAllNodes(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
// ----- Pin introspection (read-only) -----
|
||||
void HandleGetPinInfo(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleCheckPinCompatibility(const FJsonObject* Json, FJsonObject* Result);
|
||||
@@ -160,9 +155,6 @@ private:
|
||||
void HandleListFunctions(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleListProperties(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
// ----- Struct node manipulation (write) -----
|
||||
void HandleChangeStructNodeType(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
// ----- Reparent -----
|
||||
void HandleReparentBlueprint(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
@@ -198,12 +190,6 @@ private:
|
||||
void HandleRemoveComponent(const FJsonObject* Json, FJsonObject* Result);
|
||||
void HandleListComponents(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
// ----- Property defaults -----
|
||||
void HandleSetBlueprintDefault(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
// ----- Generic node spawning via action database -----
|
||||
void HandleSearchNodeActions(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
// ----- Diagnostic -----
|
||||
void HandleTestSave(const FJsonObject* Json, FJsonObject* Result);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user