コンテンツにスキップ

MCP サーバ

コンパイラ本体を AI クライアントから呼べるようにするサーバです。パッケージに同梱されていて、クライアントが設定に従って起動します。

Unity のメニューの TsukimiCode から Tsukimi MCP を開きます。使うクライアントにチェックを付けて主ボタンを押すと、チェックしたクライアントの設定・Skill・最終チェック(作業完了時のコンパイル検査)がまとめて書き込まれます。

Tsukimi MCP のウィンドウ。8 つのクライアントすべてにチェックと ✓ が付き、Server は found、Skill は up to date、Final check は not installed で、主ボタンは Set Up (8 clients)

場所中身
ツールバーパッケージの版と、設定ファイルを読み直してマークを更新する Refresh
クライアントの行8 行。チェック・設定ファイルの場所・マークが並ぶ。チェックはプロジェクトごとに UserSettings/TsukimiMcpClients.json に保存される。保存が無いうちは、Claude Code と、設定に tsukimi の項目が既にあるクライアントにチェックが付く
Server同梱のサーバ DLL が見つかるか
SkillAI が参照する手順書の状態(Skills)
Final check作業完了の報告時にコンパイルを検査するフックの状態。Claude Code だけ
主ボタンチェックしたクライアントの設定・Skill・最終チェックをまとめて書き込む。文言は状態で変わる
More起動コマンド・AGENTS.md への注記・手で貼る設定・最終チェックの削除。最初は閉じている
最下段Last check(最終チェックの最後の結果)と、導入のページを開く Open the guide
マーク意味
✓インストール済みで、最新
空の丸まだインストールしていない
!インストール済みだが古い。前の版が書き込んだ物か、別のサーバかプロジェクトを指している
✕インストールできない。同梱のサーバか、Skill の元のファイルが見つからないときに出る
行文言意味
Serverfound同梱のサーバが見つかっている
Servernot found · reinstall the package to restore itサーバの DLL が見つからない。主ボタンも押せない。パッケージを導入し直すと戻る
Skillup to date · shared by every client最新。どのクライアントからも同じ Skill を読む
Skillout of date · shared by every client前の版の Skill がインストールされている
Skillout of date (changed by hand) · shared by every client前の版の Skill がインストールされていて、インストール後に手で変えたファイルがある
Skillnot installed · shared by every clientインストールされていない
Skillsource not foundパッケージの中に Skill の元のファイルが無い
Final checkup to date · Claude Code only最新
Final checkout of date · Claude Code only別のサーバかプロジェクトを指している
Final checknot installed · Claude Code onlyインストールされていない
文言出る条件ボタンの下の注記
Set Up (N clients)チェックしたクライアント・Skill・最終チェックのどれかが、まだインストールされていないか、インストールできないWrites the checked clients, the Skill and the final check. Restart your AI client afterwards.
Update (N clients)全部インストール済みで、どれかが古いThe package was updated. Restart your AI clients afterwards.
Set Up Again全部が最新Everything is in place.
項目内容
Nチェックしたクライアントの数(1 つなら client)
文言に入る対象チェックしたクライアント・Skill・最終チェック。最終チェックは Claude Code にチェックがあるときだけ
押したときの動作どの文言でも同じ。チェックしたクライアントの設定と Skill を書き込み、Claude Code にチェックがあれば最終チェックも書き込む。Skill はチェックに関係なくインストールされる
最新の物これも書き直す。Set Up Again は、書き方を今の版に揃えるときに使う
押せないときServer が not found のとき
押した後AI クライアントを再起動する。クライアントは設定と Skill を起動時にしか読まない
場合文言選んだときの動作
設定ファイルが JSON として読めない... could not be read as JSON. Replace it with a file that holds only the tsukimi entry?Replace でファイルを tsukimi の項目だけにする。Cancel ならそのクライアントは書き込まない
Skill と同名で中身の違うファイルがあるThese files already exist and differ. Replace them? と、そのファイルの一覧Replace で上書きする。Cancel なら Skill はインストールされない
.claude/settings.local.json が JSON として読めない... could not be read as JSON, so it was left alone.最終チェックはインストールされない。ファイルはそのまま
found同梱のサーバが見つかっています
not foundサーバの DLL が見つかっていません。主ボタンは押せず、マークは ✕ になります。パッケージを導入し直すと戻ります
起動コマンドMore の Start command に、クライアントが実行するコマンドが出ます

設定ファイルもキーもクライアントごとに異なるため、8 種類のクライアントそれぞれに合わせた設定を生成します。

クライアント設定ファイルキー書式サーバの経路補足
Claude Code.mcp.jsonmcpServersJSONプロジェクトからの相対パス
GitHub Copilot CLI.mcp.jsonmcpServersJSONプロジェクトからの相対パスClaude Code と同じファイル。プロジェクトのフォルダで起動する
Visual Studio.mcp.jsonserversJSON絶対パス(プロジェクトの場所も書く)同じファイルの別のキー
VS Code.vscode/mcp.jsonserversJSON${workspaceFolder} で始まるパス
Cursor.cursor/mcp.jsonmcpServersJSON${workspaceFolder} で始まるパス
Roo Code.roo/mcp.jsonmcpServersJSONプロジェクトからの相対パス
Gemini CLI.gemini/settings.jsonmcpServersJSON絶対パス(プロジェクトの場所も書く)ほかの設定と同じファイル
Codex CLI.codex/config.tomlmcp_serversTOML絶対パス(プロジェクトの場所も書く)プロジェクトの信頼が別に必要
項目内容
相対パスと ${workspaceFolder} で書く相手サーバの経路だけを書き、プロジェクトの場所は書かない。サーバは自分のファイルの場所から上へたどり、Assets と ProjectSettings の両方を持つ最初のフォルダをプロジェクトとして使う。そのため、別のマシンや別のフォルダへ clone しても同じ設定で起動する
絶対パスで書く相手サーバとプロジェクトの両方の絶対パスを書く
パッケージをプロジェクトの外に置いた場合どのクライアントにも絶対パスを書く
クライアントのマークの決め方設定に書かれた経路が指す先で決める。書き方がウィンドウの書く形と違っても、今のサーバとこのプロジェクトを指していれば ✓
前の版のウィンドウが書いた絶対パス前の版はどのクライアントにも絶対パスを書いていた。今のサーバとプロジェクトを指していれば ✓ と出て、自動では書き直されない。相対パスか ${workspaceFolder} へ移すには、主ボタン(全部 ✓ なら Set Up Again)を押す

More を開き、Paste by hand のドロップダウンでクライアントを選ぶと、貼り付ける内容がそのまま出ます。

{
"mcpServers": {
"tsukimi": {
"command": "dotnet",
"args": ["<プロジェクトから見たパッケージの場所>/Server~/TsukimiCode.Mcp.dll"]
}
}
}
{
"servers": {
"tsukimi": {
"command": "dotnet",
"args": ["${workspaceFolder}/<プロジェクトから見たパッケージの場所>/Server~/TsukimiCode.Mcp.dll"]
}
}
}
[mcp_servers.tsukimi]
command = "dotnet"
args = ["<パッケージの場所>/Server~/TsukimiCode.Mcp.dll", "<プロジェクトの場所>"]
項目内容
出る内容ウィンドウが書き込む内容と同じ。パスにはそのプロジェクトでの値が入る
上の例順に Claude Code(相対パス)・VS Code(${workspaceFolder}・キーは servers)・Codex CLI(絶対パス・TOML)
引数のプロジェクトの場所絶対パスで書く相手にだけ入る。サーバが、そのプロジェクトに生成された実行環境の API のデータベースを読むために使う
省略した場合サーバが自分のファイルの場所から上へたどってプロジェクトを探す。サーバがプロジェクトの外にあって見つからないときは、API の存在確認が行われない

パッケージを更新した後の書き直し

Section titled “パッケージを更新した後の書き直し”
対象どうなるか
時機Unity がスクリプトを読み込むとき(起動やパッケージの更新の後)。ウィンドウでインストールした Skill の記録が前の版のときだけで、同じ版では何もしない
Skillインストールしたときのまま手を付けていないファイルを書き直す(Skills)
手で変えた Skill のファイル書き直さずに残し、Console の警告で名指しする。置き換えるには主ボタンを押し、同名のファイルの確認で Replace を選ぶ
クライアントの設定tsukimi の項目が別のサーバか別のプロジェクトを指しているものだけ書き直す
最終チェックインストール済みで古いときだけ書き直す
Skill の記録が無いプロジェクト何も書き直さない。0.9.0 より前のウィンドウでインストールした Skill には記録が無いので、最初の 1 回だけ主ボタンでインストールし直す
書き直した後Console に Updated ... for TsukimiSharp <版>. Restart your AI client so that it reads them. の 1 行が出る。クライアントを再起動する
書き直す物が無かった場合版が前回このプロジェクトで読み込んだ版と違い、どれかのクライアントの設定に tsukimi の項目があれば、Console に TsukimiSharp <版> is loaded. If your AI client was already running, restart it, or reconnect its MCP servers, so that it uses this version. の 1 行が出る。クライアントを再起動するか、MCP サーバを接続し直す

カードの下にある More を開くと、普段は使わない 4 つの欄が出ます。

欄ボタン中身
Start commandCopyClaude Code の設定に書く内容と同じ起動コマンド。パッケージがプロジェクトの中にあればサーバの経路は相対パスなので、手で起動するときはプロジェクトのフォルダで実行する
Note in AGENTS.mdAdd常に読み込まれる AGENTS.md へ短い注記を追加する(Skills)
Paste by handCopyドロップダウンで選んだクライアントの設定に貼る内容
Final checkRemove最終チェックのフックを削除する。インストールされていないときは押せない

More を開いたところ。Start command・Note in AGENTS.md・Paste by hand(Claude Code を選んだ状態)・Final check の欄が見える

Claude Code にチェックを付けて主ボタンを押すと、.claude/settings.local.json にフックが登録されます。このフックは、AI が作業完了を報告しようとした時点で、そのセッションで変更された T# のソースを 1 回だけコンパイルします。

場合どうなるか
コンパイルが通らなかった診断を提示して作業の続行を求めます
警告だけが出た戻しません
コンパイルできた何も言いません。ウィンドウの Last check に最後の結果が出ます
検査そのものが動かない止めずに通します。壊れた検査が作業を止め続けないためです
同じ診断が 2 回続いた通します。修正できないと判断して打ち切ります
対象のクライアントClaude Code だけです。フック機能を持つクライアントが他に無いためです
書き込み先共有向けでない設定ファイルです。中身に絶対パスが入るためです
最後の結果ウィンドウの最下段の Last check に出ます。一度も実行されていなければ not run yet です
削除More の Final check の Remove で、このフックだけを削除します。同じファイルの他の設定は保持されます

7 つあります。

ツール内容
pingサーバが起動しているかの確認
inspectソースのコンパイルと、診断・解析結果の返却
test[TsukimiTest] を付けたメソッドの実行
diagnosticsエラー番号の一覧
specこの言語の説明の生成
decompileコンパイルされたアセンブリを読める形にする
profileUnity で開いているシーンのプログラムの命令と extern の数の読み出し

中心になるのは inspect と test で、ping は接続の確認、diagnostics と spec は inspect が返した内容の解釈、decompile はすでにあるプログラムの確認に使います。

サーバが起動しているかどうかと、起動しているサーバの版を確認します。引数はありません。

"tsukimi-mcp ok (version x.y.z; static-analysis MCP; liveness check)"

x.y.z の位置に、起動しているサーバの版が入ります。登録した直後に、設定が有効かどうかを切り分けるために使います。

パッケージを更新した後も更新の前に起動したサーバが動いていると、ping 以外のツールは実行されず、次の文がエラー(isError: true)として返ります(ping は上の 1 行の後ろに空白を 1 つ挟んで同じ文を続け、エラーにはしません)。

The TsukimiSharp package was updated after this MCP server started (running x.y.z, installed x.y.z). Restart your AI client, or reconnect its MCP servers, to use the new version.

installed は更新後のパッケージの版で、読めないときは省かれます。クライアントを再起動するか、クライアントで MCP サーバを接続し直すと、更新後のサーバが起動します。

ソースをコンパイルして、結果を構造化した JSON で返します。

引数内容
sourceソース 1 ファイル分の全文
file診断の位置に使うファイル名。省略すると <inline>
sources複数のファイル。{name, text} の配列。source より優先される
pathUnity プロジェクトの中のファイルを、本文の代わりにパスで渡す。1 つか配列で、プロジェクトのフォルダからの相対パス(Assets/Lamp/Lamp.cs など)。.cs は、Unity がそのプログラムをコンパイルするときに集めるファイル(同じフォルダとその下のフォルダのファイル・TsukimiShared フォルダのファイル。Editor という名前のフォルダの下は除く)と一緒にコンパイルされる。プログラムのアセット(.asset)はそれがコンパイルする .cs と同じ扱いで、フォルダはその下の .cs を全部渡す。ディスクに保存された内容を読むので、保存していない変更のあるファイルは本文も渡す。名前が path で読んだファイルと一致する本文は、そのファイルの代わりに使われる
mochi.cs の代わりに MoCHI の .mochi.xml を確認する。中身は MoCHI の inspect
cost命令数とヒープ使用量を測定するかどうか。省略すると測定しません。測定時はビルド時と同じ最適化を実行するため、この呼び出しの所要時間の大半はここに費やされます

1 つのソースが宣言できる具象の Behaviour は 1 つだけなので、次のような形を確認したいときは sources にまとめて渡します。

  • インタフェースを Behaviour で実装する
  • 基底の Behaviour と派生の Behaviour に分ける
  • ある Behaviour から別の Behaviour のメソッドを呼ぶ
  • Behaviour の型でコンポーネントを受け取る

1 つの source に 2 つ書いてエラーになるのは渡し方の誤りであり、言語の制限ではありません(sources で渡した場合、結果は Behaviour ごとに分かれ、最上位ではなく programs の各要素に入ります)。

コンパイルできたときの返り値

Section titled “コンパイルできたときの返り値”

次のソースを source に渡し、cost を真にした結果です。cost を指定しないと、heap と cost の 2 つはキー自体が出力されません。

using UnityEngine;
using Tsukimi;
public class Lamp : TsukimiBehaviour
{
[SerializeField] private Light target;
[UdonSynced] private bool on;
public override void Interact()
{
on = !on;
target.enabled = on;
RequestSerialization();
}
}
{
"schemaVersion": 1,
"compiles": true,
"diagnostics": [],
"facts": {
"heap": { "slots": 11, "limit": 1048576, "remaining": 1048565 },
"cost": {
"instructionCount": 12,
"staticExternCount": 3,
"nsPerExtern": 77,
"nsPerNonExtern": 5.4,
"isStraightLine": true
},
"entries": [ "Interact" ],
"recursiveMethods": [],
"loopCount": 0,
"methods": [
{
"name": "Interact", "isEntry": true, "isRecursive": false,
"params": 0, "locals": 1, "loops": 0, "externs": 3,
"entryName": "_interact"
}
],
"runtimeRisk": [],
"contract": {
"synced": [ { "name": "on", "type": "SystemBoolean", "sync": "none" } ],
"exportedFields": [],
"syncMode": "any"
},
"nullDerefRisks": [
{
"kind": "unassignedFieldDeref",
"severity": "warning",
"origin": "runtime",
"message": "The reference field 'target' (type UnityEngineLight) is shown in the Unity Inspector and is never assigned in code, so its value comes only from there. ...",
"method": "Interact",
"field": "target",
"type": "UnityEngineLight",
"deref": "UnityEngineLight.__set_enabled__SystemBoolean__SystemVoid"
}
]
},
"summary": { "total": 0, "bySeverity": {}, "byOrigin": {} },
"externDb": { "resolved": true, "unknownApiChecks": true, "externCount": 32898 }
}
読みどころ
diagnostics が空・compiles が真このソースは変換できています
nullDerefRisks に 1 件target はコードのどこでも代入されておらず、値は Inspector からしか入りません。割り当てを忘れると実行時に null のままになり、target.enabled への代入でイベント全体が中断されます(Udon には例外処理がないので、ログにも何も出ません)
cost の nsPerExtern と nsPerNonExternextern の呼び出し 1 回と、それ以外の命令 1 つのおおよその所要時間です。命令数そのものより、extern を何回呼ぶかのほうが影響することが、この 2 つの差から読み取れます

Udon に存在しない型を使った例です。

using System.Collections.Generic;
using UnityEngine;
using Tsukimi;
public class Bag : TsukimiBehaviour
{
private List<int> items;
public override void Interact()
{
items = new List<int>();
items.Add(1);
Debug.Log(items.Count);
}
}
{
"schemaVersion": 1,
"compiles": false,
"diagnostics": [
{
"code": "TUKI0102",
"severity": "error",
"message": "Variable type does not exist in Udon: field items has the type SystemCollectionsGenericList",
"explain": "This type does not exist in Udon (outside the extern database).",
"location": { "file": "Bag.cs", "startLine": 7, "startCol": 23,
"endLine": 7, "endCol": 23 },
"fix": "This type cannot be used here (it is outside the usable Udon extern set). ... For lists and dictionaries, use the VRChat data containers DataList / DataDictionary (VRC.SDK3.Data) - generic List<T> / Dictionary<K,V> are not usable.",
"witness": "SystemCollectionsGenericList",
"origin": "subset",
"path": null
},
{
"code": "TUKI0101",
"severity": "error",
"message": "Not exposed to Udon: SystemCollectionsGenericList.__ctor____SystemCollectionsGenericList",
"explain": "This API is not exposed to Udon.",
"location": { "file": "Bag.cs", "startLine": 11, "startCol": 17,
"endLine": 11, "endCol": 17 },
"fix": "This API is not exposed to Udon. Use an API that exists in the Udon extern set (see the `spec` tool, topic \"api\").",
"witness": "SystemCollectionsGenericList.__ctor____SystemCollectionsGenericList",
"origin": "subset",
"path": null
}
],
"facts": null,
"summary": {
"total": 4,
"bySeverity": { "error": 4 },
"byOrigin": { "subset": 4 }
},
"externDb": { "resolved": true, "unknownApiChecks": true, "externCount": 32898 }
}
読みどころ
facts が nullcompiles が偽のときは常に null です。コンパイルできていない以上、ヒープ消費もコストも測定できないためです。facts は存在するのに heap と cost だけが無い場合は別で、cost を指定していないことを意味します
diagnostics が 2 件4 件のうち先頭の 2 件だけを載せています(残りは List のメソッド呼び出しに対する同種の指摘)。全体の件数は summary.total にあります
witnessエラーと判定した根拠となった識別子が入ります。この例では型名 SystemCollectionsGenericList と、見つからなかった extern の署名で、メッセージを読み解かなくても何が無かったのか分かります
キー内容
schemaVersionこの出力形式のバージョン。形式が変わると上がる
compilesUdon のバイトコードまで変換できたか。実行環境で動作することの保証ではない
diagnosticsエラーと警告の配列。番号・重大度・位置・直し方・原因の区分が入る
summarydiagnostics を重大度と原因の区分で数えたもの
facts変換できたときだけ入る。エラーのときは null
facts.heap使うヒープの数と、残り。limit は実行環境がヒープに許す最大の数です。cost を真で渡したときだけ入ります
facts.cost命令数・extern の呼び出し数と、1 回あたりのおおよその所要時間。cost を真で渡したときだけ入ります。入っていないのは測っていないという意味で、費用が無いという意味ではありません
facts.entries実行環境から呼ばれるエントリポイントの名前
facts.methodsメソッドごとの内訳。ローカル変数・ループ・extern の数
facts.recursiveMethods実行中にもう一度入りうるので、呼び出しの前後で引数とローカル変数を退避するメソッドの名前(実行中のメソッドへの入り直し)
facts.contract同期するフィールドと、外へ公開しているフィールドと、その Behaviour 全体の同期方式。方式はフィールドごとの sync とは別の軸です
facts.runtimeRiskコンパイルは通るが実行時に停止しうる箇所
facts.nullDerefRisksnull になりうる参照をそのまま辿っている箇所
externDb実行環境の API のデータベースを参照できたか。参照できた API の総数

diagnostics の各要素には origin が付き、4 つの区分によって修正すべき場所が変わります(runtime はこの表には含まれず、facts.runtimeRisk と facts.nullDerefRisks にのみ付きます)。

区分意味
subsetこの言語が対応していない構文。書き方を変えればコンパイルできる
environment実行環境に存在しない。書き方を変えてもコンパイルできない
costコンパイルはできるが、コストが上限を超える
toolコンパイラか静的解析の内部エラー。修正すべき場所は書いたコードではない

tool だけは性質が異なり、コンパイラ側の失敗を示すため、コードを書き直しても結果は変わりません。

ソースをコンパイルして、[TsukimiTest] を付けたメソッドを Unity なしで実行します。

受け取るのは 5 つです。

引数内容
sourcesまとめてコンパイルするファイル。inspect と同じ形。テストは 名前.Tests.cs に書いて、確認したい Behaviour と一緒に渡します(書き方は テスト)
pathinspect と同じです。.cs を渡すと、その 名前.Tests.cs も一緒に読みます。保存していない変更のあるファイルは sources にも渡します
projectPathUnity プロジェクトの場所。省略可。渡すと同じ内容がそのプロジェクトの中にも書かれ、Unity へ戻ってウィンドウを開き直すとそこに出ます。path もこのプロジェクトから読みます
fast素の C# として実行するかどうか。省略すると既定の道で実行します。速いので書いている途中の確認に向きますが、答える問いが違います——書いた規則が正しいかを確認し、コンパイルした形が正しいかは確認しません(テスト)
summary真なら、成功しなかったテストだけを cases に返します。省略すると全部を返します。passed・failed・notRunnable・allPassed は全部のテストから数え、省いた成功の数は passedOmitted に入ります。projectPath に書かれる結果は全部のテストのままです
{
"schemaVersion": 1,
"origin": "mcp",
"ranAt": "2026-08-13T05:57:52.7817272Z",
"passed": 2,
"failed": 1,
"notRunnable": 0,
"allPassed": false,
"cases": [
{
"name": "OneBumpAddsOne",
"source": "Counter.Tests.cs",
"outcome": "passed"
},
{
"name": "TwoBumpsMakeTwo",
"source": "Counter.Tests.cs",
"outcome": "passed"
},
{
"name": "DeliberatelyWrong",
"source": "Counter.Tests.cs",
"expected": "99",
"actual": "1",
"location": "32:9",
"outcome": "assertFailed"
}
]
}
キー読み方
outcome4 種類あります。passed は成功、assertFailed は Assert が成立しなかったもの、halted は実行環境でも同じ箇所で停止するもの、notRunnable は実行そのものができなかったものです。notRunnable はテストの失敗ではなく、コードを書き直しても結果は変わらないため、まず detail を読んでください
allPassedテストが 1 本も見つからなかった場合と、1 本でも実行不可があった場合も偽になります。どちらも成功と誤認されないようにするためです
originどちらの道で実行したかが値で入ります。mcp は既定の道、mcp-fast は素の C# の道、editor は Unity のウィンドウからの実行です。失敗を読む前にここを見ます
trace失敗したときだけ入ります。実行中に記録された事象が時系列で並びます
passedOmittedsummary を真で渡したときだけ入ります。cases から省いた成功の数です

エラー番号の一覧を返します(引数はありません)。inspect が返した番号の意味を参照するために使います。

{
"code": "TUKI0101",
"defaultSeverity": "error",
"en": "This API is not exposed to Udon.",
"fixTemplate": "This API is not exposed to Udon. Use an API that exists in the Udon extern set ...",
"origin": "subset"
}

上は配列の 1 要素で、inspect が返す個々の診断と違って位置が入りません(番号そのものの定義を参照する表だからです)。

この言語の説明を Markdown で返します(topic で選べる話題は 4 つ)。

話題内容根拠
subset対応している形の規則。エラー番号ごとに、エラーになる条件と直し方が並ぶ診断の一覧から自動生成。コンパイラの版が変われば内容も変わる
api実行環境が持っている型の名前の一覧。名前を参照できることと、その API が実際に使えることは別で、使えるかどうかは inspect に通して確認するextern データベースから自動生成。同上
pitfalls通常の C# と挙動が違うところ。null の発生源、イベントが黙って終わるケースなど手書きの解説。コンパイラの定義からは自動生成できない内容
builtinsこの言語固有の組み込み要素。属性・基底クラス・Assert・カーネル API。実行環境の API ではないので api には出ないコンパイラが持つ型定義から自動生成
(省略)全体の見取り図と話題の索引extern データベースを参照できているかどうかも書かれる。参照できていないと未知の API と未知の型の検査(TUKI0101・TUKI0102)が実行されないので、その状態でエラーになった形は、書き方ではなくデータベースが無いことが理由かもしれない
(知らない話題)使える話題を並べたメッセージ
  • compiles が真でも、実行環境で動作するとは限りません。バイトコードまで変換できたことだけを表します
  • runtimeRisk と nullDerefRisks が空でも安全ではありません。この検出は意図的に狭く、null を返しうる呼び出しの直後に連ねた形しか追っていません。いったんローカル変数へ代入すると、そこで追跡が切れます。コンポーネントの取得や実行環境から取る値は、結果の内容にかかわらず自分で確認してください
  • externDb.resolved が偽のときは、未知の API と未知の型の検査が実行されていません。この状態では、データベースを参照できないせいでエラーになっている形が混ざります
  • 重大度が info の診断は止める理由になりません。compiles が真でも出ます

コンパイルされた Udon のアセンブリを、C# に似た読める形にします。すでにワールドに置かれているプログラムの確認に使い、引数は 2 つです。

引数内容
uasmアセンブリのテキスト
fileアセンブリファイルのパス。uasm を省略したときだけ読まれます
{
"schemaVersion": 1,
"file": "Lamp.uasm",
"source": "public class Lamp\n{\n ...\n}",
"fidelity": {
"isOriginalSource": false,
"isCompileChecked": false,
"receiverIsInferred": true,
"note": "This is a readable rendering of the assembly you passed in. ..."
},
"externDb": { "resolved": true, "externCount": 32898 },
"warnings": [],
"facts": {
"heap": { "slots": 11, "limit": 1048576, "remaining": 1048565 },
"cost": { "instructionCount": 42, "staticExternCount": 6,
"nsPerExtern": 77, "nsPerNonExtern": 5.4 },
"entries": ["_interact"],
"externs": ["UnityEngineGameObject.__SetActive__SystemBoolean__SystemVoid"],
"loopCount": 0
}
}
キー読み方
source可読化した結果です。元のソースではありません。ローカル変数名・クラス名・ブロック構造は、アセンブリだけから再構成したものです(アセンブリはそれらを持っていません)
fidelityこのツールの出力の性質を示す固定値です。入力ごとに判定するものではなく、常に同じ値です。source より先に読みます
externDb呼び出しの受け手を、データベースを参照して決めたか、周囲の命令列から推定したかが分かります。推定は間違うことがあり、間違った結果は普通のコードに見えます
warnings結果が信用できない箇所です。receiverNotResolved は、ドットの左側に置いた式がその呼び出しのレシーバとして成立しないもの、notRaisedToStatements は、スタックの操作のまま残した行です。空でも、すべてが正しく出たという意味にはなりません
facts渡したアセンブリから測った値です。heap は inspect と同じ数え方で、cost は命令数と静的な外部呼び出しの数です
facts.entriesアセンブリに定義されたエントリポイントの名前です。inspect の同じキーが C# の名前(Interact)を返すのに対し、こちらは実行環境が呼ぶ名前(_interact)を返します
facts.cost.isStraightLineありません。アセンブリからはループが見えても再帰は見えないため、loopCount が数えるのは後ろ向きのジャンプだけです
自分で書いたソースinspect を使います。このツールの出力を inspect にかけ直す使い方は想定していません
返すものUnity で開いているシーンに置いたプログラムごとの命令と extern の数です。数は Unity が Library/Tsukimi/profile.json に書いた物で、このツールは数え直しません
書かれる時点メニューの TsukimiCode > Tsukimi Profiler を選んだときと、保存した TsukimiSharp のスクリプトを Unity がコンパイルし終えたときです(プロファイラ)
引数program だけです。プログラムの名前(programs[].name)を渡すと、その 1 本だけを返します。省略するとシーンの全部を返します
ファイルが無いときisError: true で、メニューを選ぶかスクリプトを保存するよう案内する文が返ります
{
"schemaVersion": 1,
"writtenAt": "2026-10-11T08:12:34.5678901Z",
"scene": "SampleScene",
"tsukimiVersion": "0.9.0",
"programs": [
{
"name": "ReactiveLamp",
"asset": "Assets/ReactiveLamp.asset",
"tsukimiSharp": true,
"placed": 3,
"instructions": 395,
"externs": 45,
"codeSizeBytes": 2944,
"syncedCount": 0,
"events": [
{ "name": "_interact", "instructions": 129, "externs": 15, "perFrame": false, "measuredExterns": 7 },
{ "name": "_start", "instructions": 49, "externs": 7, "perFrame": false, "measuredExterns": 4 }
],
"stale": false
}
]
}
キー読み方
writtenAt・scene・tsukimiVersion要約を書いた時刻と、そのとき開いていたシーンと、パッケージの版です
placedシーンの中で、そのプログラムを使っている UdonBehaviour の数です
instructions・externsプログラム全体の命令と extern の数です。数え方は プロファイラ と同じです
events[].instructions・events[].externsそのエントリポイントから届く命令と extern の数です。呼び出したメソッドの本体は含みません
events[].perFrame毎フレーム実行されるイベントかどうかです
events[].measuredExternsTsukimiSharp のプログラムだけに入ります。フィールドが既定値のままの状態でそのエントリポイントを 1 回実行したときに呼んだ extern の回数で、呼び出したメソッドの中で呼んだ回数も含みます。既定値では条件の早期 return を通ることが多いので、実際に遊んだときの回数ではありません
events[].notMeasured実行できなかったエントリポイントに、数の代わりに理由が入ります
staleTsukimiSharp のプログラムだけに入ります。true は、数えた後でディスクのアセットが別のプログラムに変わったことを示します。メニューを選び直すと数え直されます
数の単位どの数も回数であって、時間ではありません。Play 中の値も入りません

ping を呼ぶと、次の 1 行が返ります。

"tsukimi-mcp ok (version x.y.z; static-analysis MCP; liveness check)"

クライアント側にも、接続しているサーバの一覧があります。

クライアントから見たサーバの一覧

見えるツール7 つ(ping・inspect・test・diagnostics・spec・decompile・profile)
1 つも見えないとき設定を書き込む前にクライアントを起動したか、プロジェクトの外で起動しています

短いソースを 1 つ inspect にかけると、externDb が返ります。

"externDb": { "resolved": true, "unknownApiChecks": true, "externCount": 32898 }
resolved真なら参照できています。偽の間は、実在する API も未知として報告されます
偽になる条件Unity でこのプロジェクトをまだ一度も開いていないときです
externCount参照できた API の数。導入した SDK の版で変わるので、手元の値が上と違っていても構いません

シーンへの配置・Inspector での参照の割り当て・Play モードでの確認はこのサーバの対象外で、これらも AI に操作させたい場合は、Unity エディタを外部から操作する MCP サーバを併用します。

この種のサーバは第三者が公開しているもので、このパッケージには含まれません(MCP for Unity の場合は、Unity の Package Manager の Add package from git URL に次のアドレスを入力します)。

https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main
症状原因対処
メニューに TsukimiCode が出ないパッケージが入っていないか、プロジェクトのコンパイルが通っていないUnity のコンソールを読む。コンパイルエラーが出ていれば、そちらが先
クライアントに tsukimi のツールが出ない設定の前に起動していたか、プロジェクトの外で起動しているプロジェクトの直下で再起動する。ウィンドウで該当クライアントのマークが ✓ になっているかを見る
主ボタンを押したのに変わらない起動中のクライアントは、設定を起動時にしか読まないクライアントを再起動する
主ボタンを押したのに AI が手順書を知らないインストールした Skill も、クライアントは起動時にしか読まないクライアントを再起動する
AI が Skill を参照せずにコードを書いているSkill がクライアントに読み込まれていないウィンドウの Skill の行が up to date かを確認し、主ボタンを押してから再起動する
Codex CLI だけ接続できないプロジェクトが信頼されていないそのクライアントの手順で信頼させてから、再起動する
GitHub Copilot CLI だけ接続できない設定のサーバの経路がプロジェクトからの相対パスで、別のフォルダで起動しているプロジェクトのフォルダで起動し直す
パッケージの更新後に接続できない設定に書かれたサーバの場所が更新で変わり、自動の書き直しが実行されていない(ウィンドウで Skill をインストールした記録が無いプロジェクトでは実行されない)ウィンドウを開き、! の付いた行があれば主ボタンを押して、クライアントを再起動する
0.8.1 から上げたら Configure・Install Skill・Install Check のボタンが無い0.9.0 でウィンドウを作り直し、1 つの主ボタンにまとめた。0.8.1 でインストールした Skill には記録が無く、自動の書き直しの対象にならない使うクライアントにチェックを付けて主ボタンを 1 回押す(同名のファイルの確認が出たら Replace)。次の更新からは自動で書き直される
clone した先でサーバが起動しない0.8.1 のウィンドウは設定に絶対パスを書いていた。元のプロジェクトでは今のサーバとプロジェクトを指すので ✓ と出て、自動の書き直しの対象にもならない元のプロジェクトで主ボタン(全部 ✓ なら Set Up Again)を押すと、相対パスか ${workspaceFolder} で書き直す。Visual Studio・Gemini CLI・Codex CLI は絶対パスのまま
パッケージの更新後、ツールが The TsukimiSharp package was updated after this MCP server started … を返すクライアントが、更新の前に起動したサーバを動かしたまま。サーバは自分のファイルが更新されたことを検出すると、古いファイルと新しいファイルを混ぜて実行しないように、ツールを実行せずにこの文を返すクライアントを再起動するか、クライアントで MCP サーバを接続し直す。コードやツールの不具合ではない
パッケージの更新後、ツールが Method not found などのエラーで失敗する更新の前に起動したサーバが 0.9.0 以前の版で、更新を検出しないクライアントを再起動するか、クライアントで MCP サーバを接続し直す
Server の行が not found同梱のサーバ DLL が見つからない。主ボタンも押せないパッケージを導入し直す
実在するはずの API が無いと言われ続ける実行環境の API のデータベースが生成されていないUnity でこのプロジェクトを一度開く。externDb.resolved が偽の間はこの状態
完了時の検査が動作しているか分からないコンパイルできたときは何も出ないウィンドウの最下段の Last check を見る。Final check の行が out of date なら、Claude Code にチェックを付けて主ボタンを押す
AI がファイルを置いたのに Unity で何も起きないUnity は、フォーカスが戻るまで外で置かれたファイルをインポートしないUnity のウィンドウを 1 度クリックする
シーンで触っても何も起きないInspector の参照が空UdonBehaviour の欄に割り当てる。Udon には例外処理がないので、ログには何も出ない

どの行の対処でも解決しないときは、ウィンドウの Refresh を押してマークを上から順に確認し、最初に ✓ でない行から対処してください。