# Ferramentas personalizadas — Unreal Engine · AI Game Developer Wiki

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.

Esta página foi traduzida automaticamente do inglês. [Leia o original em inglês](https://ai-game.dev/docs/wiki/unreal/custom-tools).

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](https://ai-game.dev/pt-br/docs/wiki/unreal/extensions) prontas.

## Escolha o tipo certo de contribuição

| Você quer que o agente… | Contribua com | Interface |
| --- | --- | --- |
| Ler ou alterar dados do editor de um recurso do engine ou dos seus próprios tipos | Um **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ção | **Ferramentas** | `IUnrealMcpToolProvider` |
| Buscar um template de prompt reutilizável | **Prompts** | `IUnrealMcpPromptProvider` |
| Ler conteúdo fixo por URI | **Recursos** | `IUnrealMcpResourceProvider` |

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:

```cpp
#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](https://github.com/IvanMurzak/Unreal-MCP).

## Opção 2: ferramentas personalizadas

### Passo 1: adicione a dependência

No `Build.cs` do seu módulo:

```csharp
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:

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

### Passo 2: implemente o provider

```cpp
#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

```cpp
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++:

```cpp
#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:

```text
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](https://ai-game.dev/pt-br/docs/wiki/unreal/installation#editor-only).

---

Source (HTML): https://ai-game.dev/pt-br/docs/wiki/unreal/custom-tools

Machine-translated (pt-BR) from the English page: https://ai-game.dev/docs/wiki/unreal/custom-tools
