自訂工具
用 C# 撰寫你自己的 Godot MCP 工具,在主執行緒上呼叫 Godot API,並從執行中的 Godot 遊戲對外提供工具、提示詞與資源。
你可以在專案內用純 C# 將自己的 MCP 工具加進 Godot MCP。自訂工具就是一個 AI 代理可以呼叫的方法,並附上描述告訴模型它的用途。本頁涵蓋編輯器工具、主執行緒規則,以及讓代理能與執行中遊戲溝通的選用執行階段。
撰寫編輯器工具
工具家族是一個標上 [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,或請代理執行 script-build)。Godot 會重新載入組件,外掛會重新連線,新工具就會出現在代理的工具清單與停靠面板的 Tools 視窗中。
讓工具保持可靠的規則
- Godot 物件只能在主執行緒操作。 工具方法是在主執行緒之外被呼叫的。任何對
Node、Resource、SceneTree或EditorInterface的呼叫都必須透過MainThread.Instance.Run(...)進行。從背景執行緒存取它們可能導致編輯器當機。 - 回傳資料,而非格式化文字。 回傳帶有屬性的類別(會序列化給模型),或對只有副作用的工具回傳
void。凡是代理需要解析的內容,都避免自己拼接字串。 - 標記選用參數。 使用可為 null 的型別並給予預設值,例如
string? filter = null,模型就會把該參數視為選用。 - 把一切描述清楚。 模型讀的就是這些描述。說明工具做什麼、何時使用,以及每個參數代表什麼。
- 僅限編輯器的程式碼要放在
#if TOOLS之後。 使用編輯器 API 的程式碼絕不能編譯進匯出的遊戲中。
提示與目標
[AiTool] 可接受選用提示,例如 ReadOnlyHint = true 與 IdempotentHint = true,用來告訴用戶端該工具不會改變任何東西,或可安全地重複執行。Target 決定工具註冊的位置:ToolTarget.Editor(僅編輯器)、ToolTarget.Runtime(僅遊戲),或預設的兩者皆可。
讓代理來撰寫工具
系統工具 godot-skill-create 會在你的專案中寫入新的 C# 工具檔案;下次建置後該工具即可被呼叫。在撰寫新工具之前,先確認 RQL 是否已能完成這件事:大多數的編輯器資料存取(節點、資源、檔案、專案設定)只要一次 rql-query 或 rql-mutate 就能搞定。參見 Tools。
執行中遊戲裡的工具
Godot MCP 也能在執行中或已匯出的遊戲內運作,無論是 debug 或 release 版本。這讓代理能讀取並驅動即時的遊戲狀態,例如一款由 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)標記僅限遊戲的工具類別,這樣編輯器就不會註冊它們,即使編輯器已連線,代理仍能連到遊戲。
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與真實權杖。 - 只註冊你需要的工具;攻擊面就正好是你註冊的那些工具。
- 除非你已針對此用途設計並做好防護,否則不要在發行組建中把連線暴露在公開網路介面上。
完整的工具清單請見 Tools;打包好的工具集請見 Extensions。