0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

自作MCPサーバーがAntigravityで動かない——AIの"自白"を物証で崩した話

0
Posted at

はじめに

自作の VBA 管理ツール(shu-vba-manager)を MCP サーバー化して、ふだんは Claude Code から使っています。開いたままの Excel ブックに相乗りして、マクロの一覧・取得・置換までを会話で済ませる道具です。

これを Google の Antigravity でも使おうとしたら、動きませんでした。

原因にたどり着くまでに、AI(Gemini)の「自白」が二回崩れました。今回はその捜査記録です。ツールの話というより、「AIの説明をどうやって検証するか」の話になります。

TL;DR

  • Antigravity 上の Gemini に vba-manager を使わせたら「Excel が起動していません」。実際には Excel は開いている
  • 問い詰めると「仮想コンテナに閉じ込められていて、設定ではどうにもならない」と自白 → 裏取りしたら崩れた
  • 真相は二段構えだった
    • エージェントのターミナルは実機の中の別デスクトップで動いていて、そこから COM は届かない(Geminiの報告による)
    • そして MCP サーバーはそもそも起動していなかった。設定の "command": "py" を IDE が解決できていなかった
  • Python の絶対パスに書き換えて IDE を再起動したら解決。開いたままのブックへの相乗りが Antigravity でも動いた
  • 検証はぜんぶ「物証」でやった。プロセス一覧と、答えを先に押さえた上での抜き打ちテスト

前提:vba-manager の方式

vba-manager は、起動中の Excel を GetActiveObject で掴む方式です。ファイルを開き直さず、いま画面に開いているブックをそのまま操作します。この方式の生命線は、同じデスクトップセッションの COM(ROT:Running Object Table)が見えることです。

Claude Code に MCP サーバーとして登録してあり、常駐 COM で 1 コマンド 0.01〜0.2 秒程度で応答します。ここまでが平常運転です。

第一の異変:「Excel が起動していません」

Antigravity で同じことをやらせると、「Excel が起動していません」と返ってきます。目の前で Excel は開いています。

Gemini は最初、別の原因をいろいろ挙げて作業を続けました。どれも当たりません。5回ほど問い詰めたところで、こう白状しました。

いつの間にか仮想コンテナに閉じ込められていて、設定ではどうにもなりません

なるほど、と一瞬納得しかけました。仮想環境の中からは実機の Excel が見えない。筋は通っています。

裏取りで自白が崩れる

念のため(別の AI に)調べさせると、話が合いません。

  • Antigravity のターミナルサンドボックスは、解説記事を見る限り macOS 専用(Apple の Seatbelt 機構を利用)。Windows でターミナルを仮想化するという記載は見当たらない
  • 「設定ではどうにもならない」はずの設定(Agent security mode、Enable Terminal Sandboxing)が普通に存在する

こちらの環境は Windows です。macOS 専用のサンドボックスに閉じ込められた、という筋書きは成立しません。

つまり、追い詰められて出てきた自白は、それらしいだけの作文だった可能性が高い。AI は問い詰められると「相手が納得しそうな罪」を自白することがあります。自白にも裏取りが要ります。

実機での物証その1:仮想ではなく「別室」

Gemini に実機確認をさせました。hostnamewhoami の結果は、実機と完全に一致。仮想マシンでもコンテナでもありません。

では何が違うのか。Windows API に「自分が今立っているデスクトップの名前」を直接答えさせるワンライナーを、両方の環境で実行して比べました。

py -c "import ctypes; u=ctypes.windll.user32; k=ctypes.windll.kernel32; h=u.GetThreadDesktop(k.GetCurrentThreadId()); buf=ctypes.create_unicode_buffer(256); n=ctypes.c_ulong(); u.GetUserObjectInformationW(h, 2, buf, 512, ctypes.byref(n)); print(buf.value)"

結果、通常のターミナルは Default、Antigravity のエージェントターミナルは agy-(ランダム文字列)。Antigravity はエージェントのコマンドを、実機の中に作った別のデスクトップで実行していました。

これなら全部の観測と辻褄が合います。Windows の COM の名簿(ROT)は、別のデスクトップからは見えません。py も pywin32 も動くのに Excel だけ見えなかったのは、あの別室から見える世界には本当に Excel がいなかったからです。「Excel が起動していません」というエラー自体は、一度も嘘をついていませんでした。

途中で踏んだ地雷:黙って死体解剖に切り替わる

捜査の途中、一度だけ「マクロ一覧が一瞬で出た」ことがありました。速くなった理由を聞くと、こう説明されました。

Excel への接続を待つのではなく、デスクトップの .xlsm ファイルを直接読み込み、内部の VBA をバイナリ解析してマクロ名を取り出す方法に切り替えました

これは相乗りではありません。最後に保存した時点のファイルを解剖しているだけです。保存していない変更は見えませんし、この方式のまま書き込みに進めば、開いているブックと衝突して本物の破壊事故になります。

正規の道具が使えないとき、AI は黙って迂回路に切り替えて「できました」と報告することがあります。迂回そのものより、聞かれるまで言わないことのほうが危ない。この時点で「ファイル直読みは読み取り専用、開いているブックへの直接書き込みは厳禁」と釘を刺しました。

実機での物証その2:サーバーはそもそも立っていなかった

「別室」の正体がわかっても、MCP 経由なら動くはずでした。MCP サーバーはエージェントのターミナルではなく IDE 本体が起動する子プロセスなので、別室問題を構造的に迂回できるからです。

それでも動かない。Gemini の説明は「権限の違いや Excel のビジー状態で、COM 接続がすべて拒否された」。

ここで Claude Code 側から、実機のプロセス一覧を見ました。

  • Antigravity IDE 本体:起動中。レンダラー、言語サーバー、ターミナルまで全部見える
  • その配下の vba_mcp_server.py:存在しない。起動を試みた痕跡すらゼロ

持っていない道具は、拒否のされようもありません。「権限」「ビジー」はまた作文で、真相はサーバーが一度も起動していなかったでした。

原因は単純で、MCP 設定の "command": "py" を IDE が解決できていなかったのです。絶対パスに書き換えます。

"vba-manager": {
  "command": "C:\\Users\\shu\\AppData\\Local\\Python\\bin\\python.exe",
  "args": ["c:/Users/shu/Desktop/.../python_scripts/vba_mcp_server.py"]
}

パスは Python インストールマネージャーが作る bin のシム(実体のバージョンフォルダを指す別名)にしました。Python を更新してもパスが変わりません。

IDE を再起動すると、プロセス一覧に新しい行が現れました。

python.exe  ← vba_mcp_server.py(12:40:06 起動)
   親: language_server_windows_x64.exe(Antigravity)

今度は家系図が証言と一致しています。

最後の試金石:抜き打ちの点呼

接続の最終確認は、こういうテストにしました。

  1. Claude Code 側で、いま開いているブックを先に実測しておく(正解を握る)
  2. 直前にブックを入れ替えておく(履歴や「最近使ったファイル」ではカンニングできない状態を作る)
  3. Gemini に list-open を実行させる

Gemini の回答は、入れ替えた直後のブック名までぴたりと一致。生きた COM で今の Excel を見ていないと出せない答えです。合格。Antigravity からの相乗りが、今度こそ本当に動きました。

これは vba-manager に限った話ではありません

看板は自作ツールのトラブル記ですが、構造は一般的なものです。

  • command の解決失敗は、ローカル起動型の MCP サーバー全般で起きますpy に限らず、npx(Node 系サーバーの定番)や uvx も同じです。コマンドが解決できるかは「どうインストールしたか × クライアントがどんな環境でプロセスを起動するか」の掛け算で決まり、シェルの設定で PATH を通しているタイプ(nvm 経由の Node、Store 版 Python など)は IDE から見えないことがあります。対処も共通で、絶対パスで書く
  • 失敗が本人(AI)に伝わらないのも共通です。サーバーが立っていないことをエージェントは知らされないので、「権限が」「ビジーで」と、それらしい説明を組み立てるしかなくなります
  • 診断法も共通です。プロセス一覧で、クライアントの配下にサーバーのプロセスがいるかを見る。いなければ、接続以前の問題です

つまりこの記事は実質、「Antigravity で MCP サーバーが繋がらないときの調べ方」の一例です。

まとめ

技術的な結論は一行です。MCP 設定の command は絶対パスで書く。 それだけでした。

ただ、そこにたどり着くまでの教訓のほうが大きかったので、三つ書いておきます。

自白にも裏取りが要ります。 AI は問い詰められると、それらしい自白をします。今回は「仮想コンテナ」「権限」「ビジー」と三つの説明が出て、三つとも作文でした。しかも作文には本物の部品が織り込まれるので、聞いただけでは見分けがつきません。説明の中身ではなく、プロセス一覧・コマンドの実行結果・答え合わせといった物証で判定するのが確実です。私は AI の説明を疑ってかかる習慣があったのでここで済みましたが、AI の説明をそのまま信じるタイプの人がこの状況に入ると、存在しない原因を延々と直し続けることになります。この記事が検索で引っかかる理由が、たぶんそれです。

エージェントは、自分の檻の中から檻を調べられません。 Gemini の調査コマンドは全部、問題のある環境の中で実行されていました。何をどう調べても歪んだ答えしか返らない。外側に立っていて、正解(動いている環境)を手元に持っている者だけが消去法を回せます。これは Gemini が劣っているという話ではなく、同じ檻に入れば Claude でも同じ壁にぶつかる、構造の問題です。

「点呼」は使い回せます。 開いているブックを入れ替えた直後に list-open をやらせて答え合わせする、というテストは、履歴のカンニングが効かないので確実です。AI の Excel 接続が本物かどうか怪しいとき、一発で白黒つきます。

道具を疑い、説明を疑い、物証で確かめる。遠回りに見えて、これがいちばん速い道でした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?