커스텀 MCP 클라이언트를 위한 OAuth
자체 MCP 클라이언트(CLI, SDK, IDE 플러그인)를 만들고 있다면, 이 페이지는 우리의 OAuth 구현을 설명합니다: 지원하는 표준, 엔드포인트, redirect_uri 규칙, 그리고 일반적인 오류 디버깅 방법입니다. Claude.ai와 ChatGPT 사용자에게는 이 페이지가 필요하지 않습니다 — 대신 Quickstart를 사용하세요.
우리가 구현하는 표준
mcp-telegram.com은 MCP 생태계가 의존하는 OAuth 사양을 완벽히 준수합니다 — 독점 확장도 없고, 클라이언트에 박혀 있는 공유 시크릿도 없습니다.
엔드포인트
PKCE를 사용한 authorization code 플로우
표준 RFC 6749 §4.1 + RFC 7636 플로우입니다. 깜짝 놀랄 일은 없습니다 — 여러분의 OAuth 라이브러리가 "authorization code + PKCE"를 처리할 수 있다면 그대로 작동합니다.
클라이언트 등록하기
POST /oauth/register에 { redirect_uris: ["http://127.0.0.1:«port»/callback"], client_name: "your-client-name" }을 전송합니다. 서버는 client_id와 client_secret을 반환합니다 (시크릿은 퍼블릭 PKCE 클라이언트에는 선택 사항이지만 받아도 무방합니다).
PKCE 쌍 생성하기
43–128자의 랜덤한 code_verifier를 생성한 다음, code_challenge = BASE64URL(SHA256(code_verifier))를 계산합니다. verifier는 4단계를 위해 로컬에 저장하세요.
브라우저에서 /oauth/authorize 열기
사용자를 /oauth/authorize?response_type=code&client_id=...&redirect_uri=...&state=...&code_challenge=...&code_challenge_method=S256로 리다이렉트합니다. 서버는 QR 코드를 표시하며, 사용자가 Telegram 앱에서 스캔하여 인증합니다.
authorization code 받기
QR 스캔 후 서버는 ?code=...&state=...과 함께 여러분의 redirect_uri로 리다이렉트합니다. state 파라미터가 보낸 값과 일치하는지 확인하세요.
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가 정확히 일치해야 합니다 — 단 포트는 달라도 됩니다. 네이티브 클라이언트는 실행마다 바뀔 수 있는 OS 할당 임시 포트에 바인드하기 때문에, 이는 RFC 8252 §7.3에서 요구하는 사항입니다.
- 등록된 http://127.0.0.1:36201/callback은 authorize 시점의 http://127.0.0.1:50000/callback과 일치합니다 ✅
- 등록된 http://127.0.0.1:36201/callback은 http://127.0.0.1:50000/different-path와는 일치하지 않습니다 — path는 정확히 일치해야 합니다
- 등록된 http://[::1]:36201/cb는 http://127.0.0.1:36201/cb와는 일치하지 않습니다 — IPv4와 IPv6 loopback은 별개의 식별자입니다
HTTPS (https://your-domain.example/...)
path, query, 포트를 포함해 바이트 단위로 정확한 일치가 필요합니다 (RFC 6749 §3.1.2). 유연성은 없습니다.
localhost (권장하지 않음)
우리는 http://localhost를 일반 호스트명으로 취급합니다 — 정확한 일치가 필요하며, 포트 유연성은 없습니다. RFC 8252 §8.3에서는 DNS 해석이 구현에 의존하기 때문에 localhost 대신 IP 리터럴 (127.0.0.1 / [::1])을 사용할 것을 권장합니다.
일반적인 오류
테스트된 클라이언트
우리 서버와의 상호 운용성이 확인되었습니다. 새로운 것을 만들어서 작동한다면, PR을 보내서 여기에 추가해 주세요.
하나의 OAuth 연결로 여러 Telegram 계정 관리
v2.32.0부터 하나의 OAuth 연결로 여러 Telegram 아이덴티티를 보유하고 단일 도구 호출로 전환할 수 있습니다. Disconnect/Connect 사이클이나 새로운 클라이언트 등록이 필요하지 않습니다.
연결된 계정 확인하기
telegram-accounts-list를 호출합니다. 프라이머리(OAuth에 바인딩된) 계정이 활성 상태인 경우 ⭐ 표시와 함께 표시되며, 추가한 세컨더리 계정도 함께 표시됩니다.
다른 계정 추가하기
telegram-accounts-add를 호출하며, 선택적으로 라벨(예: "testing")을 지정할 수 있습니다. 도구는 일회용 URL(TTL 10분)을 반환하므로, 원하는 디바이스에서 열어 추가하려는 Telegram 계정으로 QR을 스캔하십시오.
활성 계정 전환하기
telegram-accounts-switch를 identifier=label, @username, account_id 또는 'primary'와 함께 호출합니다. 다음 telegram-* 도구 호출부터 해당 계정이 즉시 사용됩니다. 재연결은 필요하지 않습니다.
세컨더리 계정 분리하기
세컨더리 계정에 대해 telegram-accounts-remove identifier=…를 호출합니다. Telegram 계정 자체는 로그아웃되지 않으며, 여기서의 바인딩만 해제됩니다. 프라이머리는 이 방법으로 제거할 수 없습니다. 완전히 로그아웃하려면 클라이언트의 Disconnect 흐름을 사용하십시오.
각 OAuth 연결은 격리되어 있습니다. Hermes를 통해 추가한 계정은 동일한 Telegram 아이덴티티라도 Claude.ai나 ChatGPT에서는 보이지 않습니다. 서로 다른 MCP 클라이언트에 서로 다른 계정을 연결하려면 각 클라이언트를 개별적으로 등록하고 해당 세션 내에서 telegram-accounts-add를 사용하십시오.