本页由英文机器翻译而成。阅读英文原文。

自定义工具

用 C# 编写你自己的 Godot MCP 工具,在主线程执行 Godot API 调用,并从运行中的 Godot 游戏里暴露工具、提示和资源。

更新于 2026年11月4日 查看 Markdown 版本

你可以在项目内用纯 C# 为 Godot MCP 添加自己的 MCP 工具。自定义工具就是一个 AI agent 可以调用的方法,并带有描述,告诉模型它做什么。本页介绍编辑器工具、主线程规则,以及让 agent 与运行中的游戏通信的可选运行时。

编写编辑器工具

一个工具族就是一个标记了 [AiToolType] 的 partial class。每个工具就是一个标记了 [AiTool("tool-name")] 的方法,方法本身和每个参数上都要有 [Description],这样模型才知道何时以及如何调用它。

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

构建 C# 项目(编辑器的 Build 按钮、godot-cli build,或让 agent 运行 script-build)。Godot 会重新加载程序集,插件会重新连接,新工具就会出现在 agent 的工具列表和停靠面板的 Tools 窗口中。

让工具保持可靠的规则

  • Godot 对象只能在主线程访问。 工具方法是在主线程之外被调用的。对 Node、Resource、SceneTree 或 EditorInterface 的任何调用都必须通过 MainThread.Instance.Run(...)。从后台线程访问它们可能导致编辑器崩溃。
  • 返回数据,而不是格式化文本。 返回一个带属性的类(它会为模型序列化),或者对只有副作用的工具返回 void。凡是 agent 需要解析的内容,都不要用手工拼接的字符串。
  • 标记可选参数。 使用带默认值的可空类型,例如 string? filter = null,模型就会把该参数视为可选。
  • 为一切写描述。 模型读的就是这些描述。说明工具做什么、何时使用,以及每个参数的含义。
  • 仅限编辑器的代码放在 #if TOOLS 之后。 使用编辑器 API 的代码绝不能编译进导出的游戏。

提示与目标

[AiTool] 接受可选提示,例如 ReadOnlyHint = true 和 IdempotentHint = true,它们告诉客户端该工具不改变任何东西,或者可以安全地重复调用。Target 决定工具注册到哪里:ToolTarget.Editor(仅编辑器)、ToolTarget.Runtime(仅游戏)或默认值,两者都注册。

让 agent 来编写工具

系统工具 godot-skill-create 会把新的 C# 工具文件写入你的项目;该工具在下次构建后即可调用。在编写新工具之前,先确认 RQL 是否已经能完成这件事:大多数编辑器数据访问(节点、资源、文件、项目设置)只需一次 rql-query 或 rql-mutate。参见 工具。

运行中游戏里的工具

Godot MCP 也可以运行在运行中或已导出的游戏内,无论是调试版还是发布版。这使 agent 能够读取并驱动实时游戏状态,例如一个由 LLM 提供机器人走法的国际象棋游戏。有两点是刻意设计的:

  • 它绝不会自行连接。 由你的代码决定是否以及何时调用 Connect()。
  • 默认不暴露任何东西。 每个工具、提示和资源都由你自己注册。插件的编辑器工具不会被编译进游戏构建。

在 SceneTree 存在之后再启动它,例如在某个 autoload 的 _Ready() 中:

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

用 [AiToolType(Target = ToolTarget.Runtime)](来自 com.IvanMurzak.McpPlugin.Common)标记仅游戏用的工具类,这样编辑器就不会注册它们,即使编辑器已连接,agent 也能访问到游戏。

Builder 选项

调用作用
WithConfig(...)在代码中设置 Host、Token、ConnectionMode 和 AuthOption。
WithToolsFromAssembly(...) / WithTools(...)从程序集注册 [AiToolType] 类,或注册指定类型。
WithPromptsFromAssembly(...) / WithPrompts(...)注册 [AiPromptType] 提示类。
WithResourcesFromAssembly(...) / WithResources(...)注册 [AiResourceType] 资源类。
WithRuntimeErrorCapture()捕获游戏内错误,并注册 runtime-errors-get / runtime-errors-clear。默认关闭。
WithScriptExecute()在游戏中注册 script-execute。默认关闭;需要在 .csproj 中选择启用。
ConnectWhenRunFromEditor()当从编辑器用 Play 启动游戏时也进行连接。默认关闭。
WithoutMainThreadDispatcher()跳过自动的主线程调度器(仅在你安装了自己的调度器时使用)。

Host 和 token 也可以来自 GODOT_MCP_* 环境变量或 .env 文件,它们的优先级高于代码。游戏永远不会读取编辑器保存的设置。

提示与资源

除了工具之外,游戏还可以暴露 MCP prompts(具名指令模板,[AiPromptType] 搭配 [AiPrompt] 方法)和 resources(通过 URI 获取的只读内容,[AiResourceType] 搭配 [AiResource] 方法)。这两种类型都是可选的,注册方式与工具相同。

在游戏内运行 C#

要让 agent 在游戏中运行 C#,需要在游戏的 .csproj 中选择启用,并调用 WithScriptExecute():

<PropertyGroup>
  <GodotMcpCodeExecInGame>true</GodotMcpCodeExecInGame>
  <DefineConstants>$(DefineConstants);GODOT_MCP_CODE_EXEC_IN_GAME</DefineConstants>
</PropertyGroup>

此功能仅适用于桌面平台的 CoreCLR 构建,不适用于 NativeAOT 或 iOS。

游戏构建的安全检查清单

  • 优先在 localhost 或 127.0.0.1 上使用 Custom 模式,并配合 AuthOption.token 和真实 token。
  • 只注册你需要的工具;攻击面正是你所注册的那些工具。
  • 在发布构建中,不要把连接暴露在公网网络接口上,除非你已为此做了专门的设计与安全加固。

完整工具列表请参见 工具;打包好的工具集请参见 扩展。