接入 —— 把 Depot 连上你的 agent
五分钟接上:注册 MCP 端点 → 读面 op 清单 → 四步闭环 → 取信任锚 → 读懂这条链的边界与今天的弱值。全程零人类浏览网页也成立(本页只是给人看的同一份东西)。
① 注册 MCP 端点(两种写法)
Depot 的 typed 面是一个 HTTP MCP 端点:https://atd.run/mcp。它匿名只读 —— 没有 token,没有注册流程,连上就能用。
写法 A —— Claude Code CLI
claude mcp add --transport http atd-depot https://atd.run/mcp
想让它在所有项目里都可用(user 级):
claude mcp add --scope user --transport http atd-depot https://atd.run/mcp
写法 B —— 通用 HTTP MCP 客户端的配置片段
{
"mcpServers": {
"atd-depot": {
"type": "http",
"url": "https://atd.run/mcp"
}
}
}
公网这一面上只有读面工具:另外 5 个写面工具(depot:publish.assert_harm · depot:publish.submit · depot:publish.unyank · depot:publish.yank · depot:submission.release)根本没有在公网注册表里注册(ADR-0010 D6.3),它们只在运维机侧的本地 UDS 面上存在。这不是「功能还没做」——是刻意的:发布口的鉴权与身份归发布流水线,不靠一个公网端点上的开关。
浏览器直连这个端点会被拒(它必发 Origin,而这一面的 origin 白名单恒空 —— ADR-0010 D6.2)。这同样是刻意的:typed 面是给 agent 的,人走本站这份投影(AN-1:Web 是投影,不是并列实现)。
② 这一面有哪些 op(6 个,读面)
| op | 它是什么(wire 上的原话) |
|---|---|
depot:artifact.manifest | Full declaration of one artifact version, with per-component kinds |
depot:catalog.find | Search the artifact catalogue and return a short page of ranked hits |
depot:catalog.stat | Entry card for one artifact version: provenance, consequence, evidence grades |
depot:install.plan | Install plan for one artifact version: digest, steps, post-conditions |
depot:submission.status | Read one queued submission, or list the whole public queue |
depot:trust.evidence | Trust evidence for one artifact version: signatures, attestations, tiers, gaps |
🔴 这张表不是版式里手抄的清单:它由构建期的一次 tools/list 生成,每一行的 op id 与那句话都逐字来自 registry 里那个 op 自己的条目(因此每行带着自己的来源标记)。「零平行词表」(AN-6)在这一页上的形态就是这件事 ——一份手抄的清单会在某个 op 改名的当天开始说谎,而没有任何一格门禁会红。
渐进披露是严格单调的:find ⊂ stat ⊂ manifest ⊂ evidence,每一级有成文的 token 预算。别从证据级开始 —— 那会为没用上的证据付四倍预算。
③ 四步闭环,一行一步
| 步 | 做什么 | 用哪个 op |
|---|---|---|
| ① 发现 | 按 kind / 关键词拿一页候选;0 命中给指南针,过宽给截断 + 收窄建议 | depot:catalog.find |
| ② 审读 | 条目卡 → 完整声明 → 信任证据。作者自述与 Depot 背书永远分块,别把前者读成后者 | depot:catalog.statdepot:artifact.manifestdepot:trust.evidence |
| ③ 安装 | 拿一份数据对象形态的安装计划;本站与 Depot 都不执行它的任何一步 | depot:install.plan |
| ④ 验证 | plan.steps 本身就是验证程序:fetch → 重算 sha256 比对(T1)→ 验签名(T2)→ 落盘。结论是三态,不是 exit 0 | (同上,无第五个 op) |
最小可复制的一次调用(发现面,L0):
curl -sS -X POST https://atd.run/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"depot:catalog.find","arguments":{"kind":"skill","limit":5}}}'
🔴 第④步里你不被要求信任 Depot 自己的结论(ADR-0012 D3.1):摘要来自一份被签名覆盖的索引快照,字节来自内容寻址的键 —— 两边都在你手上,用 curl + sha256sum 就能把 T1 级复核做完,不存在、也不需要一个「帮你验」的端点。
安装成功 = verified / unverified{reason} / contradicted 三态判定;未验证的后果绝不呈现为成功(ADR-0002 D5)。
④ 取信任锚:三行
GET https://atd.run/bytes/index/latest.json → 读 signature.trust_anchors(一个 sha256 摘要) → GET https://atd.run/bytes/trust-root/sha256/<摘要前两位>/<摘要>.json
- 本次快照指向的信任锚文档(字节面键)
- trust-root/sha256/7b/7b9223430a0b48f7d8a9423561611b24676770fbd356f460fb54e60a1b0d015c.json
这份锚文档里是 Depot 的公钥;你之后验的每一个签名,公钥都来自它。字节面是纯 HTTP GET:零 RPC、零列目录、零查询参数,index/latest.json 是唯一可变的键,其余一切写入即不可变。
⑤ 🔴 诚实边界 —— 这条链能证明什么、不能证明什么
你是经 https://atd.run 的 TLS 通道拿到信任锚的。因此这条链的信任根就是你怎么拿到它的:本阶段的信任根 = Web PKI + 域名控制权,不多不少(ADR-0012 D1)。
| 攻击者 | 这条链闭合吗 |
|---|---|
| 能改写字节面(换一份制品字节 / 换一份快照 / 换一份 attestation) | ✅ 闭合 —— 摘要链与签名会当场发现 |
能取得 atd.run 的域名控制权或 TLS 私钥 | 🔴 不闭合 —— 它可以给你一整棵自洽的伪造树,连同伪造的信任锚 |
🔴 因此:MUST NOT 把「离线可验证」表述为「抗主动攻击」(ADR-0012 D1.2)。本阶段的信任下限与 npm 的公钥端点同档,低于 TUF / 内嵌 pin 路线。这是为「任何 agent 会话今天就能端到端跑通」自愿支付的过渡代价 —— 它被写在这里,而不是藏在文档的缺席里。
🔴 零 pin 阶段(ADR-0012 D2.1):不要把任何 key_id、公钥或摘要硬编码进你的 skill / 配置 / 代码。本阶段不提供、也不邀请任何内嵌 pin 形态;每次消费都从指针重新解析锚。(一个被 pin 的公钥会立刻关死密钥轮转的窗口 —— 那是一次需要新裁定的决策,不是可以顺手做的优化。)
同理 MUST NOT 硬编码快照 TTL:读响应里的 expires_at,不要推算天数。
⑥ 今天你会读到的弱值(本次语料的实数,不粉饰)
发布者签名状态 signature_state(逐条制品统计)
| 值 | 制品数 |
|---|---|
unsigned | 4 |
unsigned 逐字意为这份制品没有任何发布者签名。Depot 的副署证明的是「我在某个时刻收下并核过它的字节」,不是「发布者是谁」—— 两件事不许被读成一件(AN-5 / ADR-0012 D3.3)。
⑥b 后果四轴的著录 gap(按 kind 拆,不合总数)
| kind | 制品数 | 后果未著录 |
|---|---|---|
| skill | 4 | 4 |
| tool | 未著录(absent) | 未著录(absent) |
| device_adapter | 未著录(absent) | 未著录(absent) |
这是 gaps 字段的原样投影:Depot 绝不替没著录后果的制品推断一份(AN-5:缺席即缺席,绝不合成)。唯一允许的加工就是量化它,并按 kind 拆开公布 ——不许用一个总数掩盖某个品类的塌陷。
🔴 它的下游:没著录后果 ⇒ 也没有 verify 声明 ⇒ 安装计划里的 open_loop_reason 是 no_spec,意思是「这一问没被回答」。它与 open_loop(「这类制品本来就没有安装后读回通道」)不是一回事,上游把它们分成两个值正是为了让你的重试策略分得开 ——都不要读成「验证失败」。
认证档的分布在度量页(M6),每一件制品的逐条判据在它自己的证据页上。
⑦ 还有什么
本站的每一页都是同一份 typed 面的投影:目录索引(L0 命中)· 条目卡 / 完整声明 / 信任证据(L1-L3,从索引点进去)· 度量(gap 被量化)· ratify 与治理(人在这条链路上的两个合法位置)。
你在这些页面上看到的每一条数据,用上面那几个 op 都能自己取到 ——这就是「Web 是投影」的可证伪形态:不存在只能在网页上完成的动作(AN-1)。