对应 ant-copilot 的两处收敛:打开 Studio 只留 open_studio(追加 waitSeconds 确认 executor_online 的典型节奏);query_knowledge 因需宿主注入知识库回调、远程形态不接入,已从工具一览移除并说明原因。
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 领域技能