ブログ一覧

X 公式 MCP が Docker サンドボックスで認可できない

自分宛てのリプライ検知や X API の利用状況を秘書として使っている AI エージェントに見せるために、X が公式配布する MCP サーバーDocker サンドボックスから使おうとしましたが、制約があって使えず、結果的に認証は X 公式の CLI である xurl を使い、ホスト側のブリッジに置く設計に落ち着きました。

MCP(Model Context Protocol)は、AI エージェントに外部サービスのツールを見せるための規格で、X はこれに沿ったサーバーを公式配布しています。Docker サンドボックスは Docker がホストに用意する使い捨ての実行環境で、CLI 名は sbx です。動的クライアント登録(RFC 7591)は、認可サーバーが登録用のエンドポイントを公開し、コールバック URL をそのつど登録し直せる仕組みです。

サンドボックスと X の認可が噛み合わない理由

sbx の MCP ゲートウェイは、認可のコールバックをホストの空いているポートで受け、相手が動的クライアント登録に対応していれば、そのポートをその場で認可サーバーに登録する設計です。X の認可サーバーは、この前提に乗りません。

  • redirect_uri は Developer Portal に事前登録した値とポート込みで完全一致していなければならず、動的な差し替えは想定されていない
  • 認可サーバーメタデータ(RFC 8414 形式)に registration_endpoint が存在せず、動的クライアント登録そのものに非対応
  • sbx 側にもコールバックポートを固定するフラグが無く、双方から歩み寄る手段が無い状態

コールバックのポートは呼び出しごとに変わり、X 側は固定登録しか受け付けないため、認可がそこで弾かれます。redirect_uri の事前登録による固定は、任意の URL にトークンが渡るのを防ぐための一般的な OAuth の安全策で、動的クライアント登録を持たない他の認可サーバーでも同じ制約は起こり得ます。

認可をホストのコマンドへ切り出す

そこで、認可をサンドボックスの外、ホスト側のプログラムに切り離しました。

xurl は X が公式配布する CLI で、コールバックを固定のローカルアドレスで受け、取得したトークンをホスト側の設定ファイルに保存して自動更新します。コールバック URL が変わらないため、ポータルに事前登録した値と常に一致します。ホスト側のコマンドとして、次のように登録します。

sbx mcp add x-api --command sh --args "-c,CLIENT_ID=<Client ID> xurl mcp https://api.x.com/mcp"

CLIENT_ID は Developer Portal のアプリの OAuth 2.0 Client ID で、起動コマンドに含めないとトークン更新時の再ログインが失敗します。この登録によって、サンドボックスから見た X は「リモートの OAuth サーバー」ではなく「ホストで動くローカルのコマンド」になり、認可はホストのポートで完結します。サンドボックス側に見えるのは MCP のツール呼び出しだけで、トークンの値は一度も現れません。

App-only の Bearer トークン(アプリそのものの名前で API を呼ぶ認証)を Authorization ヘッダーに直接書き、認可を経ずに繋ぐ方式は採用しませんでした。トークンがサンドボックスの環境変数に残ることと、App-only にはユーザーコンテキストが無く自分宛てのメンションを読めないことが理由です。

関連

この記事をシェア