ArtCraft 自動化:制御チャネル、CLI と MCP
声明
本スキルは ArtCraft シリーズソフトウェア向けのエージェントスキルであり、ArtCraft 公式リポジトリではありません。 ArtCraft / LightCraft / FilmCraft / PhotoCraft の著作権と公式ドキュメントは storyteller(github.com/storytold)に帰属します。本リポジトリは、公式で公開されているプロトコルと CLI を AI エージェント向けの操作マニュアルとツールスクリプトとして整理したものであり、公式との所属関係や推薦関係はありません。上流のドキュメントと本リポジトリの内容に矛盾がある場合は、公式を優先してください。
公式リポジトリ:lightcraft · filmcraft · photocraft
これは何か
ArtCraft スイート(github.com/storytold)の各デスクトップアプリは、UI でクリックできるすべてのメニュー項目、スライダー、ブラシストロークを安定した ID と JSON パラメータを持つコマンドとして実装し、以下の3つの同等なエントリポイントを提供します:
| エントリ | 外観 | 適した用途 |
|---|---|---|
| 制御チャネル | アプリが TCP ポートを開き、JSON 行を送受信 | ユーザーが表示しているウィンドウを操作 |
| CLI | lightcraft-cli / filmcraft-cli / photocraft-cli | ヘッドレスバッチ処理 |
| MCP | xxx-cli mcp | Claude などのクライアントに操作させる |
3つは同一のコマンドレジストリをスケジュールするため、スクリプトやエージェントは人間と同じように操作でき、編集操作は undo 可能です。
4つの鉄則(最初にこれを覚えてから他を読むこと)
- ランタイム発見優先。本スキルのリファレンスドキュメントは特定バージョン時点のスナップショットであり、ナビゲーションとフォールバックのみを目的とします。実際の情報は実行中のインスタンスを基準にしてください:
engine.commands(コマンドレジストリ)、methods(メソッドテーブル)、CLI の--help/commands/controls。記憶だけでコマンド ID を書くのは禁止——各アプリ、各バージョンでレジストリは異なります。 - 認証方式は3アプリで異なり、かつ変更される可能性があります。操作を始める前に
scripts/craft_env.pyを実行してローカルマシンのauthフィールドを確認し、ブログなどに書かれているポートやコマンドをそのままコピーしないでください。既知の3つの状態:- LightCraft:チャネルは認証なし(ローカルプロセスは誰でも制御可能。使い終わったらすぐ閉じる)
- FilmCraft:認証情報は各リクエストのトップレベル
tokenフィールドに含める(新しいバージョンでは必須;リリース済みの 0.9.0 では実際には必須ではない) - PhotoCraft:各接続の最初のフレームは必ず
authである必要がある。ファイルアクセスは自動化による読み書きがルートディレクトリに制限された fail-closed 方式scripts/craft_ctl.py --app <light|film|photo>は対応する方式を自動的に適用します。認証情報がない場合、勝手に失敗せず、サーバー側の判定に任せてエラーをそのまま読み取ります。
- 認証情報をコマンドライン、ログ、リポジトリに含めない。トークンファイル(Unix mode 0600)または環境変数を使用してください。共有マシンではトークンを平文でプロセスに渡さないでください。
- 編集前に影響範囲を説明する。ユーザーの実際の画像ライブラリやプロジェクトを変更する前に、何を変更するか、undo 可能か、エクスポート先を明確に説明してください。範囲が不明な場合は質問してください。
はじめに:環境セルフチェック
python3 scripts/craft_env.py --table # インストールされているバージョン、CLI の場所、チャネルの状態、認証情報の場所
python3 scripts/craft_env.py # 同じ内容の JSON
この手順は「このバージョンをインストールしたはず」という記憶に代わるものです。読み取りのみで書き込みは行いません。
エントリの選択
| ユーザーの希望 | 選択 | 一言理由 |
|---|---|---|
| 「このソフトを開いているので、クリック/表示してほしい」 | 制御チャネル | 実際のウィンドウ状態を確認できる唯一のエントリ |
| 「この200枚をバッチ処理したい」 | CLI headless | ウィンドウ描画に依存せず、より速く安定 |
| 「今後は AI に直接この作業を頼みたい」 | MCP | 一度接続すれば長期利用可能 |
| 「今、どのコマンドが使えるのか知りたい」 | 任意のエントリの engine.commands / command_list | 唯一の信頼できるコマンドリスト |
A. 制御チャネル
起動
3つのアプリはすべて --control PORT でチャネルを開きますが、起動フラグと認証要件が異なるため、まず craft_env.py と references/app-matrix.md を確認してください:
# LightCraft:一時的なメモリセッション。テストに最適。ディスクに書き込まない
nohup "/Applications/LightCraft.app/Contents/MacOS/LightCraft" --control 7980 --memory > /tmp/lc.log 2>&1 & disown
# FilmCraft:最初に認証情報をエクスポートする必要がある。そうしないとリッスンしない
export FILMCRAFT_CONTROL_TOKEN="$(python3 -c 'import secrets; print(secrets.token_hex(32))')"
nohup "/Applications/FilmCraft.app/Contents/MacOS/FilmCraft" --control 9876 > /tmp/fc.log 2>&1 & disown
# PhotoCraft:トークンファイル(アプリ初回起動時に自動生成、mode 0600)
nohup "/Applications/PhotoCraft.app/Contents/MacOS/PhotoCraft" --control 7878 \
--control-token-file ~/.photocraft/control.token > /tmp/pc.log 2>&1 & disown
プロセス生存維持:単純な
&で起動した GUI は、起動したシェルが終了すると回収され、以降の接続はすべて拒否されます。nohup ... & disownを使用するか、「起動→操作→終了」を1つのコマンドにまとめてください。
操作
付属のクライアントを使用し、毎回ソケットコードを書き直さないでください:
# 汎用形式:--app で認証方式を決定、--port でポートを指定
python3 scripts/craft_ctl.py --app light --port 7980 engine.commands
python3 scripts/craft_ctl.py --app film --port 9876 --method engine.execute --params '{"command":"sequence.inspect"}'
python3 scripts/craft_ctl.py --app photo --port 7878 --token-file ~/.photocraft/control.token '{"method":"ui.inspect"}'
# 条件発見:コマンドレジストリの簡略テーブル(--filter でフィルタリング、何千行もの出力を防ぐ)
python3 scripts/craft_ctl.py --app light --port 7980 --discover --filter develop
# スクリプトモード:stdin に1行1リクエスト、'#' で始まる行はコメント
echo '{"method":"engine.commands"}' | python3 scripts/craft_ctl.py --app light --port 7980
終了コード:0 すべて成功 / 1 ok=false あり / 2 使用法または接続エラー
B. CLI(ヘッドレスバッチ処理)
CLI は独立したリリースアセットであり、.app 内には含まれておらず、ArtCraft Launcher もインストールしません。取得とインストールについては references/cli-reference.md を参照してください。
lightcraft-cli run --import in.dng develop.set control=light.exposure value=0.7 app.export path=out.jpg longEdge=2048
lightcraft-cli render in.dng -o out.jpg --set light.exposure=0.5
lightcraft-cli commands --json # コマンドレジストリ(チャネルの engine.commands と同等)
lightcraft-cli controls --json # develop スライダー ID と範囲
photocraft-cli run wave.psd --cmd filter.sharpen.smartSharpen --params '{"amount":80}' --out out.png
photocraft-cli batch --actions grade.json --in ./raw --out ./graded
filmcraft-cli commands razor # キーワードでコマンド ID を検索
filmcraft-cli describe timeline.razor # 単一コマンドのメニュー/ショートカット/パラメータ/現在の有効状態
filmcraft-cli --project p.fcproj --save exec timeline.razor seconds=3.5
filmcraft-cli --bridge 127.0.0.1:9876 exec window.workspace.color # 実行中のアプリを逆制御
共通ルール:オプションの位置は任意;出力は JSON;終了コード 0=成功 / 1=コマンド失敗 / 2=使用法エラー;key=value は JSON としてパース可能なら JSON、そうでなければ文字列として扱う;ドット記法のキーはネストを表す(color.r=1)。
C. MCP(Claude などのクライアントに接続)
claude mcp add lightcraft -- lightcraft-cli mcp ~/Pictures/shoot
claude mcp add lightcraft-app -- lightcraft-cli mcp --connect 127.0.0.1:7980
claude mcp add filmcraft -- filmcraft-cli mcp --bridge 127.0.0.1:9876
claude mcp add photocraft -- photocraft-cli mcp --bridge 127.0.0.1:7878 --control-token-file /path/token
ヘッドレス(プロセス内エンジン、ウィンドウなし)とブリッジ(起動済みアプリを制御)の2つのモードがあります。認証要件は references/mcp-servers.md を参照してください。
コアワークフロー:発見 → 実行 → 検証 → 元に戻す
- 発見:
engine.commands/command_listでレジストリを取得し、label/menu から目的のコマンド ID とパラメータドキュメントを探します。 - 実行:
engine.execute {command, params}。意味の違いに注意——ui.menu.invokeは「メニュークリック」(パラメータなしだとコマンドのダイアログを開く)、engine.executeはデフォルトパラメータで直接実行し、ダイアログは開かない。 - 検証:推測ではなく状態を読み取る。
ui.inspectは汎用 UI 状態;各アプリにはさらにドメイン固有の状態メソッドがあります(LightCraftlibrary.state/photo.inspect/develop.get、FilmCraftsequence.inspect、PhotoCraftdocument.inspect)。 - 結果を確認:
ui.screenshot {path}でウィンドウをキャプチャ(レンダリング完了後にキャプチャ;ウィンドウがフレームを描画しない場合は headless スクリーンショットを使用)。 - 元に戻す:
edit.undo/edit.redo。エージェントによる編集も undo スタックに記録されます。
プロトコルの鉄則(3アプリで共通する部分):
- 1行に1つの JSON リクエスト、1行に1つのレスポンス。順序通り対応:
{"id":N,"method":...,"params":{...}}→{"id":N,"ok":true,"result":...}または{"id":N,"ok":false,"error":"..."}。 - イベントプッシュなし:チャネルはリクエストにのみ応答します。GUI 側で何が起こったかを知りたい場合は、inspect メソッドをポーリングしてスナップショットを比較してください。
- 各リクエストは独立したスナップショット:オブジェクトを切り替えたら必ず状態を再読み取りし、キャッシュされた ID を使って現在の状態を推測しないでください。
- サーバーの応答上限は 60 秒;タイムアウトしたコマンドはまだ実行中である可能性があるため、再試行する前に状態を確認してください。長時間タスクには
wait:falseを使用し、jobs.listをポーリングしてください。
セキュリティ境界
- すべてのチャネルは
127.0.0.1のみをリッスンし、プロトコルは暗号化されません——信頼できないホストにトンネルやプロキシをしないでください。ループバックはリモートからのアクセスを防ぐだけであり、同一マシン上の他のプロセスは防げません。 - LightCraft チャネルは認証なし:必要に応じて有効にし、
LIGHTCRAFT_CONFIG_DIRで設定を分離して自動化を行い、使用しないときは無効にしてください。 - PhotoCraft ファイルシステム fail-closed:自動化による読み書きは
--automation-read-root/--automation-write-root内に制限され、許可がない場合は拒否されます。file.open/file.saveはチャネルで拒否されるため、代わりにapp.open/app.saveを使用してください。 - FilmCraft の
FILMCRAFT_CONTROL_TOKENは完全な制御権限と同等です:機密情報として扱い、コマンド履歴や MCP 設定に含めないでください。 - デフォルトではユーザーの既存データ(例:LightCraft の
~/Pictures/LightCraft Library)には触れません。ユーザーが明示的に要求した場合のみ操作します。
問題が発生したらまずここを確認
references/known-pitfalls.md には実際に踏んだ落とし穴(接続拒否、フレームなしタイムアウト、PhotoCraft に --help がない、エクスポートのアトミック保存がシステムポリシーでブロックされる、レイヤー原点オフセット、quad 相対座標など)がまとめられています。まず表を確認し、同じ誤ったコマンドを繰り返さないでください。
リファレンスドキュメント一覧
| ファイル | 内容 |
|---|---|
references/app-matrix.md | 3アプリの違いクイックリファレンス(起動フラグ、認証情報、サンドボックス、状態メソッド、CLI/MCP エントリ)——最初にこれを確認 |
references/control-protocols.md | 制御チャネルプロトコル:共通メカニズム + 各アプリのメソッドテーブル + 3つの認証状態 |
references/cli-reference.md | 3つの CLI の取得方法、サブコマンド、パラメータセマンティクス、終了コード |
references/mcp-servers.md | MCP サーバーツール一覧、2つのモード、接続方法 |
references/known-pitfalls.md | 実際に踏んだ落とし穴とトラブルシューティング手順 |
references/upstream-sources.md | 上流ドキュメントのアドレス、スナップショット日付、このリファレンスを更新する方法 |
scripts/craft_ctl.py | 制御チャネルクライアント(3アプリの認証差分を内蔵) |
scripts/craft_env.py | 環境セルフチェック:アプリ、バージョン、CLI、チャネル、認証情報 |