# Unity MCP Server Architecture
UnityにおけるMCP (Model Context Protocol) サーバーの構築ガイドと技術仕様。
---
## 概要
Unity MCP Serverは、Claude CodeなどのAIツールからUnity Editorを操作するためのサーバーです。MCP (Model Context Protocol) に準拠し、JSON-RPC 2.0ベースの通信を行います。
### アーキテクチャ図

<details>
<summary>テキスト版(ASCII図)</summary>
```
┌─────────────────────────────────────────────────────────────────┐
│ Claude Code │
└─────────────────────────────────────────────────────────────────┘
│ stdio
▼
┌─────────────────────────────────────────────────────────────────┐
│ MCP Bridge (Node.js) │
│ Server~/mcp-bridge/index.js │
└─────────────────────────────────────────────────────────────────┘
│ HTTP (port 5051)
▼
┌─────────────────────────────────────────────────────────────────┐
│ Unity Editor │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ UnityMcpHttpServer (HTTP) │ │
│ │ port 5051 │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ API Router │ │ │
│ │ │ - tools/list → ApiRegistry │ │ │
│ │ │ - tools/call → Controller Methods │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ UnityMcpServer (WebSocket) │ │
│ │ port 5050 │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ McpSession │ │ │
│ │ │ - WebSocket Handshake │ │ │
│ │ │ - JSON-RPC Message Processing │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ ApiRegistry │ │
│ │ - API Definitions (770+ APIs) │ │
│ │ - Edition Filtering (Public/Standard/Pro) │ │
│ │ - tools/list Response Generation │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Controllers │ │
│ │ - SceneController │ │
│ │ - GameObjectController │ │
│ │ - ComponentController │ │
│ │ - AudioController │ │
│ │ - ... (50+ Controllers) │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
</details>
### JSON-RPC リクエストフロー

---
## コアコンポーネント
### 1. UnityMcpServer (WebSocket)
**ファイル:** `Editor/UnityMcpServer.cs`
WebSocketサーバーのメインクラス。TCPリスナーでクライアント接続を受け付け、各接続に対してMcpSessionを生成します。
```csharp
public class UnityMcpServer
{
private TcpListener tcpListener;
private int port = 5050;
private List<McpSession> activeSessions;
public void StartServer(int serverPort = 5050);
public void StopServer();
}
```
**特徴:**
- シングルトンパターン (`Instance`)
- バックグラウンドスレッドで動作
- 複数クライアントの同時接続対応
- Unity Editor終了時の自動クリーンアップ
### 2. McpSession
**ファイル:** `Editor/McpSession.cs`
個々のWebSocket接続を管理するクラス。WebSocketハンドシェイク、JSON-RPCメッセージの受信・処理を行います。
```csharp
public class McpSession
{
private TcpClient client;
private NetworkStream stream;
public void HandleClient(); // メインループ
private bool PerformWebSocketHandshake(); // WebSocketハンドシェイク
private void ProcessMessage(string json); // JSON-RPC処理
public void SendMessage(string message); // メッセージ送信
}
```
**WebSocketハンドシェイク:**
```
Client → Server: HTTP Upgrade Request
Sec-WebSocket-Key: xxx
Server → Client: HTTP 101 Switching Protocols
Sec-WebSocket-Accept: yyy
```
### 3. UnityMcpHttpServer (HTTP)
**ファイル:** `Editor/UnityMcpHttpServer.cs`
HTTP REST APIサーバー。MCPブリッジからのリクエストを受け付けます。
```csharp
public class UnityMcpHttpServer
{
private HttpListener httpListener;
private int port = 5051;
public void StartServer(int serverPort = 5051);
public void StopServer();
}
```
**エンドポイント:**
| エンドポイント | メソッド | 説明 |
|---------------|---------|------|
| `/health` | GET | ヘルスチェック |
| `/api/mcp` | POST | JSON-RPC リクエスト |
### 4. ApiRegistry
**ファイル:** `Editor/ApiRegistry.cs`
API定義を管理するレジストリ。MCP `tools/list` レスポンスを生成します。
```csharp
public static class ApiRegistry
{
public static McpEdition CurrentEdition { get; set; }
public static List<ApiDefinition> GetAllApis();
public static List<ApiDefinition> GetApisByCategory(string category);
public static string GenerateToolsList();
}
public class ApiDefinition
{
public string name; // "unity.scene.list"
public string category; // "scene"
public string description; // API説明
public McpEdition edition; // Public/Standard/Pro
public InputSchema inputSchema;
}
```
**エディション:**

| エディション | API数 | 対象 |
|-------------|-------|------|
| Public | ~100 | 基本操作 (scene, gameObject, component, prefab, asset) |
| Standard | ~350 | 拡張機能 (timeline, cinemachine, recorder, uitoolkit) |
| Pro | ~770 | 全機能 (probuilder, lighting, shadergraph, audio) |
---
## JSON-RPC 2.0 プロトコル
### リクエスト形式
```json
{
"jsonrpc": "2.0",
"method": "unity.scene.list",
"params": {
"maxDepth": 2
},
"id": 1
}
```
### レスポンス形式(成功)
```json
{
"jsonrpc": "2.0",
"result": {
"sceneName": "SampleScene",
"objects": [...]
},
"id": 1
}
```
### レスポンス形式(エラー)
```json
{
"jsonrpc": "2.0",
"error": {
"code": -32600,
"message": "GameObject not found: Player"
},
"id": 1
}
```
---
## MCP標準メソッド
### tools/list
利用可能なAPIの一覧を返します。
**リクエスト:**
```json
{
"jsonrpc": "2.0",
"method": "tools/list",
"params": {},
"id": 1
}
```
**レスポンス:**
```json
{
"jsonrpc": "2.0",
"result": {
"tools": [
{
"name": "unity.scene.list",
"description": "シーン内のGameObject一覧を取得",
"inputSchema": {
"type": "object",
"properties": {
"maxDepth": {
"type": "integer",
"description": "階層の深さ"
}
}
}
}
]
},
"id": 1
}
```
### tools/call
指定したAPIを実行します。
**リクエスト:**
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unity.gameObject.create",
"arguments": {
"name": "NewObject",
"parentPath": "/Canvas"
}
},
"id": 2
}
```
---
## Controller パターン
### 基本構造
```csharp
public static class ExampleController
{
// パラメータクラス
public class CreateParams
{
public string name;
public string parentPath;
}
// 結果クラス
public class CreateResult
{
public bool success;
public string path;
}
// APIメソッド
public static string Create(string paramsJson, object id)
{
try
{
var p = JsonUtility.FromJson<CreateParams>(paramsJson);
// Unity API操作
var go = new GameObject(p.name);
Undo.RegisterCreatedObjectUndo(go, "Create Object");
// 結果を返す
var result = new CreateResult { success = true, path = go.name };
return JsonRpcResponse.Success(result, id).ToJson();
}
catch (Exception e)
{
return JsonRpcResponse.Error(e.Message, id).ToJson();
}
}
}
```
### 命名規則
| 項目 | 規則 | 例 |
|------|------|-----|
| API名 | `unity.{category}.{action}` | `unity.audio.createSource` |
| Controllerクラス | `{Category}Controller` | `AudioController` |
| パラメータクラス | `{Action}Params` | `CreateSourceParams` |
| 結果クラス | `{Action}Result` | `AudioSourceInfo` |
---
## ルーティング
### HTTP ルーティング (UnityMcpHttpServer.cs)
```csharp
private string RouteToolCall(string method, string paramsJson, object id)
{
// Audio API
if (method == "unity.audio.createSource")
return AudioController.CreateSource(paramsJson, id);
if (method == "unity.audio.play")
return AudioController.Play(paramsJson, id);
// Scene API
if (method == "unity.scene.list")
return SceneController.List(paramsJson, id);
// ... 他のAPI
}
```
### WebSocket ルーティング (McpSession.cs)
HTTPと同様の構造。両方に同じルーティングを追加する必要があります。
---
## ファイル構成

```
Editor/
├── UnityMcpServer.cs # WebSocketサーバー本体
├── McpSession.cs # WebSocketセッション管理
├── UnityMcpHttpServer.cs # HTTPサーバー
├── ApiRegistry.cs # API定義レジストリ
├── JsonRpcResponse.cs # JSON-RPCレスポンスヘルパー
├── McpSetupWindow.cs # セットアップGUI
│
├── SceneController.cs # シーン操作API
├── GameObjectController.cs # GameObject操作API
├── ComponentController.cs # コンポーネント操作API
├── AudioController.cs # オーディオAPI
├── ... # その他のController
│
├── Timeline/ # パッケージ依存API
│ ├── TimelineBuilder.cs
│ └── LocalMcp.UnityServer.Timeline.Editor.asmdef
│
├── Cinemachine/
├── ProBuilder/
├── Volume/
└── ...
Server~/
└── mcp-bridge/
├── index.js # MCPブリッジ(Node.js)
├── package.json
└── README.md
```
---
## 自動起動
### McpAutoStart.cs
Unity Editor起動時にサーバーを自動起動します。
```csharp
[InitializeOnLoad]
public static class McpAutoStart
{
static McpAutoStart()
{
EditorApplication.delayCall += () =>
{
var wsServer = new UnityMcpServer();
wsServer.StartServer(5050);
var httpServer = new UnityMcpHttpServer();
httpServer.StartServer(5051);
// ランタイム設定ファイルを生成
WriteRuntimeConfig();
};
}
}
```
### .unity-mcp-runtime.json
```json
{
"projectName": "MyProject",
"projectPath": "/path/to/project",
"unityVersion": "6000.2.8f1",
"wsPort": 5050,
"httpPort": 5051,
"serverVersion": "0.7.2",
"timestamp": "2025-12-19T10:00:00Z"
}
```
---
## Assembly Definition
### パッケージ依存APIの分離
パッケージ依存のAPIは専用のasmdefで分離し、パッケージ未インストール時のコンパイルエラーを防止します。
```json
// Editor/Timeline/LocalMcp.UnityServer.Timeline.Editor.asmdef
{
"name": "LocalMcp.UnityServer.Timeline.Editor",
"references": ["Unity.Timeline", "Unity.Timeline.Editor"],
"includePlatforms": ["Editor"],
"defineConstraints": ["UNITY_TIMELINE"],
"versionDefines": [
{
"name": "com.unity.timeline",
"expression": "1.0.0",
"define": "UNITY_TIMELINE"
}
]
}
```
### リフレクションベース呼び出し
メインasmdefからパッケージ依存APIを呼び出す場合はリフレクションを使用:
```csharp
// PackageApiInvoker.cs
public static string Invoke(string assemblyName, string typeName,
string methodName, string paramsJson, object id)
{
var assembly = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == assemblyName);
if (assembly == null)
return JsonRpcResponse.Error("Package not installed", id).ToJson();
var type = assembly.GetType(typeName);
var method = type.GetMethod(methodName);
return (string)method.Invoke(null, new object[] { paramsJson, id });
}
```
---
## エラーハンドリング
### 標準エラーコード
| コード | 説明 |
|--------|------|
| -32700 | Parse error (JSONパースエラー) |
| -32600 | Invalid Request |
| -32601 | Method not found |
| -32602 | Invalid params |
| -32603 | Internal error |
### カスタムエラー
```csharp
return JsonRpcResponse.Error("GameObject not found: " + path, id).ToJson();
```
---
## ベストプラクティス
### 1. Undo対応
すべての変更操作にUndoを登録:
```csharp
Undo.RegisterCreatedObjectUndo(go, "Create Object");
Undo.RecordObject(component, "Modify Component");
```
### 2. メインスレッド実行
Unity APIはメインスレッドでのみ実行可能。`EditorApplication.delayCall`を使用:
```csharp
EditorApplication.delayCall += () =>
{
// Unity API操作
};
```
### 3. エディションフィルタリング
APIをエディションで分類:
```csharp
AddApi(new ApiDefinition {
name = "unity.probuilder.createPrimitive",
edition = McpEdition.Pro, // Pro限定API
// ...
});
```
---
## バージョン情報
### MCP Server 1.0 (現行)
現在のアーキテクチャは **MCP Server 1.0** として位置づけられます。
**特徴:**
- Node.js MCP Bridge によるプロトコル変換
- HTTP/WebSocket 二重サーバー構成
- 770+ API の一括提供 (`tools/list`)
- エディション別フィルタリング (Public/Standard/Pro)
- リフレクションベースのパッケージ依存API呼び出し
**課題:** (GitHub Issues #77-#82)
- API数の爆発問題(LLMのコンテキストを圧迫)
- Node.jsブリッジのオーバーヘッド
- API選択・発見の非効率性
- セットアップの複雑さ
- リアルタイム性の欠如
- エラーハンドリングの不十分さ
---
## MCP Server 2.0 ロードマップ
### アーキテクチャ概要

**2.0 の主要コンポーネント:**
- **Native MCP Server (C#)**: Node.js 不要、直接 stdio 通信
- **Dynamic API Loader**: カテゴリベースの動的 API 提供
- **API Recommender**: シーン状態に基づく API 推薦
- **Event Notifier**: Unity → Claude Code へのプッシュ通知
- **IPC Bridge**: Unity Editor との高速プロセス間通信
### 2.0 の主要改善点
#### 1. Node.js ブリッジの排除 (Issue #78)
**現状 (1.0):**
```
Claude Code → stdio → Node.js Bridge → HTTP → Unity
```
**目標 (2.0):**
```
Claude Code → stdio → Unity (Native MCP Server)
```
**実装アプローチ:**
- C# で MCP プロトコルを直接実装
- `System.Console` の stdin/stdout を使用
- Unity Editor 起動時に別プロセスとして MCP Server を起動
- IPC (Inter-Process Communication) で Unity Editor と通信
```csharp
// 構想: NativeMcpServer.cs
public class NativeMcpServer
{
public void Start()
{
// stdin から JSON-RPC メッセージを読み取り
while (true)
{
var line = Console.ReadLine();
var response = ProcessMessage(line);
Console.WriteLine(response);
}
}
}
```
#### 2. カテゴリベース動的API提供 (Issue #77, #79)
**現状 (1.0):**
- `tools/list` で 770+ API を一括返却
- LLM のコンテキストを大量消費
**目標 (2.0):**
- 階層的 API ディスカバリ
- 必要な時に必要な API のみを提供
**実装アプローチ:**
```json
// Step 1: カテゴリ一覧を取得
{
"method": "tools/list",
"params": { "level": "categories" }
}
// → ["scene", "gameObject", "timeline", "audio", ...]
// Step 2: 特定カテゴリのAPIを取得
{
"method": "tools/list",
"params": { "category": "timeline" }
}
// → timeline関連の42 APIのみ返却
```
**API階層設計:**
```
unity.
├── core/ # 常に利用可能(~30 API)
│ ├── scene.*
│ ├── gameObject.*
│ └── log.*
│
├── standard/ # 要求時に展開
│ ├── timeline.*
│ ├── cinemachine.*
│ └── animator.*
│
└── pro/ # 要求時に展開
├── probuilder.*
├── lighting.*
└── volume.*
```
#### 3. スマートAPI推薦 (Issue #79)
**コンテキスト認識型API提案:**
```csharp
public class ApiRecommender
{
// 現在のシーン状態から推奨APIを返す
public List<string> GetRecommendedApis()
{
var recommendations = new List<string>();
// Timeline がシーンにあれば timeline API を推奨
if (HasTimelineInScene())
recommendations.Add("timeline");
// Cinemachine カメラがあれば cinemachine API を推奨
if (HasCinemachineCamera())
recommendations.Add("cinemachine");
// 選択中のオブジェクトに基づく推奨
if (Selection.activeGameObject?.GetComponent<AudioSource>())
recommendations.Add("audio");
return recommendations;
}
}
```
#### 4. リアルタイムイベント通知 (Issue #81)
**現状 (1.0):**
- ポーリングベース(状態確認は毎回 API 呼び出し)
**目標 (2.0):**
- プッシュ型イベント通知
- Unity Editor の変更を即座に LLM へ通知
**実装アプローチ:**
```csharp
// MCP notifications (Server → Client)
public class UnityEventNotifier
{
public void Initialize()
{
// シーン変更を監視
EditorSceneManager.sceneOpened += (scene, mode) =>
{
SendNotification("unity/sceneChanged", new {
sceneName = scene.name,
scenePath = scene.path
});
};
// 選択変更を監視
Selection.selectionChanged += () =>
{
SendNotification("unity/selectionChanged", new {
selectedObjects = Selection.gameObjects.Select(g => g.name)
});
};
// コンパイル状態を監視
CompilationPipeline.compilationStarted += _ =>
{
SendNotification("unity/compilationStarted", new { });
};
}
private void SendNotification(string method, object data)
{
var notification = new {
jsonrpc = "2.0",
method = method,
@params = data
};
Console.WriteLine(JsonUtility.ToJson(notification));
}
}
```
**通知イベント一覧:**
| イベント | 説明 |
|---------|------|
| `unity/sceneChanged` | シーン変更 |
| `unity/selectionChanged` | 選択オブジェクト変更 |
| `unity/hierarchyChanged` | ヒエラルキー構造変更 |
| `unity/compilationStarted` | コンパイル開始 |
| `unity/compilationFinished` | コンパイル完了 |
| `unity/playModeChanged` | Play/Edit モード変更 |
| `unity/assetImported` | アセットインポート完了 |
#### 5. エラーハンドリング強化 (Issue #82)
**構造化エラーレスポンス:**
```json
{
"jsonrpc": "2.0",
"error": {
"code": -32001,
"message": "GameObject not found",
"data": {
"errorType": "NotFound",
"searchedPath": "/Canvas/Button",
"suggestions": ["/Canvas/StartButton", "/Canvas/ExitButton"],
"context": {
"sceneObjects": ["Canvas", "EventSystem", "Main Camera"]
},
"documentation": "https://docs.unity3d.com/..."
}
},
"id": 1
}
```
**エラーカテゴリ:**
| コード | カテゴリ | 説明 |
|--------|---------|------|
| -32001 | NotFound | オブジェクト/アセットが見つからない |
| -32002 | InvalidState | 不正な状態(Play中に編集など) |
| -32003 | PackageNotInstalled | 必要なパッケージ未インストール |
| -32004 | PermissionDenied | 操作権限なし |
| -32005 | Timeout | 操作タイムアウト |
#### 6. ゼロコンフィグ接続 (Issue #80)
**現状 (1.0):**
1. npm install 実行
2. .mcp.json 作成
3. Unity でサーバー起動確認
4. Claude Code 再起動
**目標 (2.0):**
1. Unity パッケージインストール → 自動完了
**実装アプローチ:**
- Claude Code の設定ファイルを自動検出・更新
- Unity 起動時に MCP Server 自動起動
- ヘルスチェック & 自動再接続
---
## 2.0 マイルストーン
### Phase 1: 基盤整備
- [ ] Native MCP Protocol 実装 (C#)
- [ ] stdio 通信基盤
- [ ] Unity Editor ↔ MCP Server IPC
### Phase 2: API最適化
- [ ] カテゴリベース API 提供
- [ ] 動的 tools/list
- [ ] API 推薦システム
### Phase 3: リアルタイム機能
- [ ] イベント通知システム
- [ ] 状態同期機構
- [ ] 双方向通信
### Phase 4: DX改善
- [ ] ゼロコンフィグセットアップ
- [ ] エラーハンドリング強化
- [ ] デバッグツール
---
## 参考リンク
- [Model Context Protocol Specification](https://modelcontextprotocol.io/)
- [JSON-RPC 2.0 Specification](https://www.jsonrpc.org/specification)
- [Unity Editor Scripting](https://docs.unity3d.com/Manual/ExtendingTheEditor.html)