Files
deta-agent-plugins/plugins/deta

deta 插件(Codex 插件 / dsh 组合包)

DETA 领域能力(AML 建筑模型读写、编译校验、围护结构统计、空间邻接查询) 以远程 MCP 服务形态挂进 Agent harness:同一个目录既是 Codex 插件根, 也是 dsh 组合包根,两端共享 skills/ 与同一份 MCP 后端。

端点与凭据

项 值
端点 https://deta.city/mcp-api/mcp(MCP Streamable HTTP)
凭据来源 deta.city 账号;两种取得方式:OAuth 浏览器登录(推荐)或换令牌后手工传
Codex 侧 OAuth 2.1(授权码 + PKCE S256,动态客户端注册),由 codex mcp login deta_mcp 发起;令牌由 Codex 保管并自动续期,无需手工配置
dsh / 脚本 环境变量 DETA_TOKEN,作为 Authorization: Bearer 或 X-API-Key 发送

端点除探活接口(服务端 GET /health,经 Nginx 前缀对外为 /mcp-api/health)外全部需要鉴权:

  • 无凭据 / 凭据失效 → 401,且响应带 OAuth 发现提示: WWW-Authenticate: Bearer resource_metadata="https://deta.city/.well-known/oauth-protected-resource/mcp-api/mcp", scope="mcp" 标准 MCP 客户端据此自动进入浏览器授权流程(Codex 走的就是这条),无需手工配令牌。 401 的含义是「当前环境没有可用的 deta.city 登录态」,不是工具或模型出错。
  • 服务端认证服务不可用(ANT_ADMIN_SERVER 未配置或不可达)→ 500,同样不放行。

账号的工作区在服务端按账号隔离(<工作区根>/<账号 ID>), 不同账号的设计源码互不可见;同一账号的新会话继续使用自己的工作区。

工具面:编辑归宿主,MCP 只做引擎与同步

AML 是纯文本 DSL,读写、搜索、重构一律由宿主原生的文件工具完成 (Codex 的 read / patch / grep、shell;dsh 的同名能力),MCP 不再是编辑入口:

分工 谁做
读取 / 修改 / 搜索 aml.xml、bss.md、rules.yml、behaviors.yml、design-brief.md 宿主原生工具(本地项目目录里的文件)
编译、规范校验、规则检查、围护结构统计、空间邻接、领域脚本 MCP 引擎工具(apply_design / validate_model / analyze_gsa_issues / analyze_rules_compliance / envelope_stats / query_spatial_graph / run_script …)
本地改动送上云端、取回云端工作区 MCP push_project / pull_project

远程 HTTP 形态的工具面按部署形态裁剪:编辑类工具 (read_source / edit_source / list_workspace / search_workspace / workspace_diff 等依赖宿主 AML、工作区文件清单、画布或计算回调的工具)不出现在 tools/list; 引擎类工具与 push_project / pull_project 保留。本机 stdio 开发形态仍是全量面 (DETA_TOOL_SURFACE=full,缺省即 full;远程形态缺省 engine,可用同名环境变量覆盖)。

本地项目目录约定

一个 DETA 项目就是一个普通目录,引擎工具读的是服务端工作区,因此改动要先 push:

my-project/
├── deta.json          # 可选:项目绑定({ "projectId": "...", "name": "..." })
├── aml.xml            # 必需:建筑模型唯一事实源
├── bss.md             # 可选:样式/构造附属文档
├── rules.yml          # 可选:校验规则
├── behaviors.yml      # 可选:声明式行为规则
└── design-brief.md    # 可选:设计任务书
  • deta.json 里的 projectId 是 deta.city 云项目 ID;带上它的 push_project 会把同一个 ID 绑定到服务端工作区(写 deta.json),之后 generate_aml / pull_project 会带上同一个 Studio 深链 https://deta.city/design/<projectId>。
  • 文件名沿用服务端约定(aml ↔ aml.xml、brief ↔ design-brief.md 等), 本地目录与服务端工作区结构一致,pull_project 的结果可直接落盘回本地目录。

端到端工作流:本地编辑 → push → 校验 → Studio 查看

1. 本地编辑     read/patch/grep 直接改 aml.xml(MCP 不参与编辑)
2. 推送         push_project({ files: { "aml.xml": "<全文>", "rules.yml": "…" },
                              projectId: "<云项目 ID>" })
                → { ok: true, files: ["aml.xml", "rules.yml"],
                    projectId: "<云项目 ID>", studioUrl: "https://deta.city/design/<ID>" }
                (带 projectId 时同时在服务端工作区写入 deta.json 绑定)
3. 引擎校验     apply_design()      → 编译 AML 为建筑模型(服务端工作区内的最新版本)
                validate_model()    → 语法/几何问题,逐条修复后重新 push + 编译
                envelope_stats() / query_spatial_graph() → 围护结构与空间邻接
4. Studio 查看  在右侧内置浏览器面板打开返回的 studioUrl
                (https://deta.city/design/<projectId>,例:云项目 11 → https://deta.city/design/11);
                已有相同 URL 的标签优先复用,不要为同一项目重复开新标签,也不要 goto 重载已有标签
5. 跑模拟       在面板里的 Studio 界面运行(分析/模拟面板、GH 模板)——模拟由 Studio 执行,
                本插件 MCP 不执行模拟;面板首次使用需先登录一次 deta.city
6. 反向核对     pull_project({ projectId }) → { files, projectId, studioUrl }
                (工作区为空时 files 为 {})

路径安全:push_project 只接受工作区相对路径,绝对路径与 .. 穿越会被拒绝, 单次载荷上限 1 MiB(与请求体上限一致)。

安装与登录(Codex)

# 1. 添加市场并安装插件
codex plugin marketplace add https://git.deta.city/deta/deta-agent-plugins.git
codex plugin add deta@deta

# 2. 登录(一次性):浏览器里完成 deta.city 账号登录
codex mcp login deta_mcp

codex mcp login deta_mcp 会打印一条形如 https://deta.city/oauth/authorize?response_type=code&client_id=…&code_challenge=… 的地址并打开浏览器; 页面上用 deta.city 账号登录(支持「账号密码」与「邮箱验证码」两个入口),点「登录并授权」后 浏览器提示 Authentication complete,终端输出 Successfully logged in to MCP server 'deta'。

登录态由 Codex 保存,access token 有效期 1 小时并用 refresh token 自动续期; 换机器或换 CODEX_HOME 需重新 codex mcp login deta_mcp。退出登录:

codex mcp logout deta_mcp      # 撤销并删除本地凭据

插件默认走 OAuth。若要把令牌固定为环境变量(自动化、容器、CI),装好后改为:

codex mcp remove deta_mcp
codex mcp add deta_mcp --url https://deta.city/mcp-api/mcp --bearer-token-env-var DETA_TOKEN
export DETA_TOKEN=<管理端签发的 API Key 或门户登录令牌>

登录助手(dsh / 脚本 / 预发环境)

OAuth 之外仍保留令牌方式,供不支持 OAuth 的宿主与脚本使用:

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>             # 自建/预发环境
source ~/.deta/env                                            # 导出 DETA_TOKEN

标识(identifier)填门户登录页上用的那一个:用户名、已验证邮箱、已验证手机号,服务端都会解析到同一账号。 助手先匿名调用 /login/check 预检标识是否已注册,再走 /login 做密码校验(不走门户的「登录即注册」端点, 不会误建账号)。失败时按服务端提示给出下一步:

服务端提示 含义与处理
该标识在 <host> 未注册 标识不是门户上用的那一个;邮箱验证码注册的账号标识填邮箱
用户不存在/密码错误 服务端不区分「账号不存在」与「密码不匹配」;已确认标识存在,即密码不符,或改用 --email-code
该邮箱/手机号尚未验证… 先用验证码方式登录一次门户完成验证
该登录方式未开放 用 GET <base>/prod-api/login/methods 查当前启用项

安装(dsh)

node ~/Dev/ant/deta-agent-plugins/plugins/deta/bin/deta-login.mjs
source ~/.deta/env
dsh plugin --profile <name> add ~/Dev/ant/deta-agent-plugins/plugins/deta

cordis.patch.yml 默认启用远程 streamable-http 段(Bearer 取自 DETA_TOKEN)。

本地 stdio 形态(开发用)

bin/deta-mcp.sh 走本机 stdio(node dist/src/headless/mcp-server.js), 仅本机开发用,默认关闭:不校验 deta.city 账号、不隔离工作区。 需要在本机迭代领域能力时,打开 cordis.patch.yml 里注释掉的 stdio 段 (并注释掉远程段),设置 DETA_SERVER_ROOT 指向已构建的领域服务仓库:

cd ~/Dev/ant/ant-copilot && npm run build
node dist/src/headless/mcp-server.js   # 冒烟:应等待 stdin/stdout

文件

.codex-plugin/plugin.json   Codex 插件清单
.mcp.json                   Codex MCP 声明(远程 streamable-http)
package.json                dsh 组合包声明(dsh.bundle.patch)
cordis.patch.yml            dsh 配置层(挂载 MCP 服务)
bin/deta-login.mjs          登录助手(写 ~/.deta/credentials.json + ~/.deta/env)
bin/deta-mcp.sh             本地 stdio 启动器(开发用)
skills/aml-design/SKILL.md  领域技能