返回 Quickstart

面向自定义 MCP 客户端的 OAuth

如果你正在开发自己的 MCP 客户端(CLI、SDK、IDE 插件),本页将介绍我们的 OAuth 实现:我们支持的标准、各个端点、redirect_uri 规则,以及如何调试常见错误。Claude.ai 和 ChatGPT 用户不需要这页 — 请改用 Quickstart。

我们实现的标准

mcp-telegram.com 完全符合 MCP 生态系统所依赖的 OAuth 规范 — 没有专有扩展,也没有写死在客户端中的共享密钥。

RFC 6749OAuth 2.0 Authorization Framework — 带 refresh 令牌的基础 authorization code grant
RFC 7591Dynamic Client Registration — 任何客户端都可以通过 /oauth/register 自行注册,无需事先协调
RFC 7636PKCE (Proof Key for Code Exchange) — 公共客户端必须使用 S256 challenge
RFC 8252OAuth 2.0 for Native Apps — 支持临时端口灵活性的 loopback IP redirect URI
RFC 8414OAuth 2.0 Authorization Server Metadata — 位于 /.well-known/oauth-authorization-server 的发现文档
RFC 9728OAuth 2.0 Protected Resource Metadata — MCP 资源边界的发现

端点

Authorization 服务器元数据 (RFC 8414)
动态客户端注册 (RFC 7591)
Authorization 端点
Token 端点
MCP 资源 (Streamable HTTP)

使用 PKCE 的 authorization code 流程

标准的 RFC 6749 §4.1 + RFC 7636 流程。没有意外 — 如果你的 OAuth 库能处理"authorization code + PKCE",它就能正常工作。

1

注册你的客户端

向 POST /oauth/register 发送 { redirect_uris: ["http://127.0.0.1:«port»/callback"], client_name: "your-client-name" }。服务器返回 client_id 和 client_secret (对公共 PKCE 客户端来说密钥是可选的,但收到也无妨)。

2

生成 PKCE 对

生成一个 43–128 字符的随机 code_verifier,然后计算 code_challenge = BASE64URL(SHA256(code_verifier))。把 verifier 保存在本地,供第 4 步使用。

3

在浏览器中打开 /oauth/authorize

将用户重定向到 /oauth/authorize?response_type=code&client_id=...&redirect_uri=...&state=...&code_challenge=...&code_challenge_method=S256。服务器会显示一个二维码;用户在 Telegram 应用中扫描以完成认证。

4

接收 authorization code

扫描二维码后,服务器会带着 ?code=...&state=... 重定向到你的 redirect_uri。请验证 state 参数与你发出的值一致。

5

用 code 交换令牌

向 POST /oauth/token 发送 grant_type=authorization_code、code、redirect_uri、code_verifier、client_id。你将收到一个 access_token(TTL 为 10 年 — 见下面的 Token Lifetime)和一个 refresh_token。在 /mcp 请求中将 access_token 用作 Authorization: Bearer ...。

redirect_uri 匹配规则

我们严格遵循 RFC 8252 §7.3 和 §8.4。匹配算法取决于注册的 URI 是否为 loopback IP 字面量。

Loopback (http://127.0.0.1 或 http://[::1])

如果你注册的是 loopback URI,那么 authorize 时的 redirect_uri 在 scheme、host、path 和 query 上必须完全匹配 — 但端口可以不同。RFC 8252 §7.3 要求如此,因为原生客户端绑定的是操作系统分配的临时端口,在不同的运行之间可能会变化。

HTTPS (https://your-domain.example/...)

必须做到逐字节完全匹配,包括 path、query 和端口 (RFC 6749 §3.1.2)。没有任何灵活性。

localhost (不推荐)

我们把 http://localhost 当作普通主机名处理 — 必须完全匹配,端口也不能灵活。RFC 8252 §8.3 建议使用 IP 字面量 (127.0.0.1 / [::1]) 而不是 localhost,因为 DNS 解析的行为依赖于具体实现。

PKCE 是必需的每个 authorize 请求都必须带 code_challenge_method=S256。Plain method 会被拒绝。如果你完全跳过 code_challenge,/token 交换将在 code_verifier 校验时失败。
令牌生命周期access_token 的 TTL 有意设置得很长(10 年),因为有些 MCP 客户端不能可靠地持久化 refresh_token。即便如此,refresh_token 仍然会被签发,并在每次 refresh 时轮转 (RFC 6819 §5.2.2.3)。用户可以随时在 /my/sessions 撤销所有令牌,或通过退出 Telegram 来撤销。用户也可以显式向 /oauth/revoke (RFC 7009) 发起 POST 请求来终止一个会话。

常见错误

已测试的客户端

确认可与我们的服务器互操作。如果你做了新东西并且能跑通,请发 PR 把它加进来。

Claude.ai web — 通过内置的 MCP connector
ChatGPT Apps — 通过内置的 MCP connector
Hermes Agent — 开源 CLI MCP 客户端 (RFC 8252 loopback flow)
Cursor MCP — IDE 插件 (RFC 8252 loopback flow)
任何符合 RFC 6749 + RFC 7591 + RFC 7636 + RFC 8252 的客户端都应该可以在不修改我们这端代码的情况下正常工作。

在一个 OAuth 连接中管理多个 Telegram 账号

自 v2.32.0 起,单个 OAuth 连接可以同时持有多个 Telegram 身份,并通过一次工具调用在它们之间切换——无需 Disconnect/Connect 循环,也无需重新注册客户端。

1

查看已连接的账号

调用 telegram-accounts-list。如果您的 primary(绑定到 OAuth 的)账号处于活动状态,将带有 ⭐ 标记显示,同时也会列出您添加的所有副账号。

2

添加另一个账号

调用 telegram-accounts-add,可选传入标签(例如 "testing")。该工具会返回一个一次性 URL(TTL 10 分钟)——在任意设备上打开它,并使用您想添加的 Telegram 账号扫描 QR 码。

3

切换活动账号

调用 telegram-accounts-switch,identifier 可为 label、@username、account_id 或 'primary'。下一次 telegram-* 工具调用将立即使用该账号。无需重新连接。

4

分离副账号

对副账号调用 telegram-accounts-remove identifier=…。Telegram 账号本身不会被登出——仅解除此处的绑定。primary 无法通过此方式移除;如需完全登出,请使用客户端的 Disconnect 流程。

每个 OAuth 连接都是隔离的:您通过 Hermes 添加的账号在 Claude.ai 或 ChatGPT 中是不可见的,即使它们是同一个 Telegram 身份。若要将不同账号连接到不同的 MCP 客户端,请分别注册每个客户端,并在各自的会话中使用 telegram-accounts-add。