Claude Code 生成团队工具并经审批上线
教程通过 MCP 连接 Claude Code 与 osFoundry,让智能体在本地生成站会计时器,再提交完整源码供用户审批后创建 Room 应用。流程说明工作区授权、Room 可见范围、沙箱执行方式及上线状态回读的边界。
AI 深度解读
Claude Code 写完一个内部小工具,怎样才能把它放进团队的工作空间,同时保留人工审核?作者用一个每人 90 秒的站会计时器,演示了 osFoundry 的完整流程:本地写代码、向云端 Room 提案、由人查看文件并批准,再读取状态确认入口已经出现。
这套方案的价值在于把代码生成、发布授权和结果确认分开。不过,「所有人都能打开」不代表数据共享,批准提案也不代表完成了一次构建部署。这两个边界,决定了它适合拿来做什么。
连上 MCP,为什么还看不到 Room
第一步是把 osFoundry 接入 Claude Code。下面的命令用于查看连接方式,--print 只打印原本要执行的命令:
$ 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 Code 中打开 /mcp,选择 osfoundry,再选择 Authenticate,通过浏览器选定 workspace。工具随后以 mcp__osfoundry__… 的名称出现。
认证完成还不够。目标必须是归属于某个项目的云端 Room,Claude Code 的连接也必须加入同一个项目。操作位置分别是 Room 设置中的 Project,以及钥匙图标 → Connected → 对应连接 → Projects。

这里有个容易忽略的授权范围:连接加入项目后,带入的不只有 Room,还包括 Notes、知识库等同步内容;项目内容也可被该项目及其上层项目成员访问。
Tools 面板默认开启全部支持的工具。若只想让 Claude Code 查看 Room,可以取消两个 propose 工具并保存。连接成功、资源可见、允许提案,是三个不同条件。
本机 Room 则无法通过这条云端 MCP 路径访问。它只是某台设备桌面数据库里的数据,不会同步;read_room 明确写着「Local Rooms are unavailable」。需要先使用云端 Room,已有本机分页也可以通过「Move to cloud room…」迁移。
小工具可以很快写出来,运行限制必须先交代
作者示范的需求很小:一份名单,每人 90 秒,提供 Next 按钮,并保存名单。
Claude Code 先用 list_granted_resources 找到获授权项目,再用 list_project_resources 查询 Room,接着调用 read_room 和 list_room_apps,确认目标位置以及是否已有同类工具,然后写文件并调用 propose_room_snippet_app。
但 Room 分页不是任意 React 项目的托管环境。它使用 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。
否则,模型很容易生成一份常规浏览器应用,代码看起来合理,却不符合 Room 的运行条件。原文的实现包含 63 行 src/App.tsx 和 14 行 src/styles.css,名单使用 kv 保存;但正文没有给出这两个文件的完整源码,无法据此复核倒计时和状态处理细节。
批准的是代码进入 Room,确认的是入口已经出现
propose_room_snippet_app 提交后,Room 不会立即出现新分页。用户需要进入 Connected 中该连接的「Needs your approval」,展开「Review all proposed files」,查看两个完整文件,再点击 Approve and create;Decline 则丢弃提案。

snippet 没有 build 步骤,也没有 manifest 要检查,因此这里的审核集中在源码。批准后,计时器才会进入 Room 的 app 分页列。
每次提案调用还要携带长度为 8 到 128 个字符的 idempotency_key。它解决的是重试问题:响应丢失后使用同一个键重试,应被识别为同一提案,避免重复生成审批卡片。卡片也有到期时间。
用户批准之后,Claude Code 再调用 list_room_apps 和 read_room_app_status 验证结果。示例中的 app 数量从 2 个变成 3 个,状态显示计时器已在 launcher 上。

不过,这只能确认入口已经出现。两个读取接口不会返回 app 配置、secret、文件或数据库内容,状态接口也不提供 log。因此,不能把这个结果当作完整的功能验收。
更关键的是数据归属。snippet 分页把数据保存在用户自己的设备上,每位队友都有各自的名单。入口在 Room 中共享,名单仍然按设备保存。 要把数据带入 workspace,需要由人在 osFoundry 中把分页保存成 app,再从 Room 部署,Claude Code 没有对应工具。
另一条路径是 propose_room_repo_app:它引用同项目 GitNest repository 的固定版本。需要数据、secret、数据库、connector 或计算资源的 app,会被该工具拒绝,必须由人配置。其审批卡明确说明不会 build 或 deploy bundle,并提示可能产生正常的 app-serving usage。
我的判断
这套流程合理的地方,是让模型负责准备代码,让人决定代码是否进入共享入口,再通过接口确认执行结果。幂等键和有限的状态读取,也分别处理了重复提交与信息暴露的问题。
但它是一篇操作演示,没有提供开发耗时、故障率或与手工发布的对照数据。能证明的是流程如何串起来,不能据此断言团队效率提高多少。
它更适合边界清楚的小工具。若需求包括共享业务数据、外部接口或后端资源,示例中的 snippet 路径就不够了。相比团队已有的仓库、CI 和部署流程,repository 固定版本更便于对应审核对象,但原文已经明确:这个提案工具不会替你完成构建部署。
能拿来做什么
- 给 Claude Code 写 Room 工具时,把 React 18、入口文件、依赖白名单和数据访问限制写进 CLAUDE.md,减少生成后再返工。
- 做站会计时器这类工具前,先确认保存的是个人名单还是团队名单;需要共享数据时,应提前安排人工保存 app 和部署。
- 把「提案已提交」「人工已批准」「入口已出现」作为不同状态处理,批准后读取实际状态,再由人检查功能。
- 需要按版本审查时,可以按原文建议把代码 push 到同项目 GitNest repository,再用固定版本调用
propose_room_repo_app,并单独处理资源配置与部署。