このページは英語から機械翻訳されています。英語の原文を読む。

カスタムツール

任意のC++プラグインから独自のAIツール、RQLモジュール、プロンプト、リソースをUnreal MCPに追加し、実行中のゲームでゲームプレイツールを公開できます。

2026年11月4日に更新 Markdownで表示

Unreal MCPでは、自分のゲームプロジェクトのプラグインを含め、任意のUnrealプラグインがAIエージェント向けの機能を追加できます。Unreal MCPをフォークする必要はありません。小さな公開インターフェースを実装してUnrealのモジュラーフィーチャーとして登録するだけで、モジュールの読み込み時にプラグインがそれを認識します。

このページはC++開発者向けです。エンジンのカバレッジを増やしたいだけの場合は、まず既成の拡張機能を確認してください。

適切な種類のコントリビューションを選ぶ

エージェントに求めていること…提供するものインターフェース
エンジン機能や独自型のエディタデータを読み取り・変更する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)

コンテキストで追加できるもの:

  • ソース(クエリの開始点): AddObjectSource、AddObjectListSource、AddAssetSource、AddClassDefaultsSource。
  • オペレーション(callで呼び出し): AddApiClassまたはAddApiSourceは、クラスのすべてのUFUNCTIONを呼び出し可能にします。それらをUFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))として宣言してください。各関数の上のドキュメントコメントが、エージェントが読む説明になります。
  • メンバー: リフレクションから隠れたプロパティにはExposeProperties、読み取り専用の計算メンバーにはAddJsonMember、AddObjectMember、AddObjectListMember。
  • ガイド: AddGuideはunreal-rqlスキルにセクションを追加します。

ミューテーションは1つのエディタトランザクションで実行されるため、オブジェクトはRF_Transactionalで作成し、変更するものにはModify()を呼び出してください。エディタのExtensionsセクションにモジュールが表示され、無効化できます。ビルド可能なリファレンスは、Unreal-MCPリポジトリの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: プロバイダーを実装する

#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));
            });
    }
};

ビルダーは.Title、.Description、パラメータヘルパー.ParamString、.ParamInt、.ParamNumber、.ParamBool、.ParamVector(必須にする場合はEUnrealMcpParamRequirement::Requiredを渡す)、4つのMCPヒント、そして.Handleを提供します。ハンドラーはゲームスレッドで実行されるため、エディタやUObjectのAPIを直接呼び出せます。

重要なルール:

  • ツールIDはケバブケースです。小文字と数字を単一のハイフンで区切ります。
  • すべてのツールにタイトルと4つのヒントをすべて設定してください。削除や上書きを行うものは破壊的としてマークしてください。
  • 自分で.ExtensionId(...)を呼び出さないでください。GetExtensionId()の値が自動的に設定されます。

ステップ3: モジュラーフィーチャーとして登録する

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();
    }
}

プロバイダーは登録されている間は生かしておき、シャットダウン時には必ず登録解除してください。

登録の動作

  • 検出とホットリロード。 プロバイダーはエディタ起動時に検出されます。後からモジュールを読み込みまたはアンロードするとレジストリが再構築され、AIクライアントはその変更を自動的に認識します。
  • 決定的な順序。 プロバイダーは拡張IDの昇順でマージされ、1つのプロバイダー内のツールは宣言順を保ちます。
  • 分離。 無効なツール(不正なID、壊れたスキーマ、ハンドラーなし)や重複したツール名は破棄され、拡張のエントリに記録されます。他のツールや他の拡張機能は影響を受けません。ハンドラー内のクラッシュは依然としてエディタのクラッシュになるため、入力を検証してFUnrealMcpToolResult::Error(...)を返してください。
  • 可視性と切り替え。 ツールには、組み込みのものと同じくMCP ToolsウィンドウにVisibleチェックボックスが表示されます。無効化された拡張は何も提供しません。

プロンプトとリソース

プロンプトとリソースは同じパターンを使用し、IUnrealMcpPromptProvider と FUnrealMcpPromptRegistry、IUnrealMcpResourceProvider と FUnrealMcpResourceRegistry を組み合わせます。プロンプトは同じ Param* ヘルパーでパラメータを宣言し、ロールタグ付きのメッセージを返します。リソースは URI で識別され、テキストまたは MIME タイプ付きの base64 blob のいずれかを返します。現在サポートされているのは固定 URI のみで、テンプレート化された URI には対応していません。組み込みの level-design-brief プロンプトと unreal://project/levels リソースは動作する参照例です。

エージェントでツールを生成する

プラグインをソースからインストールしている場合、unreal-skill-create システムツールがプラグインのエディタモジュールに新しい C++ ツールファイルを書き込みます。ツールはエディタを再ビルド(Live Coding またはプロジェクトの再ビルド)した後にのみ存在します。

ゲーム内(ランタイム)ツール

Unreal MCP は実行中のゲーム(Play In Editor、Standalone、またはパッケージ化された Development ビルド)にも接続できるため、AI エージェントがそれを操作できます。ランタイム接続ではエンジンツールは提供されず、ゲームが登録したツールのみが利用できます。

  1. ゲームモジュールを UnrealMcpRuntime(UnrealMcpEditor ではない)に依存させ、上記とまったく同じ方法でツールを記述します。
  2. Project Settings, Plugins, Unreal MCP (Runtime) を有効にします。このスイッチはデフォルトでオフで、DefaultGame.ini に保存されます。
  3. 明示的に接続します。ゲームが自動的に接続することはありません。

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.Disconnect

Connect() に組み込まれた安全規則:

  • Shipping ビルドは、bUnrealMcpAllowShipping フラグを含めてコンパイルしない限り接続を拒否します。
  • bAllowRemoteHost = true を渡さない限り、ループバックホストのみが許可されます。
  • ランタイムモードはデスクトッププラットフォーム(Windows、macOS、Linux)でのみ動作します。

リポジトリ内の samples/UnrealAIRuntimeSample プラグインは、実行中のゲームでワールドのタイムディレーションを読み取り、設定する game-time-dilation ツールを追加します。ランタイムツールが不要な場合は、Installation で説明されているように、パッケージ化されたビルドからプラグインを除外してください。