所有頁面
本頁內容

preview

agent 可以用 preview 把有網頁介面的東西放到公開連結上,讓你能從手機開啟,或傳給別人:可以是監聽中繼所在機器某個連接埠的 dev server,也可以是一個存放純檔案的資料夾。它也能列出並關閉自己對話中的預覽。

用平常的話提出要求就行:「啟動 dev server,給我一個連結」、「讓我看看建置好的網站」。agent 會被告知:只要你想看、試用或分享網頁介面,就使用這個工具,而且絕不要叫你去開 localhost。

預覽連結是公開的

任何拿到連結的人都不必登入就能開啟這個應用程式。連結中的 token 是唯一的保護。agent 會被告知在給你連結時說明這一點。預覽用完後請把它關閉。

你會看到什麼 #

  • 對話的背景任務面板中有這個預覽的卡片,附有 Open(開啟)、Copy link(複製連結)和 Close(關閉)。
  • 對話紀錄中,agent 發布預覽的那則回覆上有一張連結卡片。預覽消失後,卡片會顯示 closed 徽章。對話的分享檢視只顯示卡片上的名稱,絕不顯示連結。
  • 中繼的每個預覽(涵蓋所有對話)都列在 Settings → Previews(設定 → 預覽)下,每個都附有關閉按鈕。
  • 連接埠預覽背後的 dev server 停止回應時,卡片上會出現 offline 徽章。連結仍保持登記:在同一個連接埠上重新啟動伺服器,同一個連結就又能使用。

不透過 agent,你也可以在輸入區輸入 /preview 做同樣的事:

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

設定 #

在中繼的管理者設定好之前,預覽都是關閉的。預覽需要自己的主機名稱,與中繼的主機名稱分開,這樣被預覽的應用程式就永遠無法存取中繼本身。需要三件事:

  1. 一個你能控制的主機名稱,與中繼的主機名稱不同——必須是名稱不同,不能只是連接埠不同。
  2. 一個前端 proxy(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
  }
}

不論是否完成這些設定,agent 都有這個工具。沒有設定時,create 呼叫會傳回原因,而 agent 會被告知把原因轉告你:這要由管理者來修正。

依供應商 #

供應商
Claude、Claude API 0.9.18 新增、DeepSeek 0.9.17 新增、Cursor 有 preview 工具
Grok;擴充功能引擎上的 GitHub Copilot 與 OpenAI 有 preview 工具,透過 OAR 的 MCP 伺服器 0.9.4 新增
SDK 引擎上的 GitHub Copilot 與 OpenAI 沒有工具。預覽已設定好時,agent 會被告知如何呼叫中繼的預覽 API,規則相同,而且呼叫中已寫入它的對話。你看到的結果一樣。
Claude Cloud 無:雲端 session 在 Anthropic 的沙箱中執行,你的機器上沒有可發布的連接埠或資料夾

動作 #

動作 作用 參數
create 發布一個連接埠或資料夾 port 或 dir,可另加 label
list 列出此對話的預覽
close 關閉此對話的其中一個預覽 token,對話中恰好只有一個預覽時可省略

結果是 JSON,內容為 "ok": true,或 "ok": false 加上一段 error 文字。這個工具不會以其他方式失敗;錯誤的參數會以 agent 讀得懂的 error 傳回。

create #

發布一個連接埠或一個資料夾,一次呼叫中不會兩者都發布。 0.9.11 新增 在同一個對話中再次發布同一個連接埠或資料夾,會傳回已在運作的那個預覽,連結相同,名稱不變;這時結果會寫著 "existing": true。

參數 類型
port 1024–65535 dev server 的本機連接埠
dir 路徑 要以純檔案提供的資料夾:絕對路徑,或相對於對話工作資料夾的路徑
label 文字,最多 120 個字元 預覽卡片上的名稱

Dev server(port) #

中繼會把請求轉送給監聽該連接埠的伺服器。它不會啟動、監看或重新啟動那個伺服器;那個伺服器仍是 agent 的一般背景任務,有自己的停止按鈕。

每個預覽都位於預覽主機名稱下自己的路徑。瀏覽器請求的是 /test_<token>/…;中繼在轉送請求前會移除這個前綴,並透過 X-Forwarded-Prefix 告訴應用程式這個前綴。它不會改寫頁面。所以,只要應用程式送出的連結和資源位址是相對路徑或帶有前綴,同時能處理不帶前綴的請求,它就能正常運作。從主機根目錄請求 /assets/app.js 的應用程式會找不到它。

因此 agent 會被告知要先呼叫 create,從結果中讀取 basePath,然後才啟動 dev server。

agent 收到的指示不適用於每一種 dev server

工具本身的說明建議在啟動伺服器時設定 base path(Vite --base、Next.js basePath、Express 的掛載前綴)。但這樣設定後若伺服器預期收到的請求帶有前綴,就與中繼轉送的內容不符:Vite 的 dev server 和掛載在該前綴上的 Express router 都不是這樣運作的。預覽說明了可行的做法。

{ "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 也會告訴 agent 把 dev server 綁定到 127.0.0.1,而不是 0.0.0.0:中繼的 proxy 在那裡連得到它,其他任何東西都不應該連得到。只有具備 preview 工具的 session 會收到這一行(見依供應商)。被教導使用預覽 API 而不是工具的 agent 不會收到: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 #

列出 agent 自己對話中的預覽,包含 token、label、url、target(資料夾,或 localhost:<port>)、online 和所屬對話。0.9.14 新增 0.9.14 之前,這份清單涵蓋中繼的所有預覽;預覽的 token 是它唯一的保護,所以 agent 現在只看得到自己的預覽。整個中繼的清單是給你看的,在 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 #

關閉連結。連結背後的 dev server 會繼續執行。

參數 類型
token 32 個十六進位字元 來自 create 或 list 的 token。對話中恰好只有一個預覽時可以省略。

沒有 token 而對話中有多個預覽時,呼叫會傳回 error 以及可供選擇的清單。

0.9.14 新增 agent 只能關閉自己對話中的預覽。其他對話的預覽 token 會被拒絕:

{ "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)
agent 能列出和關閉哪些預覽 自己對話中的 0.9.14 新增
連接埠 1024–65535,且絕不能是中繼自己的連接埠
連接埠預覽可以指向哪裡 中繼自己的機器(迴路位址),以及管理者在 previews.allowedTargetHosts 中列出的主機
資料夾預覽可以指向哪裡 對話的工作資料夾內
存續期間 直到被關閉,或所屬對話被刪除。0.9.11 新增 預覽在中繼重新啟動後仍會保留;連接埠預覽在機器重新開機時結束,資料夾預覽則在資料夾不再位於工作資料夾內時結束。預覽不會自行過期。
名稱 120 個字元

預覽與中繼彼此隔離:預覽在另一個連接埠、另一個主機名稱下提供,那裡沒有任何中繼自己的頁面或 API。預覽之間共用那個主機名稱,各自位於自己的路徑下。

對話範圍並不是一道牆

中繼會把預覽請求的範圍限定在請求所指名的對話,對話寫在 conversationId 查詢參數中,或寫在每個 session worker 和 OAR 的 MCP 伺服器都會傳送的對話標頭中。agent 使用和你相同的中繼 token,所以範圍是由請求自行宣告的,而不是經過證明的:沒有指名對話的請求仍然會拿到所有預覽。這個範圍讓工具和 agent 被教導的呼叫只限於自己的對話;它擋不住讀取中繼 token 並自己動手呼叫 API 的 agent。見 OAR 會暴露什麼。