Diese Seite wurde maschinell aus dem Englischen übersetzt. Englisches Original lesen.

Eigene Tools

Füge eigene KI-Tools, RQL-Module, Prompts und Ressourcen aus jedem C++-Plugin zu Unreal MCP hinzu und biete Gameplay-Tools im laufenden Spiel an.

Aktualisiert am 4. November 2026 Als Markdown anzeigen

Unreal MCP ermöglicht jedem Unreal-Plugin – auch den Plugins deines eigenen Spielprojekts –, Fähigkeiten für KI-Agenten hinzuzufügen. Du forkst Unreal MCP nicht: Du implementierst eine kleine öffentliche Schnittstelle, registrierst sie als Unreal modular feature, und das Plugin greift sie auf, sobald dein Modul geladen wird.

Diese Seite richtet sich an C++-Entwickler. Wenn du nur mehr Engine-Abdeckung möchtest, schau dir zuerst die fertigen Erweiterungen an.

Die richtige Art von Beitrag wählen

Du möchtest, dass der Agent …BeitragSchnittstelle
Editor-Daten für eine Engine-Funktion oder deine eigenen Typen lesen oder ändernEin RQL-Modul (empfohlen für Editor-Arbeit)IUnrealMcpRqlModule
Eine Aktion ausführen, die kein Datenzugriff ist, oder im laufenden Spiel agierenToolsIUnrealMcpToolProvider
Eine wiederverwendbare Prompt-Vorlage abrufenPromptsIUnrealMcpPromptProvider
Feste Inhalte per URI lesenRessourcenIUnrealMcpResourceProvider

Alle Erstanbieter-Erweiterungen sind RQL-Module, sodass der Agent sie über dieselben Tools rql-query und rql-mutate erreicht wie den Rest des Editors.

Option 1: ein RQL-Modul

Hänge in der Build.cs deines Editor-Moduls vom Modul UnrealMcpRql ab und deklariere das Plugin UnrealMCP im Plugins-Array deiner .uplugin. Implementiere dann das Modul:

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

Was der Kontext hinzufügen kann:

  • Quellen (wo eine Abfrage beginnt): AddObjectSource, AddObjectListSource, AddAssetSource, AddClassDefaultsSource.
  • Operationen (aufgerufen mit call): AddApiClass oder AddApiSource machen jede UFUNCTION einer Klasse aufrufbar. Deklariere sie als UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true")); der Doc-Kommentar darüber wird zur Beschreibung, die der Agent liest.
  • Member: ExposeProperties für Properties, die Reflection verbirgt, und schreibgeschützte berechnete Member mit AddJsonMember, AddObjectMember, AddObjectListMember.
  • Leitfäden: AddGuide fügt dem Skill unreal-rql einen Abschnitt hinzu.

Eine Mutation läuft in einer einzigen Editor-Transaktion, erstelle Objekte daher mit RF_Transactional und rufe Modify() auf allem auf, was du änderst. Der Abschnitt Extensions des Editors listet dein Modul auf und kann es deaktivieren. Die baubare Referenz ist das Plugin samples/UnrealAITemplate im Unreal-MCP-Repository.

Option 2: eigene Tools

Schritt 1: Abhängigkeit hinzufügen

In der Build.cs deines Moduls:

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

Füge in deiner .uplugin die Plugin-Abhängigkeit hinzu, damit die Ladereihenfolge aufgelöst wird:

{
  "Plugins": [ { "Name": "UnrealMCP", "Enabled": true } ]
}

Schritt 2: Provider implementieren

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

Der Builder bietet .Title, .Description, die Parameter-Helfer .ParamString, .ParamInt, .ParamNumber, .ParamBool und .ParamVector (übergib EUnrealMcpParamRequirement::Required für einen erforderlichen), die vier MCP-Hints und .Handle. Der Handler läuft im Game-Thread, du kannst also Editor- und UObject-APIs direkt aufrufen.

Wichtige Regeln:

  • Tool-IDs sind Kebab-Case: Kleinbuchstaben und Ziffern, getrennt durch einzelne Bindestriche.
  • Gib jedem Tool einen Titel und alle vier Hints. Markiere alles, was löscht oder überschreibt, als destruktiv.
  • Rufe .ExtensionId(...) nicht selbst auf; deine GetExtensionId() wird automatisch eingetragen.

Schritt 3: als modular feature registrieren

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

Halte den Provider am Leben, solange er registriert ist, und melde ihn beim Herunterfahren immer ab.

Wie sich die Registrierung verhält

  • Erkennung und Hot Reload. Provider werden beim Editor-Start gefunden. Wenn du dein Modul später lädst oder entlädst, wird die Registry neu aufgebaut, und die KI-Clients sehen die Änderung automatisch.
  • Deterministische Reihenfolge. Provider werden in aufsteigender Extension-ID-Reihenfolge zusammengeführt; Tools innerhalb eines Providers behalten ihre Deklarationsreihenfolge.
  • Isolation. Ein ungültiges Tool (schlechte ID, fehlerhaftes Schema, kein Handler) oder ein doppelter Tool-Name wird verworfen und im Eintrag deiner Erweiterung vermerkt. Deine anderen Tools und andere Erweiterungen sind nicht betroffen. Ein Absturz in einem Handler ist weiterhin ein Editor-Absturz, also validiere Eingaben und gib FUnrealMcpToolResult::Error(...) zurück.
  • Sichtbarkeit und Schalter. Deine Tools erhalten im Fenster MCP Tools dieselbe Visible-Checkbox wie integrierte Tools. Eine deaktivierte Erweiterung trägt nichts bei.

Prompts und Ressourcen

Prompts und Ressourcen folgen demselben Muster mit IUnrealMcpPromptProvider plus FUnrealMcpPromptRegistry sowie IUnrealMcpResourceProvider plus FUnrealMcpResourceRegistry. Ein Prompt deklariert Parameter mit denselben Param*-Helfern und gibt rollenmarkierte Nachrichten zurück. Eine Ressource wird über ihre URI identifiziert und gibt entweder Text oder einen base64-Blob mit einem MIME-Typ zurück. Derzeit werden nur feste URIs unterstützt, keine templatisierten. Der integrierte Prompt level-design-brief und die Ressource unreal://project/levels sind funktionierende Referenzen.

Ein Tool mit dem Agenten generieren

Mit einer Quellinstallation des Plugins schreibt das System-Tool unreal-skill-create eine neue C++-Tool-Datei in das Editor-Modul des Plugins. Das Tool existiert erst, nachdem du den Editor neu baust (Live Coding oder ein Projekt-Rebuild).

In-Game-(Runtime-)Tools

Unreal MCP kann auch ein laufendes Spiel verbinden (Play In Editor, Standalone oder ein gepackter Development-Build), sodass ein KI-Agent es steuern kann. Eine Runtime-Verbindung bietet keine Engine-Tools: nur die Tools, die dein Spiel registriert.

  1. Lass dein Spielmodul von UnrealMcpRuntime abhängen (nicht von UnrealMcpEditor) und erstelle Tools genau wie oben beschrieben.
  2. Aktiviere Project Settings, Plugins, Unreal MCP (Runtime). Der Schalter ist standardmäßig aus und wird in DefaultGame.ini gespeichert.
  3. Verbinde dich explizit. Das Spiel verbindet sich nie von selbst.

Aus C++:

#include "UnrealMcpRuntimeSubsystem.h"

if (UUnrealMcpRuntimeSubsystem* Mcp = UUnrealMcpRuntimeSubsystem::Get(this))
{
    Mcp->RegisterToolProvider(MyToolProvider);
    Mcp->Connect(TEXT("http://localhost:8080"), TEXT("my-token"));
}

Verwende in Blueprint Get Unreal MCP Runtime Subsystem und dann Connect, Disconnect und Is Connected. Aus der Konsole:

UnrealMcp.Connect <host> [token]
UnrealMcp.Disconnect

In Connect() eingebaute Sicherheitsregeln:

  • Shipping-Builds verweigern die Verbindung, es sei denn, du kompilierst das Flag bUnrealMcpAllowShipping ein.
  • Nur Loopback-Hosts sind erlaubt, es sei denn, du übergibst bAllowRemoteHost = true.
  • Der Runtime-Modus funktioniert nur auf Desktop-Plattformen (Windows, macOS, Linux).

Das Plugin samples/UnrealAIRuntimeSample im Repository fügt ein Tool game-time-dilation hinzu, das die Zeitdilatation der Welt in einem laufenden Spiel liest und setzt. Wenn du keine Runtime-Tools brauchst, schließe das Plugin wie unter Installation beschrieben aus gepackten Builds aus.