Esta página se tradujo automáticamente del inglés. Lee el original en inglés.

Herramientas personalizadas

Añade herramientas de IA, módulos RQL, prompts y recursos a Unreal MCP desde cualquier plugin de C++ y expón herramientas de gameplay en el juego.

Actualizado el 4 de noviembre de 2026 Ver como Markdown

Unreal MCP permite que cualquier plugin de Unreal, incluidos los del propio proyecto de tu juego, añada capacidades para agentes de IA. No bifurcas Unreal MCP: implementas una pequeña interfaz pública, la registras como modular feature de Unreal y el plugin la detecta cuando se carga tu módulo.

Esta página es para desarrolladores de C++. Si solo quieres más cobertura del motor, consulta primero las extensiones ya listas.

Elige el tipo de contribución adecuado

Quieres que el agente…Contribuye conInterfaz
Leer o cambiar datos del editor para una característica del motor o tus propios tiposUn módulo RQL (recomendado para trabajo en el editor)IUnrealMcpRqlModule
Ejecutar una acción que no sea acceso a datos, o actuar dentro de un juego en ejecuciónHerramientasIUnrealMcpToolProvider
Obtener una plantilla de prompt reutilizablePromptsIUnrealMcpPromptProvider
Leer contenido fijo por URIRecursosIUnrealMcpResourceProvider

Todas las extensiones propias son módulos RQL, así que el agente accede a ellas mediante las mismas herramientas rql-query y rql-mutate que al resto del editor.

Opción 1: un módulo RQL

Depende del módulo UnrealMcpRql en el Build.cs de tu módulo de editor y declara el plugin UnrealMCP en el array Plugins de tu .uplugin. Después, implementa el módulo:

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

Lo que el contexto puede añadir:

  • Fuentes (donde comienza una consulta): AddObjectSource, AddObjectListSource, AddAssetSource, AddClassDefaultsSource.
  • Operaciones (se invocan con call): AddApiClass o AddApiSource hacen que cualquier UFUNCTION de una clase se pueda invocar. Decláralas UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true")); el comentario de documentación que hay encima de cada una se convierte en la descripción que lee el agente.
  • Miembros: ExposeProperties para propiedades que la reflexión oculta, y miembros calculados de solo lectura con AddJsonMember, AddObjectMember, AddObjectListMember.
  • Guías: AddGuide añade una sección a la skill unreal-rql.

Una mutación se ejecuta en una única transacción del editor, así que crea los objetos con RF_Transactional y llama a Modify() en lo que modifiques. La sección Extensions del editor lista tu módulo y permite deshabilitarlo. La referencia compilable es el plugin samples/UnrealAITemplate del repositorio Unreal-MCP.

Opción 2: herramientas personalizadas

Paso 1: añade la dependencia

En el Build.cs de tu módulo:

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

En tu .uplugin, añade la dependencia del plugin para que se resuelva el orden de carga:

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

Paso 2: implementa el proveedor

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

El builder ofrece .Title, .Description, los helpers de parámetros .ParamString, .ParamInt, .ParamNumber, .ParamBool y .ParamVector (pasa EUnrealMcpParamRequirement::Required para uno obligatorio), los cuatro hints de MCP y .Handle. El handler se ejecuta en el hilo del juego, así que puedes llamar directamente a las API del editor y de UObject.

Reglas importantes:

  • Los ids de las herramientas usan kebab-case: letras minúsculas y dígitos separados por un único guion.
  • Asigna un título a cada herramienta y los cuatro hints. Marca como destructiva cualquier herramienta que elimine o sobrescriba.
  • No llames tú a .ExtensionId(...); tu GetExtensionId() se aplica automáticamente.

Paso 3: regístralo como una 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();
    }
}

Mantén el proveedor vivo mientras esté registrado y anula siempre su registro al apagar.

Cómo funciona el registro

  • Descubrimiento y recarga en caliente. Los proveedores se detectan al iniciar el editor. Cargar o descargar tu módulo después reconstruye el registro y los clientes de IA ven el cambio automáticamente.
  • Orden determinista. Los proveedores se fusionan en orden ascendente de id de extensión; las herramientas dentro de un mismo proveedor conservan su orden de declaración.
  • Aislamiento. Una herramienta no válida (id incorrecto, esquema roto, sin handler) o un nombre de herramienta duplicado se descarta y se registra en la entrada de tu extensión. Tus demás herramientas y las demás extensiones no se ven afectadas. Un fallo dentro de un handler sigue siendo un fallo del editor, así que valida las entradas y devuelve FUnrealMcpToolResult::Error(...).
  • Visibilidad y conmutadores. Tus herramientas tienen la misma casilla Visible en la ventana MCP Tools que las integradas. Una extensión deshabilitada no aporta nada.

Prompts y recursos

Los prompts y los recursos usan el mismo patrón con IUnrealMcpPromptProvider más FUnrealMcpPromptRegistry, y IUnrealMcpResourceProvider más FUnrealMcpResourceRegistry. Un prompt declara parámetros con los mismos helpers Param* y devuelve mensajes etiquetados por rol. Un recurso se identifica por su URI y devuelve texto o un blob en base64 con un tipo MIME. Hoy solo se admiten URIs fijas, no con plantillas. El prompt integrado level-design-brief y el recurso unreal://project/levels son referencias que funcionan.

Genera una herramienta con el agente

Con una instalación del plugin desde el código fuente, la herramienta de sistema unreal-skill-create escribe un nuevo archivo de herramienta en C++ en el módulo de editor del plugin. La herramienta solo existe después de recompilar el editor (Live Coding o una recompilación del proyecto).

Herramientas en el juego (tiempo de ejecución)

Unreal MCP también puede conectar un juego en ejecución (Play In Editor, Standalone o una compilación Development empaquetada) para que un agente de IA pueda controlarlo. Una conexión en tiempo de ejecución no ofrece herramientas del motor: solo las herramientas que registre tu juego.

  1. Haz que tu módulo de juego dependa de UnrealMcpRuntime (no de UnrealMcpEditor) y crea las herramientas exactamente como se ha descrito arriba.
  2. Activa Project Settings, Plugins, Unreal MCP (Runtime). El interruptor está desactivado por defecto y se guarda en DefaultGame.ini.
  3. Conéctate explícitamente. El juego nunca se conecta por sí solo.

Desde C++:

#include "UnrealMcpRuntimeSubsystem.h"

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

Desde Blueprint, usa Get Unreal MCP Runtime Subsystem y luego Connect, Disconnect e Is Connected. Desde la consola:

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

Reglas de seguridad integradas en Connect():

  • Las compilaciones Shipping se niegan a conectarse a menos que compiles con el flag bUnrealMcpAllowShipping.
  • Solo se permiten hosts de loopback a menos que pases bAllowRemoteHost = true.
  • El modo de tiempo de ejecución solo funciona en plataformas de escritorio (Windows, macOS, Linux).

El plugin samples/UnrealAIRuntimeSample del repositorio añade una herramienta game-time-dilation que lee y establece la dilatación temporal del mundo en un juego en ejecución. Si no necesitas herramientas en tiempo de ejecución, excluye el plugin de las compilaciones empaquetadas como se describe en Instalación.