すべてのページ
このページの内容

preview

preview を使うと、エージェントは Web UI を持つものを公開リンクに載せられます。スマートフォンから開いたり、誰かに送ったりするためです。対象は、リレーのマシンのポートで待ち受ける開発サーバーか、通常のファイルを入れたフォルダーです。自分の会話のプレビューを一覧表示したり閉じたりすることもできます。

普通の言葉で頼みます。「開発サーバーを起動してリンクをちょうだい」「ビルドしたサイトを見せて」のように。エージェントには、Web UI を見たい、試したい、共有したいときは必ずこのツールを使い、localhost を案内しないよう指示されています。

プレビューのリンクは公開されます

リンクを持っている人は誰でも、サインインせずにアプリを開けます。リンク内のトークンが唯一の保護です。エージェントには、リンクを渡すときにそのことを伝えるよう指示されています。使い終わったらプレビューを閉じてください。

表示される内容 #

  • 会話のバックグラウンドタスクのパネルにあるプレビューのカード。Open(開く)、Copy link(リンクをコピー)、Close(閉じる)があります。
  • トランスクリプト内のリンクカード。エージェントがプレビューを公開した返信に付きます。プレビューがなくなると closed バッジが表示されます。会話の共有ビューではカードのラベルだけが表示され、リンクは表示されません。
  • リレーのすべてのプレビュー(すべての会話にまたがるもの)は Settings → Previews(設定 → プレビュー)にあり、それぞれに閉じるためのボタンがあります。
  • ポートのプレビューの背後にある開発サーバーが応答しなくなると、カードに offline バッジが表示されます。リンクは登録されたままなので、同じポートでサーバーを再び起動すれば、同じリンクがまた使えます。

エージェントを使わずに、入力欄に /preview と入力して同じことができます。

/preview 5173 web app        publish a port
/preview ./dist built site   publish a folder
/preview list                list the previews
/preview close               close one

設定する #

プレビューは、リレーの運用者が設定するまでオフです。プレビューしているアプリがリレー自体に決して届かないよう、リレーとは別の専用のホスト名が必要です。必要なものは 3 つです。

  1. 自分が管理していて、ポートだけでなく名前がリレーのものと異なるホスト名。
  2. このホスト名をプレビューのポートに向けるフロントプロキシ(Caddy、Cloudflare Tunnel など)。
  3. リレーの config.json の previews ブロック:
{
  "publicHostnames": ["relay.example.com"],
  "previews": {
    "enabled": true,
    "port": 3334,
    "bindHost": "127.0.0.1",
    "publicBaseUrl": "https://preview.example.com",
    "allowedTargetHosts": [],
    "maxLive": 8
  }
}

これを済ませていなくても、エージェントはこのツールを持っています。済ませていない場合、create の呼び出しは理由とともに返ってきます。エージェントにはその理由をあなたに伝えるよう指示されています。直すのは運用者です。

プロバイダー別 #

プロバイダー
Claude、Claude API 0.9.18 で追加、DeepSeek 0.9.17 で追加、Cursor preview ツールがあります
Grok、拡張機能エンジンの GitHub Copilot と OpenAI OAR の MCP サーバーを通じて preview ツールがあります 0.9.4 で追加
SDK エンジンの GitHub Copilot と OpenAI ツールはありません。プレビューが設定されている間は、リレーのプレビュー API の呼び出し方がエージェントに伝えられます。ルールは同じで、自分の会話はあらかじめ呼び出しに書き込まれています。表示される内容は同じです。
Claude Cloud ありません。クラウドセッションは Anthropic のサンドボックスで動き、公開できるポートやフォルダーが自分のマシン上にないためです

アクション #

アクション 動作 パラメーター
create ポートまたはフォルダーを公開します port または dir、任意で label
list この会話のプレビューを一覧表示します
close この会話のプレビューを 1 つ閉じます token。会話のプレビューがちょうど 1 つなら省略できます

結果は、"ok": true、または "ok": false と error のテキストを含む JSON です。ツールがそれ以外の形で失敗することはありません。パラメーターの誤りも、エージェントが読める error として返ってきます。

create #

ポートかフォルダーのどちらかを公開します。1 回の呼び出しで両方を公開することはありません。 0.9.11 で追加 同じ会話で同じポートやフォルダーをもう一度公開すると、すでに公開中のプレビューが、同じリンクと変わらないラベルで返されます。このとき結果には "existing": true が含まれます。

パラメーター 型
port 1024–65535 開発サーバーのローカルポート
dir パス 通常のファイルとして配信するフォルダー。絶対パス、または会話の作業フォルダーからの相対パス
label テキスト、120 文字まで プレビューのカードに表示される名前

開発サーバー(port) #

リレーは、そのポートで待ち受けるサーバーにリクエストを中継します。そのサーバーの起動、監視、再起動は行いません。サーバーは、専用の停止ボタンを持つ、エージェントの通常のバックグラウンドタスクのままです。

各プレビューは、プレビューのホスト名の下にある専用のパスに置かれます。ブラウザーは /test_<token>/… を要求します。リレーはリクエストを中継する前にこのプレフィックスを取り除き、X-Forwarded-Prefix でアプリにプレフィックスを伝えます。ページの書き換えは行いません。そのため、アプリが動くのは、送り出すリンクやアセットのアドレスが相対パスかプレフィックス付きで、かつプレフィックスなしのリクエストに応答する場合です。ホストのルートから /assets/app.js を要求するアプリは、それを見つけられません。

そのため、エージェントには、開発サーバーを起動する前に最初に create を呼び出し、結果から basePath を読むよう指示されています。

エージェントへの指示は、すべての開発サーバーに当てはまるわけではありません

ツール自身の説明では、ベースパスを設定してサーバーを起動するよう勧めています(Vite の --base、Next.js の basePath、Express のマウントプレフィックス)。そうすると、受け取るリクエストにプレフィックスがあることを前提にするサーバーは、リレーが中継するものと一致しません。Vite の開発サーバーや、プレフィックスにマウントした Express のルーターは、この方法では動きません。何が動くかはプレビューで説明しています。

{ "action": "create", "port": 5173, "label": "web app" }
{
  "ok": true,
  "existing": false,
  "url": "https://preview.example.com/test_0123456789abcdef0123456789abcdef/",
  "basePath": "/test_0123456789abcdef0123456789abcdef/",
  "token": "0123456789abcdef0123456789abcdef",
  "mode": "port",
  "hint": "Serve the app under /test_0123456789abcdef0123456789abcdef/ (the proxy strips the prefix and sends X-Forwarded-Prefix). Bind the dev server to 127.0.0.1, not 0.0.0.0: the relay's proxy reaches it there and nothing else should. Tell the user the URL and that the link is public."
}

0.9.17 で追加 hint は、開発サーバーを 0.0.0.0 ではなく 127.0.0.1 にバインドするようにもエージェントに伝えます。リレーのプロキシはそこで開発サーバーに届き、それ以外のものが届くべきではないからです。この 1 行を受け取るのは、preview ツールを持つセッションだけです(プロバイダー別を参照)。ツールの代わりにプレビュー API を教わるエージェントは受け取りません。SDK エンジンの GitHub Copilot と OpenAI、そしてリレーが OAR_MCP_SERVER=0 で動いているときの Grok と Copilot の拡張機能エンジンです。

フォルダー(dir) #

リレー自身がフォルダーのファイルを配信します。何も動かす必要がないので、ビルドの出力、モックアップ、単一の HTML ファイル、カバレッジレポートに向いています。

  • フォルダーは会話の作業フォルダーの中になければなりません。これはリクエストのたびに改めて確認されるので、後からリンクの行き先を外に向けることはできません。
  • 名前がドットで始まるファイルとフォルダー(.git、.env)は決して配信されません。鍵ファイル(*.pem、*.key、id_rsa…)も同様です。
  • フォルダーのパスには index.html が配信されます。
  • 相対パスのアセットはそのまま動きます。ホストのルートからのパス(/assets/app.js)は動きません。
  • WebSocket 接続はできません。
{ "action": "create", "dir": "./dist", "label": "built site" }

結果のフィールドは同じで、"mode": "static" になります。

list #

エージェント自身の会話のプレビューを、token、label、url、target(フォルダー、または localhost:<port>)、online、会話とともに一覧表示します。0.9.14 で追加 0.9.14 より前は、一覧にはリレーのすべてのプレビューが含まれていました。プレビューのトークンが唯一の保護なので、現在エージェントに見えるのは自分のプレビューだけです。リレー全体の一覧は、Settings → Previews と /preview list であなたが見られます。再起動後にリレーが確認できなかったプレビューには "unverified": true が付き、確認の応答があるまで配信されません(リレーの再起動後を参照)。

{ "action": "list" }
{
  "ok": true,
  "enabled": true,
  "previews": [
    { "token": "0123456789abcdef0123456789abcdef", "label": "web app", "url": "https://preview.example.com/test_0123456789abcdef0123456789abcdef/", "target": "localhost:5173", "online": true, "conversationId": "3f9c…" }
  ]
}

close #

リンクを閉じます。背後にある開発サーバーは動き続けます。

パラメーター 型
token 16 進数 32 文字 create または list で得た token。会話のプレビューがちょうど 1 つなら省略できます。

token を指定せず、会話にプレビューが複数ある場合、呼び出しは error と、選ぶための一覧とともに返ってきます。

0.9.14 で追加 エージェントが閉じられるのは、自分の会話のプレビューだけです。別の会話のプレビューのトークンは拒否されます。

{ "ok": false, "error": "This preview belongs to another conversation; a conversation can close only its own previews. The owner can close it in Settings → Previews." }
{ "action": "close", "token": "0123456789abcdef0123456789abcdef" }
{ "ok": true, "closed": { "token": "0123456789abcdef0123456789abcdef", "label": "web app" } }

制限 #

制限 値
同時に公開できるプレビュー(リレー全体) 8(previews.maxLive)
エージェントが一覧表示して閉じられるプレビュー 自分の会話のもの 0.9.14 で追加
ポート 1024–65535。リレー自身のポートは使えません
ポートのプレビューの転送先 リレー自身のマシン(ループバック)と、運用者が previews.allowedTargetHosts に挙げたホスト
フォルダーのプレビューの対象 会話の作業フォルダーの中
有効期間 閉じられるか、その会話が削除されるまで。0.9.11 で追加 リレーの再起動後も残ります。ポートのプレビューはマシンの再起動で、フォルダーのプレビューはフォルダーが作業フォルダーの外に出たときに終わります。プレビューが自然に期限切れになることはありません。
ラベル 120 文字

プレビューはリレーから切り離されています。別のポートで、別のホスト名の下で配信され、そこにはリレー自身のページも API も存在しません。プレビュー同士はそのホスト名を共有し、それぞれが専用のパスの下にあります。

会話の範囲は壁ではありません

リレーは、プレビューのリクエストを、そのリクエストが指定する会話に限定します。指定は、conversationId クエリ、または各セッションワーカーと OAR の MCP サーバーが送る会話のヘッダーで行われます。エージェントはあなたと同じリレーのトークンを使うので、範囲はリクエストが宣言するものであって、証明されたものではありません。会話を指定しないリクエストは、すべてのプレビューを受け取ります。この範囲は、ツールとエージェントが教わる呼び出しを自分の会話に留めますが、リレーのトークンを読んで手作業で API を呼び出すエージェントを止めるものではありません。OAR が公開するものを参照してください。