# カスタムツール — Godot · AI Game Developer Wiki

独自のGodot MCPツールをC#で書き、メインスレッドでGodot APIを呼び出し、実行中のGodotゲームからツール、プロンプト、リソースを公開できます。

このページは英語から機械翻訳されています。[英語の原文を読む](https://ai-game.dev/docs/wiki/godot/custom-tools)。

Godot MCP には、プロジェクト内でプレーンな C# を使って独自の MCP ツールを追加できます。カスタムツールとは AI エージェントが呼び出せるメソッドのことで、その動作をモデルに伝える説明が付きます。このページではエディタツール、メインスレッドのルール、そしてエージェントが実行中のゲームとやり取りできるオプトインのランタイムについて説明します。

## エディタツールを作成する

ツールファミリーは `[AiToolType]` でマークされた `partial class` です。各ツールは `[AiTool("tool-name")]` でマークされたメソッドで、モデルがいつ、どのように呼び出せばよいか分かるように、メソッドとすべてのパラメータに `[Description]` を付けます。

```csharp
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` を返します。エージェントが解析する必要があるものに手組みの文字列を使うのは避けてください。
- **任意パラメータを明示する。** デフォルト値付きの nullable 型を使います（例：`string? filter = null`）。そうするとモデルはそのパラメータを任意として扱います。
- **すべてを説明する。** モデルが読むのはこの説明です。ツールが何をするか、いつ使うか、各パラメータが何を意味するかを書いてください。
- **エディタ専用コードは `#if TOOLS` の内側に。** エディタ API を使うコードは、エクスポートされたゲームにコンパイルされてはいけません。

### ヒントとターゲット

`[AiTool]` は `ReadOnlyHint = true` や `IdempotentHint = true` などの任意のヒントを受け取り、ツールが何も変更しないこと、または安全に繰り返せることをクライアントに伝えます。`Target` はツールを登録する場所を決めます：`ToolTarget.Editor`（エディタのみ）、`ToolTarget.Runtime`（ゲームのみ）、またはデフォルトの両方です。

### エージェントにツールを書かせる

システムツール `godot-skill-create` は新しい C# ツールファイルをプロジェクトに書き込みます。ツールは次回のビルド後に呼び出し可能になります。新しいツールを書く前に、その仕事を RQL がすでにカバーしていないか確認してください。エディタのデータアクセスのほとんど（ノード、リソース、ファイル、プロジェクト設定）は 1 回の `rql-query` または `rql-mutate` で済みます。詳しくは [Tools](https://ai-game.dev/ja/docs/wiki/godot/tools#rql) を参照してください。

## 実行中のゲームでのツール

Godot MCP は、実行中またはエクスポートされたゲーム（デバッグ版・リリース版を問わず）の内部でも動作できます。これにより、エージェントはライブのゲーム状態を読み取って操作できます。たとえば、ボットの指し手が LLM から来るチェスゲームなどです。次の 2 点は意図的な設計です：

- **自分から接続することはありません。** `Connect()` を呼ぶかどうか、いつ呼ぶかはあなたのコードが決めます。
- **デフォルトでは何も公開しません。** ツール、プロンプト、リソースはすべて自分で登録します。アドオンのエディタツールはゲームビルドにはコンパイルされません。

`SceneTree` が存在するようになったら起動します。たとえば autoload の `_Ready()` から：

```csharp
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` から）を付けます。これによりエディタはそれらを登録せず、エディタが接続中でもエージェントはゲームに到達できます。

### ビルダーのオプション

| 呼び出し | 動作内容 |
| --- | --- |
| `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()` | 自動のメインスレッドディスパッチャーをスキップします（自前のものを導入する場合のみ）。 |

ホストとトークンは `GODOT_MCP_*` 環境変数や `.env` ファイルからも取得でき、これらはコードより優先されます。ゲームがエディタの保存済み設定を読み取ることはありません。

### プロンプトとリソース

ツールに加えて、ゲームは MCP プロンプト（名前付きの命令テンプレート、`[AiPromptType]` と `[AiPrompt]` メソッド）とリソース（URI で取得する読み取り専用コンテンツ、`[AiResourceType]` と `[AiResource]` メソッド）を公開できます。どちらの種類も任意で、ツールと同じ方法で登録します。

### ゲーム内で C# を実行する

エージェントにゲーム内で C# を実行させるには、ゲームの `.csproj` でオプトインし、`WithScriptExecute()` を呼び出します:

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

これはデスクトップの CoreCLR ビルドでのみ動作し、NativeAOT や iOS では動作しません。

**注意**

ゲーム内の `script-execute` は任意のコード実行であり、ランタイムエラーのキャプチャは、パスやユーザー名、シークレットを含みうる完全なメッセージとスタックトレースを転送します。どちらも開発ビルドでのみ、実際のトークンを使ったループバックホスト上で使用し、公開リリースでは有効にしたまま出荷しないでください。

## ゲームビルドのためのセキュリティチェックリスト

- `localhost` または `127.0.0.1` 上で、`AuthOption.token` と実際のトークンを使う Custom モードを推奨します。
- 必要なツールだけを登録してください。攻撃対象領域は、登録したツールそのものです。
- そのために設計・保護していない限り、リリースビルドでパブリックなネットワークインターフェースに接続を公開しないでください。

ツールの全リストは [ツール](https://ai-game.dev/ja/docs/wiki/godot/tools) を、パッケージ化されたツールセットは [拡張機能](https://ai-game.dev/ja/docs/wiki/godot/extensions) を参照してください。

---

Source (HTML): https://ai-game.dev/ja/docs/wiki/godot/custom-tools

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