sandbox_review

試したバージョンを人に渡し、フィードバックか確認完了を待ちます。カードと製品の入口は、アプリにすぐ表示されます。長い待機への対応を宣言していないクライアントでは、既定の上限は 25 秒です。設定済みのクライアントは最大 30 分待てます。

入力 出力
id、what と open(新しいカード)か reviewId(再開)のどちらか。open は web か box。port(整数 1–65535)は open: "web" のときだけ。任意の waitSec(整数 0–1800、クライアントが対応する上限まで。宣言がなければ最大 25 秒) ok、reviewId、shareUrl(人に渡すリンク:製品とフィードバックの道具がある確認ページ)、productUrl(製品そのもの)、open(web か box)、status、note。待機後、またはそのラウンドにすでにレポートがあるときは outcome、レポート受信時は reportId、fromHuman と画像も返る

まず人が使う場所で試します。スマホやデスクトップのアプリはボックスの画面でタップ・入力し(sandbox_shot で結果を確認)、Web は新しいブラウザーセッションでサインインの入口から操作します。製品を最初の画面に戻し、what でカードを作ります。人が読む言語で書きます。カードには最初の 2 行しか表示されないので、まず人に試してほしいこと(どこから始め、何をタップまたは入力し、うまくいくと何が見えるか)を書き、最後に自分で試したことを短く 1 文で添えます。カードにはこの文(最大 400 文字)、製品の画像、開くボタンが入り、ボタンは open で指定した入口を開きます(後述)。試してもらう価値のあるバージョンごとに渡します(仕上げ)。

{ "id": "<boxId>", "what": "タスクを追加してから一覧に戻ってください。追加したタスクが一覧に残っています。自分でも新しいブラウザーセッションでタスクを追加し、一覧に戻って確かめました。", "open": "web", "port": 5173 }

呼び出しは対応する待機上限の範囲で待ちます。待機上限の交渉、進捗、キャンセルの転送には stdio アダプター parallelsandbox-mcp 0.4.2 以降を使います。進捗には reviewId、shareUrl、productUrl がすぐ表示され、以後 15 秒ごとに更新されます。人がレポートを送ると、outcome: "report" と完全な fromHuman が返ります。内容はメモ、URL を更新したファイル、囲み画像、録画、時刻付き文字起こしです。これらを読んでから、現在の会話で作業を続けます。ほかの結果は done、superseded、cancelled、timed_out、wait_cancelled です。完了や配信の状態は引き渡しの状態であり、製品の承認や AI の修正完了を意味しません。

人に渡すのは shareUrl です。確認待ちの間は、ParallelSandbox アプリでこの確認をアカウントもサインインもなしで開き、製品とレポートの道具があり、同僚も同じリンクを使えます。確認が終わったあとはアプリのボックスのページになり、アカウントのサインインが要ります。productUrl は製品そのものです。open: "web" なら port のページ、open: "box" なら同じ確認ページです。レポートの道具がないので、渡すリンクではありません。

Codex で 30 分間待つには、ホストのツールタイムアウトとアダプターのタイムアウトの両方を設定します。人が長い待機を求めたとき、既存の stdio サーバー項目に以下を追加します。すでに長いタイムアウトを設定している場合はそれを保ち、ほかの設定も残します。

[mcp_servers.parallelsandbox]
tool_timeout_sec = 1920
env = { PSBX_TOOL_TIMEOUT_SEC = "1920" }

既存の env があれば PSBX_TOOL_TIMEOUT_SEC を統合し、クライアントを再接続します。アダプターは安全に待てる上限をサーバーに宣言します。waitSec だけを増やしてもクライアントの上限は延びません。設定しない場合は短い待機で戻りますが、確認カードは残ります。

タイムアウトや待機のキャンセル後も、カードとフィードバックは残ります。同じ reviewId でその回を再開します。

{ "id": "<boxId>", "reviewId": "<reviewId>" }

そのラウンドにすでに人のレポートがあるときは、waitSec に関係なくすぐ返します。outcome: "report"、reportId、完全な fromHuman が入るので、先に sandbox_status と sandbox_report を呼ぶ必要はありません。

新しい what は前のカードを置き換え、reviewId は同じカードを再開します。渡してすぐ戻る場合は waitSec: 0 を指定します。待機中の呼び出しは現在の会話にフィードバックを返せます。

AI の応答後に自動再開するには、parallelsandbox-agent でネイティブの会話を開始します(クイックスタート)。常駐実行器は Codex、Claude Code、Gemini の driver を使って一つのネイティブプロセスを管理し、このツールが返した reviewId を元の会話 ID に登録します。アプリからフィードバックが送られると、AI のターンが終わっていても同じ ID で再開し、実行中のターンがあればキューで待ちます。再開した AI が sandbox_report でその完全なレポートを読み、ネイティブのターンが正常に終了してから read を返します。この受領状態は配信とそのターンの完了を示し、依頼された修正すべての完了を意味しません。

通常の未登録 MCP 接続では、元の会話を自分で続けます。アプリの AI へのメッセージをコピー を押して元の会話に貼り付けるか、元の reviewId で待機を再開し、既知の reportId を読み直します。モデル、ツールの権限、元の会話の復旧方法はネイティブ会話のフィードバック設定をご覧ください。

id、what、open を渡します。カードが何を開くかはあなたが指定し、プラットフォームは選んだり検出したりしません。

  • open: "web" と port:ボックス内でそのポートから配信されるページです。ポートはプロセスが待ち受けるポート(たとえば dev サーバーの 5173)です。人は自分の端末の自分のブラウザーで開きます。そこには、あなたがボックスで試したブラウザーのサインイン状態や Cookie はありません。製品にサインインが要るなら、人と同じように新しいブラウザーセッションで試し、自分でサインインするページを渡してください。たとえばボックスのコピーに dev 専用のログイン経路を足し、シード済みのテストアカウントでサインインして開始画面へ移るようにして、そのポートを渡します(カードはポートのルートを開くので、その経路をルートに置くか、ルートからそこへ転送します)。そうでなければテストアカウントとサインイン方法を what に書きます。UI を dev サーバーから読み込むデスクトップアプリ(Electron と Vite など)も、その dev サーバーのポートを指定すればこの方法で渡せます。そのポートにまだ URL がなければ、同じ呼び出しで URL が付きます。そのポートで宣言済みのサービスがあれば web を付け、なければ web-<port> という名前のサービスを宣言して web を付けます。古い boxd のボックスでそのポートに URL を付けられないときは、呼び出しが 409 で失敗し、サービスを web: true で宣言した新しいボックスの起動を案内します。
  • open: "box"(port なし):カードはボックスの画面を開き、人が自分でタップ、スワイプ、入力します。対象はデスクトップアプリ(DISPLAY=:99 のウィンドウ。Electron、GTK、Qt、ゲームなど)か、sandbox_device のデバイスで動くスマホアプリで、Android でも iPhone シミュレーターでも同じです。アプリはディスプレイやデバイスで動かしたままにします。画面に何も映っておらず、準備済みのスマホもなければ、nothing is on this box's screen for a person to use: … を返します。アプリを起動して試し、もう一度 sandbox_review を呼びます。ブラウザーで開くページなら、そのポートを付けて open: "web" を使います。
  • 人がブラウザーで試せるものは web で渡します。そのほうが人にとってスムーズです。
{ "id": "<boxId>", "what": "アプリを開いて「設定」、「ダークモード」の順にタップしてください。すべての画面がすぐ暗くなります。自分でもボックスの画面で切り替えて確かめました。", "open": "box" }

open と port は、ボックスに触れる前に確認します。what に open がない、または値が正しくない(open is required with what…)、open: "web" に port がない(open: web needs port…)、open: "box" に port がある(port goes with open: web…)、reviewId に open か port がある(open and port go with what (a new review)…)と、それぞれエラーを返します。sandbox_start.services や sandbox_wire の web: true は引き続きサービス専用の URL とアプリの「使う」ボタンを用意しますが、sandbox_review が何を開くかは決めません。

詳細:

  • 画面は、呼んだ時点でボックス内で撮ったスクリーンショットです。web ならそのページの URL、box ならボックスの画面(デバイスがつながっていればスマホそのものの画面)。撮れなければ、画像なしでカードが届きます。
  • open はあなたが指定した入口です。web のカードは渡した時点のページの URL を保ち、あとで接続を変えても変わりません。AI のライブ画面を見る機能はアプリの別の入口で、sandbox_takeover はそのセッションで本人にしかできない操作を引き渡します。
  • 人が box のカードを開いている間はボックスを操作しているので、そのボックスへの sandbox_exec は人が離れるまで HTTP 423(人が画面を操作中)を返します。sandbox_shot で画面を撮れば、人が何をしているかは見えます(takeover: true)。人が試しているのであって、ボックスが壊れたのではありません。その間にアプリを入れ直したり再起動したりしないでください。
  • 待っているカードは何も起こしておきません。ボックスとそのデバイスは、通常のアイドルの規則どおり、使用がないまま 10 分たつと凍結され、期限が来れば停止します(ボックスの状態)。レビュー待ちがないときと同じです。人がレビューを開くと凍結したボックスが起き、デバイスも一緒に戻ります(iPhone シミュレーターのアプリは起動し直します)。その間にボックスが停止していれば、レビューはそこで終わり、新しいボックスで渡し直します。
  • カードは、人がレポートを送る、「確認しました」を押す(POST /v1/boxes/{id}/review/done)、あなたが置き換える、またはボックスが停止するまで残ります。GET /v1/boxes は確認待ちのカードを review(id、what、url、shotUrl、createdAt)として返します。
  • web のとき、人のリクエストはボックスの URL のほかの利用と同じくボックスを起こしておき(ボックスの状態)、sandbox_scene は人が開いているそのページに届きます。

すべてのツールとトピックはツールリファレンスに並んでいます。