字huozi.app

两条 pipeline

huozi 支持两条平行的 pipeline,适配不同执行环境。两条最终都拿到 Bearer token 调 /mcp,但凭证来源、流程、token 形态都不同。按你 Agent 跑在哪决定走哪条。

并排对比

维度选择二 · 本地终端 / GUI选择一 · Agent 自己装
标准RFC 8252 + PKCERFC 8628
适用场景用户在自己电脑终端;有 TTY、有系统浏览器、能绑 localhost 回调。Chat-mode Agent;非 TTY shell 工具、可能 headless / 沙箱 / 远端,无 localhost 回调。
触发方式客户端原生 mcp add CLI 或 GUI 的 Add connector 入口。Agent 读 /llms.txt 后自己跑;用户粘一段 prompt。
用户动作点一次浏览器 Approve(本机弹起)。点一次链接(任意设备),登录后 Approve。
拿到的凭证OAuth access_token(短期,1 小时)+ refresh_token(可轮转,30 天)。静态 hz_* api_key(长期,直到撤销或 TTL 到期)。
凭证存哪客户端自己的 token store(~/.hermes/mcp-tokens/、Cursor keychain 等),不进 config 文件。Host 的 MCP config 文件,Bearer 头明文。
两条路用同一个 /mcp 端点;服务器只看 Authorization header,不区分 token 怎么来的。换路径不要重新装,只换凭证发放方式。

RFC 8252 · OAuth-on-first-use

标准 OAuth 2.1 authorization code 流,带 PKCE-S256(RFC 7636)和 dynamic client registration(RFC 7591)。客户端不用预先注册,首次连 /mcp 失败时自动发现授权服务器、本机弹浏览器、收 localhost 回调。

流程

Step 1. Client → server:    POST /mcp  (no Authorization)
Step 2. Server → client:    401 + WWW-Authenticate: resource_metadata=/.well-known/oauth-protected-resource
Step 3. Client → server:    GET /.well-known/oauth-protected-resource
Step 4. Client → server:    GET /.well-known/oauth-authorization-server
Step 5. Client → server:    POST /oauth/register      (dynamic client registration)
Step 6. Client opens browser → /oauth/authorize?code_challenge=<S256>&...
Step 7. User signs in (OTP / password) + clicks Approve
Step 8. Browser → 127.0.0.1:<port>/callback?code=...
Step 9. Client → server:    POST /oauth/token  grant=authorization_code + code_verifier
Step 10. Server → client:   { access_token, refresh_token, expires_in, scope }
Step 11. Client retries:    POST /mcp  Authorization: Bearer <access_token>  → 200 OK

支持这条路的客户端

Claude Code(claude mcp add)、OpenAI Codex CLI(codex mcp add)、Hermes(hermes mcp add --auth oauth)、Cursor(~/.cursor/mcp.json)、Claude Desktop / Cowork(Customize → Connectors)、OpenClaw(部分,WIP)。

RFC 8628 · Device Authorization Grant

为没浏览器、没 TTY、跨设备的客户端设计的 OAuth 扩展。Agent 调一个端点拿 device_code + 用户码,把验证 URL 给用户(用户在任意设备点开),Agent 后台轮询 token 端点直到拿到 access_token。彻底解开了 8252 的「必须能收 callback」假设。

流程

Step 1. Agent → server:     POST /auth/device-code  { client_name, agent_kind }
Step 2. Server → agent:     { device_code, user_code, verification_url_complete, expires_in: 900, interval: 5 }
Step 3. Agent prints verification_url_complete to user
Step 4. User opens URL → /device?code=ABCD-1234 (any device)
Step 5. User signs in (Cloud OTP / Edge password) + clicks Approve
Step 6. Agent polls every 5s:  POST /auth/token  { device_code }
        - 202 authorization_pending → keep polling
        - 200 { api_key, key_id, workspace } → done
Step 7. Agent writes api_key to host MCP config
Step 8. Agent/host calls:  POST /mcp  Authorization: Bearer <api_key>  → 200 OK

标准 OAuth 端点也支持 device flow

原生支持 RFC 8628 的 MCP 客户端可以直接调 POST /oauth/token 用 form-encoded body grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=... ,服务端会按 OAuth 标准 envelope 返回 {access_token, token_type: "Bearer", scope}。这样客户端能从 /.well-known/oauth-authorization-server 自动发现,无需读这份 prompt。

/llms.txt 协议

Chat-mode Agent 不读这份 docs(它读的是机器友好的 /llms.txt)。 该端点跟着部署域名走 —— Cloud 是 cloud.huozi.app/llms.txt,Edge 是 <your-deploy>/llms.txt —— 内容由 route handler 按请求 host 模板生成。

?for=<agent_kind> 过滤

带 ?for=<kind> 查询参数访问 /llms.txt 会把 Step 4(写 host config 那段)过滤到只剩这一个 host 的 snippet,文档体积砍 ~70%。小 context window 模型(Haiku、本地小模型)就不会吃满。

可用 kind 值:

  • claude-code
  • cursor
  • hermes
  • openclaw
  • codex
  • cowork
  • desktop
  • generic

Self-check 段

/llms.txt 顶部有「Before you start」自检段:列出 Agent 需要的工具能力(HTTP request、用户链接打印、文件写),没全部具备的话直接告诉用户去 Choice 2 自己装,而不是闷头试到失败。

安全

  • RFC 8252 OAuth token 由 MCP 客户端持有,不会进入对话上下文。
  • RFC 8628 device flow 拿到的是静态 api_key,需要 Agent 守住 prompt 里的「don't print api_key」纪律。
  • 所有 key 都可在 cloud.huozi.app/workspace(或 Edge 等价路径)随时撤销。
  • RFC 8252 token 默认 1 小时过期,需要 refresh 续命。RFC 8628 api_key 默认无过期,但每个 connection 可独立设 sliding-window TTL。

更多