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로 리다이렉트합니다. 서버는 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)를 호출하여 세션을 종료할 수도 있습니다.

일반적인 오류

/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 토큰은 이를 완화하기 위해 특별히 10년 TTL을 갖지만, 클라이언트가 더 짧은 기간에 토큰을 만료시킨다면 refresh_token을 유지하거나 필요할 때 /oauth/revoke + 재인증을 호출해야 합니다.

테스트된 클라이언트

우리 서버와의 상호 운용성이 확인되었습니다. 새로운 것을 만들어서 작동한다면, PR을 보내서 여기에 추가해 주세요.

하나의 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를 사용하십시오.