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의 discovery 문서
RFC 9728OAuth 2.0 Protected Resource Metadata — MCP 리소스 경계의 discovery

엔드포인트

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로 리다이렉트합니다. 서버는 QR 코드를 표시하며, 사용자가 Telegram 앱에서 스캔하여 인증합니다.

4

authorization code 받기

QR 스캔 후 서버는 ?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가 정확히 일치해야 합니다 — 단 포트는 달라도 됩니다. 네이티브 클라이언트는 실행마다 바뀔 수 있는 OS 할당 임시 포트에 바인드하기 때문에, 이는 RFC 8252 §7.3에서 요구하는 사항입니다.

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])을 사용할 것을 권장합니다.

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에서 로그아웃할 수 있습니다. 또한 명시적으로 POST /oauth/revoke (RFC 7009)를 호출하여 세션을 종료할 수도 있습니다.

일반적인 오류

테스트된 클라이언트

우리 서버와의 상호 운용성이 확인되었습니다. 새로운 것을 만들어서 작동한다면, 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를 호출합니다. 프라이머리(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 계정 자체는 로그아웃되지 않으며, 여기서의 바인딩만 해제됩니다. 프라이머리는 이 방법으로 제거할 수 없습니다. 완전히 로그아웃하려면 클라이언트의 Disconnect 흐름을 사용하십시오.

각 OAuth 연결은 격리되어 있습니다. Hermes를 통해 추가한 계정은 동일한 Telegram 아이덴티티라도 Claude.ai나 ChatGPT에서는 보이지 않습니다. 서로 다른 MCP 클라이언트에 서로 다른 계정을 연결하려면 각 클라이언트를 개별적으로 등록하고 해당 세션 내에서 telegram-accounts-add를 사용하십시오.