MCP Telegram
返回 Quickstart

面向自定义 MCP 客户端的 OAuth

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

我们实现的标准

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

端点

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 请求来终止一个会话。

常见错误

/oauth/authorize 返回 HTTP 400 "Invalid redirect_uri"

redirect_uri 查询参数与此 client_id 注册的任何 URI 都不匹配。对于 loopback 客户端:检查 scheme + host + path + query 是否完全一致(只有端口是灵活的)。对于 HTTPS 客户端:需要完整的逐字节相等 — 注意尾部斜杠和 URL 编码差异。

HTTP 400 "Unknown client"

client_id 在我们的数据库中不存在。可能是你跳过了 /oauth/register 步骤,或者注册响应在你保存 client_id 之前就丢失了,又或者用户通过 /my/clients 撤销了该客户端。

客户端反复提示 "Needs Auth"

如果你的客户端持久化了 access_token 但没有持久化 refresh_token,那么 access_token 过期时就会出现这种情况。我们的 access token 之所以使用 10 年的 TTL,就是为了缓解这个问题;但如果你的客户端自己在更短的窗口内让令牌过期,你就需要持久化 refresh_token,或在需要时调用 /oauth/revoke + 重新认证。

已测试的客户端

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

在一个 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。