Quay lại Quickstart

OAuth cho MCP client tùy chỉnh

Nếu bạn đang xây dựng MCP client của riêng mình (CLI, SDK, plugin IDE), trang này mô tả cách triển khai OAuth của chúng tôi: các tiêu chuẩn được hỗ trợ, các endpoint, quy tắc redirect_uri và cách debug các lỗi thường gặp. Người dùng Claude.ai và ChatGPT không cần trang này — hãy dùng Quickstart.

Các tiêu chuẩn chúng tôi triển khai

mcp-telegram.com tuân thủ đầy đủ các đặc tả OAuth mà hệ sinh thái MCP dựa vào — không có phần mở rộng độc quyền, không có shared secret nhúng vào client.

RFC 6749OAuth 2.0 Authorization Framework — authorization code grant cơ bản kèm refresh token
RFC 7591Dynamic Client Registration — bất kỳ client nào cũng có thể tự đăng ký tại /oauth/register mà không cần thỏa thuận trước
RFC 7636PKCE (Proof Key for Code Exchange) — challenge S256 là bắt buộc với public client
RFC 8252OAuth 2.0 for Native Apps — redirect URI loopback IP với độ linh hoạt cho port ephemeral
RFC 8414OAuth 2.0 Authorization Server Metadata — tài liệu discovery tại /.well-known/oauth-authorization-server
RFC 9728OAuth 2.0 Protected Resource Metadata — discovery ranh giới của MCP resource

Các endpoint

Metadata của authorization server (RFC 8414)
Dynamic client registration (RFC 7591)
Authorization endpoint
Token endpoint
MCP resource (Streamable HTTP)

Authorization code flow với PKCE

Flow chuẩn RFC 6749 §4.1 + RFC 7636. Không có gì bất ngờ — nếu thư viện OAuth của bạn xử lý được "authorization code + PKCE" thì nó sẽ chạy.

1

Đăng ký client của bạn

POST /oauth/register với { redirect_uris: ["http://127.0.0.1:«port»/callback"], client_name: "tên-client-của-bạn" }. Server trả về client_id + client_secret (secret là tùy chọn với public PKCE client nhưng nhận được cũng không sao).

2

Tạo cặp PKCE

Tạo một code_verifier ngẫu nhiên dài 43–128 ký tự, sau đó tính code_challenge = BASE64URL(SHA256(code_verifier)). Lưu verifier ở local để dùng cho bước 4.

3

Mở /oauth/authorize trong trình duyệt

Redirect người dùng đến /oauth/authorize?response_type=code&client_id=...&redirect_uri=...&state=...&code_challenge=...&code_challenge_method=S256. Server sẽ hiển thị mã QR; người dùng quét nó trong ứng dụng Telegram để xác thực.

4

Nhận authorization code

Sau khi quét QR, server redirect về redirect_uri của bạn với ?code=...&state=.... Hãy kiểm tra tham số state trùng khớp với giá trị bạn đã gửi đi.

5

Đổi code lấy token

POST /oauth/token với grant_type=authorization_code, code, redirect_uri, code_verifier, client_id. Bạn nhận được access_token (TTL 10 năm — xem Token Lifetime bên dưới) và refresh_token. Dùng access_token làm Authorization: Bearer ... trên các request tới /mcp.

Quy tắc matching redirect_uri

Chúng tôi tuân thủ nghiêm ngặt RFC 8252 §7.3 và §8.4. Thuật toán matching phụ thuộc vào việc URI đã đăng ký có phải là literal IP loopback hay không.

Loopback (http://127.0.0.1 hoặc http://[::1])

Nếu bạn đăng ký URI loopback, redirect_uri tại thời điểm authorize phải khớp chính xác về scheme, host, path và query — nhưng port có thể khác. RFC 8252 §7.3 yêu cầu điều này vì native client gắn vào một port ephemeral do OS cấp, có thể thay đổi giữa các lần chạy.

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

Yêu cầu khớp chính xác từng byte, bao gồm path, query và port (RFC 6749 §3.1.2). Không có độ linh hoạt.

localhost (KHÔNG khuyến khích)

Chúng tôi coi http://localhost như một hostname thông thường — yêu cầu khớp chính xác, không có độ linh hoạt cho port. RFC 8252 §8.3 khuyến nghị dùng literal IP (127.0.0.1 / [::1]) thay vì localhost vì việc phân giải DNS phụ thuộc vào cách triển khai.

PKCE là bắt buộccode_challenge_method=S256 là bắt buộc trong mọi authorize request. Method plain bị từ chối. Nếu bạn bỏ qua hoàn toàn code_challenge, bước trao đổi /token sẽ thất bại tại bước xác minh code_verifier.
Thời gian sống của tokenTTL của access_token được đặt dài có chủ ý (10 năm) vì một số MCP client không lưu refresh_token một cách đáng tin cậy. refresh_token vẫn được phát hành và xoay vòng sau mỗi lần refresh (RFC 6819 §5.2.2.3). Người dùng có thể thu hồi toàn bộ token bất cứ lúc nào tại /my/sessions hoặc bằng cách đăng xuất khỏi Telegram. Người dùng cũng có thể POST tường minh tới /oauth/revoke (RFC 7009) để kết thúc một session.

Các lỗi thường gặp

Các client đã kiểm thử

Đã xác nhận tương thích với server của chúng tôi. Nếu bạn xây dựng cái gì đó mới và nó hoạt động, hãy gửi PR để bổ sung vào danh sách này.

Claude.ai web — qua MCP connector tích hợp sẵn
ChatGPT Apps — qua MCP connector tích hợp sẵn
Hermes Agent — CLI MCP client mã nguồn mở (RFC 8252 loopback flow)
Cursor MCP — plugin IDE (RFC 8252 loopback flow)
Bất kỳ client nào tuân thủ RFC 6749 + RFC 7591 + RFC 7636 + RFC 8252 đều có thể hoạt động mà không cần thay đổi code ở phía chúng tôi.

Nhiều tài khoản Telegram trên một kết nối OAuth

Kể từ v2.32.0, một kết nối OAuth có thể giữ nhiều danh tính Telegram và chuyển đổi giữa chúng chỉ bằng một lệnh gọi tool — không cần chu kỳ Disconnect/Connect, không cần đăng ký client mới.

1

Liệt kê các tài khoản đã gắn

Gọi telegram-accounts-list. Bạn sẽ thấy tài khoản primary (đã gắn OAuth) được đánh dấu bằng ⭐ nếu nó đang hoạt động, cùng với mọi tài khoản phụ mà bạn đã thêm.

2

Gắn thêm một tài khoản

Gọi telegram-accounts-add với một label tùy chọn (ví dụ "testing"). Tool trả về một URL dùng một lần (TTL 10 phút) — mở URL đó trên thiết bị bất kỳ và quét mã QR bằng tài khoản Telegram mà bạn muốn thêm.

3

Chuyển tài khoản đang hoạt động

Gọi telegram-accounts-switch với identifier=label, @username, account_id, hoặc 'primary'. Lệnh gọi tool telegram-* tiếp theo sẽ sử dụng tài khoản đó ngay lập tức. Không cần reconnect.

4

Gỡ một tài khoản phụ

Gọi telegram-accounts-remove identifier=… trên một tài khoản phụ. Bản thân tài khoản Telegram KHÔNG bị đăng xuất — chỉ liên kết tại đây bị gỡ bỏ. Tài khoản primary không thể gỡ theo cách này; hãy sử dụng luồng Disconnect của client để đăng xuất hoàn toàn.

Mỗi kết nối OAuth được cô lập: các tài khoản bạn gắn qua Hermes sẽ không nhìn thấy được từ Claude.ai hay ChatGPT, ngay cả khi đó là cùng một danh tính Telegram. Để kết nối các tài khoản khác nhau với các MCP client khác nhau, hãy đăng ký từng client riêng biệt và sử dụng telegram-accounts-add bên trong session của chính nó.