Unity Editor integration with Model Context Protocol (MCP) enabling AI assistants like Claude to interact with Unity projects. Features a TypeScript MCP server and C# Unity plugin with extensible command handler architecture, TCP/IP communication, and dynamic plugin discovery.
Unity と Model Context Protocol (MCP) を統合するための拡張可能なフレームワークです。このフレームワークにより、Claude などの AI 言語モデルがスケーラブルなハンドラーアーキテクチャを通じて Unity エディタと直接対話することができます。
https://github.com/isuzu-shiranui/UnityMCP.git?path=jp.shiranui-isuzu.unity-mcp
Unity MCPにはTypeScriptクライアントの簡単なインストールと設定のためのツールが含まれています。
これで、Claude Desktopが自動的にUnity MCPクライアントに接続し、Unity Editorとのシームレスな連携が可能になります。
build/index.js
ファイルのフルパスを控えておきますclaude_desktop_config.json
を開きます{
"mcpServers": {
"unity-mcp": {
"command": "node",
"args": [
"path/to/index.js"
]
}
}
}
※ path/to/index.js
は実際のパスに置き換えてください(Windowsの場合はバックスラッシュをエスケープ"\\"するか、フォワードスラッシュ"/"を使用)
Unity MCP フレームワークは主に 2 つのコンポーネントで構成されています:
Unity MCPでは、Model Context Protocol (MCP) に基づく以下の3種類のハンドラータイプをサポートしています:
パッケージには以下のサンプルが含まれています:
Unity MCP Handler Samples
Unity MCP Handler Samples JavaScript
build/handlers
ディレクトリにコピーして使用してください⚠️ 注意: サンプルコードには任意コード実行機能が含まれています。本番環境での使用には十分注意してください。
サンプルのインポート方法:
IMcpCommandHandler
を実装する新しいクラスを作成:
using Newtonsoft.Json.Linq;
using UnityMCP.Editor.Core;
namespace YourNamespace.Handlers
{
internal sealed class YourCommandHandler : IMcpCommandHandler
{
public string CommandPrefix => "yourprefix";
public string Description => "ハンドラーの説明";
public JObject Execute(string action, JObject parameters)
{
// コマンドロジックを実装
if (action == "yourAction")
{
// パラメータを使って何かを実行
return new JObject
{
["success"] = true,
["result"] = "結果データ"
};
}
return new JObject
{
["success"] = false,
["error"] = $"不明なアクション: {action}"
};
}
}
}
IMcpResourceHandler
を実装する新しいクラスを作成:
using Newtonsoft.Json.Linq;
using UnityMCP.Editor.Resources;
namespace YourNamespace.Resources
{
internal sealed class YourResourceHandler : IMcpResourceHandler
{
public string ResourceName => "yourresource";
public string Description => "リソースの説明";
public string ResourceUri => "unity://yourresource";
public JObject FetchResource(JObject parameters)
{
// リソースデータを取得する処理を実装
var data = new JArray();
// 何かデータを取得・加工してJArrayに追加
data.Add(new JObject
{
["name"] = "項目1",
["value"] = "値1"
});
return new JObject
{
["success"] = true,
["items"] = data
};
}
}
}
BaseCommandHandler
を拡張して新しいハンドラーを作成:
import { IMcpToolDefinition } from "../core/interfaces/ICommandHandler.js";
import { JObject } from "../types/index.js";
import { z } from "zod";
import { BaseCommandHandler } from "../core/BaseCommandHandler.js";
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<string, IMcpToolDefinition>();
// ツールを定義
tools.set("yourprefix_yourAction", {
description: "アクションの説明",
parameterSchema: {
param1: z.string().describe("パラメータの説明"),
param2: z.number().optional().describe("オプションパラメータ")
},
annotations: {
title: "ツールのタイトル",
readOnlyHint: true,
openWorldHint: false
}
});
return tools;
}
protected async executeCommand(action: string, parameters: JObject): Promise<JObject> {
// コマンドロジックを実装
// リクエストを Unity に転送
return await this.sendUnityRequest(
`${this.commandPrefix}.${action}`,
parameters
);
}
}
BaseResourceHandler
を拡張して新しいリソースハンドラーを作成:
import { BaseResourceHandler } from "../core/BaseResourceHandler.js";
import { JObject } from "../types/index.js";
import { URL } from "url";
export class YourResourceHandler extends BaseResourceHandler {
public get resourceName(): string {
return "yourresource";
}
public get description(): string {
return "リソースの説明";
}
public get resourceUriTemplate(): string {
return "unity://yourresource";
}
protected async fetchResourceData(uri: URL, parameters?: JObject): Promise<JObject> {
// リクエストパラメータを処理
const param1 = parameters?.param1 as string;
// Unityにリクエストを送信
const response = await this.sendUnityRequest("yourresource.get", {
param1: param1
});
if (!response.success) {
throw new Error(response.error as string || "リソース取得に失敗しました");
}
// 応答データを整形して返す
return {
items: response.items || []
};
}
}
BasePromptHandler
を拡張して新しいプロンプトハンドラーを作成:
import { BasePromptHandler } from "../core/BasePromptHandler.js";
import { IMcpPromptDefinition } from "../core/interfaces/IPromptHandler.js";
import { z } from "zod";
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<string, IMcpPromptDefinition>();
// プロンプト定義を登録
prompts.set("analyze-component", {
description: "Unityコンポーネントを分析する",
template: "以下のUnityコンポーネントを詳細に分析し、改善点を提案してください:\n\n```csharp\n{code}\n```",
additionalProperties: {
code: z.string().describe("分析対象のC#コード")
}
});
return prompts;
}
}
注意: C#側のIMcpCommandHandler
またはIMcpResourceHandler
を実装したクラスはプロジェクト内のどこに配置しても、アセンブリ検索によって自動的に検出・登録されます。TypeScript側も同様にhandlers
ディレクトリに配置することで自動検出されます。
Edit > Preferences > Unity MCP から設定にアクセス:
TypeScript サーバーの環境変数:
MCP_HOST
: Unity サーバーホスト (デフォルト: 127.0.0.1)MCP_PORT
: Unity サーバーポート (デフォルト: 27182)接続エラー
ハンドラーが登録されない
リソースが見つからない
code_execute
コマンドを含むハンドラーは任意コード実行可能なため、運用環境では無効化を検討してください。このプロジェクトは MIT ライセンスの下で提供されています - 詳細はライセンスファイルを参照してください。
Shiranui-Isuzu いすず
{ "mcpServers": { "unitymcp": { "command": "node", "args": [ "path/to/index.js" ] } } }
Related projects feature coming soon
Will recommend related projects based on sub-categories