UnityNaturalMCPで独自のMCPツールをC#で自由に作ってClaude Codeにそれを実行させる方法です。
Unity6000.2.0f1
UnityNaturalMCP 0.5.0
UnityNaturalMCPとは?
UnityNaturalMCPはUnityエディタを操作するためのMCPサーバです。
基本的な使い方は以下の記事で解説していますので、必要に応じて参照してください。
このUnityNaturalMCPの特徴として、C#で独自のMCPツールを作成できるという点があります。
そこで本記事では、UnityNaturalMCPでカスタムMCPツールを作ってClaude Codeに独自の処理を実行させる方法をまとめます。
作るもの
UnityNaturalMCPはデフォルトではアセットを作ることができません。
そこで、指定した型のScriptableObjectのアセットを作るツールを作ってみます。
以下のScriptableObjectクラスを作成しておき、このアセットが生成できることをゴールとします。
using UnityEngine; public class ExampleConfig : ScriptableObject { public int maxLives = 3; public float moveSpeed = 5f; }
ツールを作る
まず指定したScriptableObjectのアセットを作るツールを作成します。
説明はコメントとして記載しました。
using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Threading.Tasks; using Cysharp.Threading.Tasks; using ModelContextProtocol.Server; using UnityEditor; using UnityEngine; [McpServerToolType] [Description("ScriptableObjectのアセットを作成するためのツール")] public class ScriptableObjectTools { [McpServerTool] [Description("指定型のScriptableObjectのアセットを新規作成")] // 非同期メソッドにする場合、戻り値はValueTaskで public async ValueTask<Dictionary<string, string>> CreateScriptableObject(string typeName, string assetPath) { try { // メインスレッドに切り替え(サブスレッドから呼ばれる可能性もあるが、UnityAPIは対応してないため) await UniTask.SwitchToMainThread(); // 型名からScriptableObjectの型を取得 var type = FindTypeByName(typeName); var instance = ScriptableObject.CreateInstance(type); // フォルダ作成 var directory = Path.GetDirectoryName(assetPath); if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) Directory.CreateDirectory(directory); // アセット作成 AssetDatabase.CreateAsset(instance, assetPath); // アセットの情報を返す var guid = AssetDatabase.AssetPathToGUID(assetPath); return new Dictionary<string, string> { { "guid", guid }, { "path", assetPath }, { "type", typeName }, { "name", instance.name } }; } catch (Exception e) { // UnityNaturalMCPのREADMEより: // > MCPツール内でエラーが発生した場合、それはログに表示されません。 // > try-catchブロックを使用して、エラーをログに記録し、再スローすることを推奨します。 Debug.LogError(e); throw; } } private static Type FindTypeByName(string typeName) { var type = Type.GetType(typeName); if (type != null) { if (!typeof(ScriptableObject).IsAssignableFrom(type)) throw new Exception($"Type is not ScriptableObject: {typeName}"); return type; } var scriptableObjectTypes = TypeCache.GetTypesDerivedFrom<ScriptableObject>(); type = scriptableObjectTypes.FirstOrDefault(t => t.FullName == typeName); if (type != null) return type; type = scriptableObjectTypes.FirstOrDefault(t => t.Name == typeName); if (type != null) return type; throw new Exception($"Type not found: {typeName}"); } }
ツールビルダーを作る
次にこのツールをMCPサーバに登録するためのスクリプト(ツールビルダー)を作成します。
ボイラープレートです。
using Microsoft.Extensions.DependencyInjection; using UnityEngine; using UnityNaturalMCP.Editor; [CreateAssetMenu(fileName = "ScriptableObjectToolsBuilder", menuName = "UnityNaturalMCP/ScriptableObject Tools Builder")] public class McpScriptableObjectToolsBuilder : McpBuilderScriptableObject { public override void Build(IMcpServerBuilder builder) { builder.WithTools<ScriptableObjectTools>(); } }
基底クラスを見るとわかるように、ツールビルダーはScriptableObjectになっています。
このScriptableObjectのアセットを作成することで、ツールがMCPサーバに登録されます。
CreateAssetMenuアトリビュートに指定したメニュー(今回であればAssets > Create > UnityNaturalMCP > ScriptableObject Tools Builder)を実行し、このビルダーのアセットを作成します。
ここまででツールのクラスとツールビルダーのクラスおよびそのScriptableObjectアセットができました。
MCPサーバの更新
ここまでできたら Edit > Project Settings > Unity Natural MCP > Refresh
でMCPサーバを再起動します。
(手元の環境ではさらにClaudeCodeを一度再起動しないとうまくいきませんでした。
これでMCPサーバにツールが読み込まれたはずです。以下のようにClaude Codeに聞いてみましょう。
UnityNaturalMCPで使えるツールを全部教えて
返答はこんな感じです。CreateScriptableObjectがあるので正常に更新されてそうです。
⏺ UnityNaturalMCPで利用可能なツールは以下の6つです: 1. RunPlayModeTests - Play Modeのテストを実行 2. RunEditModeTests - Edit Modeのテストを実行 3. CreateScriptableObject - 指定型のScriptableObjectアセットを新規作成 4. GetCurrentConsoleLogs - 現在のコンソールログを取得 5. ClearConsoleLogs - コンソールログをクリア 6. RefreshAssets - AssetDatabase.Refresh()を実行(スクリプトコンパイル時にも必要) 7. GetCompileLogs - コンパイルエラーを取得 各ツールはフィルタリングやオプション設定が可能で、テスト実行時はassemblyNames、groupNames、tes tNamesでの絞り込み、ログ取得時はlogTypes、filter、maxCountなどでの制御ができます。
動作確認
それでは次に以下のようにClaude Codeに指示してみましょう。
ExampleConfigのアセットを作って
すると以下のようなメッセージと共に、アセットを作成してくれることを確認できます。
⏺ ExampleConfigのScriptableObjectアセットを作成します。 ⏺ unity-natural-mcp - CreateScriptableObject (MCP)(typeName: "ExampleConfig", assetPath: "Assets/ExampleConfig.asset") ⎿ { "guid": "668cbf529834644f6bfc027587b69711", "path": "Assets/ExampleConfig.asset", "type": "ExampleConfig", "name": "ExampleConfig" } ⏺ ExampleConfigアセットを作成しました。 - パス: Assets/ExampleConfig.asset - GUID: 668cbf529834644f6bfc027587b69711