Ferramentas personalizadas
Crie ferramentas Godot MCP em C#, chame a API Godot na thread principal e exponha ferramentas, prompts e recursos de um jogo em execução.
Você pode adicionar suas próprias ferramentas MCP ao Godot MCP em C# puro, dentro do seu projeto. Uma ferramenta personalizada é um método que o agente de IA pode chamar, com uma descrição que diz ao modelo o que ela faz. Esta página aborda ferramentas de editor, a regra da thread principal e o runtime opt-in que permite a um agente conversar com um jogo em execução.
Escreva uma ferramenta de editor
Uma família de ferramentas é uma partial class marcada com [AiToolType]. Cada ferramenta é um método marcado com [AiTool("tool-name")], com um [Description] no método e em cada parâmetro para que o modelo saiba quando e como chamá-lo.
using System.ComponentModel;
using com.IvanMurzak.McpPlugin; // [AiToolType], [AiTool]
using com.IvanMurzak.ReflectorNet.Utils; // MainThread
[AiToolType]
public partial class Tool_MyFeature
{
[AiTool("my-custom-task", Title = "Do a custom task")]
[Description("Explain to the LLM what this does and when to call it.")]
public string CustomTask
(
[Description("Explain to the LLM what this parameter is.")]
string inputData
)
{
// Work that does not touch the Godot API can run here, on a background thread.
return MainThread.Instance.Run(() =>
{
// Touch EditorInterface, Node or Resource here, on the main thread.
return "[Success] Operation completed.";
});
}
}Compile o projeto C# (o botão Build do editor, godot-cli build, ou peça ao agente para executar script-build). O Godot recarrega o assembly, o addon se reconecta e a nova ferramenta aparece na lista de ferramentas do agente e na janela Tools do dock.
Regras que mantêm as ferramentas confiáveis
- Somente a thread principal para objetos do Godot. Os métodos das ferramentas são chamados fora da thread principal. Qualquer chamada em
Node,Resource,SceneTreeouEditorInterfacedeve passar porMainThread.Instance.Run(...). Acessá-los a partir da thread em segundo plano pode travar o editor. - Retorne dados, não texto formatado. Retorne uma classe com propriedades (ela é serializada para o modelo) ou
voidpara ferramentas apenas com efeitos colaterais. Evite strings montadas à mão para qualquer coisa que o agente precise interpretar. - Marque parâmetros opcionais. Use um tipo anulável com um valor padrão, por exemplo
string? filter = null, e o modelo trata o parâmetro como opcional. - Descreva tudo. As descrições são o que o modelo lê. Diga o que a ferramenta faz, quando usá-la e o que cada parâmetro significa.
- Código exclusivo do editor fica atrás de
#if TOOLS. Código que usa APIs do editor não deve ser compilado em um jogo exportado.
Dicas e alvos
[AiTool] aceita dicas opcionais como ReadOnlyHint = true e IdempotentHint = true, que informam aos clientes que a ferramenta não altera nada ou pode ser repetida com segurança. Um Target decide onde a ferramenta é registrada: ToolTarget.Editor (somente editor), ToolTarget.Runtime (somente jogo) ou o padrão, ambos.
Deixe o agente escrever a ferramenta
A ferramenta de sistema godot-skill-create grava um novo arquivo de ferramenta C# no seu projeto; a ferramenta fica chamável após a próxima compilação. Antes de escrever uma nova ferramenta, verifique se o RQL já cobre a tarefa: a maior parte do acesso a dados do editor (nós, recursos, arquivos, configurações do projeto) está a um rql-query ou rql-mutate de distância. Veja Ferramentas.
Ferramentas em um jogo em execução
O Godot MCP também pode rodar dentro de um jogo em execução ou exportado, debug ou release. Isso permite que um agente leia e controle o estado ao vivo do jogo, por exemplo um jogo de xadrez cujos movimentos do bot vêm de um LLM. Duas coisas são intencionais:
- Ele nunca se conecta sozinho. Seu código decide se e quando chamar
Connect(). - Ele não expõe nada por padrão. Você mesmo registra cada ferramenta, prompt e recurso. As ferramentas de editor do addon não são compiladas em um build do jogo.
Inicie-o assim que existir um SceneTree, por exemplo no _Ready() de um autoload:
using System.Reflection;
using com.IvanMurzak.Godot.MCP.Connection;
using com.IvanMurzak.Godot.MCP.Runtime;
using McpServerConsts = com.IvanMurzak.McpPlugin.Common.Consts.MCP.Server;
using Godot;
public partial class GameMcp : Node
{
private GodotMcpRuntimeHandle? _mcp;
public override async void _Ready()
{
_mcp = GodotMcpRuntime.Initialize(builder =>
{
builder.WithConfig(config =>
{
config.ConnectionMode = GodotMcpConnectionMode.Custom;
config.Host = "http://localhost:8080";
config.AuthOption = McpServerConsts.AuthOption.token;
config.Token = "your-secret-token";
});
builder.WithToolsFromAssembly(Assembly.GetExecutingAssembly());
}).Build();
await _mcp.Connect();
}
public override async void _ExitTree()
{
if (_mcp is not null)
await _mcp.Disconnect();
}
}Marque classes de ferramentas exclusivas do jogo com [AiToolType(Target = ToolTarget.Runtime)] (de com.IvanMurzak.McpPlugin.Common), para que o editor não as registre e o agente alcance o jogo mesmo enquanto o editor está conectado.
Opções do builder
| Chamada | O que faz |
|---|---|
WithConfig(...) | Define Host, Token, ConnectionMode e AuthOption no código. |
WithToolsFromAssembly(...) / WithTools(...) | Registra classes [AiToolType] de um assembly, ou tipos específicos. |
WithPromptsFromAssembly(...) / WithPrompts(...) | Registra classes de prompt [AiPromptType]. |
WithResourcesFromAssembly(...) / WithResources(...) | Registra classes de recurso [AiResourceType]. |
WithRuntimeErrorCapture() | Captura erros dentro do jogo e registra runtime-errors-get / runtime-errors-clear. Desativado por padrão. |
WithScriptExecute() | Registra script-execute no jogo. Desativado por padrão; requer opt-in no .csproj. |
ConnectWhenRunFromEditor() | Também conecta quando o jogo é iniciado com Play a partir do editor. Desativado por padrão. |
WithoutMainThreadDispatcher() | Ignora o dispatcher automático de thread principal (apenas se você instalar o seu próprio). |
O host e o token também podem vir de variáveis de ambiente GODOT_MCP_* ou de um arquivo .env, que têm precedência sobre o código. Um jogo nunca lê as configurações salvas do editor.
Prompts e recursos
Além das ferramentas, um jogo pode expor prompts MCP (modelos de instrução nomeados, [AiPromptType] com métodos [AiPrompt]) e recursos (conteúdo somente leitura obtido por URI, [AiResourceType] com métodos [AiResource]). Cada tipo é opcional e registrado da mesma forma que as ferramentas.
Executando C# dentro do jogo
Para permitir que o agente execute C# no jogo, habilite a opção no .csproj do jogo e chame WithScriptExecute():
<PropertyGroup>
<GodotMcpCodeExecInGame>true</GodotMcpCodeExecInGame>
<DefineConstants>$(DefineConstants);GODOT_MCP_CODE_EXEC_IN_GAME</DefineConstants>
</PropertyGroup>Isso funciona apenas em builds CoreCLR de desktop, não em NativeAOT ou iOS.
Checklist de segurança para builds do jogo
- Prefira o modo Custom em
localhostou127.0.0.1comAuthOption.tokene um token real. - Registre apenas as ferramentas de que você precisa; a superfície de ataque é exatamente as ferramentas que você registra.
- Não exponha a conexão em uma interface de rede pública em uma build de lançamento, a menos que você a tenha projetado e protegido para isso.
Para a lista completa de ferramentas, consulte Ferramentas; para conjuntos de ferramentas empacotados, consulte Extensões.