自訂工具
從任何 C++ 外掛將你自己的 AI 工具、RQL 模組、提示與資源加入 Unreal MCP,並在執行中的遊戲裡公開遊戲玩法工具。
Unreal MCP 讓任何 Unreal 外掛(包括你自己遊戲專案的外掛)為 AI 代理新增能力。你不需要 fork Unreal MCP:只要實作一個小型的公開介面,將它註冊為 Unreal modular feature,外掛就會在你的模組載入時接手。
本頁面是給 C++ 開發者看的。如果你只是想要更多引擎涵蓋範圍,請先查看現成的 extensions。
選擇正確的貢獻類型
| 你希望代理… | 貢獻類型 | 介面 |
|---|---|---|
| 讀取或變更某個引擎功能或你自己型別的編輯器資料 | RQL 模組(編輯器工作推薦) | IUnrealMcpRqlModule |
| 執行非資料存取的动作,或在執行中的遊戲內操作 | 工具 | IUnrealMcpToolProvider |
| 取得可重複使用的提示範本 | 提示 | IUnrealMcpPromptProvider |
| 依 URI 讀取固定內容 | 資源 | IUnrealMcpResourceProvider |
所有第一方擴充功能都是 RQL 模組,因此代理會透過與編輯器其餘部分相同的 rql-query 與 rql-mutate 工具來存取它們。
選項 1:RQL 模組
在你的編輯器模組 Build.cs 中相依於 UnrealMcpRql 模組,並在 .uplugin 的 Plugins 陣列中宣告 UnrealMCP 外掛。接著實作該模組:
#include "IUnrealMcpRqlModule.h"
class FMyRqlModule : public IUnrealMcpRqlModule
{
public:
virtual FString GetRqlModuleName() const override { return TEXT("Niagara"); }
virtual FString GetExtensionId() const override { return TEXT("com.example.niagara-ai"); }
virtual FString GetExtensionVersion() const override { return UnrealMcpRql::PluginVersion(TEXT("MyNiagaraAI")); }
virtual void ConfigureRql(FUnrealMcpRqlModuleContext& Context) override
{
Context.AddAssetSource(TEXT("niagaraSystems"), TEXT("Niagara system assets"), UNiagaraSystem::StaticClass());
Context.AddApiSource(TEXT("niagara"), TEXT("Niagara operations"), UMyNiagaraOperations::StaticClass(),
TEXT("NiagaraOperations"));
Context.AddGuide(TEXT("Niagara"), TEXT("... markdown with example queries ..."));
}
};
IMPLEMENT_MODULE(TUnrealMcpRqlEditorModule<FMyRqlModule>, MyNiagaraAI)context 可以加入的內容:
- 來源(查詢的起點):
AddObjectSource、AddObjectListSource、AddAssetSource、AddClassDefaultsSource。 - 操作(以
call呼叫):AddApiClass或AddApiSource會讓某個類別的每個UFUNCTION都可被呼叫。將它們宣告為UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"));每個函式上方的 doc 註解就會成為代理所讀取的說明。 - 成員:
ExposeProperties用於反射所隱藏的屬性,以及透過AddJsonMember、AddObjectMember、AddObjectListMember建立的唯讀計算成員。 - 指南:
AddGuide會在unreal-rql技能中加入一個章節。
一次 mutation 會在單一編輯器交易中執行,因此請以 RF_Transactional 建立物件,並對你變更的物件呼叫 Modify()。編輯器的 Extensions 區段會列出你的模組,並可將它停用。可建置的參考範例是 Unreal-MCP repository 中的 samples/UnrealAITemplate 外掛。
選項 2:自訂工具
步驟 1:加入相依性
在你模組的 Build.cs 中:
PublicDependencyModuleNames.AddRange(new string[] { "Core" });
PrivateDependencyModuleNames.AddRange(new string[]
{
"CoreUObject", "Engine", "Projects",
"Json", // the registry header includes Dom/JsonObject.h
"UnrealMcpEditor", // the extension contract and tool registry
});在你的 .uplugin 中,加入此外掛相依性,讓載入順序得以解析:
{
"Plugins": [ { "Name": "UnrealMCP", "Enabled": true } ]
}步驟 2:實作 provider
#include "IUnrealMcpToolProvider.h"
#include "UnrealMcpToolRegistry.h"
class FMyExtensionProvider : public IUnrealMcpToolProvider
{
public:
virtual FString GetExtensionId() const override { return TEXT("com.foo.my-extension"); }
virtual FText GetDisplayName() const override { return NSLOCTEXT("Foo", "Name", "My Extension"); }
virtual FString GetExtensionVersion() const override { return TEXT("1.0.0"); }
virtual void RegisterTools(FUnrealMcpToolRegistry& Registry) override
{
Registry.Tool(TEXT("hello-extension"))
.Title(TEXT("Hello Extension"))
.Description(TEXT("Returns a friendly greeting."))
.ParamString(TEXT("name"), TEXT("Who to greet. Defaults to 'world'."))
.ReadOnlyHint(true).DestructiveHint(false).IdempotentHint(true).OpenWorldHint(false)
.Handle([](const FUnrealMcpToolCall& Call) -> FUnrealMcpToolResult
{
const FString Name = Call.Has(TEXT("name")) ? Call.GetString(TEXT("name")) : TEXT("world");
return FUnrealMcpToolResult::Success(FString::Printf(TEXT("Hello, %s!"), *Name));
});
}
};builder 提供 .Title、.Description、參數輔助方法 .ParamString、.ParamInt、.ParamNumber、.ParamBool 與 .ParamVector(必填參數請傳入 EUnrealMcpParamRequirement::Required)、四個 MCP hints,以及 .Handle。處理常式會在遊戲執行緒上執行,因此你可以直接呼叫編輯器與 UObject API。
重要規則:
- 工具 id 採 kebab-case:小寫字母與數字,並以單一連字號分隔。
- 每個工具都要有標題與全部四個 hints。任何會刪除或覆寫的工具都要標示為 destructive。
- 不要自行呼叫
.ExtensionId(...);你的GetExtensionId()會自動被標記上去。
步驟 3:註冊為 modular feature
virtual void StartupModule() override
{
Provider = MakeUnique<FMyExtensionProvider>();
IModularFeatures::Get().RegisterModularFeature(
IUnrealMcpToolProvider::GetModularFeatureName(), Provider.Get());
}
virtual void ShutdownModule() override
{
if (Provider.IsValid())
{
IModularFeatures::Get().UnregisterModularFeature(
IUnrealMcpToolProvider::GetModularFeatureName(), Provider.Get());
Provider.Reset();
}
}在註冊期間保持 provider 存活,並務必在關閉時取消註冊。
註冊的行為
- 探索與熱重載。 Provider 會在編輯器啟動時被找到。之後載入或卸載你的模組會重建註冊表,AI 用戶端會自動看到變更。
- 確定性順序。 Provider 依 extension-id 遞增順序合併;同一個 provider 內的工具則維持其宣告順序。
- 隔離。 無效的工具(id 錯誤、schema 損壞、沒有處理常式)或重複的工具名稱會被丟棄,並記錄在你的擴充功能項目上。你的其他工具與其他擴充功能不受影響。處理常式內部的當機仍會造成編輯器當機,因此請驗證輸入並回傳
FUnrealMcpToolResult::Error(...)。 - 可見性與開關。 你的工具在 MCP Tools 視窗中會取得與內建工具相同的 Visible 核取方塊。被停用的擴充功能不會貢獻任何內容。
提示與資源
提示(prompt)與資源(resource)採用相同的模式:IUnrealMcpPromptProvider 搭配 FUnrealMcpPromptRegistry,以及 IUnrealMcpResourceProvider 搭配 FUnrealMcpResourceRegistry。提示會用同一組 Param* 輔助函式宣告參數,並回傳帶有角色標記的訊息。資源以其 URI 識別,回傳文字或附帶 MIME 型別的 base64 blob。目前僅支援固定 URI,不支援樣板化 URI。內建的 level-design-brief 提示與 unreal://project/levels 資源是可運作的參考範例。
使用 agent 產生工具
在以外掛原始碼安裝的情況下,unreal-skill-create 系統工具會在外掛的編輯器模組中寫入一個新的 C++ 工具檔案。必須重新建置編輯器(Live Coding 或重新建置專案)之後,這個工具才會存在。
遊戲內(執行階段)工具
Unreal MCP 也能連線到執行中的遊戲(Play In Editor、Standalone 或打包後的 Development 建置),讓 AI agent 直接操作。執行階段連線不提供任何引擎工具:只有你的遊戲所註冊的工具。
- 讓你的遊戲模組相依於
UnrealMcpRuntime(而非UnrealMcpEditor),並完全依照上述方式撰寫工具。 - 啟用 Project Settings, Plugins, Unreal MCP (Runtime)。此開關預設為關閉,設定會存放在
DefaultGame.ini中。 - 明確呼叫連線。遊戲本身絕不會自動連線。
從 C++:
#include "UnrealMcpRuntimeSubsystem.h"
if (UUnrealMcpRuntimeSubsystem* Mcp = UUnrealMcpRuntimeSubsystem::Get(this))
{
Mcp->RegisterToolProvider(MyToolProvider);
Mcp->Connect(TEXT("http://localhost:8080"), TEXT("my-token"));
}在 Blueprint 中,使用 Get Unreal MCP Runtime Subsystem,再呼叫 Connect、Disconnect 與 Is Connected。從主控台:
UnrealMcp.Connect <host> [token]
UnrealMcp.DisconnectConnect() 內建的安全規則:
- 除非你在編譯時開啟
bUnrealMcpAllowShipping旗標,否則 Shipping 建置會拒絕連線。 - 除非傳入
bAllowRemoteHost = true,否則只允許 loopback 主機。 - 執行階段模式僅支援桌面平台(Windows、macOS、Linux)。
儲存庫中的 samples/UnrealAIRuntimeSample 外掛新增了一個 game-time-dilation 工具,可讀取並設定執行中遊戲世界的時間縮放(time dilation)。如果你不需要執行階段工具,請依照 Installation 的說明,在打包建置時排除此外掛。