How-To: Add MCP Tools to a Plugin
Goal: expose your plugin's editor operations to AI agents over Model Context Protocol (MCP), the way CrimsonEditorUtilities does. CrimsonCommonEditor gives you the master switch every Crimson plugin honors; you author the tools themselves on a UToolsetDefinition in your own editor module. This is an editor-only, C++ task.
CrimsonCommonEditor, and its .uplugin declares CrimsonCommon, ModelContextProtocol, and ToolsetRegistry in the Plugins array. CrimsonEditorUtilities is a complete working example.UCrimsonMCPSettings::IsEnabled() (from MCP/CrimsonMCPSettings.h). That single Project Settings toggle - Crimson -> Crimson MCP - is what lets users turn the whole suite's MCP surface off. Skipping the gate breaks that guarantee.1. Recommended: a UToolsetDefinition
UE 5.8's Toolset Registry is the modern, discoverable path: tools authored here show up in an agent's list_toolsets. Declare a UToolsetDefinition subclass with static UFUNCTION(meta = (AICallable)) functions - the class name becomes the toolset name and each function is one tool. Report failures with UKismetSystemLibrary::RaiseScriptError. Add ToolsetRegistry and Kismet to the editor module's .Build.cs.
// MyPluginToolset.h#include "ToolsetRegistry/ToolsetDefinition.h"#include "MyPluginToolset.generated.h"/** Tools for my plugin. */UCLASS(BlueprintType, Hidden)class UMyPluginToolset : public UToolsetDefinition{GENERATED_BODY()public:/*** One-line description the agent sees.* @param Name What this parameter means.*/UFUNCTION(meta = (AICallable), Category = "MyPlugin")static FString DoThing(const FString& Name);};
Register the toolset in the editor module's StartupModule (gated), and unregister on shutdown:
#include "ToolsetRegistry/UToolsetRegistry.h"#include "MCP/CrimsonMCPSettings.h"void FMyPluginEditorModule::StartupModule(){if (UCrimsonMCPSettings::IsEnabled()){UToolsetRegistry::RegisterToolsetClass(UMyPluginToolset::StaticClass());}}void FMyPluginEditorModule::ShutdownModule(){if (UToolsetRegistry::IsAvailable()){UToolsetRegistry::UnregisterToolsetClass(UMyPluginToolset::StaticClass());}}
list_toolsets. Run ModelContextProtocol.RefreshTools after live-coding a tool method.2. Advanced results (images, audio, async)
For results richer than a string or struct - screenshots, audio, or operations that span multiple frames - return the engine's native ToolsetRegistry async result types (UToolCallAsyncResultImage, the ToolCallAsyncResult* family, ToolsetImage.h) from your AICallable function. The old Crimson low-level tool base (TCrimsonMCPTool / FCrimsonMCPToolRegistrar) was retired on 2026-07-17; every tool now goes through UToolsetDefinition.
See also
- CrimsonEditorUtilities -> Quick Start - enable Crimson MCP and connect an agent
- CrimsonEditorUtilities -> Concept: How Crimson MCP Works - toolsets, tool search, and the master-switch cascade