Patina Unity MCP について
Patina Unity MCPは、C#ブリッジを備えたRust製MCPサーバーで、Unity Editorを操作します。AIコーディングツールからローカル接続でシーンやアセット、スクリプトなどを確認・編集できます。
主な機能
- 01シーン階層の確認と編集
- 02GameObjectの作成と変更
- 03プレハブとアセットの管理
- 04スクリプトとコンポーネントの読み書き
- 05スクリプトのコンパイルとエラー確認
- 06検出したクライアントのワンクリック設定
活用シーン
- 01AIコーディングツールからUnityシーンを確認
- 02シーンオブジェクトの作成や変形
- 03プレハブアセットとマテリアルの編集
- 04スクリプトのコンパイルエラー確認
MCP 対応
RustサーバーがUnity EditorのコマンドをMCPツールとして公開し、ローカルTCPブリッジでエディターと通信します。クライアントはstdioでサーバーに接続します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Patina
任意の MCP ホストから Unity Editor を操作できます。パッケージをインストールしてワンクリックするだけで、AI アシスタントがシーンを確認し、オブジェクトを作成し、コンソールとやり取りできるようになります。
Patina は、Rust MCP サーバーと C# Unity ブリッジを組み合わせたものです。手動設定なしで、ローカル TCP チャネルを介してお気に入りの AI コーディングツールを Unity Editor に直接接続します。
Patina を選ぶ理由
- ワンクリックでセットアップ。 UPM パッケージをインストールしてボタンをクリックすると、サポート対象のすべてのホストが自動的に設定されます。
- Rust は不要。 リリースパッケージには Windows、Linux、macOS 用のビルド済みバイナリが含まれています。インストールするだけですぐに使えます。
- 速度を重視した設計。 Rust サイドカーが MCP レイヤーを高速かつ軽量に保ち、Unity はメインスレッドで動作します。
- 複数のホストに対応。 Claude Code、Cursor、VS Code、Gemini CLI、JetBrains Rider、Codex CLI などで動作します。
仕組み
MCP Host <-- stdio --> Patina Server <-- local TCP --> Unity Editor
ホストは stdio MCP 経由で Rust バイナリを起動します。Rust サーバーはローカルのループバック TCP ブリッジを通じて、ツール呼び出しを Unity に転送します。Unity はメインスレッドで実行し、結果を返します。
クイックスタート
1. Unity パッケージをインストールする
Unity で Project Settings > Package Manager を開き、スコープ付きレジストリを追加してから、パッケージ名でインストールします。
スコープ付きレジストリ:
| 項目 | 値 |
|---|---|
| 名前 | npmjs |
| URL | https://registry.npmjs.org |
| スコープ | com.taygunsavas |
次に、Package Manager(Window > Package Manager)を開き、左上の + アイコンをクリックして、Add package by name... を選択し、次を入力します。
com.taygunsavas.patina-unity-mcp
レジストリのリリースは、Unity Package Manager の検証に対応するため、リリースワークフロー中に署名されます。
または、Package Manager を開き、+ アイコンをクリックして、Add package from git URL... を選択し、次を入力します。
https://github.com/taygunsavas/patina-unity-mcp.git?path=/unity-package
Patina は、エディターコード、Plugins/<platform>/ 配下のネイティブ Rust ランタイムバイナリ、インポートに必要な Unity メタデータを含む、完全な Unity パッケージアーティファクトとして配布されます。エンドユーザーが Rust ツールチェーンや、このリポジトリの Git チェックアウトを用意する必要はありません。
2. ワンクリックセットアップを実行する
Window > Patina Unity MCP を開き、One-Click Setup をクリックします。
セットアップの手順では、バイナリの検証、Unity ブリッジの起動、検出されたすべてのホストの自動設定、古い設定の置き換えを行い、必要に応じて再起動の案内を表示します。
Patina は、プロジェクトごとの Unity パッケージキャッシュパスではなく、安定したユーザーレベルのランタイムパスにホスト設定を書き込みます。パッケージを更新すると、Unity エディターパッケージが管理対象ランタイムを自動的に更新するため、パッケージキャッシュのパスが変わっただけで、サポート対象の MCP ホストを再設定する必要はありません。
3. ビルドを始める
MCP ホストを開き、次のように試してみてください。
- 「Unity のコンソールに hello と記録して」
- 「シーンの階層を見せて」
- 「位置 0, 2, 0 に立方体を作成して」
利用可能な機能
Patina は、ホストがすべての Unity コマンドスキーマをコンテキストに読み込まずに済むよう、公開する MCP の機能をコンパクトに保っています。エージェントは次のツールを使用してください。
| MCP ツール | 説明 |
|---|---|
patina_capabilities | Unity コマンドカタログを検索または参照し、特定のコマンドのスキーマのみを要求します |
patina_call | JSON パラメーターを指定して、カタログのコマンドを実行します |
patina_health | Patina のバージョン、コマンド数、ブリッジポート、任意の Unity エディターの状態、ブリッジの診断情報を確認します |
以下の 87 個のコマンドは、patina_capabilities および patina_call から利用できます。
シーン
| ツール | 説明 |
|---|---|
get_hierarchy | アクティブシーンの GameObject ツリーをネストされた JSON として取得します。max_depth と name_filter をサポートします |
get_scene_info | アクティブシーンのメタデータ(名前、パス、ビルドインデックス、ルート数、変更状態)を取得します。読み込み済みのすべてのシーンを対象にするには、include_all_scenes を指定します |
open_scene | プロジェクト相対パスでシーンを開きます。mode は single(デフォルト)または additive です |
save_scene | アクティブシーンまたは読み込み済みの任意のシーンを保存します。名前を付けて保存にも対応しています |
new_scene | 任意で空のシーン、またはデフォルトのゲームオブジェクトを含むシーンを作成して保存します |
GameObject
| ツール | 説明 |
|---|---|
create_game_object | 空の GameObject、または組み込みプリミティブ(Cube、Sphere、Capsule、Cylinder、Plane、Quad)を生成します |
delete_game_object | GameObject とそのすべての子を完全に削除します |
duplicate_game_object | GameObject とその子を複製します |
reparent_game_object | GameObject を新しい親の下に移動します。シーンルートに昇格させるには null を指定します |
get_game_object_info | 指定した GameObject の詳細(トランスフォーム、タグ、レイヤー、すべてのコンポーネントプロパティ)を取得します |
set_active_state | SetActive() を使用して GameObject を表示または非表示にします |
set_tag | GameObject にタグを設定します(タグは Tags & Layers に登録されている必要があります) |
set_layer | 名前でレイヤーを設定します。任意で、すべての子にも適用できます |
set_transform | 1 回の呼び出しで、ワールド空間またはローカル空間の位置、回転(オイラー角)、および/またはスケールを設定します |
コンポーネントとプロパティ
| ツール | 説明 |
|---|---|
add_component | 短縮名(Rigidbody)または完全修飾名でコンポーネントを追加します |
remove_component | 型名でコンポーネントを削除します |
set_property | 名前で指定したコンポーネントのパブリックフィールド、書き込み可能なパブリックプロパティ、または [SerializeField] フィールド(継承されたものを含む)を設定します |
get_game_object_components | GameObject の簡易コンポーネント一覧を返します |
一括操作
| ツール | 説明 |
|---|---|
batch_set_properties | 複数の GameObject に対して、set_property と同様の変更(パブリックメンバーまたは [SerializeField] フィールド)を適用します |
batch_add_components | 複数の GameObject にコンポーネントを追加します |
batch_set_transform | 複数の GameObject にトランスフォームの変更を適用します |
プレハブ
| ツール | 説明 |
|---|---|
create_prefab | シーンの GameObject をプレハブアセットとして保存します |
instantiate_prefab | オプションのワールド座標を指定して、プレハブをシーンにインスタンス化します |
get_prefab_info | プレハブアセットまたはシーンインスタンスを調べます。アセットの種類、オーバーライドの一覧、インスタンスの状態を返します |
unpack_prefab | プレハブインスタンスとのリンクを解除します。outermost(デフォルト)または completely を指定します |
apply_prefab_overrides | インスタンスのすべてのオーバーライドを、ディスク上のソースプレハブアセットに適用します |
revert_prefab_overrides | プレハブインスタンスをソースアセットと一致する状態に戻します |
list_prefab_components | プレハブアセット上のコンポーネントの種類とインスタンス ID を一覧表示します。オプションで、トランスフォームパス付きの子 GameObject も含めます |
edit_prefab_asset | プレハブアセットに対して、一括編集操作(コンポーネントの追加/削除、子の追加/削除、フィールドの設定)を実行します。オブジェクト参照フィールドと、GameObject レベルの layer、tag、isStatic、name、activeSelf も対象です。保存後、変更したコンポーネントで OnValidate を実行し、再度保存します |
open_prefab_stage | 編集のため、Unity のプレハブステージでプレハブアセットを開きます。close_prefab_stage で終了します |
close_prefab_stage | アクティブなプレハブステージを閉じます。save_changes パラメーターを指定すると、Unity のブロッキング保存プロンプトを表示せずに未保存のステージを処理し、保存または破棄を選択できます |
保存と再インポートの後、edit_prefab_asset は、変更した GameObject に対する add_component または set_field で変更された各コンポーネントの種類すべてについて、保存済みアセット上でリフレクションを使って OnValidate を実行し、その後、再度保存します。これにより、そこで計算された状態(Netcode の NetworkObject ハッシュなど)が保持されます。OnValidate が例外をスローした場合もコマンドは成功し、結果には、OnValidate がスキップされた、または例外をスローしたコンポーネントを示す warnings 文字列配列が追加されます。保存済みプレハブを読み込めない場合や、追跡対象のパスまたはコンポーネントを解決できない場合も含まれます。
例:GameObject レベルの値を設定する。
component_type を省略するか、"GameObject" または "UnityEngine.GameObject" を指定すると、set_field は GameObject 自体を対象にします。サポートされている field_name の値は、layer(インデックス 0~31 またはレイヤー名)、tag、isStatic、name、activeSelf です(プレハブルートの名前はアセットファイル名に従うため、ルートでの name は拒否されます)。add_child では、オプションで layer、tag、is_static も指定できます。
{
"asset_path": "Assets/Prefabs/MyPrefab.prefab",
"actions": [
{"action_type": "add_child", "child_name": "Wall0", "layer": "Water", "tag": "Player", "is_static": true},
{"action_type": "set_field", "transform_path": "Wall0", "component_type": "UnityEngine.GameObject", "field_name": "layer", "value": 5}
]
}
例:プレハブ内のコンポーネント参照を設定する。
シリアライズされたフィールドを同じプレハブ内の別のコンポーネントに設定するには、オブジェクト参照値を指定した set_field を含む edit_prefab_asset アクションを渡します。value 内の transform_path は、アクション自身の transform_path ではなく、プレハブルートを基準に解決されます。
{
"asset_path": "Assets/Prefabs/MyPrefab.prefab",
"actions": [
{
"action_type": "set_field",
"component_type": "MyNamespace.MyComponent",
"field_name": "targetReference",
"value": {"transform_path": "Container/Button", "component_type": "MyNamespace.TargetComponent"}
}
]
}
アセット
| ツール | 説明 |
|---|---|
find_assets_by_type | 型フィルター(t:Material、t:Prefab、t:Texture2D など)を使って、アセットデータベースを検索します |
find_assets_by_name | 名前の一部一致でアセットデータベースを検索します |
get_asset_info | アセットのメタデータを取得します。GUID、型、ファイルサイズ、ラベル、インポーター設定が含まれます |
create_folder | アセットデータベースに新しいフォルダーを作成します |
move_asset | アセットをプロジェクト相対パスの新しい場所に移動します |
rename_asset | アセットの名前をその場で変更します |
delete_asset | プロジェクト相対パスを指定してアセットを削除します |
refresh_asset_database | AssetDatabase.Refresh を実行します。差分更新または強制再インポートを指定できます |
set_asset_labels | アセットのラベル一覧全体を置き換えます |
マテリアル
| ツール | 説明 |
|---|---|
create_material | 新しい Material アセットを作成します。デフォルトは URP/Lit です |
get_material_properties | 公開されているシェーダープロパティすべてについて、名前、型、現在の値を読み取ります |
set_material_property | シェーダープロパティ(float、bool、色、ベクトル、またはテクスチャパス)を設定します |
assign_material | 特定の Renderer スロットに Material を割り当てます |
スクリプト
| ツール | 内容 |
|---|---|
create_script | テンプレート(monobehaviour、scriptableobject、editor_window、plain_class、interface)またはそのままの内容から、新しい C# スクリプトを作成します |
resolve_script_type | 完全修飾 C# 型から MonoScript の GUID とアセットパスを解決します |
force_recompile | AssetDatabase.Refresh(ForceUpdate) を介して Unity スクリプトの再コンパイルを実行します |
compile_and_get_errors | スクリプトの再コンパイルを実行し、コンパイラーエラーのみを返します。また、compilationRan、domainReloadObserved、reloadCount も返します |
get_compilation_errors | 現在のコンパイラーエラーと警告の一覧を取得します |
get_script_content | プロジェクト内のスクリプトファイルの内容を読み取ります |
get_assembly_types | 特定のアセンブリで宣言されているすべての型を一覧表示します |
request_script_reload | EditorUtility.RequestScriptReload() を介してドメインの再読み込みをリクエストし、完了後に返します。これにより、再読み込み時のエラーを確認できます |
Scriptable オブジェクト
| ツール | 内容 |
|---|---|
get_scriptable_object | ScriptableObject アセットからシリアライズされたフィールドを読み取ります |
set_scriptable_object_field | シリアライズされた ScriptableObject フィールドを 1 つ設定します |
検証とヘルスチェック
| ツール | 内容 |
|---|---|
validate_scene | アクティブなシーンをスキャンし、品質上の問題(スクリプト参照の欠落、シリアライズされたフィールドの null 値、壊れたプレハブ接続)を検出します |
validate_assets | 1 つのプレハブアセットまたはフォルダーを再帰的に検証し、スクリプトの欠落、壊れたオブジェクト参照、未割り当ての必須シリアライズフィールドを検出します |
get_scene_stats | アクティブなシーンの簡易統計情報(オブジェクト数、コンポーネント数、型の種類ごとの数、最大深度など)を返します |
検索とクエリ
| ツール | 内容 |
|---|---|
find_game_objects_by_tag | 指定されたタグを持つアクティブな GameObject をすべて検索します |
find_game_objects_by_component | 指定されたコンポーネント型を持つシーン内のオブジェクトをすべて検索します |
find_game_objects_by_layer | 指定されたレイヤー名を持つシーン内のオブジェクトをすべて検索します |
query_game_objects | 複合フィルターに一致する GameObject を検索します |
find_game_objects_by_path | 階層パスのプレフィックスで GameObject を検索します |
コンソール
| ツール | 内容 |
|---|---|
log_to_console | Unity コンソールにメッセージ(info、warning、error)を出力します |
get_console_logs | バッファーされたコンソールエントリーを、エントリーごとの phase フィールド(normal、reloadTeardown、reloadStartup)とともに読み取ります。種別でフィルターでき、max_results で件数を制限できます。また、reloadWindowEntryCount も含まれます |
clear_console | コンソールログをすべて消去します |
エディターの状態と制御
| ツール | 内容 |
|---|---|
get_editor_state | 現在のエディターフラグとメインスレッドの応答性を返します。Unity がエディターの更新を処理していない場合は、blockedByModalDialogLikely を含む制限付きのブロック状態を返します |
get_project_settings | 主要なプロジェクト設定(バージョン、ビルドターゲット、色空間、物理演算の重力など)の読み取り専用スナップショットを取得します |
set_play_mode | プレイモードに入る、終了する、一時停止する、一時停止を解除する、またはステップ実行します |
execute_menu_item | エディターメニュー項目をフルパスで実行します(例:Assets/Refresh) |
get_selection | 現在のエディターの選択内容(シーンオブジェクトやアセットパス)を返します |
set_selection | 特定の GameObject やアセットパスをエディターで選択します |
元に戻す
| ツール | 内容 |
|---|---|
begin_undo_group | 名前付きの Unity Undo グループを開始します |
end_undo_group | 操作を現在の Undo グループにまとめます |
undo | 1 回以上の Undo を実行します |
redo | 1 回以上の Redo を実行します |
get_undo_stack | 現在の Undo スタックと Redo スタックのエントリー名を返します |
ビルドとプレイヤーの設定
| ツール | 内容 |
|---|---|
get_build_settings | ビルド設定のスナップショットを取得します。有効なターゲット、スクリプティングバックエンド、シーン一覧全体が含まれます |
set_build_scenes | ビルド設定のシーン一覧を、シーンパスの順序付きリストで置き換えます |
get_player_settings | ビルドターゲットグループ(Standalone、Android、iOS、WebGL)のプレイヤー設定を読み取ります |
set_player_settings | プレイヤー設定のフィールドを書き込みます。変更されるのは null 以外のフィールドだけです |
set_build_target | 有効なビルドターゲットを切り替えます(大規模なプロジェクトではメインスレッドをブロックします) |
テストランナー
| ツール | 内容 |
|---|---|
run_tests | Unity Test Runner の実行を開始します。filter はテスト名またはフルネームの大文字と小文字を区別する部分文字列です。一致するテストがない場合、エラーが返されます。レスポンスには runId と matchedCount が含まれます(フィルターが指定されていない場合、matchedCount は null です) |
get_test_results | 最新のテスト実行結果を、runId、startedAt、finishedAt とともに返します。実行中にドメインリロードが発生すると、これらは空の結果とともに null にリセットされます。これは実行結果が失われたことを意味します |
get_test_list | 利用可能な Unity テストを一覧表示します |
アニメーション
| ツール | 内容 |
|---|---|
get_animator_info | Animator Controller のパラメーターとステート情報を読み取ります |
set_animator_parameter | プレイモードで Animator のパラメーターを設定します |
list_animation_clips | プロジェクト内の AnimationClip アセットを一覧表示します |
対応ホスト
| ホスト | セットアップ |
|---|---|
| Antigravity CLI (agy) | 自動 |
| Claude Code (Anthropic CLI) | 自動(~/.claude.json) |
| Claude Desktop | 自動 |
| Cursor | 自動 |
| Visual Studio Code | 自動 |
| GitHub Copilot (VS Code) | VS Code の設定経由でリンク |
| Gemini CLI | 自動 |
| JetBrains Rider / Junie | 自動 |
| Codex CLI | 自動 |
セットアップウィンドウでは、古いエントリーや見つからないホストも検出され、ホストから Patina を削除するための操作も利用できます。
トラブルシューティング
Patina の呼び出しで EDITOR_BLOCKED が報告される場合や、Unity がモーダルダイアログを待っている可能性があるというメッセージが表示される場合は、Unity Editor に変更の保存を促すメッセージなど、操作を妨げるポップアップが表示されていないか確認してください。Unity がユーザー入力を待っている間、Patina はキューに入ったエディターコマンドを安全に実行できません。Unity のメッセージに対応してから、MCP コマンドを再試行するか、{"include_unity_state": true} を指定して patina_health を実行してください。
Prefab ステージの保存ダイアログ
Patina は、モーダルダイアログで処理を止めるのではなく、保存するかどうかの問いにプログラムで応答することで、変更のある Prefab ステージに対応します。close_prefab_stage を呼び出すと、save_changes パラメーターによって結果が直接決まります。true の場合は保存し、false(デフォルト)の場合は変更を破棄します。この設定は該当するコマンド呼び出しにのみ適用され、人が手動で作業しているときの Editor の動作は変更しません。
モーダルダイアログが表示されると、Unity のメインスレッドがブロックされ、人がダイアログを閉じるまでその状態が続きます。キューに入ったすべてのコマンドは、同じブロックされたスレッドで処理されるため、実質的な解決策は発生を防ぐことだけです。エージェントが記述したエディタースクリプトでは、PrefabUtility.LoadPrefabContents で Prefab を読み込み、SerializedObject に変更を適用し、PrefabUtility.SaveAsPrefabAsset で保存してから、PrefabUtility.UnloadPrefabContents を呼び出す方法が安全です。この方法では Prefab ステージは開きません。ステージを開く必要がある場合は、close_prefab_stage で閉じてください。変更のあるステージを残したまま、手動で StageUtility.GoToMainStage() を呼び出すと、Editor がロックされます。
Unity には、プロセス全体でダイアログを無効にする起動フラグ -automated があります。エージェントだけが操作する Editor では適している場合がありますが、人とエージェントが同じ Editor を共有するハイブリッドなワークフローでは問題が発生します。未保存の変更に対する確認が表示されず、一部の操作が通知なしにキャンセルされます。Patina では -automated は不要です。コマンド単位でダイアログに応答する機能は、このフラグなしでも確実に動作し、-automated を指定して起動した Editor でも正しく動作します。
現在の Editor の状態とダイアログの自動化状況を確認するには、patina_health を呼び出し、デフォルトの出力で broker.sessions[].automated を確認するか、{"include_unity_state": true} を渡して isAutomatedMode と dialogAutomationAvailable を確認してください。
ロードマップ
| フェーズ | 主な内容 |
|---|---|
| フェーズ 1 ✓ | コアツール:コンソール、ヒエラルキー、オブジェクトの作成 |
| フェーズ 2 ✓ | 対応範囲の拡大:シーン管理、アセット操作、コンポーネント編集 |
| フェーズ 3(現在) | 配布と普及:Git URL インストール用ドキュメント、パッケージ構成、リリースパイプライン |
ローカル開発
コントリビューター向けのソースチェックアウト
リポジトリから unity-package/ または rust-server/ を直接編集する場合に使用してください。
- Unity でローカルのパッケージチェックアウトを指定します。
file:<your-clone-path>/unity-package
- Rust サーバーをビルドします。
cd rust-server && cargo build --release
- 現在のバイナリをローカル開発ランタイムパスに公開します。
# Windows
pwsh -File scripts/publish-dev-runtime.ps1
# macOS / Linux
./scripts/publish-dev-runtime.sh
- Unity で Window > Patina Unity MCP を開き、Use Local Runtime (Contributor) を有効にして、One-Click Setup をクリックします。
これにより、管理対象のパッケージランタイムではなく、ローカル開発ランタイムを参照するホスト設定が書き込まれます。新たに cargo build --release と publish-dev-runtime を実行するたびに、One-Click Setup を再実行してください。パッケージ版のワークフローに戻す前に、Remove Patina From Hosts を使用してください。
ローカル UPM テストパッケージをステージングする
ソースチェックアウトそのものではなく、公開時の状態でパッケージをテストする場合に使用してください。
pwsh -File scripts/stage-local-upm.ps1
次に、Unity でディスク上のステージング済みパッケージを追加します。
dist/local-upm/com.taygunsavas.patina-unity-mcp/package.json
パッケージ構成、インポート動作、リリース用パッケージを検証する場合は、ステージング済みのローカルパッケージを推奨します。ソースを直接編集して、編集からビルド、実行までを最速で繰り返したい場合は、ソースチェックアウトのパスを推奨します。
コントリビューター向けワークフローの詳細は、CONTRIBUTING.md を参照してください。
コミュニティとコントリビューション
- ローカルでの開発手順、検証の要件、プルリクエストのガイドラインについては、まず CONTRIBUTING.md をご確認ください。
- 再現可能なバグ、機能の提案、使い方に関する質問には GitHub の issue フォームを使用して、メンテナーが必要な情報を得られるようにしてください。
- サポートを依頼する前に .github/SUPPORT.md をお読みください。
- 脆弱性を非公開で報告する方法については .github/SECURITY.md をお読みください。
- issue やプルリクエストに参加する前に .github/CODE_OF_CONDUCT.md をお読みください。
mainを対象とするプルリクエストは、CI に合格し、リポジトリのルールが有効になった後は CODEOWNERS と Copilot によるレビューを受ける必要があります。
要件
- Unity 6(6000.3 LTS 以降)
- サポート対象の MCP ホスト
- Rust 1.75 以降(コントリビューターのみ)
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。