ClassCAD について
ClassCAD は、CAD ユーザーやエージェント向けの MCP サーバーで、ClassCAD エンジンを WebAssembly でローカル実行します。エージェントと組み込み CAD アプリが同じ部品やアセンブリを扱い、モデルの確認、描画、ファイルの入出力を行えます。
主な機能
- 01スクリプトによる部品・アセンブリ作成
- 02モデル構造ツリーの確認
- 03モデルスナップショットの描画
- 04STEP、STL、OFB ファイルの保存と読み込み
- 05CAD アプリとのライブセッション共有
活用シーン
- 01エージェントによる CAD 部品の作成
- 02アセンブリ構造と描画スナップショットの確認
- 03組み込みアプリでエージェント作成モデルを編集
MCP 対応
MCP クライアントに、ClassCAD のライブセッションを操作するツールを提供します。WASM エンジンを内蔵し、ClassCAD アプリのセッションにも参加できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
21掲載時のツール一覧 · 1 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| logout | boolean | いいえ | 代わりに、このマシンをサインアウトさせます。 |
詳細
@classcad/mcp
ClassCAD CAD エンジン用の Model Context Protocol サーバーです。自己完結型で、ClassCAD エンジン自体(WASM)を実行するため、セットアップするサーバーはありません。
MCP 対応ホスト(Claude Code、Claude デスクトップアプリ、VS Code Copilot、Cursor など)から、稼働中の ClassCAD セッションを操作できます。スクリプトでパーツやアセンブリを作成し、構造ツリーを調べ、スナップショットをレンダリングし、STEP、STL、OFB を保存および読み込みできます。
セッションは共有されます。CAD アプリのBuerligonsがセッションにドッキングし、ユーザーはエージェントが作成するモデルと同じモデルを回転、選択、編集できます。そのリンクは同僚に送ったり、別のデバイスで開いたりできます(共有リレー経由)。また、エージェントはユーザーがすでに開いているアプリのセッションに参加することもできます。
仕組み
Claude tab 1 ── stdio ──► classcad-mcp (shim) ──┐
Claude tab 2 ── stdio ──► classcad-mcp (shim) ──┤ HTTP (MCP Streamable HTTP, 127.0.0.1:9097)
VS Code ── stdio ──► classcad-mcp (shim) ──┘
▼
classcad-mcp daemon (ONE per machine)
session (one per host connection), its drawings (one per model):
drawing d-… ── worker thread ──► ClassCAD WASM (the MCP's own engine)
drawing d-… ── WebSocket ─────► ClassCAD worker (classcad-cli, optional)
drawing d-… ── WebSocket ─────► a session an app shares (by invite)
127.0.0.1:9098 ◄── the app, docked into a drawing · apps that host a session of their own
wss, dialled out ──► share relay (Cloudflare) ◄── the app on any other machine, by share link
- 自己完結型です。 MCP は独自のエンジンを備えています。公開されている ClassCAD WASM ビルドをデーモンのワーカースレッドで実行します。設定が必要なサーバーやキーはありません。エンジンのキーは、無料の classcad.ch アカウントで一度サインインすると取得できます。初回使用時にリリースアセット(約 16 MB)を一度ダウンロードしてキャッシュします。
- すべてのホストは、MCP を stdio 子プロセス(
npx -y @classcad/mcp@latest)として起動します。このプロセスは薄い シムです。127.0.0.1:9097でデーモンを探し、稼働中でなければ起動して、ホストの JSON-RPC をデーモンに転送します。最初のタブがデーモンを起動し、以降のすべてのタブがそれを再利用します。 - デーモンが実際の MCP です。ホスト接続ごとに 1 つのセッションを保持し、その中に描画ごとに 1 つの MCP サーバーインスタンス(専用エンジン、キャッシュ、ツールキュー、招待。詳しくは描画を参照)と、セッションへの参加に使われる 1 つのリスナー(
127.0.0.1:9098)があります。アプリはそこから MCP のセッションにドッキングし、独自のページでエンジンを実行するアプリはそこにセッションを提供します。セッションがなくなり、そのようなアプリも待機していない場合、CLASSCAD_DAEMON_IDLE_MS(60 秒)経過後に自動終了します。インストールや管理は不要です。このパッケージの一部(dist/daemon.js)であり、使用中のみ動作します。 - デーモンを使う理由:MCP はポートをリッスンし、ポートを使用できるのは 1 つのプロセスだけです。デーモンを 1 つにすることで、すべてのセッションのアプリリンクが同じアドレスになり、MCP を探すアプリが見つけられるようになります。
- ユーザーと共有されます。 すべての描画には、同じエンジンにドッキングされた稼働中の CAD アプリがあります。詳しくはアプリを参照してください。セッションプロトコルは ClassCAD サーバーが使用するものと同じなので、どの buerli アプリも同じ方法で参加できます。詳しくは共有を参照してください。
- マシンの外とも共有されます。 セッションは共有リレー(
packages/relay、Cloudflare Worker)でも提供されるため、アプリのリンクはどのマシンでも機能します。MCP からリレーへ接続するため、マシン上で外部向けにリッスンするものはありません。詳しくは別の場所から参加する場合を参照してください。 - オプションのエンジンです。
classcad-cli workerに接続できる場合(CLASSCAD_WS_URL、デフォルトはws://localhost:9094/)、デフォルトのポリシーautoはローカルエンジンの代わりにそれを使用します。詳しくはエンジンを参照してください。 - エンジンは描画で最初のツール呼び出しがあるまで起動しないため、アイドル状態のセッションにはコストがかかりません。また、使用されない描画はエンジンを手放します(休止状態になります。詳しくは描画を参照してください)。
- フォールバック:
127.0.0.1:9097が classcad デーモン以外のプロセスに使用されている場合、シムはインプロセスで MCP を提供します(独自のリスナーを使用し、9098が使用中の場合は空きポートを使用)。その旨を stderr に出力します。
前提条件
- Node.js 20 以降(
node、npx) - 初回使用時のインターネット接続(パッケージは npm から、エンジンは awvstatic.com から取得します。その後はオフラインで動作します)
- 無料の classcad.ch アカウント。マシンごとに一度サインインしてください(Google、GitHub、またはメール)。MCP は初回使用時に自動でサインインを求めます。詳しくはサインインを参照してください。
ほかに必要なものはありません。ClassCAD サーバーもキーも不要です。
インストール
クローンやビルドは不要です。どのホストでも、1つのコマンドでサーバーを起動できます。
npx -y @classcad/mcp@latest
@latest を指定すると、キャッシュ済みのものを再利用せず、npx が最新リリースを取得します。-y はインストールの確認を省略します。npx が sharp のインストールスクリプトを実行しなかったという警告を表示する場合がありますが、問題ありません。sharp にはビルド済みバイナリが含まれています。
Windows(ネイティブ環境。WSL ではありません): ホストは npx を直接起動できません。コマンドに cmd を指定し、引数に /c npx -y @classcad/mcp@latest を指定してください。たとえば、claude mcp add classcad --scope user -- cmd /c npx -y @classcad/mcp@latest のようにします。JSON 設定では "command": "cmd", "args": ["/c", "npx", "-y", "@classcad/mcp@latest"] を指定してください。(下記の Claude Code プラグインでは、この変更は不要です。)
ソースからの実行は、npm に接続できない場合に限ります。git clone https://github.com/awv-informatik/classcad-ai.git && cd classcad-ai && npm install && npm run build を実行し、npx コマンドの代わりに node /abs/path/to/classcad-ai/packages/mcp/dist/server.js を使用してください(echo "$PWD/packages/mcp/dist/server.js" でパスを表示できます)。
ホストを設定する
どのホストでも、上記のコマンドを設定し、新しいセッションを開始(または再起動)してサーバーを起動する必要があります。環境変数は不要です。
Claude Code(CLI、およびデスクトップアプリの Code タブ)
このプラグインを使うと、macOS、Linux、Windows のいずれでも、MCP サーバーと ClassCAD スキルを利用できます。
claude plugin marketplace add awv-informatik/classcad-ai
claude plugin install classcad@classcad
または、MCP サーバーのみを設定します(2つの方法のうち、どちらか一方を選んでください)。
claude mcp add classcad --scope user -- npx -y @classcad/mcp@latest
--scope user は ~/.claude.json に書き込みます(すべてのプロジェクトが対象です)。--scope project は現在のリポジトリに .mcp.json を書き込みます。claude mcp list で確認してください。項目に ✔ Connected と表示されます。ツールは次のセッションで利用できるようになります(各セッションが独自の MCP プロセスを起動します)。実行中のセッションでは /mcp を使って再接続してください。
~/.claude.json / .mcp.json での同等の手動設定:
{
"mcpServers": {
"classcad": { "command": "npx", "args": ["-y", "@classcad/mcp@latest"] }
}
}
Claude デスクトップアプリ(Chat / Cowork)
デスクトップアプリのチャット側には独自の設定があり、~/.claude.json は読み込みません。
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
上記と同じ mcpServers ブロックを追加してください。アプリはすべてのチャットで1つの MCP 接続を共有します。各チャットはそれぞれ独自の図面を扱うため(図面を参照)、あるチャットが別のチャットのモデルに触れることはありません。アプリはシェルから起動されないため、PATH が設定されていません。npx を起動できない場合は、command に絶対パスを指定してください(which npx で確認できます。macOS の Homebrew の場合は /opt/homebrew/bin/npx です)。その後、node が見つからない場合は "env": { "PATH": "<node があるフォルダー>:/usr/bin:/bin" } を追加してください。アプリを終了して再度開いてください。MCP サーバーが起動するのはアプリの起動時のみです。サーバーは「設定」→「開発者」の下に表示され、チャットにはスナップショット画像がインラインで表示されます。
Codex
~/.codex/config.toml:
[mcp_servers.classcad]
command = "npx"
args = ["-y", "@classcad/mcp@latest"]
VS Code — GitHub Copilot Chat(エージェントモード)
コマンドパレットから MCP: Add Server を選ぶか、.vscode/mcp.json(ワークスペース)またはユーザー MCP 設定を編集します。
{
"servers": {
"classcad": { "type": "stdio", "command": "npx", "args": ["-y", "@classcad/mcp@latest"] }
}
}
(トップレベルキーは servers で、"type": "stdio" の明示的な指定が必要です。)Copilot Chat を Agent モードに切り替えると、classcad ツールを選択できるようになります。
Cursor
すべてのプロジェクトを対象にする場合は ~/.cursor/mcp.json、1つのプロジェクトを対象にする場合は .cursor/mcp.json に、Claude Code のセクションにある mcpServers ブロックを指定します。
OpenCode
opencode.json:
{
"mcp": {
"classcad": { "type": "local", "command": ["npx", "-y", "@classcad/mcp@latest"] }
}
}
その他のホスト
ほとんどのホストは、Claude 形式の mcpServers JSON を使用できます。
最初のテスト
新しいセッションで、エージェントに箱を作ってと依頼します。初回はサインイン用リンクが表示されるので、リンクを開いてサインインすると、エージェントが自動で処理を続けます。その後、run_script が呼び出され、体積を含む回答が返されると、アプリに箱が表示されます(デスクトップアプリの Browser ペイン、またはブラウザー内)。回答で名前が示された図面に対して session_info を実行すると、ワーカーが実行中でなければ "transport": "wasm"、ワーカーが実行中なら "ws" と表示されます。初回の呼び出しには、WASM アセットのダウンロードにより少し時間がかかります。
図面
モデルを操作するすべてのツールには、drawingが必要です。モデルに対する最初の呼び出しでは"new"を渡します。MCPは図面を開きます。これは、独自のツールキュー、チェックポイント、アプリを持つエンジンセッションです。応答にはそのID(d-k3v9q2xa)が含まれます。そのモデルに対する以降の呼び出しでは、すべてそのIDを渡します。別の無関係なモデルは、別の図面になります。docs、list_methods、describe_method、login、accountは図面を必要としません。また、図面を指定せずにsession_infoを呼び出すと、MCP全体の情報が返されます。
理由。 ホストによっては、1つの接続を介して複数の会話を処理します。ClaudeのデスクトップチャットアプリとCoworkは、すべての会話に対して1つのMCPプロセスを起動します。CursorとVS Codeは、ウィンドウごとに1つ起動します。リクエストには、どの会話から送られたのかを示す情報がありません。接続ごとに図面が1つだけだと、ある会話でのclearやloadによって、別の会話のモデルが失われてしまいます。図面のIDはランダムで、図面を開いた会話にしか通知されないため、ほかの会話からアクセスすることはできません。IDを指定しない呼び出しや、この接続では認識されないIDを指定した呼び出しは拒否され、何も変更されません。図面は並行して実行されるため、2つの会話のスクリプトが互いに待たされることはありません。
図面は、そのセッション(ホストの接続)が終了すると終了します。それ以降もモデルを保持するには、saveで保存してください(OFBではフィーチャーも保持されます)。
アイドル状態の図面は休止します。 ローカルエンジンはメモリを消費します。デーモン内の最初のエンジンは約850 MB、それ以降はそれぞれ約350 MBを使用します。CLASSCAD_DRAWING_IDLE_MS(10分)の間使われなかった図面は、エンジンを解放します。図面はデーモン内でOFBとして待機し、次の呼び出し、またはドッキングされたアプリの次のコマンドでエンジンが起動し、チェックポイントとIDを保持したまま再読み込みされます。接続ごとに起動状態を保てる図面は最大CLASSCAD_DRAWINGS_AWAKE(3)個です。最も長く使われていない図面が最初に休止します。再起動には1、2秒かかります。ワーカー上の図面はワーカーのセッションであり、休止しません。
アプリ
すべての図面には、図面独自のエンジンに組み込まれたライブ CAD アプリ、Buerligons(buerli CAD アプリ)があります。パッケージにはそのビルドが含まれており、アプリ自体もパッケージから提供されるため、インストールは不要で、オフラインでも動作します。
- 図面の最初のモデルとともに起動し、エージェントによる変更をすべて、その都度表示します。起動場所はホストによって異なります。Claude デスクトップアプリ(Code タブ)では、会話の横にあるアプリ独自のブラウザーペインで起動し、エージェントがそこで開きます。それ以外の場所では、MCP がユーザーのデフォルトブラウザーを開きます。最初のモデルを作成するスクリプトの結果には、図面ごとに一度だけリンク(
App: …)が含まれます。エージェントはそのリンクを回答のたびに含めるわけではありません。session_infoにはリンクが記載され、viewはリンクを返してアプリを再び開きます(ユーザーがすでに開いている場合は除きます。図面ごとにタブが一つあれば十分です)。 - ユーザーもアプリを操作できます。 回転やズーム、計測、選択ができます。フィーチャーの値を編集したり、スケッチを描いて拘束したり、フィーチャーを追加または削除したり、最初からやり直したり、ファイルを開いたりできます。モデルは同じものです。ユーザーが変更した内容はエージェントが次に読み取るツリーに反映され、エージェントが作成した内容はすぐにアプリに表示されます。アプリからのコマンドは実行中のスクリプトが終わるまで待機するため、両者の処理が交互に割り込むことはありません。
- 選択対象の指定。 エージェントはアプリでユーザーが選択した対象を
get_selectionで読み取ります(「このエッジをフィレット」)。set_selectionを使うと、エージェントがユーザーに対象をハイライト表示します。 - ファイル。 アプリの「ファイル」メニューでは、モデルをOFB(フィーチャーを含むClassCAD独自の形式)、STEP、またはSTL形式で保存でき、これらのファイルをセッションに開くこともできます。
- 図面ごとにリンクは一つで、リンクは引き継がれます。 リンクには、特定の一つの図面のセッションへの招待が含まれるため、複数の図面(会話、タブ、ホスト)をそれぞれ専用のアプリで並行して扱えます。デフォルトでは共有リンク
https://<relay>/?invite=…となり、同じリンクを同僚やユーザーのタブレットでも使えます(別の場所から参加するを参照)。リレーがセッションを保持していない場合、またはCLASSCAD_SHARE=askやoffの場合、リンクはこのマシン上のhttp://127.0.0.1:9098/?invite=…になります。セッションが終了するか、別のエンジンに移動すると、アプリがその旨を表示し、再参加を案内します。 - モデルの保存場所。 セッションとそのエンジンはユーザーのマシン上にとどまります。MCP は
127.0.0.1:9098(CLASSCAD_VIEWER_PORT。そのポートが使用中の場合は別の空きポート)でアプリを提供し、自身をホストとして指定したリクエストにのみ応答します。その場所から開いた場合、モデルのデータがマシンの外に出ることはありません。共有リンクから開いた場合、アプリのフレームはリレーを経由しますが、リレーがフレームを保存することはありません。招待はセッションへの鍵となるため、リンクは秘密情報です。共有リンクを持つ人は誰でも参加できます。
CLASSCAD_VIEWER_OPENでは、アプリの起動場所を指定します。browser(ユーザーのデフォルトブラウザー)、host(エージェントがホスト独自のブラウザーペインで開く。ブラウザーペインがあるホストで使用できます)、または0(起動せず、エージェントがリンクを渡す)を指定できます。未設定の場合、Claude デスクトップアプリではhost、それ以外ではbrowserになります。CLASSCAD_APP_URLでは、このパッケージのアプリの代わりに、別の場所でホストされているアプリを指定します。この場合、リンクは<url>?invite=…となり、アプリはws://127.0.0.1:9098/sessionでその招待に参加する必要があります(ページ内のエンジン用にビルドされたBuerligonsは参加できます)。公開サイトのページから127.0.0.1に接続できるかどうかは、ブラウザーの設定によります。下記のブラウザーで許可が必要なことを参照してください。CLASSCAD_VIEWER=readonlyを指定すると、アプリの代わりに読み取り専用の3Dビューが表示されます(モデルを回転したりエクスポートしたりするだけのページです。このパッケージのアプリなしビルドにも含まれています)。CLASSCAD_VIEWER=offを指定すると、何も表示されません。
サインイン
MCP は、サインイン済みの classcad.ch アカウントで、マシンごとに 1 回利用できます。インストールするエージェントは最後の手順でサインインします(login、またはターミナルで classcad-mcp login)。そうでない場合、サインインしていないマシンで最初にエンジンツールを呼び出すと、ツールは実行されずにサインインが開始されます。
- サインインページはユーザーのブラウザーで自動的に開きます(
open/xdg-open/start。ただし、ディスプレイのないリモートシェルやCLASSCAD_AUTH_NO_BROWSER=1の場合を除きます)。フォールバックとして、エージェントも同じリンクを表示します:https://classcad.ch/connect?port=…&state=…。その間、MCP はこのサインインのために127.0.0.1:<port>で待ち受けます(15 分間)。 - ユーザーがリンクを開き、サインインするかアカウントを作成します(Google、GitHub、またはメール)。classcad.ch にすでにサインインしている場合は、「Continue」を 1 回クリックするだけです。
- ページからサインイン情報が
http://127.0.0.1:<port>/callbackに返されます(トークンは URL フラグメント内に含まれ、サーバーからは見えません)。MCP は Firebase で確認し、~/.classcad-mcp/auth.jsonに保存します。 - その間、エージェントは
loginツールで待機します。サインイン情報が届くと、ツールはすぐに結果を返します。ブラウザーのタブには、エージェントに戻るよう表示されます。
マシンでの以降のセッションはすべてサインイン済みになります。MCP は Firebase でアカウントを再確認しますが、その頻度は 1 時間に 1 回までです。アカウントが取り消されたり無効になったりすると、そのマシンはサインアウトされます。ネットワークに接続できない場合、最後の確認は 14 日間有効です。session_info でアカウントを確認できます。ドキュメントツール(list_methods、describe_method、docs)はサインインなしで利用できます。
ターミナルからも同じ手順を実行できます(チェックアウト内で node dist/server.js <command>)。さらに、次の操作もできます。
classcad-mcp loginはリンクを表示し、リンクが使用されるまで待機しますclasscad-mcp whoamiはサインイン状態を表示しますclasscad-mcp logoutはマシンをサインアウトします(またはlogout: trueを指定してloginツールを使用します)
環境変数
| 変数 | 目的 |
|---|---|
CLASSCAD_WS_URL | オプションの ClassCAD ワーカーの WebSocket URL です。デフォルトは ws://localhost:9094/ です。接続できない場合は、ローカル WASM エンジンを使用します。到達可能なワーカーであれば使用できます(wss://…)。 |
CLASSCAD_SNAPSHOT_DIR | 呼び出しで outDir が渡されない場合に、snapshot が PNG を書き込む場所です。デフォルトは <tmpdir>/classcad-snapshots です。 |
CLASSCAD_SKILL_PATH | インストール済みの @classcad/skill に含まれるバンドルの代わりに、スキルディレクトリ(チェックアウトの packages/skill)からドキュメントを直接読み込みます。再ビルドしなくても編集内容が反映されます。 |
CLASSCAD_MCP_PORT | 127.0.0.1 上のデーモンの HTTP エンドポイントのポートです。デフォルトは 9097 です。シムとデーモンの設定を一致させる必要があります(シムはデーモンの起動時にこの値を渡します)。 |
CLASSCAD_MCP_URL | http://127.0.0.1:<port> の代わりに指定するデーモンの完全な URL です(通常は不要です)。 |
CLASSCAD_DAEMON_IDLE_MS | セッションがなく、独自のセッションを提供するアプリもない状態で、デーモンが終了するまでの時間です。デフォルトは 60000 です。 |
CLASSCAD_DRAWING_IDLE_MS | ローカルエンジン上の図面が使用されないまま、エンジンを解放するまでの時間です(図面)。デフォルトは 600000(10 分)です。 |
CLASSCAD_DRAWINGS_AWAKE | 1 つの接続でローカルエンジンを稼働状態に保つ図面の数です。この数を超えると、最も長く使用されていない図面がスリープします。デフォルトは 3 です。 |
CLASSCAD_MCP_LOG | デーモンのログファイルです。デフォルトは <tmpdir>/classcad-mcp/daemon.log です(シムは起動時に stderr にパスを出力します)。 |
CLASSCAD_ENGINE | トークンや URL で決定されない場合のエンジンポリシーです。auto(デフォルト:ワーカー、なければローカル WASM エンジン)、drogon(ワーカーのみ)、wasm(ローカルエンジンのみ)を指定できます。 |
CLASSCAD_VIEWER | セッションでユーザーに表示するものです。デフォルトはアプリです。readonly:読み取り専用の 3D ビュー。off:何も表示しません。 |
CLASSCAD_VIEWER_PORT | 127.0.0.1 上でセッションが接続されるリスナーのポートです。デフォルトは 9098 です。使用中の場合は空きポートが使われます(0:常に空きポートを使用)。独自のセッションをホストするアプリは、9098 で MCP を探します。 |
CLASSCAD_VIEWER_OPEN | 最初のモデルを表示するアプリの起動先です。browser(ユーザーのデフォルトブラウザー)、host(エージェントがホストのブラウザーペインで開く)、0(どこにも開かず、リンクを渡す)を指定できます。デフォルトは Claude デスクトップアプリの Code タブでは host、それ以外では browser です。セッションごとに設定されます。 |
CLASSCAD_APP_URL | セッションにドッキングするアプリを、別の場所でホストしている場合に指定します(例:https://buerligons.io/)。リンクは <url>?invite=… になります。デフォルトはこのパッケージ内のアプリです。 |
CLASSCAD_RELAY_URL | セッションの共有に使用する共有リレー(https://…、packages/relay)です。off:セッションを共有しません。デフォルトは https://classcad-share.it-5ca.workers.dev(src/share/relay.ts の DEFAULT_RELAY_URL)です。 |
CLASSCAD_SHARE | セッションがそのマシンの外でも使えるリンクを取得するタイミングです。always(デフォルト — 最初のモデルから共有され、アプリもそのリンクで開きます)、ask(ユーザーが要求した場合。share ツールを使用します。アプリ独自のリンクは 127.0.0.1 のままです)、off(共有しません)。 |
CLASSCAD_BACKEND | classcad(デフォルト):プラン用バックエンド。classcad.ch でサインインします。develop:同じバックエンドを使用し、classcad.ch の開発ビルド(http://localhost:9090)でサインインします。staging:https://staging01.classcad.ch でサインインします。 |
CLASSCAD_TOKEN | シークレットのアクセストークン(ccsk_…、classcad.ch/account で作成)です。CI など、サインインしないマシンで使用します。サインインの代わりに、このトークンでエンジンのキーを取得します。 |
CLASSCAD_AUTH_URL | サインインページです。デフォルトは https://classcad.ch/connect です(CLASSCAD_BACKEND=develop の場合は http://localhost:9090/connect)。 |
CLASSCAD_AUTH_FILE | サインイン情報の保存先です。デフォルトは ~/.classcad-mcp/auth.json です。 |
CLASSCAD_AUTH_NO_BROWSER | 1:サインインページをブラウザーで開かず、エージェントがリンクを表示します(CI が設定されている場合も同様です)。 |
CLASSCAD_WASM_KEY | バックエンドから取得するキーの代わりに、ローカルエンジン用の独自のキーを指定します。インターネットに接続できないマシンや、契約により必要な場合に使用します。それ以外では不要です。 |
CLASSCAD_WASM_ORIGIN | ローカルエンジンが稼働元として示すオリジンです。デフォルトは http://localhost で、ローカル使用向けのキーは任意のポートで使用できます。 |
CLASSCAD_WASM | off:ローカルエンジンを使用しません(ワーカーのみ)。 |
CLASSCAD_KEY_URL, CLASSCAD_KEY_FILE | トークン交換先(デフォルトはプラン用バックエンドの /api/v1/key)と、エンジンのキーの保存先(デフォルトは ~/.classcad-mcp/engine-key.json)です。 |
CLASSCAD_WASM_VERSION | ホストする ClassCAD のリリースです。デフォルトは 21.2.0(buerli アプリが読み込むバージョン)です。 |
CLASSCAD_WASM_DIR | リリースアセットのキャッシュ先です。デフォルトは ~/.classcad-mcp/wasm/<version> です。 |
CLASSCAD_WASM_URL | ダウンロード元のベース URL の上書き値です。デフォルトは https://awvstatic.com/classcad/download/release/<version>/wasm です。 |
必須のものはありません。ホストの MCP 設定の env ブロックに設定してください。shim はそれらを起動するデーモンに引き渡します。CLASSCAD_WS_URL、CLASSCAD_ENGINE、CLASSCAD_VIEWER_OPEN はセッションごとに設定されます。デーモンは新しいセッションごとにそれらを受け取るため、2 つのタブで異なるワーカーを指定でき、Claude デスクトップアプリのタブではアプリがペイン内に表示される一方、ターミナルのタブではブラウザーが開きます。 |
デーモンの実際の動作
- どのプロセスがどれか:
classcad-mcpのシムは、ホストが起動したプロセス(dist/server.js)で、タブごとに1つあり、タブを閉じると終了します。dist/daemon.jsは長時間稼働するプロセスです。GET http://127.0.0.1:9097/healthでは、その PID、バージョン、アクティブなセッション数、セッション内の図面(drawings)、そのうちエンジンが稼働中の数(awake)、セッション内のアプリ数(apps)、セッションが参加しているアドレス(join)、ログファイルを確認できます。 - 複数のタブ: 各タブは同じデーモン内の1つのセッションであり、その会話で開いた図面を含みます。セッションと図面は独立しています(ある図面のスクリプトが、別の図面のエンジンやキャッシュに影響することはありません)。図面を指定した
session_infoで、その図面が何に接続されているかを確認できます。 - 稼働期間: 最後のセッションが閉じられてから1分後にデーモンは終了します。ただし、アプリが独自のセッションを提供している場合は除きます(エンジンがページ内にある buerli アプリはデーモンを稼働状態に保つため、次のタブはすぐに参加できます)。このようなアプリは、再起動したデーモンを5秒以内に自動で検出します。
use_sessionはそのために8秒待機します。シムは、ホストが stdin を閉じるか SIGTERM を送信すると終了します。デーモンはそのセッションをただちに破棄し、そのセッションに接続していたアプリにはセッションが終了したと通知されます。 - アップグレード:
npm run buildの実行後(またはパッケージ更新後)、次のシムはバージョンまたはビルドスタンプの不一致を検出します(/healthには両方が表示されます。スタンプはデーモンの起動時に取得され、dist/daemon.jsと@classcad/rendererおよび@classcad/scriptのビルドを対象とします)。アイドル状態の古いデーモンはシャットダウンされ、新しいものに置き換えられます。稼働中のデーモン(他のタブが接続中)は drain 状態に移行し、新しいセッションを受け付けず、最後のタブが閉じると終了します。その間、新しいタブは現在のビルドをプロセス内で実行します(アプリ用に空きポートで独自のリスナーを起動します)。古いタブでは、再起動されるまで古いコードが使われます。 - ログ: シムはセッションの開始・終了ごとに1行を stderr に書き込みます(ホストの MCP ログに表示されます)。デーモンは
CLASSCAD_MCP_LOGに書き込みます。ログを確認するには、手動で起動します:CLASSCAD_MCP_DAEMON=1 node dist/daemon.js(CLASSCAD_MCP_LOGが未設定の場合は stderr に出力します)。 - トラブルシューティング:
curl http://127.0.0.1:9097/health— 応答がない場合はデーモンが起動していません(次のツール呼び出しで起動します)。joinのアドレスのポートが9098以外の場合、そのポートは別のプログラムに使われています(通常は古いビルドの MCP プロセスです。そのタブを閉じてください)。アプリへのリンクは引き続き動作しますが、独自のセッションをホストするアプリは MCP を検出できません。nameがclasscad-mcp以外の場合、9097は別のプログラムに使われています(CLASSCAD_MCP_PORTを設定してください)。classcad-mcp stopはアイドル状態のデーモンを停止します(以下を参照)。ポート:9094 worker(ws)、9095 worker(wss)、9097 daemon、9098 アプリとセッション — worker を除き、すべて127.0.0.1上です。共有リレーには送信 WebSocket(443)で接続します。session_infoのsharedには、セッションを保持しているかどうかが表示されます。 - 停止/再起動: パッケージのバイナリは簡易 CLI も兼ねています(チェックアウト内では
node dist/server.js <command>):classcad-mcp status— 実行中のデーモンの/health(PID、ビルド、セッション、図面、アプリ、ログファイル)。classcad-mcp stop— アクティブなセッションがない場合にデーモンを停止します。セッションがある場合は拒否されます(終了コード1)。classcad-mcp stop --force— セッションの有無にかかわらず SIGTERM を送信します(5秒後に SIGKILL)。たとえば、ビルドし直したレンダラーをすぐに読み込む場合に使います。接続中の各タブではすべての図面が失われます。シムは次のツール呼び出し時に再接続し、新しいデーモンを起動してホストのinitializeを再送信するため、ホストを再起動する必要はありません。
- セキュリティ: デーモンは
127.0.0.1にバインドし、Originヘッダーを含むすべてのリクエスト、およびHostが127.0.0.1/localhost/[::1]以外のすべてのリクエストを拒否します(403)。DNS リバインディングを使った場合でも、ウェブページから操作することはできません。9098のリスナーはブラウザーアプリ向けです。ホストとして自身を指定したリクエストにのみ応答し、サインイン済みのマシン上で招待リンク(122ビットのランダムトークン)を使った場合にのみセッションに参加できます。マシン外とのセッション共有でポートが開くことはありません。MCP はリレーに発信接続し、マシンのサインインを確認した場合にのみオファーを受け付けます。また、そのセッションの共有招待リンクを持つユーザーを受け入れます。これは独自の招待リンクであり、リスナーは受け付けず、shareが受け取ります。
ツール
モデルに対して動作するすべてのツールには、drawingとして"new"、または以前の回答で指定されたID(図面)を指定します。
| ツール | 目的 |
|---|---|
run_script | 唯一の実行手段です。api.v1.*、api.tree()、api.graphic()に対してJavaScriptを実行します。状態はスクリプト間で保持され、後続のスクリプトは既存のモデルに追加されます。 |
tree / find / inspect | 構造ツリー(キャッシュされ、要求に応じて取得)、クラス名/名前による検索、親の連鎖を含むノードの詳細情報 |
snapshot | 図面をPNGにレンダリングします(アイソメ/上面/正面など、断面、四面図シート、隠線付きの製図図面、ハイライト、マーカー) |
list_methods / describe_method / docs | メソッド一覧、LLM向けの注意点を含むメソッドごとのリファレンス、レシピ |
account | サインイン中のアカウントのプランと利用可能な内容:商用利用、エクスポート、ウェブアプリを実行できる場所(localhost、登録済みドメイン)、アプリのページ用の公開アクセストークン。読み取り専用です。recipes/buerli-appの最初の手順です。 |
view | セッションのアプリを開きます。リンクを返し、ホスト側のブラウザペインまたはユーザーのブラウザーで表示します(ユーザーがすでに開いている場合を除く)。local: trueを指定すると、このマシン上のリンクを返します。共有リンクが読み込まれない場合に使用します。 |
share | 別のマシンから利用できる、セッションのアプリへのリンクです。stop: trueを指定すると共有を停止します。 |
get_selection / set_selection | アプリでユーザーが選択しているもの(面、エッジ、頂点、ツリーオブジェクト)と、API呼び出しで使用するIDを取得します。また、対象を示すためにアプリ上で選択します。 |
save / load / clear / checkpoint / restore | saveはSTEP、STL、GLB、OFBをディスク上のpathに書き込みます(またはbase64を返します)。analyticを指定すると、STEPではBスプライン曲面ではなく、平面、円柱、円錐として保存されます。loadはディスク上のpathからOFB/STEP/STLを読み込みます(またはbase64コンテンツから読み込みます)。checkpoint/restoreは、MCPのメモリに保持される取り消しポイントです。 |
login | マシンにサインインします(リンクを返し、利用されるまで待機します)、またはサインアウトします。 |
session_info / use_session | 状態(エンジン、アプリのリンク、shared内の共有リンク、セッション内の他の参加者、サインイン状態)を確認します。エンジンを切り替えるか、アプリの招待リンクを使ってそのセッションに参加します。 |
snapshotは、モデル向けにPNGをインライン画像ブロックとして返し、CLASSCAD_SNAPSHOT_DIRに書き込みます。Claude CodeとデスクトップアプリのCodeタブでは、ツール結果の画像はユーザーに表示されません。ツール結果にはその旨と保存ファイル名が示されるため、モデルはファイルをユーザーに渡せます(Claude CodeではSendUserFileを使用します)。デスクトップアプリのチャットでは画像が直接表示されます。Claude Codeがプレビューできるのは、セッション専用のフォルダー(スクラッチパッドまたはプロジェクト)にある送信ファイルだけです。それ以外のファイルは灰色のプレースホルダーカードとして表示されるため、ツールはモデルにoutDirへスクラッチパッドを指定するよう伝えます。
**ツール呼び出しは図面ごとに直列化されます。**図面内のすべてのツールは同じエンジン接続を共有するため、サーバーは一度に1つの図面ツール呼び出しだけを実行します(ドキュメントの参照を除く)。run_scriptと並行して実行されたsnapshotは、作成途中のモデルをレンダリングするのではなく、スクリプトの完了を待ちます。他の図面は待ちません。親の図面を引き継いだサブエージェントは、その図面のキューを共有します。
エンジン:workerまたはローカルWASM
MCPは、2種類のエンジンのいずれかで独自のセッションを実行します。どちらを使うかはエンジンポリシーによって決まります。(アプリのセッションへの参加はエンジンの選択ではありません。エンジンはアプリ側のものです。共有を参照してください。)
| エンジン | 概要 | MCP からの接続方法 |
|---|---|---|
| ローカル WASM | 公開されている ClassCAD WASM ビルドです。MCP 自体がデーモンのワーカースレッド内で実行します。サーバーもブラウザーも不要で、アセットをキャッシュすればオフラインで動作します。 | 設定は不要です(キーはサインイン時に取得します)。ポリシー(auto/wasm)または use_session(engine="wasm") を指定します。 |
| Worker(Drogon) | classcad-cli worker です。マシン上、Docker 内、またはホスト環境で実行するサーバーです。 | CLASSCAD_WS_URL、ポリシー(auto/drogon)、use_session(sessionId) を指定します。 |
ポリシー。 CLASSCAD_ENGINE(デフォルトは auto)および use_session の engine 引数です。
auto— Worker に接続できる場合は Worker を使用し、接続できない場合はローカルエンジンを使用します。「MCP を接続して箱を作って」と指示するだけで、ほかに何も必要ありません。Worker が実行中ならそれを使用し、実行中でなければ MCP が独自のエンジンでモデリングし、session_infoでその旨を伝えます(transport: "wasm")。drogon— Worker のみを使用します。「MCP を自分の Drogon/ClassCAD サーバーに接続して」と指示します。フォールバックはありません。Worker が停止している場合は、その旨が通知されます。wasm— ローカルエンジンのみを使用します。「MCP を WASM に接続して/ローカルで作業して/オフラインで」と指示します。
選択したエンジンは use_session で変更するまでそのセッションで維持されます。招待リンクを使用している間は、そのリンクの設定が優先されます。フォールバックは Worker に接続できない場合(接続拒否、タイムアウト)にのみ実行されます。接続成功後のエラーを隠すことはなく、セッション ID を明示的に指定した場合にもフォールバックは実行されません。セッションが別のエンジンに移行すると、そのエンジンの空の図面で開始します。そこに接続されているアプリには移行が通知され、同じリンクで再参加します。
ローカルエンジンに必要なもの。
- キー。 エンジンの起動には ClassCAD キーが必要で、キーはエンジン自身が検証します。MCP はキーを保持していません。サインイン時にバックエンドにキーを要求し(
src/engine/key.ts)、アカウントのプランで許可されているキーが任意のポートのlocalhost用に発行されます。MCP はhttp://localhostで実行されていると通知しますが、これは正確です。キーは有効期限の少し前まで~/.classcad-mcp/engine-key.jsonに保存され、期限切れ前に更新されます。バックエンドに接続できない間も、保存されているキーが未期限切れであればエンジンを起動できます。CI では、サインインの代わりにCLASSCAD_TOKEN(シークレットのアクセストークン)を使用します。CLASSCAD_WASM_KEYを設定すると、独自のキーを使用します。プランで利用できるエクスポート形式はsaveとアプリのダウンロードに適用されます。Free では STL(および三角形データの GLB)をエクスポートできます。STEP、OFB、JSON は Solo 以上で利用できます。 - リリースアセット(約 16 MB:glue、メインモジュール、3 つのサイドモジュール、クラスファイル、フィルター設定)。初回使用時に awvstatic.com から
CLASSCAD_WASM_DIRに一度だけダウンロードされます。エンジンを必要とする最初のツール呼び出しには少し時間がかかり、デーモンログに進行状況が表示されます。その後はセッションごとに約 1 秒でエンジンが起動します(ヒープはそれぞれ約 130 MB。エンジンはセッションごとに 1 つ起動し、セッション終了時に終了します)。 - Node ≥ 20。
worker_threadsとfetchに必要です。パッケージのほかの部分と同じ要件です。
ローカルエンジンで異なる点。 ブラウザーアプリと同じエンジンです。図面は 1 つで、接続ごとの出力設定はありません(run_script はペイロードを抑制せずに実行されます。MCP セッションで扱うサイズであれば問題ありません)。snapshot、tree、find、inspect、save/load、checkpoint/restore はすべて動作します。サーバーがエンジンの周囲に備えているセッションレイヤー(招待、ゲスト、プレゼンス)は、MCP が独自に提供します。共有をご覧ください。
ローカルエンジンが失敗した場合。 エンジンエラーはワーカーの場合と同様に返されます(maxLevel が 51 でメッセージも含まれるため、run_script は例外をスローします)。これには、WASM エンジンがネストされた result 内だけで報告するエラーや、独立した ErrorMessage フレームとして報告するエラーも含まれます。値もレベルもない Result はエラーであり、空の成功ではありません。エンジンがクラッシュした場合、コマンドの実行中にトラップした場合、またはリクエストのタイムアウトまでに応答しない場合、そのエンジンは破棄されます。そのコマンドは理由とともに失敗し、次のコマンドでは空の図面を持つ新しいエンジンが起動します(チェックポイントは引き続き有効です。restore はチェックポイントを新しいエンジンに読み込みます)。use_session(engine="wasm"|"auto") は実行中のエンジンのヘルスチェックを行い、応答しない場合は置き換えます。正常なエンジンは、その図面とともに維持されます(clear で図面が空になります)。
共有:1つのセッション、複数の参加者
セッションには、エージェント、アプリを使うユーザー、別のマシンの同僚、別のエージェントなど、複数の参加者が参加できます。参加者は1つのエンジンと1つのモデルを共有し、誰かが変更すると、その変更はその都度ほかの参加者に送信されます。このプロトコルは ClassCAD サーバーのセッション共有に基づいています(招待、ゲスト、プレゼンス、各コマンドのフレームの全参加者への配信。ClassCAD のソースにある SessionSharing.md で仕様が定義されており、@buerli.io/classcad の WSClient がクライアントです)。セッションの所有者はエンジンの実行場所によって異なります。MCP は次の3つすべてに関与します。
| エンジンの実行場所 | セッションのホスト | ほかの参加者の参加方法 |
|---|---|---|
| MCP 内(ローカル WASM) | MCP:src/share/hub.ts は、独自のエンジン用サーバーのセッションレイヤーです | セッションの招待リンク ws://127.0.0.1:9098/session/?invite=… を使います。アプリのリンクから参加できます |
| ClassCAD ワーカー上 | サーバー | ワーカーの URL にあるサーバーの招待リンクを使います。MCP セッションのアプリはワーカーに引き継がれるため、リンクは同じです |
アプリのページ内(WASMClient) | アプリ(@buerli.io/classcad の session/host.ts) | MCP が参加者を紹介する場所で参加します。ページは ws://127.0.0.1:9098/session/?host=… で招待リンクを提供し、ゲストは ?invite=… で参加します。リスナーが両者をつなぎます |
同僚や別のデバイスを使うユーザーは、共有リレーを通じて MCP がホストするセッションに参加できます。別の場所にいる人が参加するを参照してください。
エージェントがホストし、ユーザーが参加する
デフォルトでは、各セッションのアプリがそのセッションに接続されます(アプリを参照)。view はリンクを返します。
別の場所から参加する
127.0.0.1 のリンクはユーザーのマシン上でしか使えません。そのため、セッションは共有リレーにも提供され、リレーがセッションを保持している場合、アプリは代わりにそのリンクで開きます。リンクは 1 つです(App: https://<relay>/?invite=…)。ユーザーはこのリンクを開き、同僚に送ったり、タブレットで開いたりできます。
view() → the app's link: the share link, or the one on 127.0.0.1 while the relay does not hold the session
view(local=true) → the link on 127.0.0.1, whatever the relay does
share() → the share link again
share(stop=true) → the share link stops working, whoever has the app open under it is disconnected
セッションが壊れることはありません。 最初のスクリプトの実行中にリレーへの問い合わせが行われます。モデルの準備ができるまでに提供を断ったリレーは待たず、応答がないリレーにはさらに 6 秒待ちます。どちらの場合も、最初のモデルは 127.0.0.1 のリンクとともに表示されます。エラーにはなりません。あとからリレーが停止し、ユーザーのアプリも一緒に使えなくなった場合は、次の結果で、このマシン上のアプリが再び提供されます。また、共有リンクが読み込まれないことを検知したエージェントは、local: true を指定して view を呼び出します。リレーがセッションを受け入れるまで、バックグラウンドで提供を再試行します。CLASSCAD_SHARE=ask にするとアプリは 127.0.0.1 上に維持され、ユーザーが要求した場合にのみセッションが共有されます(share はそのとき 2 つ目のリンクを返します)。off の場合は共有されません。
共有リンクを開いた人は、同じセッションにドッキングされた同じアプリを使います。エージェントがモデルを構築する様子を見たり、回転、選択、編集したりできます。セッションの場所は変わりません。MCP は、ページがリスナー上で独自のセッションを提供するのと同じ方法で、共有リレー(packages/relay、Cloudflare Worker)上にセッションを提供します。「この招待は自分のもの」と伝える常時接続と、ゲストごとに 1 つの接続を使います。ただし、そのために外部へ接続します(src/share/relay.ts)。外部からの接続を待ち受けるものはなく、マシン上で必要なのは Node だけです。NAT やファイアウォールの背後でも動作します。
- 専用の招待リンク。 共有リンクには
127.0.0.1のリンクとは異なる招待情報が含まれ、そちらのリスナーはその招待を受け付けません。共有を取り消す(stopを指定してshareを呼び出す)と、その招待で参加した全員が切断されます。アプリをそのリンクで開いている場合はユーザーも切断されます。127.0.0.1のリンクには影響しません。再び共有すると、新しい招待が発行されます。 - 共有リンクで開いている場合、ユーザーのアプリもリレーを経由します。 すべてのフレームが Cloudflare を往復します。
CLASSCAD_SHARE=askにすると、アプリはマシン上に維持されます。 - リンクを持っている人は誰でも参加できます。 アプリ上のユーザーと同じ権限です(
viewのロールは参考情報です。src/share/protocol.tsを参照してください)。エージェントはリンクをユーザーにのみ渡します。 - リレーが認識する情報。 リレーは、サインイン済みのマシンからの提供のみを受け付けます(サインイン時の Firebase ID トークンを Google の鍵で検証します)。ホストとゲストの間でフレームを中継し、何も保持しません。また、ゲストにアプリを提供します。これは、このパッケージに含まれ、リレーとともにデプロイされるビルドです。
- 接続が切断された場合(スリープ中のノートパソコン、別のネットワークなど)、MCP は自動的に招待を再提供し、リンクは引き続き機能します。
session_infoはsharedにリンクを表示し(リレーがセッションを保持していない間は null)、peersにゲストを表示します。 - 制限。 1 セッションあたりのゲストは 16 人までです。1 つのフレームは最大 32 MiB です(Cloudflare の制限です。非常に大きなモデルのグラフィック全体は収まらない場合があります)。
CLASSCAD_RELAY_URL には組み込みのものとは別のリレーを指定できます。off にするとセッションはマシン上に維持され、share ツールはなく、エージェントにも通知されません。
ユーザーがホストし、エージェントが参加する
アプリで Sessions → Create を開き、リンクをエージェントに渡します。
use_session(url="https://app.example/?invite=…") # the link of the app, wherever its engine runs
use_session(url="wss://cad.example/?invite=…") # or a server's URL directly
MCP はゲストとしてそのセッションに参加し、アプリのモデル上で動作します。変更はすべてアプリに表示されます。どのエンジンを使うかはリンクからはわかりません。このマシン上のアプリが提供する招待にはここから参加し、それ以外の招待はワーカーに渡します(CLASSCAD_WS_URL)。ページ内でエンジンを実行するアプリは、開いたままにしておく必要があり、このマシン上で実行する必要があります。session_info はセッションと参加者を報告します。引数なしで use_session() を呼び出すと、エージェント自身のセッションに戻ります。2 つ目のエージェントは、最初のエージェントが view で取得したリンクを使って、同じ方法でそのセッションに参加します。
名前付きセッション(ClassCAD-Session-Id モデル、ワーカーのみ):use_session(sessionId="test-session")。
ブラウザーで許可が必要なもの
このパッケージのアプリは 127.0.0.1 から配信され、同じアドレスでセッションに参加するため、許可は不要です。別の場所から配信され、このマシンのリスナー(ws://127.0.0.1:9098/session)に接続する必要があるアプリは別です。たとえば、エンジンを含み、そのセッションを提供するページ、そのようなセッションに参加する別のページ、または CLASSCAD_APP_URL で指定されたアプリです。ブラウザーは、公開ページから 127.0.0.1 への接続をローカルネットワークアクセスとして扱います。Chromium ベースのブラウザーではユーザーに許可を求めます(または、埋め込みブラウザーペインのように、許可を求められるユーザーがいない場合は拒否します)。許可されないと、ページは MCP を見つけられません。localhost(開発サーバー)から配信されるアプリには影響しません。また、セッションが ClassCAD サーバー上で実行されるアプリにも影響しません。
参加者に見えるお互いの情報
モデルに加えて、参加者は プレゼンス として、自分について少量の情報を公開します。これは、セッションが全員に中継し、後から参加した人のために保持する小さなフレームです。buerli パッケージがチャネルを定義し(@buerli.io/classcad の session/selection.ts、session/identity.ts、@buerli.io/react-cad の session/sessionClient.ts)、MCP がそれらを使用します(src/share/protocol.ts)。この仕組みは、3 種類すべてのセッションで同じように機能します。
| チャネル | 送信者 | 内容 |
|---|---|---|
client | 全員 | 参加者が誰であるか:{ app, version, name, kind: 'app' | 'agent' }。session_info で他の参加者を一覧表示します。 |
selection | アプリ | 選択されているもの。選択が変わるたびに送信します:{ items: [{ kind, objectId, prodRefId, containerId, graphicId, type, name }], total }。get_selection で読み取ります。 |
select | エージェント | items を選択するリクエスト(graphicId または objectId を使用)です。set_selection が送信し、その後アプリで選択された内容を報告します。 |
config | ホスト | すべての機能ではなく一部だけをゲストに提供するホストが、セッションで利用できる機能を示します:{ saveFormats: ['STP', 'STL'] }。アプリは提供されていない機能を非表示にします。MCP 自身のセッションでは機能を制限せず、何も公開しません。 |
view、cursor | アプリ | アプリ同士で表示するカメラとポインターです。 |
選択された面、エッジ、頂点には graphicId が含まれます。これは API がその要素を指定するために受け取る ID(例:v1.sketch.create({ planeId }))で、現在のモデルに対して有効です。アプリは syncSelection(client) を呼び出して選択内容を共有します。
出力モデル
ワーカー上で、エンジンは接続ごとに出力設定を保持します(GetEmissionConfig/SetEmissionConfig)。MCP は接続の設定をエンジンのデフォルトのままにするため、アプリはセッションを共有している間、モデル内のすべての処理について構造とグラフィックを受け取り続けます。run_script の実行中は、そのスクリプトに限りペイロードを無効にし(結果のみを返します。100 コマンドのスクリプトなら、小さな応答を 100 件返します)、実行後に元に戻します。スクリプトごとに MCP が 1 回取得するため、アプリと独自のキャッシュの状態が一致します。スクリプト内で api.tree() / api.graphic() を呼び出すと、必要に応じて取得され、次の変更までキャッシュされます。
ローカルエンジンは、コマンドによって変更されたすべての内容を常に生成します。そのため、MCP がホストするセッションでは、変更のたびにすべての参加者へ、各自の接続で要求された形式で送信されます(アプリにはストリーミングフレーム、エージェントのスクリプトには結果のみ)。誰かの出力設定が、他の参加者の受信を妨げることはありません。
開発
npm install # monorepo root
npm run build # skill → script → renderer → mcp (+ buerli-ai)
cd packages/mcp
npm run build:app # the app: packages/app (Buerligons from npm, @buerli.io/buerligons) built → app/
npm run build # tsc, app/ → dist/app/; postbuild runs the contract tests (emission, daemon, sign-in, sharing, the relay)
npm test # + the live tests: the local WASM engine, and a worker on CLASSCAD_WS_URL if one runs
node dist/server.js # the stdio shim by hand (starts/uses the daemon)
CLASSCAD_MCP_DAEMON=1 node dist/daemon.js # the daemon in the foreground, logging to stderr
CLASSCAD_SHARE_DEBUG=1 … # … with every command a docked app sends: how long it waited, how long it ran
npm run dev -w @classcad/relay # the share relay on http://127.0.0.1:8787, with the app build:app made (no Cloudflare account needed) …
CLASSCAD_RELAY_URL=http://127.0.0.1:8787 … # … and sessions shared on it
npm test -w @classcad/relay # the relay's contract, in wrangler's local runtime (Node 22+)
テストではブラウザーを開かず(CLASSCAD_VIEWER_NO_BROWSER=1、CLASSCAD_AUTH_NO_BROWSER=1)、代役(test/fake-auth.mjs:CLASSCAD_AUTH_TOKEN_URL、CLASSCAD_AUTH_PROJECT、CLASSCAD_AUTH_API_KEY)に対してサインインします。
ソースマップ:src/server.ts(stdio シム:デーモンの検索/起動、プロキシ、プロセス内フォールバック)、src/daemon.ts(HTTP エンドポイント、セッション、アイドル時の終了)、src/mcp-server.ts(MCP サーバー:1 つのエンジンクライアントに接続されたツール — セッションとは何か)、src/client.ts(エンジンクライアント:ワーカーへの WebSocket 接続、またはローカルエンジン)、src/share/(共有:hub.ts はローカルエンジン用のセッションレイヤー、server.ts はアプリおよびセッション用のリスナー、relay.ts は共有リレーで提供されるセッション、session.ts は参加者とその参照先、リンク、protocol.ts)、src/engine/wasm.ts + wasm-worker.ts(ローカル WASM エンジン:アセットのダウンロード、ワーカースレッド、オリジン/XHR シム)、src/tools/、src/queue.ts(セッションごとのツールキュー)。test/daemon.mjs はデーモンの契約をテストします:2 つのシム → 2 つの独立したセッションを持つ 1 つのデーモン、アイドル時の終了、別プロセスが使用しているポートでのフォールバック。test/share.mjs はエンジンを使わずに共有の契約をテストします:サーバーがゲストに提供するのと同じ方法でのゲストへの提供(ストリーミングおよびバンドル)、プレゼンス、ホストだけが実行できる操作、リスナー経由で参加するページホスト型セッション、リレーで提供されるセッション(リレー自体は packages/relay のテストで検証するため、ここではリスナーが代役を務めます)。test/wasm-live.mjs(npm test の一部。初回実行時にアセットをダウンロードします。エンジンキーを取得する手段が必要です — CLASSCAD_TOKEN に設定するシークレットアクセストークン、CLASSCAD_BACKEND とともに CLASSCAD_LIVE_AUTH_FILE に設定する login からのサインイン、または CLASSCAD_WASM_KEY。いずれもない場合はスキップされます)では、ローカルエンジンをテストします:ポリシー wasm、ワーカー停止時の auto フォールバック、フォールバックなしの drogon、use_session による切り替え、run_script を通じて表面化するエンジンエラー、クラッシュ、ハングまたは停止状態になったエンジンの置き換え、共有:MCP のエンジンに接続されたアプリ(変更と選択の双方向同期)、2 つ目のエージェントが 1 つ目のエージェントのセッションに参加すること。
公開
リリースは、トークンや二要素認証のプロンプトなしで、GitHub Actions(release.yml)から実行します。
- アプリは Buerligons です。npm の
@buerli.io/buerligonsを使用し、バージョンはpackage.jsonで固定しています(devDependency)。mcpモード(dist/mcp)でビルドします。Buerligons は buerli リポジトリで開発されており、nextへのプッシュごとにベータ版が公開されます(npm view @buerli.io/buerligons dist-tags)。別のバージョンを出荷するには、固定するバージョンを変更します。npm run build:appによりpackages/mcp/app/にコピーされ(app/SOURCE.txtにバージョンが記載されています)、ワークフローでも同様にコピーされます。また、release-checkはアプリなしでリリースが行われるのを防ぎます。 - MCP のバージョンを、記載されているすべての場所で更新します。
package.json、src/mcp-server.tsのVERSION、server.jsonのversionとpackages[0].version、および Claude プラグイン(plugins/classcad/.claude-plugin/plugin.jsonとplugins/classcad/launch.mjsのPACKAGE)です。このプラグインはこのリポジトリのmasterからインストールされ、固定されているパッケージバージョンを実行します。README とスキルにはそのバージョンが記載されているため、リリースによってユーザー向けに変更される内容は、前もってではなく、この手順で反映してください。変更があった場合は、@classcad/skill、script、rendererのバージョンも更新します。 - リポジトリのルートで
node scripts/release-check.mjs mcp-vX.Y.Zを実行し、バージョンの整合性を確認して、npm で新しく公開される内容を一覧表示します。 - コミットしてプッシュし、その後
git tag mcp-vX.Y.Z && git push origin mcp-vX.Y.Zを実行します。
ワークフローはタグをビルドしてテストし、npm にまだ公開されていないすべての @classcad パッケージ(skill、script、renderer、mcp の順)を、provenance 付きの npm Trusted Publishing を通じて公開します。また、ワークフローの GitHub OIDC ID で認証し、server.json を公式 MCP Registry に io.github.awv-informatik/classcad として公開します。
初回のみ、npmjs.com の各パッケージで次のように設定します:Settings → Trusted publishing → GitHub Actions、organization は awv-informatik、repository は classcad-ai、workflow は release.yml です。
リリース済みの系列に対するパッチは、そのリリースブランチ(0.2.x の場合は release/mcp-0.2)で作成し、そこでタグを付けた後、master にマージします。プラグインは master からインストールされ、そのバージョンを固定するため、npm に該当バージョンが公開されてから master をプッシュしてください。
共有リレーはリリースには含まれません。独立してデプロイします(npm run deploy -w @classcad/relay。詳しくはREADMEを参照してください)。このパッケージに含まれるアプリをゲストに提供します。アプリが変更されるリリースの後には、再度デプロイしてください。
ビルド失敗時とキャンセル時の動作
run_script はエンジンエラーを拒否し、呼び出し元から MCP の進捗トークンが渡された場合は進捗を報告します。リクエストのキャンセルシグナルは、それ以降の CAD 呼び出しを停止しますが、すでに実行中のネイティブ処理は完了することがあります。そのような処理が未完了の間、描画ツールはビジーエラーを返します。ドキュメントとセッション情報は引き続き利用できます。自動的な再試行やロールバックは行われません。トランスポートのタイムアウトが発生した場合は、再接続して図面を確認してから、変更操作を再試行してください。
スナップショットはデフォルトで再生成を行わず、キャプチャのメタデータを返し、更新エラーを報告します。ジオメトリの再構築が必要な場合は、明示的に recalc:true を設定してください。適応的な細分化を行うには、これと併せて quality:'fine' を使用します。注入されたボディでは、再生成を無効のままにしてください。共有の api.inspect ヘルパーについては、packages/script/README.md に記載されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。