Dev.to AI 🤖 Ai 👁 0 📖 3 min read

如何讓 Claude Code 在你核准後把小工具放進 osFoundry 的 Room

照著這篇做完,Claude Code 會在你的電腦上寫出一個小型內部工具(這裡以站會計時器為例:一份名單、每人 90 秒、一個 Next 按鈕),然後把它提案到 osFoundry 的雲端 Room。這時 Room 裡還不會出現任何東西。你打開提案、看過兩個原始碼檔案,再按下 Approve and create。計時器就會以新分頁的形式出現在 Room 的 app 分頁列,Room 裡每個人都能打開。Claude Code 會讀取狀態

如何讓 Claude Code 在你核准後把小工具放進 osFoundry 的 Room

照著這篇做完,Claude Code 會在你的電腦上寫出一個小型內部工具(這裡以站會計時器為例:一份名單、每人 90 秒、一個 Next 按鈕),然後把它提案到 osFoundry 的雲端 Room。這時 Room 裡還不會出現任何東西。你打開提案、看過兩個原始碼檔案,再按下 Approve and create。計時器就會以新分頁的形式出現在 Room 的 app 分頁列,Room 裡每個人都能打開。Claude Code 會讀取狀態來確認結果,而不是用猜的。

誰負責什麼

Claude Code osFoundry
登入 在你電腦上的自有登入 你針對某個 workspace 核准過一次的連線,帶有 osfoundry:read 和 osfoundry:write scope
用哪個 Room 從伺服器列出的清單中挑一個 只列出已指派到該連線所屬專案的雲端 Room
程式碼 在本機寫好完整檔案,以單一 files map 送出 保存提案,並把每個檔案完整呈現給擁有者
核准 自己的工具權限提示,因為 propose 工具被標記為 destructive 你在 "Needs your approval"(待你核准)底下按 Approve and create。在那之前,Room 的分頁列不會有任何變化
執行 app 不負責執行 由 Room 以分頁形式執行:桌面版是沙箱化的 iframe,網頁版則是瀏覽器內的沙箱
能讀回什麼 list_room_apps 和 read_room_app_status 名稱、識別資訊、launcher 與最新 build 狀態。不含 app 設定、secret、檔案、log 或資料庫內容

設定步驟

1. 把 osFoundry 加進 Claude Code

加上 --print 時,osFoundry CLI 會印出它原本要執行的指令:

$ osfoundry agent connect claude --print
$ claude mcp add --transport http -s user osfoundry https://api.osfoundry.io/api/v1/external-mcp

Sign in: open Claude Code, run /mcp, pick "osfoundry", Authenticate.

拿掉 --print 直接執行,或自己貼上那行 claude mcp add。在 Claude Code 裡執行 /mcp,選 osfoundry,再選 Authenticate。瀏覽器會開啟 osFoundry,你在那裡選一個 workspace。之後工具就會以 mcp__osfoundry__… 的名稱出現。

2. 把 Room 放進專案

連線本身看不到任何 Room。Room 必須是雲端 Room(在 workspace 裡建立的,而不是只存在這台裝置上),而且必須屬於某個專案。

打開 Room,點標頭上的齒輪圖示(Room 設定)。如果 Room 還沒有專案,Project 欄位會顯示 "Add to project"。下方的說明文字是 "Project-owned content is accessible to members of this project and its ancestors."(專案擁有的內容,此專案及其上層專案的成員都能存取)。選好專案。

3. 把連線加進同一個專案

打開鑰匙圖示 → Connected,選取 Claude Code 的連線,在 Projects 底下選同一個專案,按 Add to project。該專案的 Room 會一併帶進來,Notes、知識庫和其他同步內容也是。

把連線加進 Room 所屬的專案

範例:把連線加進 Room 所屬的專案

在同一個面板打開 Tools。"All supported tools are on by default."(所有支援的工具預設都是開啟的)。Room 相關的工具會以空格取代底線顯示:

read room                 propose room snippet app
list room apps            propose room repo app
read room app status

如果想讓 Claude Code 對 Room 只能讀取,就取消勾選兩個 propose 工具,再按 Save tools。

4. 請 Claude Code 寫工具

描述你要的工具,並說明要放到哪裡。Claude Code 會像寫其他程式一樣,在工作資料夾裡寫檔案,接著提出提案。Room 分頁跑的是 React 18 搭配 TypeScript。進入點是 src/App.tsx,並使用 default export。可用的 npm 套件只有 dayjs、marked、clsx、lucide-react 和 recharts。資料要透過 app SDK(docs、kv、db)處理,不能用 localStorage,也不能 fetch 外部網站。這些要寫進你的 prompt 或 CLAUDE.md,不然 Claude Code 不會知道。

實際跑一次

工具名稱和參數名稱都是 osFoundry 伺服器從 tools/list 回傳的實際名稱。專案、Room、ID 和回覆是範例內容。兩個檔案則是這次實作的真實檔案(63 行和 14 行)。

Example

You: Build a small standup timer for the Launch room in osFoundry. Names list,
     90 seconds each, a Next button, roster saved. Propose it as a Room app.

Claude Code → mcp__osfoundry__list_granted_resources {}
            ← project "Launch plan"
Claude Code → mcp__osfoundry__list_project_resources {"project_id": "…", "resource_type": "room"}
            ← Room "Launch room" (room_7f3c)
Claude Code → mcp__osfoundry__read_room {"room_id": "room_7f3c"}
            ← cloud Room "Launch room"
Claude Code → mcp__osfoundry__list_room_apps {"room_id": "room_7f3c"}
            ← 2 apps, no standup timer
Claude Code → Write src/App.tsx      (63 lines: roster in kv, 90 s countdown, Next/Finish)
Claude Code → Write src/styles.css   (14 lines)
Claude Code → mcp__osfoundry__propose_room_snippet_app
                {"room_id": "room_7f3c", "name": "Standup timer",
                 "files": {"src/App.tsx": "import { useEffect, useState } from 'react'\n…",
                           "src/styles.css": ":root { --bg: #fff; …"},
                 "idempotency_key": "snip-1c9e…"}
            ← proposal waiting for the owner

Claude Code: I proposed "Standup timer" to Launch room. It shows up in the Room
             once you approve it under Connected → Needs your approval.

             (you approve in osFoundry)

You: Approved. Is it there?

Claude Code → mcp__osfoundry__list_room_apps {"room_id": "room_7f3c"}
            ← 3 apps, including "Standup timer"
Claude Code → mcp__osfoundry__read_room_app_status {"room_id": "room_7f3c", "instance_id": "…"}
            ← on the Room launcher

Claude Code: It's in Launch room's tab bar as "Standup timer".

中間那段是你要做的事。鈴鐺通知會顯示 " proposes a Room app"。在鑰匙圖示 → Connected 裡,該連線的面板會有一個 "Needs your approval" 區塊。卡片內容如下:

Create Room snippet app in Launch room
Standup timer
▸ Review all proposed files (2)
Approval makes this code available in the Room app launcher. Review the files before approving.
Expires …
[ Approve and create ]  [ Decline ]

Needs your approval 底下的 Room snippet app 提案,兩個檔案都已展開

範例:Needs your approval 底下的 Room snippet app 提案,兩個檔案都已展開

展開 "Review all proposed files"。每個檔案都會完整列出,最上面是路徑。審查就只有這樣,因為 snippet 沒有 build 步驟,也沒有 manifest 要檢查。按 Approve and create 會新增分頁,按 Decline 則捨棄這個提案。

核准後的 Standup timer 成為 Room 裡的新分頁

範例:核准後的 Standup timer 成為 Room 裡的新分頁

界線在哪裡

本機 Room 是碰不到的,read_room 在自己的說明裡就寫了:"Local Rooms are unavailable." 本機 Room 只是某一台電腦上桌面 app 資料庫裡的一列資料,永遠不會同步。Claude Code 連的 MCP 伺服器跑在 osFoundry 的雲端,所以它唯一能看到那個 Room 的方式,是透過你的桌面端中繼,而且綁定在那台裝置和那個專案上。伺服器的 initialize 回應寫明了通則:"Local-only data is unavailable to cloud clients." 如果這個工具要放在本機 Room,請先放到雲端 Room。本機分頁的 ⋯ 選單裡也有 "Move to cloud room…"。

提案不等於安裝。你允許多少,Claude Code 就能提多少,而每一個都要等人來處理。卡片會出現在該連線自己的面板裡,附上 Room 名稱、app 名稱和每個檔案,而且有到期時間。每次呼叫也都帶有 idempotency_key(8 到 128 個字元),所以 Claude Code 在回應遺失後重試的呼叫,會被認定是同一個提案,而不會多出一張新卡片。

propose_room_repo_app 是另一條路。它指向與 Room 同一專案中某個 GitNest repository 的固定版本,而不是呼叫裡附帶的檔案。需要資料、secret、資料庫、connector 或運算資源的 app 會被這個工具拒絕,必須由人在 osFoundry 裡設定。它的核准卡片上寫著 "This path does not build or deploy a bundle.",並註明核准 "may incur normal app-serving usage"。

Claude Code 能讀回的資訊刻意設計得很少。list_room_apps 不包含 app 設定、secret、檔案和資料庫內容,read_room_app_status 也不會回傳設定、檔案、log 或 secret。所以它能確認計時器已在 launcher 上,但讀不到你的團隊在裡面輸入的名字。

那些名字會留在輸入的地方。Snippet 分頁會把資料存在使用者自己的裝置上。在桌面 app 裡,分頁會顯示一個磁碟圖示,"On this device — data is saved on this computer only",所以每位隊友的名單都是各自的。要把這些資料帶到 workspace,得把分頁存成 app,再從 Room 部署。這件事由人在 osFoundry 裡完成,Claude Code 沒有對應的工具。

接下來可以試試 repository 這條路:請 Claude Code 把計時器 push 到同一專案的 GitNest repository,再用那個版本呼叫 propose_room_repo_app,讓 Room 執行的是固定且可審查的版本,而不是貼上的副本。Room 頁面 有分頁列和設定的介紹,內部 app 則說明 Room app 的用途。

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.