AI 用の仮想マシンに仕事を引っ越す ― 使用状況の集計・ノートの読み書き・4つの AI と Orca を、止まらない場所へ
前の記事で、家のサーバーの中に AI エージェント用の仮想マシン(以下 vm1)を作り、Claude Code・Codex・Chrome を使えるようにしました。今回はその続きです。これまでずっと電源を入れている Mac で動かしていた仕事を、vm1 に移しました。移したのは、AI の使用状況の集計、ノート(Obsidian)の読み書き、残りの AI(Gemini・Grok)と Orca です。
全体のつながり

今回いちばん気をつけたのは、vm1 からほかの機器に入れないようにすることです。AI に確認なしで作業させても、vm1 の外を壊せないようにするためです。そこで、つながりはどれも「外から vm1 へ」の向きにしました。使う鍵は相手ごとに分け、それぞれの鍵でできることを1つに限っています。
1. AI の使用状況の集計を移す
以前の記事で、4つの AI の使用状況を家のサーバーのトップページに表示するようにしました。上限に対する使用率(%)は、アカウントに対する値なので、1台で調べれば足ります。ただ、それを調べていた Mac が止まると、表示が更新されなくなっていました。そこで、ずっと動いている vm1 で調べるようにしました。
- vm1:5分ごと(cron)に集計して、結果を JSON のファイルに置く
- 家のサーバー:その1分後に、vm1 へ結果を取りに行く
- 鍵:家のサーバーの鍵で vm1 にできるのは、「このファイルを読むこと」だけ。vm1 には家のサーバーに入る鍵を置かない
# vm1 の ~/.ssh/authorized_keys(家のサーバーの鍵の行)
restrict,command="cat /home/ai/ai_usage/vm1.json" ssh-ed25519 AAAA... home-server: read usage only
restrict で転送などを全部止め、command= で実行できるものを1つに決めています。試しに、この鍵で別のコマンドを送ってみても、返ってくるのはファイルの中身だけでした。

トップページの表には、vm1 を1行目に加えました。上限の値(Claude・Codex・Gemini)は、すべて vm1 から届くようになっています。
2. vm1 の AI から、ノートを読み書きする
ノート(Obsidian の保管場所)は Google ドライブにあり、Linux からは扱いにくいので、vm1 には置いていません。代わりに、Mac で動いている Obsidian のプラグイン(Local REST API)に、vm1 からつなぐようにしました。これなら、ノートを書き換える窓口が Mac の Obsidian 1か所のままで済み、同期の衝突を起こしにくくなります。
つなぎ方は、Mac から vm1 へのリバーストンネルです。Mac が vm1 に SSH でつなぎ、「vm1 の中の 127.0.0.1:XXXX に来た通信を、Mac の Obsidian に届ける」道を開いておきます。
# Mac 側(launchd で常に張っておき、切れたら張り直す)
ssh -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \
-R 127.0.0.1:XXXX:127.0.0.1:XXXX ai@vm1
# vm1 の ~/.ssh/authorized_keys(トンネル用の鍵の行)
restrict,port-forwarding,permitlisten="127.0.0.1:XXXX",command="/bin/false" ssh-ed25519 AAAA... mac: tunnel only
- vm1 には、Mac に入る鍵を置かない。トンネル用の鍵は、決めた口を開くことしかできない
- vm1 の Claude Code と Codex には、Mac と同じ Obsidian の MCP(AI に外部の道具を使わせるつなぎ方)を登録した。Obsidian のキーは、起動のたびに vm1 の秘密情報のフォルダから読む
- 試しに、vm1 の Claude Code と Codex から、それぞれ別のノートの見出しを読ませて、正しく返ってくることを確かめた
AI 共通のルール(AGENTS.md)にも、「vm1 ではノートを Obsidian の MCP だけで読み書きする。Mac が止まっていて読み書きできないときは、ほかの方法で代えずに知らせる」と書き足しました。
3. 残りの AI と Orca を入れる

Gemini(Antigravity CLI)・Grok・Orca も、Linux 版がどれも公式に配られていました。Mac と同じ版をそろえています。
- Antigravity CLI:Mac 版を配っている Google の公開の場所に、同じ名前の付け方で Linux 版(
linux-x64/cli_linux_x64.tar.gz)があった。中身を確かめてから展開した - Grok CLI:公式のインストーラーを、先に読んで確かめた(sudo を使わず、ホームフォルダに入れて、PATH を1行足すだけ)
- Orca:公式の GitHub のリリースにある deb を入れた。画面なしで動かすモード(
orca serve)があり、Mac や iPhone の Orca から、vm1 に作業を頼めるようになる
ログインは tmux の中で
Antigravity と Grok のログインは、対話画面でしか始められませんでした。そこで、対話画面を tmux(画面を裏で動かしておける道具)の中で起動し、表示された URL とコードを読み取って、手元のブラウザで承認しました。Antigravity は、ブラウザに出た認証コードを、tmux の画面に送り込んで入力しています。
tmux new-session -d -s login -x 200 -y 50 "agy" # 裏で起動
tmux capture-pane -p -t login # 画面の文字を読む(URL が出る)
tmux send-keys -t login -l "(ブラウザに出た認証コード)"
tmux send-keys -t login Enter
Orca は常に動くサービスに
Orca のサーバーは、systemd のユーザーサービスにしました。loginctl enable-linger を設定しておくと、だれもログインしていなくても動き続けます。Mac の Orca とペアリングした後は、--no-pairing を付けて、新しい端末のペアリングを受け付けないようにしています。
[Service]
Environment=DISPLAY=:1
ExecStart=/usr/bin/orca-ide serve --pairing-address (vm1 のアドレス) --no-pairing
Restart=on-failure
つまずいたところ
1. Mac と Linux で、/usage の書き方が違う
Claude Code の /usage は、リセットの時刻を Mac では「Nov 2 at 11pm」、Linux では「Nov 3, 4am」と書いていました。最初は Linux で時刻が読めず、日付だけになっていました。両方の書き方を読めるように直しました。
2. 日付が変わると、Codex の上限が消える
Codex の上限は、Codex の作業記録に書かれた値を読んでいます。ところが、「今日の記録」からしか探していなかったため、日付が変わってからまだ Codex を使っていないと、上限の欄が空になっていました。直近7日の記録から一番新しい値を探すように直しました。あわせて、記録した後にリセットの時刻を過ぎた値は、「0%(リセット済み)」と表示するようにしています。
3. 「起動中」に、Chrome 連携の部品が数えられる
Claude in Chrome を使うと、Chrome との連携のために claude --chrome-native-host が常に動きます。これが「起動中の Claude Code」に数えられていたので、外しました。
4. ペアリングの合言葉が、作業の記録に出た
Orca のサーバーは、起動すると、ペアリング用の URL を記録に出します。この URL には、つなぐための合言葉が入っています。記録を確かめたとき、伏せる処理が一部の行(ブラウザ用の URL)に効かず、合言葉がそのまま作業の記録に出てしまいました。しかも、その合言葉は、Mac がつなぐのに使う鍵そのものでした。
- ペアリング済みの端末の一覧を空にして、Orca を起動し直し、合言葉を作り直させた(古い合言葉はもう使えない)
- Mac をつなぎ直し、
--no-pairingで新しいペアリングを受け付けないようにした - 以後、Orca の記録は、合言葉を含む行を表示しないようにしている
5. 前に起動したサーバーが残っていて、サービスが起動しない
試しに tmux の中で起動した Orca を止めた直後に、サービスとして起動しました。すると、前のサーバーがまだ終わりきっておらず、「もう別のサーバーが動いている」と数回起動に失敗しました。前のものが終わると、自動の再起動で正常に起動しました。
6. デバイスコードの期限切れ
Grok のデバイスコードは、出してから承認するまでに時間がかかり、「無効または期限切れ」になりました。ログインを出し直し、すぐに承認すると通りました。
まとめ
- AI の使用状況の集計、ノートの読み書き、4つの AI と Orca を、Mac から vm1 に移した
- つながりはどれも「外から vm1 へ」。鍵は相手ごとに分け、できることを1つに限った
- ノートの窓口は Mac の Obsidian のまま。vm1 からはトンネルを通して読み書きする
- 記録を表示するときは、合言葉やキーが混ざっていないかに気をつける
