构建助手客户端

使用 OAuth 登录

助手如何在没有 API 密钥的情况下登录:发现、注册、授权同意和令牌,适用于构建你自己的客户端。

AI 助手使用 OAuth 而不是 API 密钥登录 Setherion:用户在 Setherion 的页面上点击 Allow,助手就会收到一个令牌。本页是构建你自己的客户端时要遵循的约定。如果你只是想连接 Claude、ChatGPT、Cursor 或 VS Code,请按照连接 AI 助手操作。

这个流程是 MCP 授权规范(2025-06-18)所要求的 OAuth 2.1:

  • 授权码流程,始终要求 PKCE (S256);
  • 只支持公共客户端,没有客户端密钥;
  • 动态客户端注册(RFC 7591),所以没有人需要在任何地方粘贴客户端 ID;
  • 令牌绑定到一个资源,即 MCP 端点(RFC 8707)。

这些令牌只能用于 MCP 服务器,别处无效。本参考中的 REST 端点使用 API 密钥。

项目值
签发方https://www.setherion.com
资源https://www.setherion.com/api/mcp
范围mcp
访问令牌以 sto_ 开头,有效期 1 小时
刷新令牌以 str_ 开头,有效期 30 天,每次使用后都会被替换
授权码以 stc_ 开头,有效期 10 分钟,只能使用一次

1. 发现

不带任何凭据,向 MCP 端点发送一个请求。401 响应的 WWW-Authenticate 头会指向资源元数据(RFC 9728):

bash
curl https://www.setherion.com/.well-known/oauth-protected-resource/api/mcp
json
{
  "resource": "https://www.setherion.com/api/mcp",
  "authorization_servers": ["https://www.setherion.com"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["mcp"],
  "resource_name": "Setherion"
}

同一份文档也位于 /.well-known/oauth-protected-resource。然后读取授权服务器元数据(RFC 8414):

bash
curl https://www.setherion.com/.well-known/oauth-authorization-server
json
{
  "issuer": "https://www.setherion.com",
  "authorization_endpoint": "https://www.setherion.com/oauth/authorize",
  "token_endpoint": "https://www.setherion.com/api/oauth/token",
  "registration_endpoint": "https://www.setherion.com/api/oauth/register",
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["none"],
  "scopes_supported": ["mcp"]
}

这两份文档、注册端点和令牌端点都接受任何来源(Access-Control-Allow-Origin: *),所以浏览器页面中的客户端也可以调用它们。

2. 注册

POSThttps://www.setherion.com/api/oauth/register

套餐: 所有套餐

每次安装注册一次。注册本身不会授予任何权限:仍然需要用户点击 Allow,而且授权码只会发送回这里注册的确切地址。

bash
curl -X POST https://www.setherion.com/api/oauth/register \
  -H "Content-Type: application/json" \
  -d '{ "client_name": "My assistant", "redirect_uris": ["http://localhost:8787/callback"] }'
字段含义
redirect_uris必填。1 到 10 个地址,每个最多 2,000 个字符。重复的会被丢弃。
client_name可选。会在授权同意页面上显示给用户。超过 100 个字符会被截断;省略时为 An AI assistant。
grant_types可选。只接受 authorization_code 和 refresh_token。
response_types可选。只接受 code。

重定向地址必须是 https,或者是指回本机的 http(localhost、127.0.0.1 或 [::1])。它不能带有片段或用户名。唯一不是 https 或 http 的地址是 cursor://anysphere.cursor-mcp/oauth/callback,用于较旧的 Cursor 应用。

无论客户端请求哪种身份验证方式,它都会被注册为没有密钥的公共客户端,响应中也会这样说明:

json
{
  "client_id": "5f0c2a9d-4e30-4d7f-b8a5-6f1c2a9d4e30",
  "client_id_issued_at": 1790000000,
  "client_name": "My assistant",
  "redirect_uris": ["http://localhost:8787/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}

状态码为 201。每个网络地址每小时最多注册 20 次。

注册错误

每个错误的格式都是 { "error": "...", "error_description": "..." }。

状态码errorerror_description
400invalid_redirect_uriSend between one and ten redirect_uris.
400invalid_redirect_uriRedirect URIs must be HTTPS, or HTTP back to localhost.
400invalid_client_metadataOnly authorization_code and refresh_token are supported.
400invalid_client_metadataOnly the code response type is supported.
429slow_downToo many registrations. Try again later.
503temporarily_unavailableNot configured. 或 Connecting assistants is not switched on yet.

3. 询问用户

在用户的浏览器中打开授权端点。它是一个页面,而不是 API:如果用户还没有登录 Setherion,就先登录,然后看到你注册的名称和将被送回的地址,再点击 Allow 或 Cancel。

text
https://www.setherion.com/oauth/authorize
  ?response_type=code
  &client_id=5f0c2a9d-4e30-4d7f-b8a5-6f1c2a9d4e30
  &redirect_uri=http%3A%2F%2Flocalhost%3A8787%2Fcallback
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256
  &state=af0ifjsldkj
  &resource=https%3A%2F%2Fwww.setherion.com%2Fapi%2Fmcp
参数含义
response_type必填。code。
client_id必填。来自注册。
redirect_uri已注册地址之一,要求完全匹配。只有在你恰好注册了一个地址时才可以省略。
code_challenge必填。你的验证器的 S256 哈希值,使用 base64url 编码,43 到 128 个字符。
code_challenge_method必填。S256。不接受 plain。
state建议填写。会原样返回。最多 1,000 个字符。
resource可选。如果发送,它必须是 https://www.setherion.com/api/mcp(末尾的斜杠以及协议和主机名的大小写不影响)。

验证器使用 A-Z a-z 0-9 - . _ ~ 中的 43 到 128 个字符,并保留到第 4 步。

用户会被送回你的 redirect_uri,并带有:

  • 点击 Allow 时:code、state 和 iss(签发方);
  • 点击 Cancel 时:error=access_denied、error_description=The request was declined.、state 和 iss;
  • 请求有问题时,只要已确认客户端和地址是真实的:error、error_description、state 和 iss。error 是 unsupported_response_type、invalid_request(缺少 PKCE,或方法不是 S256)或 invalid_target(资源不是 MCP 端点)。

如果客户端未知,或者地址不是它注册过的,页面会把这一点告诉用户,并且不会把任何人送去任何地方,所以这个页面永远不能被用来把某人重定向到你没有注册的地址。

4. 交换授权码

POSThttps://www.setherion.com/api/oauth/token

套餐: 所有套餐

按 OAuth 的规定发送表单编码的字段。使用相同名称的 JSON 也可以接受。

bash
curl -X POST https://www.setherion.com/api/oauth/token \
  -d grant_type=authorization_code \
  -d code=stc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
  -d client_id=5f0c2a9d-4e30-4d7f-b8a5-6f1c2a9d4e30 \
  -d redirect_uri=http://localhost:8787/callback \
  -d code_verifier=YOUR_VERIFIER
字段含义
grant_typeauthorization_code。
code重定向中带回的授权码。
client_id授权码签发给的客户端。
redirect_uri与第 3 步中相同的地址。
code_verifier其 S256 哈希值已作为 code_challenge 发送的验证器。
resource可选。如果发送,它必须与授权码的资源一致。
json
{
  "access_token": "sto_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "str_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "scope": "mcp"
}

以 Authorization: Bearer sto_... 的形式把访问令牌发送给 MCP 服务器。令牌绝不会被缓存:响应带有 Cache-Control: no-store。

5. 刷新

访问令牌的有效期是一小时。在它到期之前,或者 MCP 服务器返回 401 时,用刷新令牌来交换:

bash
curl -X POST https://www.setherion.com/api/oauth/token \
  -d grant_type=refresh_token \
  -d refresh_token=str_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
  -d client_id=5f0c2a9d-4e30-4d7f-b8a5-6f1c2a9d4e30

响应与第 4 步相同,但带有一个新的刷新令牌。旧的会失效,所以每次都要保存新的。

重复使用刷新令牌会终止连接

第二次使用同一个刷新令牌会被视为令牌副本被盗,Setherion 会终止整个连接:来自那次授权同意的每个令牌都会失效,用户必须再次点击 Allow。唯一的例外是同一个客户端在连接仍然有效的情况下,60 秒内出示同一个令牌,这就是同一个助手的两个进程(例如两个窗口)可以同时刷新的原因。授权码被使用两次,也会以同样的方式终止其连接。

错误

令牌端点的每个错误状态码都是 400,server_error 除外,响应体为 { "error": "...", "error_description": "..." }。

令牌错误
errorerror_description
unsupported_grant_typeUse authorization_code or refresh_token.
invalid_grantUnknown code.
invalid_grantThis code was already used.
invalid_grantThis code has expired.
invalid_grantThis code was issued to another application.
invalid_grantredirect_uri does not match the one the code was issued for.
invalid_grantPKCE verification failed.
invalid_grantUnknown refresh token.
invalid_grantThis refresh token has expired.
invalid_grantThis token was issued to another application.
invalid_grantThis refresh token was already used. The connection has been ended for safety.
invalid_targetThis code was issued for another resource. 或 This token was issued for another resource.
server_error(状态码 500)Not configured. 或 Could not issue tokens.

结束连接

用户可以在 Settings,然后 AI assistants and MCP 中断开某个助手。该连接的每个令牌,无论是访问令牌还是刷新令牌,都会在下一个请求时立即失效,而不是等到一小时结束。列出和结束连接只能在已登录的 Setherion 会话中进行,所以助手持有的任何内容都无法做到这一点。

改用 API 密钥

如果客户端只能发送固定的请求头,可以跳过以上所有步骤,直接向 MCP 服务器发送 API 密钥。见身份验证。

这个页面对你有帮助吗?

加入社区

提问、交流想法,看看别人在构建什么。