Esta página foi traduzida automaticamente do inglês. Leia o original em inglês.

Ferramentas personalizadas

Adicione suas ferramentas de IA, módulos RQL, prompts e recursos ao Unreal MCP de qualquer plugin C++ e exponha ferramentas de gameplay no jogo.

Atualizado em 4 de novembro de 2026 Ver como Markdown

O Unreal MCP permite que qualquer plugin do Unreal, incluindo os plugins do seu próprio projeto de jogo, adicione capacidades para agentes de IA. Você não faz fork do Unreal MCP: você implementa uma pequena interface pública, registra-a como uma modular feature do Unreal e o plugin a detecta quando seu módulo é carregado.

Esta página é para desenvolvedores C++. Se você só quer mais cobertura do engine, confira primeiro as extensões prontas.

Escolha o tipo certo de contribuição

Você quer que o agente…Contribua comInterface
Ler ou alterar dados do editor de um recurso do engine ou dos seus próprios tiposUm módulo RQL (recomendado para trabalho no editor)IUnrealMcpRqlModule
Executar uma ação que não seja acesso a dados, ou agir dentro de um jogo em execuçãoFerramentasIUnrealMcpToolProvider
Buscar um template de prompt reutilizávelPromptsIUnrealMcpPromptProvider
Ler conteúdo fixo por URIRecursosIUnrealMcpResourceProvider

Todas as extensões oficiais são módulos RQL, então o agente as acessa pelas mesmas ferramentas rql-query e rql-mutate usadas no resto do editor.

Opção 1: um módulo RQL

Dependa do módulo UnrealMcpRql no Build.cs do seu módulo de editor e declare o plugin UnrealMCP no array Plugins do seu .uplugin. Depois implemente o 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)

O que o contexto pode adicionar:

  • Fontes (onde uma consulta começa): AddObjectSource, AddObjectListSource, AddAssetSource, AddClassDefaultsSource.
  • Operações (chamadas com call): AddApiClass ou AddApiSource tornam cada UFUNCTION de uma classe chamável. Declare-as como UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true")); o comentário de documentação acima de cada uma se torna a descrição que o agente lê.
  • Membros: ExposeProperties para propriedades que a reflexão oculta, e membros computados somente leitura com AddJsonMember, AddObjectMember, AddObjectListMember.
  • Guias: AddGuide adiciona uma seção à skill unreal-rql.

Uma mutação é executada em uma única transação do editor, então crie objetos com RF_Transactional e chame Modify() no que você alterar. A seção Extensions do editor lista seu módulo e permite desativá-lo. A referência compilável é o plugin samples/UnrealAITemplate no repositório Unreal-MCP.

Opção 2: ferramentas personalizadas

Passo 1: adicione a dependência

No Build.cs do seu 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
});

No seu .uplugin, adicione a dependência do plugin para que a ordem de carregamento seja resolvida:

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

Passo 2: implemente o 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));
            });
    }
};

O builder oferece .Title, .Description, os helpers de parâmetro .ParamString, .ParamInt, .ParamNumber, .ParamBool e .ParamVector (passe EUnrealMcpParamRequirement::Required para um obrigatório), as quatro dicas de MCP e .Handle. O handler é executado na game thread, então você pode chamar APIs do editor e de UObject diretamente.

Regras que importam:

  • Os ids das ferramentas usam kebab-case: letras minúsculas e dígitos separados por hífens simples.
  • Dê a cada ferramenta um título e as quatro dicas. Marque como destrutiva qualquer ferramenta que exclua ou sobrescreva dados.
  • Não chame .ExtensionId(...) por conta própria; seu GetExtensionId() é aplicado automaticamente.

Passo 3: registre-o como 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();
    }
}

Mantenha o provider vivo enquanto ele estiver registrado e sempre cancele o registro no shutdown.

Como o registro se comporta

  • Descoberta e hot reload. Os providers são encontrados na inicialização do editor. Carregar ou descarregar seu módulo depois reconstrói o registro e os clientes de IA veem a mudança automaticamente.
  • Ordem determinística. Os providers são mesclados em ordem crescente de extension-id; as ferramentas dentro de um provider mantêm a ordem de declaração.
  • Isolamento. Uma ferramenta inválida (id ruim, schema quebrado, sem handler) ou um nome de ferramenta duplicado é descartada e registrada na entrada da sua extensão. Suas outras ferramentas e as outras extensões não são afetadas. Um crash dentro de um handler ainda é um crash do editor, então valide as entradas e retorne FUnrealMcpToolResult::Error(...).
  • Visibilidade e toggles. Suas ferramentas recebem a mesma caixa Visible na janela MCP Tools que as nativas. Uma extensão desativada não contribui com nada.

Prompts e recursos

Prompts e resources seguem o mesmo padrão com IUnrealMcpPromptProvider mais FUnrealMcpPromptRegistry, e IUnrealMcpResourceProvider mais FUnrealMcpResourceRegistry. Um prompt declara parâmetros com os mesmos helpers Param* e retorna mensagens com marcação de papel. Um resource é identificado pela sua URI e retorna texto ou um blob base64 com um tipo MIME. Hoje só há suporte a URIs fixas, não a URIs com template. O prompt embutido level-design-brief e o resource unreal://project/levels são referências funcionais.

Gerar uma ferramenta com o agente

Com uma instalação do plugin a partir do código-fonte, a ferramenta de sistema unreal-skill-create grava um novo arquivo de ferramenta em C++ no módulo de editor do plugin. A ferramenta só passa a existir depois que você recompila o editor (Live Coding ou uma recompilação do projeto).

Ferramentas no jogo (runtime)

O Unreal MCP também pode se conectar a um jogo em execução (Play In Editor, Standalone ou uma build Development empacotada) para que um agente de IA possa controlá-lo. Uma conexão de runtime não oferece ferramentas da engine: apenas as ferramentas que o seu jogo registra.

  1. Faça seu módulo de jogo depender de UnrealMcpRuntime (e não de UnrealMcpEditor) e escreva as ferramentas exatamente como acima.
  2. Ative Project Settings, Plugins, Unreal MCP (Runtime). A opção vem desligada por padrão e fica armazenada em DefaultGame.ini.
  3. Conecte explicitamente. O jogo nunca se conecta sozinho.

Em C++:

#include "UnrealMcpRuntimeSubsystem.h"

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

No Blueprint, use Get Unreal MCP Runtime Subsystem, depois Connect, Disconnect e Is Connected. No console:

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

Regras de segurança embutidas em Connect():

  • Builds Shipping se recusam a conectar, a menos que você compile com a flag bUnrealMcpAllowShipping.
  • Somente hosts de loopback são permitidos, a menos que você passe bAllowRemoteHost = true.
  • O modo runtime funciona apenas em plataformas desktop (Windows, macOS, Linux).

O plugin samples/UnrealAIRuntimeSample no repositório adiciona uma ferramenta game-time-dilation que lê e define a dilatação temporal do mundo em um jogo em execução. Se você não precisa de ferramentas de runtime, exclua o plugin das builds empacotadas conforme descrito em Installation.