authorization code grant 需要一个可跳转的浏览器,以及一个可跳回的本地端口。两者都没有的客户端,比如服务器上的 CLI、CI 任务、无头机器上的 agent,改用 device grant。
它产出的凭证与浏览器 grant 相同:一把 blocklet- 前缀的 access key,作为 bearer token 发送。把 <host> 替换成该 blocklet 的 host。
1. 发起设备授权
curl -s -X POST https://<host>/.well-known/service/oauth/device_authorization \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=<client_id>&scope=mcp'{
"device_code": "bc0cedc2-899f-49da-b413-213f31c4aae8",
"user_code": "BZVR-ZQZQ",
"verification_uri": "https://<host>/.well-known/service/gen-access-key",
"verification_uri_complete": "https://<host>/.well-known/service/gen-access-key?__token__=bc0cedc2-…",
"expires_in": 300,
"interval": 5
}client_id 需要先注册取得 —— 见授权客户端。
| 字段 | 用途 |
|---|---|
user_code | 展示给人看。字母表排除了元音和易混字符,因此可以口头念出 |
verification_uri | 人去哪里批准 |
verification_uri_complete | 同一个页面但已预填请求 —— 能渲染链接或二维码时用它 |
expires_in | 这个请求过期前的秒数,上面是 300。它描述的不是凭证 |
interval | 两次轮询之间的最小秒数,上面是 5 |
2. 人去批准
打开 verification_uri_complete 会看到一个同意界面,上面写明发起请求的应用与账户,并有一个访问级别选择器。它提供 owner(默认)、admin、member、guest;凭证携带被选中的那个。
role 的作用域限于这个 blocklet 实例,而且是上界不是授予 —— 见访问分档。
3. 轮询取凭证
用 device code grant 轮询 token 端点,直到请求被批准或过期。请遵守 interval,这个字段存在的意义就是防止更快的轮询。
curl -s -X POST https://<host>/.well-known/service/oauth/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
--data-urlencode 'device_code=bc0cedc2-899f-49da-b413-213f31c4aae8' \
--data-urlencode 'client_id=<client_id>'批准之后:
{
"access_token": "blocklet-zEJYCdC9awCqxEPLhqreFbwXjqU6Y2BHvKVQAx6kMZfRh",
"token_type": "Bearer",
"scope": "mcp"
}批准之前、以及五分钟窗口关闭之后,同一个请求返回 400:
{"error":"invalid_grant","error_description":"Invalid or expired device_code"}invalid_grant 多数意味着窗口过期,而不是码写错了。从第 1 步重新开始。
没有 expires_in,没有 refresh_token。 authorization server 把 refresh_token 列为支持的 grant,但这条流程不返回它。把这把 access key 当作你要长期保存的凭证。
4. 使用它
curl -s -X POST https://<host>/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'Authorization: Bearer blocklet-…' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'这份凭证过的是凭证那道闸,它不过路径策略那道 —— 一次已认证的写入仍可能返回 AFS_FORBIDDEN。见授权客户端。
用哪种 grant
| 情况 | grant |
|---|---|
| 客户端能打开浏览器并监听本地端口 | 带 PKCE 的 authorization_code —— 见授权客户端 |
| 客户端没有浏览器,或批准的人在另一台设备上 | device grant,即本页 |
MCP 客户端通常实现的是 authorization code grant,不是 device grant。请把 device grant 用于你自己的工具,而不要指望第三方 MCP 客户端会去发现并驱动它。