WorkBuddy 自定义 MCP 支持 command/args/env(取证:其二进制 calculateConfigHash 先判 entry.command),因此走与 Codex 同款的本机 stdio full 工具面,不退远程引擎面。 落地:① 启动器多维护一个 MCP 稳定入口 ~/.deta/bin/deta-mcp-<档位>(指向当前插件副本,升级自动刷新;WB 信任哈希按命令行算,路径稳定=升级不重弹信任);② deta-cli 新增 install-workbuddy [--http]——备份并合并 ~/.workbuddy/mcp.json(同名旧条目与旧远程条目替换掉,防双工具面)、把插件内全部技能装进 ~/.workbuddy/skills/(单一事实源,带 icon.svg)、用宿主将执行的同一条命令做真实握手自证;③ aml-design 技能两处 Codex 特有措辞改宿主中立;④ 契约校验加 E7(装配源齐备 + README 指引);⑤ 探针 scripts/verify-workbuddy.sh(配置形态/稳定入口/技能/握手/WB 日志,5 项断言)。 实测:studio 0.3.16 已装副本重跑幂等通过(握手 39 工具);writer 0.1.7 在沙箱 HOME 验证(deta_writer + report-authoring 技能 + 握手 39 工具)。WB 侧需重启并点一次信任确认。
DETA Studio 插件(Codex 插件 / dsh 组合包)
DETA 领域能力(AML 建筑模型读写、编译校验、围护结构统计、空间邻接查询)
以本机 MCP 服务形态挂进 Agent harness:同一个目录既是 Codex 插件根,
也是 dsh 组合包根,两端共享 skills/ 与同一个启动器。
- 发行标识:
studio@deta(插件studio+ 市场deta) - MCP 服务名:
studio_mcp(工具前缀mcp__studio_mcp__…) - 产品档位:启动器
--profile studio(工作区缺省~/.deta/studio/workspace)
连接形态与凭据(唯一管道:本机 stdio)
| 项 | 值 |
|---|---|
| 形态 | 本机 stdio:宿主拉起 bin/deta-mcp.sh --profile studio,由它解析领域服务运行时与工作目录 |
| MCP 服务名 | studio_mcp(工具前缀 mcp__studio_mcp__…);其他产品用各自服务名,可同时安装 |
| 宿主声明 | Codex 读 .mcp.json;dsh 读 cordis.patch.yml——两边都只声明"调用同一个脚本、带哪个档位" |
| 工作目录 | DETA_WORKSPACE → ANT_HEADLESS_WORKSPACE → 缺省 ~/.deta/studio/workspace(启动器创建并在 stderr 回显) |
| 运行时 | DETA_SERVER_ROOT → ~/.deta/runtime → 本机开发检出(回落到开发检出时启动器打印提示) |
| 云侧能力(可选) | DETA_TOKEN(node bin/deta-login.mjs 获取):项目/楼栋列表、push_project / pull_project |
| Studio 执行器中继(可选) | ANT_WORKSPACE_BRIDGE_URL + 项目 ID(三要素齐备才启用;供模拟/画布类工具) |
本机形态不做 MCP 鉴权(进程由宿主或用户在本机拉起,没有 OAuth、没有 401、没有令牌续期)。
未注入 DETA_TOKEN 时,云类工具返回 auth_required,其余工具(编辑、编译、校验、统计、
脚本、模拟)照常工作——这是与远程形态同一份工具实现的不同输入,不是两套代码。
工具面:编辑归宿主,MCP 只做引擎与同步
AML 是纯文本 DSL,读写、搜索、重构一律由宿主原生的文件工具完成 (Codex 的 read / patch / grep / shell;dsh 的同名能力),MCP 不是编辑入口:
| 分工 | 谁做 |
|---|---|
读取 / 修改 / 搜索 aml.xml、bss.md、rules.yml、behaviors.yml、design-brief.md |
宿主原生工具(本地项目目录里的文件) |
| 编译、规范校验、规则检查、围护结构统计、空间邻接、领域脚本 | MCP 引擎工具(编译 / 校验 / 统计 / 邻接 / 脚本等) |
| 改动送进引擎工作区、取回工作区 | MCP 同步工具 |
本机形态为全量工具面(含工作区文件类工具)。当前可用的完整工具名以运行时
list_capabilities 为准,本仓文档不列举工具清单。
本地项目目录约定
一个 DETA 项目就是一个普通目录;引擎工具读的是引擎工作区,因此改动要先同步:
my-project/
├── deta.json # 可选:项目绑定({ "projectId": "...", "name": "..." })
├── aml.xml # 必需:建筑模型唯一事实源
├── bss.md # 可选:样式/构造附属文档
├── rules.yml # 可选:校验规则
├── behaviors.yml # 可选:声明式行为规则
└── design-brief.md # 可选:设计任务书
- 想让引擎直接以项目目录为工作区:启动宿主前设
DETA_WORKSPACE=<项目目录>。 deta.json里的projectId是 deta.city 云项目 ID;带上它的同步调用会把同一个 ID 绑定到引擎工作区,之后生成/拉取会带同一个 Studio 深链https://deta.city/design/<projectId>。- 文件名沿用引擎侧约定(
aml↔aml.xml、brief↔design-brief.md等), 本地目录与引擎工作区结构一致,拉取结果可直接落盘回本地目录。
端到端工作流:本地编辑 → 同步 → 校验 → Studio 查看
1. 本地编辑 read/patch/grep 直接改 aml.xml(MCP 不参与编辑)
2. 同步 把改动送进引擎工作区(带 projectId 时同时绑定云项目)
→ { ok, files, projectId, studioUrl: "https://deta.city/design/<ID>" }
3. 引擎校验 编译 AML 为建筑模型(工作区最新版本)→ 语法/几何/规则校验逐条修复
围护结构统计与空间邻接查询按需调用
4. Studio 查看 在宿主内置浏览器面板打开 studioUrl;已有相同 URL 的标签优先复用,
不为同一项目重复开新标签,也不要 goto 重载已有标签
5. 跑模拟 在面板里的 Studio 界面运行——模拟由 Studio 执行,本插件 MCP 不替代它
6. 反向核对 从引擎工作区拉回文件(工作区为空时返回空集)
路径安全:同步只接受工作区相对路径,绝对路径与 .. 穿越会被拒绝,单次载荷上限 1 MiB。
安装(Codex)
# 1. 添加市场并安装插件
codex plugin marketplace add https://git.deta.city/deta/deta-agent-plugins.git
codex plugin add studio@deta
# 2. 准备领域服务运行时(二选一)
# a) 本机引擎包已安装 → 启动器自动找到(~/.deta/runtime)
# b) 从源码构建:在领域服务仓库执行 npm run build:mcp,并让 DETA_SERVER_ROOT 指向它
#
# 冒烟(应等待 stdin/stdout):
bash <插件目录>/bin/deta-mcp.sh --profile studio
装完即用,没有 OAuth 登录步骤、也不需要终端。需要云侧能力(项目列表 / 新建项目 / 项目同步 / 打开 Studio)时:
在对话里说"登录"或直接让助手新建项目/上传到云 —— 助手会调 login 工具给出一个授权地址,
你在浏览器打开(首次输一次账号密码或邮箱验证码)→ 点「登录并授权」→ 完成。
令牌自动写入 ~/.deta 并即时生效;凭据过期时先用 refresh token 静默续期,用户无感。
命令行形态(无 login 工具时)的兜底做法:
~/.deta/bin/deta login # 由启动器自动注册;账号密码或 --email-code <邮箱>
~/.deta/bin/deta doctor # 端到端自检:运行时、凭据、GSA、MCP 握手
启动器按 DETA_TOKEN 环境变量 → ~/.deta/env → ~/.deta/credentials.json 的顺序解析令牌,
所以浏览器授权后的下一次会话也自动带着登录态——不需要 source、不需要 launchctl、不需要重启应用。
登录助手(云侧能力用)
node bin/deta-login.mjs # 交互式:读标识与密码,写 ~/.deta/*
node bin/deta-login.mjs -u <用户名|已验证邮箱|已验证手机号> # 免交互输入标识
node bin/deta-login.mjs --email-code <邮箱> # 邮箱验证码登录(未设密码的账号用)
node bin/deta-login.mjs --base-url https://<host> # 自建/预发环境
标识(identifier)填门户登录页上用的那一个:用户名、已验证邮箱、已验证手机号,服务端都会解析到同一账号。
助手先匿名调用 /login/check 预检标识是否已注册,再走 /login 做密码校验(不走门户的「登录即注册」端点,
不会误建账号)。失败时按服务端提示给出下一步:
| 服务端提示 | 含义与处理 |
|---|---|
该标识在 <host> 未注册 |
标识不是门户上用的那一个;邮箱验证码注册的账号标识填邮箱 |
用户不存在/密码错误 |
服务端不区分「账号不存在」与「密码不匹配」;已确认标识存在,即密码不符,或改用 --email-code |
该邮箱/手机号尚未验证… |
先用验证码方式登录一次门户完成验证 |
该登录方式未开放 |
用 GET <base>/prod-api/login/methods 查当前启用项 |
安装(dsh)
export DETA_PLUGIN_ROOT=<本包所在目录> # 配置层按它定位启动器
export DETA_WORKSPACE=<你的项目目录> # 可选;缺省 ~/.deta/workspace
dsh plugin --profile <name> add <本包>
cordis.patch.yml 声明本机 stdio,经 bash -lc 调用同一个 bin/deta-mcp.sh;
未设置 DETA_PLUGIN_ROOT 时启动器明确报错退出,不会静默失败。
文件
.codex-plugin/plugin.json Codex 插件清单
.mcp.json Codex MCP 声明(stdio → ./bin/deta-mcp.sh)
package.json dsh 组合包声明(dsh.bundle.patch)
cordis.patch.yml dsh 配置层(同一启动器,stdio)
bin/deta-login.mjs 登录助手(写 ~/.deta/credentials.json + ~/.deta/env,供云侧能力用)
bin/deta-mcp.sh 本机 stdio 启动器(两宿主共用;解析运行时与工作目录)
README.md 本文件(安装 / 连接 / 排障)
skills/aml-design/SKILL.md 宿主侧技能(工具使用规则;不含工具清单)
已知缺陷(实测,2026-09-10)
上游:编码代理 × 模型服务 命名空间重复
会话累积较多本插件工具调用后,代理会在请求里重复声明 MCP 命名空间,模型服务的 Responses 兼容层拒绝请求:
Duplicate namespace name 'deta'; Namespace names must be unique.
复现记录(同一插件、不同会话长度):
| 代理版本 | 会话规模 | 触发位置 |
|---|---|---|
| 0.144.4 | 一步并发 2 次调用 | input[10]、input[18] |
| 0.144.4 | 串行 7–8 次调用 | input[37]、input[47] |
| 0.154.0 | 短会话 5 工具 | 未触发 |
| 0.154.0 | 长会话(≈15+ 工具) | input[260] |
已排除/无效的手段:wire_api = "chat"(该版本已移除,仅支持 responses)、
features.non_prefixed_mcp_tool_names(仅去掉命名空间前缀,重复依旧)、
supports_parallel_tool_calls = false(削弱并发触发面,长会话仍复现)。
应对:完成一个任务后另起会话;撞到该错误不要重试,重开会话即可(工作区文件保留)。
已修缺陷(实测)
| 现象 | 根因 | 修复 |
|---|---|---|
写类工具返回 user cancelled MCP tool call |
MCP 工具默认需审批,非交互模式下无法弹窗 | .mcp.json 声明 default_tools_approval_mode: "approve"(实测 auto/writes 都会被取消,只有 approve 放行) |
本机 stdio 形态起不来:ERR_UNSUPPORTED_DIR_IMPORT |
启动器指向未打包的产物,依赖包的目录 import 在 Node ESM 下非法 | 领域服务提供打包入口;启动器优先取打包产物,回落未打包产物时打印警告 |
| 一个插件两种形态并存(远程 URL + 本机 stdio) | 历史遗留:远程端点声明与本地启动器同时存在,语义冲突 | 统一为本机 stdio 单一管道,远程端点声明从插件移除 |