現在VRChatでUnityをやっておりますが、流行りのAI開発を取り入れていこうと思い、
MCP (Model Context Protocol) サーバーを立てて Claude と連携しようとしましたので、その手順をまとめます。
今回は「現在のシーン情報を読み取って連携する」という構成を作ります。
特にWindows環境かつ日本語パスが含まれているプロジェクトだったため、ハマった箇所もありましたが、絶対パスや環境変数を駆使する事で解決しました。
今回やる事は、Unityの現在のシーン情報(Hierarchy)をJSONファイルとして書き出して、Python製のMCPサーバーを経由して「Claude Desktop」に読み込ませる仕組みの構築です。
構成
Unity → (ファイル書き出し) → JSON → Python Server (FastMCP) → Claude Desktop
0. 前提環境
- OS: Windows 11
- Unity: 2022.3.22f1
- Claude Desktop アプリ: インストール済みであること
- Python: 3.10以上 (本記事では3.14.0を使用)
1. 構築手順
1. pythonライブラリのインストール
コマンドプロンプトで以下を実行し、MCP 用ライブラリ `fastmcp` をインストールします。
python -m pip install fastmcp2. Unity 側の実装 (C#)
Unity エディタからシーン情報を書き出すスクリプトを作成します。
「Assets/Editor」フォルダを作成し、その中に「McpExporter.cs」を作成して以下のコードを保存してください。
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
using UnityEngine.SceneManagement;
public class McpExporter : MonoBehaviour
{
// 保存先:Unityプロジェクトのルートフォルダ(Assetsの1つ上)
// 日本語パス対応のため、System.Text.Encoding.UTF8 を使用
private static string FilePath => Path.Combine(Directory.GetParent(Application.dataPath).FullName, "mcp_hierarchy.json");
[MenuItem("MCP/Export Hierarchy")]
public static void ExportHierarchy()
{
var rootObjects = SceneManager.GetActiveScene().GetRootGameObjects();
var sb = new StringBuilder();
sb.AppendLine("{ \"objects\": [");
for (int i = 0; i < rootObjects.Length; i++)
{
var obj = rootObjects[i];
// 名前と座標を取得
sb.Append($" {{ \"name\": \"{obj.name}\", \"position\": \"{obj.transform.position}\" }}");
if (i < rootObjects.Length - 1) sb.Append(",");
sb.AppendLine();
}
sb.AppendLine("] }");
// UTF-8 (BOMなし推奨) で書き出し
File.WriteAllText(FilePath, sb.ToString(), new UTF8Encoding(false));
Debug.Log($"[MCP] シーン情報を書き出しました: {FilePath}");
}
}作成後、Unity上部メニューに「MCP」が表示されます。
「MCP > Export Hierarchy」を実行すると、プロジェクト直下に「mcp_hierarchy.json」が生成されます。
3. サーバー側の実装 (Python)
Unity プロジェクトのルートフォルダ(Assets フォルダと同じ階層)にサーバー用スクリプト「server.py」を作成します。
from fastmcp import FastMCP
import os
# サーバー定義
mcp = FastMCP("UnityContext")
# 自身のファイルの場所を基準にデータファイルを探す(絶対パス化)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_FILE = os.path.join(BASE_DIR, "mcp_hierarchy.json")
@mcp.resource("unity://hierarchy")
def get_hierarchy() -> str:
"""Unityの現在のシーン階層構造(Hierarchy)を読み取ります。"""
if not os.path.exists(DATA_FILE):
return "エラー: データが見つかりません。Unityで 'MCP > Export Hierarchy' を実行してください。"
try:
# 文字コードエラー防止のため utf-8 指定で開く
with open(DATA_FILE, "r", encoding="utf-8") as f:
return f.read()
except Exception as e:
return f"ファイル読み込みエラー: {str(e)}"
if __name__ == "__main__":
mcp.run()ポイント: Claudeからの実行時に cwd(カレントディレクトリ)の移動に失敗しても動作するよう、「server.py」の場所を基準に絶対パスを動的に生成しています。
4. Claude Desktop の設定 (JSON)
ここが最大の難所です。パス、エスケープ、文字コードに注意して設定ファイルを作成します。
以下のパスにある設定ファイルを開きます(なければ新規作成)。
%APPDATA%\Claude\claude_desktop_config.json
(例: C:\Users\ユーザー名\AppData\Roaming\Claude\claude_desktop_config.json)
{
"mcpServers": {
"unity-connect": {
"command": "C:\\Path\\To\\Your\\Python\\python.exe",
"args": [
"-X",
"utf8",
"C:\\Path\\To\\Your\\UnityProject\\server.py"
],
"cwd": "C:\\Path\\To\\Your\\UnityProject",
"env": {
"PYTHONUTF8": "1"
}
}
}
}【設定の重要ポイント】
- python.exe のパス: コマンドプロンプトで「python -c “import sys; print(sys.executable)”」を実行して調べた絶対パスを使用する(pip installした環境と合わせるため)。
- server.py のパス: こちらも必ず絶対パスで記述する。
- パスの区切り文字: Windowsの \ はJSON内では \ にエスケープする。
- 文字コード: PYTHONUTF8 環境変数と -X utf8 オプションをつけることで、日本語パスでのクラッシュを防ぐ。
- ファイルの保存: メモ帳などで保存する際は、必ず 文字コード: UTF-8 を選択する。
2. 実行手順
1. まずはClaude Desktopを再起動
設定を反映させるため、Claude Desktop を完全に再起動します。
×ボタンではなく、Claude Desktop 左上のメニューボタンから「ファイル→終了」と完全終了させてから再起動します。
2. Claudeと連携する
Claude Desktop のチャット欄の左下にある「+(添付)」ボタンを押下して「unity-connectから追加」→「Get hierarchy」を選択する。
3. Claudeに質問
チャットで「今のシーンについて教えて」等と質問し、Hierarchy の内容が返ってくれば成功です!
※Unity 側でシーンを変更した際は、都度「MCP > Export Hierarchy」を実行して JSON を更新する必要があります。
3. よくある問題
接続されない(アイコンが出ない)場合:
- 設定ファイル名が .json.txt になっていないか確認。
- 設定ファイルの文字コードが Shift-JIS (ANSI) になっていないか確認。
すぐ切断される場合:
- %APPDATA%\Claude\logs\mcp.log を確認。
- 「ModuleNotFoundError」なら Python のパス違い。
- パスに日本語が含まれている場合、JSON の「args」で「-X utf8」があるか「env」設定があるか確認して再確認してください。
何かエラーが出たら、「mcp.log」の中身をコピーして「AI」に聞くのが解決への近道です。
まだこの段階ではあくまでjsonファイルを読み取って、その内容をもとに回答しているにすぎません。
ようするにjsonファイルをClaudeDesktopにドラッグするのと同じです。
なので今後はファイル構成などをClaudeに認識して貰って、それを元に回答するように設定する必要があります。
