Skip to main content
Glama
README.md
# Maya MCP

Maya を AI エージェントとコマンドラインに開放します。外部から送った Python と MEL は、Script Editor で実行したときと同じ経路を通ります。

- MCP クライアントは、Maya 自身が公開する Streamable HTTP エンドポイント `http://127.0.0.1:<port>/mcp` に直接接続します。中継する別プロセスの MCP サーバーはありません。
- コマンドラインの `isuzu-maya-cli` からも、エージェントと同じツールを呼び出せます。NativeAOT の単一バイナリなので、.NET ランタイムも Python も不要です。
- 公開するツールは `execute_python` と `execute_mel` の 2 つだけで、固有のシーン操作ツールは持ちません。

## 動作環境

- Maya 2022 以降。動作確認は Maya 2023(Python 3.9.7 / PySide2)で行っています
- ビルド済みバイナリを配布しているのは Windows x64 向けです。ほかの環境ではソースからビルドしてください

Maya 内で動くサーバーは標準ライブラリだけで実装しているため、Maya の Python 環境への `pip install` は不要です。

## インストール

PowerShell で次の 1 行を実行すると、CLI と Maya 用パッケージの両方が入ります。

```powershell
irm https://raw.githubusercontent.com/isuzu-shiranui/MayaMCP/main/install.ps1 | iex
```

入るものは 2 つです。

- CLI(`isuzu-maya-cli`)は `%LOCALAPPDATA%\Programs\isuzu-maya-cli` に配置され、ユーザー PATH に追加されます。PATH の変更は新しい端末から効きます
- Maya 用パッケージは `%MAYA_APP_DIR%\scripts\MayaMCP`(既定では `%USERPROFILE%\Documents\maya\scripts\MayaMCP`)に配置されます。そこが git のクローンだった場合は、上書きせずそのまま残します

> [!NOTE]
> [GitHub Releases](https://github.com/isuzu-shiranui/MayaMCP/releases) から実行ファイルを直接ダウンロードして、`SHA256SUMS` で検証することもできます。配置先を変えたい場合や CLI だけ入れたい場合は、[インストールのカスタマイズ](#インストールのカスタマイズ環境変数)をご覧ください。

## 使い方

### 1. Maya でサーバーを起動する

Script Editor の Python タブで実行します。

```python
import MayaMCP
MayaMCP.run()
```

> [!TIP]
> Maya の起動と同時に立ち上げるなら、同じ `scripts` フォルダーの `userSetup.py` に次の 2 行を書いてください。
> ```python
> import maya.utils
> maya.utils.executeDeferred("import MayaMCP; MayaMCP.run()")
> ```

### 2. コマンドラインから呼ぶ

サーバーが起動すると、接続先とトークンを書いた descriptor ファイルが公開されます。CLI はこれを読むので、ポートやトークンを指定する必要はありません。

```bash
isuzu-maya-cli instances                              # 起動中の Maya 一覧
isuzu-maya-cli health                                 # サーバーの状態
isuzu-maya-cli tools                                  # 利用可能なツール
isuzu-maya-cli call execute_python --file snippet.py  # スクリプトの実行
isuzu-maya-cli doctor                                 # 状態ファイル・ポート・疎通の診断
```

**コードは `--file` で渡してください。** シェルと JSON エンコーダーを二重に通すと、バックスラッシュ・改行・インデントが落ちます。`--file` は base64 にエンコードして送るので、この層が消えます。

Maya を複数起動しているときは、`--scene <シーン名>` か `--pid <プロセス ID>` で対象を選べます。

Maya の GUI を開かずに使うこともできます。

```bash
isuzu-maya-cli headless start --detach
isuzu-maya-cli headless stop
```

すべてのコマンドは `isuzu-maya-cli --help` で確認できます。

## MCP クライアントから接続する

### HTTP で接続する

ポート番号は `sha256(prefsDir + Maya のバージョン)` から決まるので、Maya を再起動しても変わりません。`<port>` と `<token>` は `isuzu-maya-cli instances --raw` に出ます。

```json
"maya": {
  "type": "http",
  "url": "http://127.0.0.1:<port>/mcp",
  "headers": { "Authorization": "Bearer <token>" }
}
```

### stdio ブリッジで接続する

Maya を閉じている時間が長いなら、こちらの方が扱いやすいです。CLI が `initialize` と `tools/list` をキャッシュから返すため、Maya が起動していなくてもクライアントとの接続は成立します。

```json
"maya": {
  "type": "stdio",
  "command": "%LOCALAPPDATA%\\Programs\\isuzu-maya-cli\\isuzu-maya-cli.exe",
  "args": ["mcp-stdio"]
}
```

## ツール

| ツール | 内容 |
|---|---|
| `execute_python` | Maya のメインスレッドで Python を実行します。最後の文が式なら、その値が `returnValue` に入ります |
| `execute_mel` | 同じく MEL を実行します |
| `job_status` | 3 秒で返らず job に移った呼び出しの結果を取ります |

- コード実行の 2 つは `code` と `code_base64` を受け取り、両方あるときは `code_base64` が優先します
- 呼び出し 1 回が Undo 1 操作にまとまります。エージェントがノードを大量に作っても、Ctrl+Z 一回でまとめて戻せます
- 3 秒で返らなかった呼び出しは `202 Accepted` と job id を返し、実行は続きます。CLI はそのまま完了まで追いかけます(`--no-wait` を付けると job id だけを受け取ります)

## セキュリティ

- サーバーは `127.0.0.1` にだけバインドします
- `OPTIONS` を除くすべてのリクエストに bearer token が必要です
- CORS ヘッダーは一切返しません。ループバックへのバインドだけではブラウザーからのアクセスを防げないため、`Access-Control-Allow-Origin: *` を設定すると、開いている任意の Web ページから `execute_python` を呼べるようになってしまうからです

> [!WARNING]
> descriptor ファイルとトークンファイルは資格情報として扱ってください。これらを読めるユーザーやプログラムは、Maya 内で任意のコードを実行できます。

## 設計上の保証

- タイムアウトを返しません。3 秒で返らない呼び出しは job に移ります。タイムアウトは仕事をキューに残したままリトライを誘い、二重実行の原因になります
- キャンセルした仕事は副作用を残しません。キューの各アイテムが `Pending → Running | Abandoned` の状態を持ち、実行が始まる前にキャンセルできたものは一切実行されません
- クライアントも POST を再送しません。接続すらできなかったとき、つまり 1 バイトも届いていないと確認できたときだけ送り直します
- `/health` と `/jobs` はメインスレッドに触りません。Maya が詰まっているときこそ状態を知る必要があるからです。`queueDepth` が伸びて `reqCount` が止まっていれば、メインスレッドが閉塞しています
- ツールの定義は 1 箇所です。関数シグネチャから JSON Schema を生成するので、`/tools` と `tools/list` が食い違えません
- ポートの範囲を GUI とヘッドレスで分けています(`28200–28599` と `28600–28999`)。同じ prefs から同じ鍵が出ても、両方を同時に起動して共存させられます

---

## 開発者向け

### インストールのカスタマイズ(環境変数)

`irm | iex` はスクリプトファイルを残さないため、コマンドライン引数を渡せません。配置先などを変えたい場合は、実行前に次の環境変数を設定してください。

| 環境変数 | 用途 |
|---|---|
| `ISUZU_MAYA_CLI_VERSION` | インストールするリリースタグ。既定は最新版です |
| `ISUZU_MAYA_CLI_DIR` | CLI の配置先 |
| `MAYAMCP_SCRIPTS_DIR` | Maya 用パッケージを入れる `scripts` ディレクトリ |
| `MAYAMCP_SKIP_PACKAGE` | 値を設定すると、CLI だけをインストールします |

### 実行時の環境変数

| 名前 | 用途 |
|---|---|
| `MAYA_MCP_STATE_DIR` | descriptor ファイルの保存先。PATH と同じ区切りで複数指定できます |
| `MAYA_MCP_HOST` | descriptor に書くホストを `127.0.0.1` から差し替えます。ポートプロキシを前に置く場合に使います |
| `MAYA_MCP_TRACE` | 処理段階ごとの所要時間を stderr に出力します |
| `MAYAMCP_PORT` | 自動算出を無視してポート番号を固定します |
| `MAYAMCP_MAYAPY` | `headless start` が使う `mayapy` のパスを指定します |
| `MAYAMCP_PACKAGE` | Maya 用パッケージの読み込み元を指定します |

### リポジトリの構成

| ディレクトリ | 内容 | 実行環境 |
|---|---|---|
| `maya_side/` | Maya 内で動く HTTP + MCP サーバー | Maya 同梱 Python、標準ライブラリのみ |
| `isuzu-maya-cli/` | コマンドラインツール | .NET 10 / NativeAOT |
| `tests/` | Maya 抜きで実行できる Maya 側のテスト | 同上の Python |
| `build/` | ビルドとテストのスクリプト | PowerShell |

```powershell
.\build\run_tests.ps1
```

### ソースからビルドする

.NET 10 SDK と Visual Studio Build Tools(C++ によるデスクトップ開発ワークロード)が必要です。

```powershell
git clone https://github.com/isuzu-shiranui/MayaMCP.git "$env:USERPROFILE\Documents\maya\scripts\MayaMCP"
cd "$env:USERPROFILE\Documents\maya\scripts\MayaMCP"
.\build\build_cli.ps1
```

このスクリプトは NativeAOT で publish して `%LOCALAPPDATA%\Programs\isuzu-maya-cli` へ配置し、ユーザー PATH に追加します。

> [!NOTE]
> publish の前に `%ProgramFiles(x86)%\Microsoft Visual Studio\Installer` を PATH へ足すのは、ILCompiler が `vswhere.exe` を呼んでリンカーを探すためです。これが無いと、リンカーのエラーに見える失敗をします。

## ライセンス

MIT