如何讓 Claude Code 在你核准後把小工具放進 osFoundry 的 Room
照著這篇做完,Claude Code 會在你的電腦上寫出一個小型內部工具(這裡以站會計時器為例:一份名單、每人 90 秒、一個 Next 按鈕),然後把它提案到 osFoundry 的雲端 Room。這時 Room 裡還不會出現任何東西。你打開提案、看過兩個原始碼檔案,再按下 Approve and create。計時器就會以新分頁的形式出現在 Room 的 app 分頁列,Room 裡每個人都能打開。Claude Code 會讀取狀態
照著這篇做完,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 所屬的專案
在同一個面板打開 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 提案,兩個檔案都已展開
展開 "Review all proposed files"。每個檔案都會完整列出,最上面是路徑。審查就只有這樣,因為 snippet 沒有 build 步驟,也沒有 manifest 要檢查。按 Approve and create 會新增分頁,按 Decline 則捨棄這個提案。
範例:核准後的 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 的用途。
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.

