跳到主要内容

ARC 开发者文档

错误

agent 可能撞上的每一种失败、成因和处理方式 —— 按传输层失败与调用内失败分开,因为它们含义不同。

失败有两种形状,混淆它们会白费时间。

形状含义在哪里决定
HTTP 4xx,没有 JSON-RPC 结果调用没有到达工具方法白名单或凭证,见第 1、2 道闸
HTTP 200,带 "isError": true调用到达了工具;操作失败了路径策略或 provider,见第 3、4 道闸

200 不等于成功。每次 tools/call 都要检查 result.isError

传输层失败

/mcp 上的 401

http
HTTP/1.1 401 Unauthorized
www-authenticate: Bearer resource_metadata="https://<host>/.well-known/oauth-protected-resource"

{"error":"Unauthorized"}

无论什么原因,正文都一样。三种原因会产生它:

成因怎么判断修法
匿名调用写工具你没发 Authorization跟着挑战走 —— 授权客户端
方法不在匿名白名单上该方法不是 initialize / tools/list / resources/list / prompts/list / 被允许的 tools/call认证,或改用被允许的方法
凭证被拒你发了头,但它格式错误、未知,或由另一个 blocklet 签发这个 host 取凭证。凭证与实例绑定

匿名状态下调一个不存在的工具名也返回 401,而不是「没有这个工具」—— 白名单在查找工具之前就检查了。如果你在 tools/list 里看到过的工具名返回 401,那它是特权工具,不是拼写错误。

授权流程失败

全部是 400,带 RFC 6749 错误码。

请求响应
POST /oauth/registerredirect_uris{"error":"invalid_redirect_uri","error_description":"Missing redirect_uris"}
POST /oauth/register 用了不支持的 scheme{"error":"invalid_redirect_uri","error_description":"redirect_uris must be https, RFC 8252 loopback http, or a private-use scheme …"}
POST /oauth/token 用未知或已过期的 device_code{"error":"invalid_grant","error_description":"Invalid or expired device_code"}
POST /oauth/token 用其他任何 grant{"error":"unsupported_grant_type","error_description":"Only device_code, authorization_code, and refresh_token grants are supported"}

另有两种你应当预期、但上表没有展示的:

  • 注册按来源地址限流。 每次启动都重新注册的客户端最终会被限流。注册一次,把 client_id 存下来。
  • 从未在一次完成的授权中被使用的注册,七天后被清除。 长期存在但从未获得同意的客户端需要重新注册。

device code 上的 invalid_grant 多数意味着五分钟窗口过期了,而不是码写错了。重新发起流程即可。

调用内失败

这些以 200isError 返回。文本是一个错误码,后跟路径与解释。

AFS_FORBIDDEN

text
AFS_FORBIDDEN: Forbidden at /instance/notes.txt: network clients cannot write base paths;
use a resolver overlay or internal code

该 blocklet 没有把这条路径向网络客户端开放。各操作的变体:

操作文案
writecannot write base paths; use a resolver overlay or internal code
readcannot read base paths; declare a networkRead rule or use an overlay
listcannot list base paths; declare a networkRead rule or use an overlay
statcannot stat base paths; declare a networkRead rule or use an overlay

凭证修不了这个。 owner 身份的调用方得到同样的拒绝。只有 blocklet 自己的声明能改变它 —— 见访问分档第 3 道闸

AFS_NOT_FOUND

text
AFS_NOT_FOUND: Path not found: /new

该路径在这个 host 上不存在。路径按 host 划定作用域,因此同一条路径可能在一个 blocklet 上解析得到、在另一个上不存在,即使两者挂载了同名 provider。先对父路径做 afs_list 确认,再判断 provider 是否缺失。

按顺序排查

顺着闸往下走,每一步都排除掉它上面的全部可能。

  1. 匿名 tools/list 返回 200 吗? 否 → host 不可达,或者它不是一个 ARC blocklet。检查 URL 与 /.well-known/mcp.json
  2. 这个工具出现在 tools/list 里吗? 否 → 若是内容工具,说明该 blocklet 没有声明集合;见声明 agent 能看到什么
  3. 调用它返回 401 吗? 是 → 第 1 或第 2 道闸。跟着 WWW-Authenticate 挑战走。
  4. 返回 200 且带 AFS_FORBIDDEN 吗? 是 → 第 3 道闸。凭证没问题,是路径对网络关闭。
  5. afs_statcapabilities 里有这个操作吗? 否 → 第 4 道闸。provider 没有实现它。

刷新凭证

device grant 返回的凭证没有有效期,也没有 refresh token,所以没有需要刷新的东西。如果凭证失效,用你的工具重新登录一次即可,见接入你的工具