Unitymcp
一个由纯C#代码编写的Unity MCP Server,使用HTTP服务器,无需任何外部依赖
Installation
npx unitymcpAsk AI about Unitymcp
Powered by Claude · Grounded in docs
I know everything about Unitymcp. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Unity MCP 統合フレームワーク
Unity Editor と Model Context Protocol (MCP) を統合する拡張フレームワークです。Claude などの AI 言語モデル、または CLI (curl) から、HTTP 経由で Unity Editor を直接操作できます。
🌟 特徴 (v2.1)
- HTTP + UDP アーキテクチャ: 各 Unity Editor が HTTP サーバを持ち、UDP ブロードキャストで自動 discovery
- MCP と HTTP の両方をサポート: Claude Desktop / Claude Code からは MCP tool 経由、スクリプト / CI からは curl 直叩き
- マルチ Editor 対応: 複数 Unity Editor を同時起動しても
targetパラメータ or プロキシで名前指定ルーティング - ドメインリロード耐性:
SessionStateで port を永続化し、リロード跨ぎで同 port を自動再バインド - Editor パネルキャプチャ (Windows): Inspector / Hierarchy / Project / Console などの任意 EditorWindow をスクリーンショット
- built-in コード実行: HTTP
/execute_codeと MCP toolunity_execute_codeが標準装備 (Roslyn 使用) - 拡張可能なプラグインアーキテクチャ:
IMcpCommandHandler/IMcpResourceHandler/BasePromptHandlerを実装すればリフレクションで自動登録 - 統一レスポンスエンベロープ:
{status, result?, error?, truncated?, next?}で成功/エラー/ページングを一貫した形で返す - コンテキスト経済:
limit/offset/fields/detailパラメータでレスポンスを絞り込み可能 - 冪等性分類:
Safe/Unsafeを per-action で宣言し、TS 側がerr.cause.codeを見て再送可否を制御 (副作用操作の二重実行を構造的に排除)
📋 必要条件
- Unity 2022.3 以上 (Unity 6000 系対応)
- 2022.3.22f1、2023.2.19f1、6000.0.35f1、6000.1.17f1 で動作確認
- .NET / C# 9.0
- Node.js 18.0.0 以上 (TypeScript MCP サーバ用)
- Node.js 公式サイト から入手
🚀 はじめに
インストール方法
Unity パッケージマネージャからインストール:
- Window > Package Manager を開く
- 「+」 → 「Add package from git URL...」
https://github.com/isuzu-shiranui/UnityMCP.git?path=jp.shiranui-isuzu.unity-mcpを入力
クイックセットアップ
- Unity Editor を起動すると、
McpEditorInitializerが自動的に HTTP サーバを立ち上げます (127.0.0.1:27182、27182-27199 でフォールバック) - Edit > Preferences > Unity MCP で設定を確認
curl http://127.0.0.1:27182/healthで動作確認
Claude Desktop / Claude Code との連携
インストーラーを使う場合
- Unity Editor で Edit > Preferences > Unity MCP を開く
- 「Open Installer Window」をクリック
- インストーラーの指示に従い、Node.js の存在確認後、TypeScript クライアントをダウンロード
- 「Configuration Preview」セクションの JSON をクリップボードへコピー
- Claude Desktop の Settings > Developer > Edit Config で貼り付けて保存
- Claude Desktop を再起動
💡 macOS 利用者へ: v2.1 で Homebrew 経由の Node (
/opt/homebrew/bin/node、/usr/local/bin/node) の検出に対応しました。Finder から起動した Unity が PATH を継承しない環境でも動作します (#7)。
手動でインストールする場合
unity-mcp-tsリポジトリをクローン or リリース ZIP を取得npm install && npm run buildを実行してbuild/index.jsを生成- Claude Desktop の
claude_desktop_config.jsonに追加:
{
"mcpServers": {
"unity-mcp": {
"command": "node",
"args": ["/absolute/path/to/unity-mcp-ts/build/index.js"]
}
}
}
Windows ではパスのバックスラッシュをエスケープ (\\) するか、フォワードスラッシュを使ってください。
CLI (curl) でも使える
TypeScript サーバ不要で、HTTP 直叩きから操作可能:
# ヘルスチェック
curl http://127.0.0.1:27182/health
# C# コード実行
curl -X POST http://127.0.0.1:27182/execute_code \
-H "Content-Type: application/json" \
-d '{"code":"return GameObject.FindObjectsByType<Transform>(FindObjectsSortMode.None).Length;"}'
# Inspector のスクショ (Windows)
curl -X POST http://127.0.0.1:27182/capture_screenshot \
-H "Content-Type: application/json" \
-d '{"view":"inspector","maxSize":1024}'
マルチ Editor 用にプロキシ経由の例:
# 複数 Unity が起動中なら TS サーバの :27180 で discover
curl http://127.0.0.1:27180/projects
# プロジェクト名指定でリクエスト転送
curl -X POST http://127.0.0.1:27180/proxy/MyProject/health
Skill として ~/.claude/skills/unity-mcp/ に curl ワークフロー集を同梱しています。
🔌 アーキテクチャ (v2.1)
MCP client (Claude)
│ stdio (MCP protocol)
▼
unity-mcp-ts (Node)
├── HandlerAdapter / HandlerDiscovery (MCP tools / prompts / resources)
├── UnityConnection (HTTP fetch + retryableFetch)
│ ├── sendRequest(cmd, params) → POST /command
│ └── sendToEndpoint(path, body) → POST <path> (e.g. /execute_code)
├── ProjectRegistry (UDP :27183, state machine)
└── ProjectApi :27180-27189 (/projects, /proxy/:name/*)
│ HTTP
▼
Unity Editor(s) — McpHttpServer :27182-27199
├── HttpListener + main-thread execution queue
├── Built-in shortcuts + plugin handlers
└── UDP broadcast (27183) every 30s
Unity C# プラグイン
- McpHttpServer: HTTP リスナー + UDP ブロードキャスタ + メインスレッド実行キュー
- IMcpCommandHandler / IMcpResourceHandler: プラグイン拡張用インターフェース (Idempotency 付き)
- McpIdempotency:
Safe/Unsafeenum - ListResponseBuilder:
limit/offset/fieldsを処理する共通ユーティリティ - McpEditorInitializer:
InitializeOnLoad+AssemblyReloadEventsで SessionState 経由 port 復元 - McpHandlerDiscovery: リフレクションでハンドラー自動登録
TypeScript MCP サーバ
- HandlerAdapter: MCP SDK に tools / prompts / resources を登録
- HandlerDiscovery:
src/handlers/を走査してICommandHandler/IPromptHandler/IResourceHandlerを自動登録 - UnityConnection: HTTP クライアント (retry + idempotency + target 解決)
- ProjectRegistry: UDP 受信 + 3 値ステートマシン (healthy / reloading / unhealthy)
- ProjectApi: 27180-27189 の
/projects+/proxy/:name/* - retryableFetch:
err.cause.codeベースで Unsafe は pre-handshake のみリトライ
📄 MCP ハンドラータイプ
| 種別 | 用途 | MCP 制御 | 実装インターフェース |
|---|---|---|---|
| Tools (Command) | アクション実行 | モデル制御 | IMcpCommandHandler (C#) / BaseCommandHandler (TS) |
| Resources | データ提供 | アプリ制御 | IMcpResourceHandler (C#) / BaseResourceHandler (TS) |
| Prompts | テンプレ / ワークフロー | ユーザ制御 | BasePromptHandler (TS のみ) |
📚 組み込みハンドラー
HTTP エンドポイント (Editor 側、built-in)
| Endpoint | Idempotency | 概要 |
|---|---|---|
GET /health | Safe | バージョン、ハンドラー一覧、稼働時間 |
POST /execute_code | Unsafe | Roslyn で C# を動的コンパイル・実行 |
POST /browse_hierarchy | Safe | シーン階層をフィルタ付きで取得 (limit/offset/fields 対応) |
POST /inspect | read/list: Safe、write: Unsafe | GameObject / Component のプロパティ読み書き |
POST /capture_screenshot | Safe | Game / Scene / Editor パネル (inspector / hierarchy / project / console / window:<title>) のキャプチャ |
POST /read_logs | Safe | Console ログを取得 (limit/offset/fields/type) |
POST /play_mode | status: Safe、他: Unsafe | Play Mode 制御 (status/play/stop/pause/unpause/step) |
GET /resource | Safe | assemblies / packages 情報 |
POST /command | per-command | プラグイン系 (menu.execute、console.*) |
MCP tools (TS 側、built-in)
unity_listClients、unity_setActiveClient、unity_connectToProject、unity_getActiveClient、unity_execute_code、console_getLogs、console_getCount、console_clear、console_setFilter、menu_execute
MCP prompts (TS 側、built-in)
code_execute:unity_execute_code用の C# コードテンプレート
すべての tool / endpoint は任意で target パラメータ (projectName or clientId) を受け、複数 Editor 環境でルーティングを明示できます。
🛠️ カスタムハンドラーの作成
コマンドハンドラー (C#)
using Newtonsoft.Json.Linq;
using UnityMCP.Editor.Core;
namespace YourNamespace.Handlers
{
internal sealed class YourCommandHandler : IMcpCommandHandler
{
public string CommandPrefix => "yourprefix";
public string Description => "ハンドラーの説明";
public McpIdempotency Idempotency => McpIdempotency.Safe; // Unsafe なら明示
public JObject Execute(string action, JObject parameters)
{
if (action == "yourAction")
{
return new JObject { ["result"] = "..." };
}
// エンベロープ側で自動的に error envelope に promote される
return new JObject { ["error"] = $"Unknown action: {action}" };
}
}
}
コマンドハンドラー (TypeScript)
import { BaseCommandHandler } from "../core/BaseCommandHandler.js";
import { IMcpToolDefinition } from "../core/interfaces/ICommandHandler.js";
import { JObject } from "../types/index.js";
import { z } from "zod";
export class YourCommandHandler extends BaseCommandHandler {
public get commandPrefix(): string { return "yourprefix"; }
public get description(): string { return "ハンドラーの説明"; }
public getToolDefinitions(): Map<string, IMcpToolDefinition> {
const tools = new Map();
tools.set("yourprefix_yourAction", {
description: "アクションの説明",
parameterSchema: { param1: z.string() }
});
return tools;
}
protected async executeCommand(action: string, parameters: JObject): Promise<JObject> {
return this.sendUnityRequest(`${this.commandPrefix}.${action}`, parameters);
}
}
プロンプトハンドラー (TypeScript)
import { BasePromptHandler } from "../core/BasePromptHandler.js";
import { IMcpPromptDefinition } from "../core/interfaces/IPromptHandler.js";
export class YourPromptHandler extends BasePromptHandler {
public get promptName(): string { return "yourprompt"; }
public get description(): string { return "プロンプトの説明"; }
public getPromptDefinitions(): Map<string, IMcpPromptDefinition> {
const prompts = new Map();
prompts.set("your-template", {
description: "テンプレートの説明",
template: "以下のコードを分析してください:\n{code}"
});
return prompts;
}
}
💡 C# ハンドラーはプロジェクト内のどこに置いても
McpHandlerDiscoveryが自動検出します。TS はunity-mcp-ts/src/handlers/に置けばHandlerDiscoveryが自動登録します。
⚙️ 設定
Unity Editor 設定
Edit > Preferences > Unity MCP:
- HTTP Port: サーバ開始ポート (既定 27182、27182-27199 で先着フォールバック)
- Auto-start on Launch: Editor 起動時に自動開始
- UDP Discovery: UDP ブロードキャスト (ポート 27183、既定 30 秒間隔) の有効化
- Broadcast Interval: UDP 送信間隔
- Port Persistence: ドメインリロード跨ぎで同じ port を維持
- Reload Retry Max MS: TS/CLI 側のリトライ上限のヒント
- Detailed Logs: デバッグログの出力切替
- Handler / Resource Enabled States: ハンドラーごとの有効化トグル
⚠️ v2.1 で
Auto-restart on Play Mode Changeを削除しました。Play Mode 遷移はドメインリロードを伴う場合のみ server を Stop/Start し、AssemblyReloadEvents経由で自動復元します。
TypeScript サーバ環境変数
| Variable | 既定 | 説明 |
|---|---|---|
MCP_RELOAD_RETRY_MAX_MS | 15000 | ドメインリロード中の再試行時間上限 (ms) |
MCP_UNHEALTHY_COOLDOWN_MS | 60000 | reloading → unhealthy への昇格までの猶予 |
MCP_PROJECT_API_PORT | 27180 | ProjectApi 開始ポート (27180-27189 フォールバック) |
MCP_UDP_PORT | 27183 | UDP announce 受信ポート |
MCP_HEALTH_INTERVAL | 10000 | ヘルスポーリング間隔 (ms) |
🧪 テスト
- Unity (EditMode):
Editor/Tests/— 23 ケース (ListResponseBuilder / Envelope / Idempotency / ScreenshotCapture) - TS (Jest):
unity-mcp-ts/src/__tests__/— 68 ケース (UnityConnection / ProjectRegistry / ProjectApi / retry / cache)
cd unity-mcp-ts
npm test # Jest 68/68 pass 期待
🔍 トラブルシューティング
| 症状 | 対応 |
|---|---|
/health に接続できない | Unity Editor が起動しているか、MCP パッケージが import されているか、27182-27199 のいずれかが listen しているか確認 |
target_required エラー | 複数 Unity 起動中 + target 未指定。unity_setActiveClient か target パラメータで明示 |
| ドメインリロード後に切れる | v2.1 では自動再バインド。SessionState が機能していない場合は Unity ログ確認 |
| C# ハンドラーが登録されない | Editor アセンブリで internal/public、IMcpCommandHandler 実装、コンパイルエラー無しを確認 |
| Node が検出されない (Mac) | v2.1 で Homebrew パスにフォールバック対応。最新版を利用 (#7) |
詳細なエラーコードは unity-mcp-ts/README.md または Skill api-reference.md 参照。
🔒 セキュリティ
/execute_codeは任意の C# を実行できます。不特定多数がアクセスできる環境では McpSettings から無効化するか、listener を loopback のみに制限してください (v2.x は既定で 127.0.0.1 のみ bind)。- 外部ネットワーク非公開: HTTP/UDP すべて loopback 限定。LAN 公開はサポート外です。
📖 外部リソース
- Model Context Protocol (MCP) 仕様
- unity-mcp-ts README (TS サーバ詳細)
- Unity パッケージ README (Editor 側詳細)
- CHANGELOG
📄 ライセンス
MIT License — 詳細はリポジトリのライセンスファイルを参照。
Shiranui-Isuzu いすず
