MCP Telegram
Quickstart に戻る

カスタム MCP クライアント向け OAuth

自前の MCP クライアント(CLI、SDK、IDE プラグイン)を開発している場合、このページでは私たちの OAuth 実装について説明します。サポートする標準、エンドポイント、redirect_uri のルール、よくあるエラーのデバッグ方法を解説します。Claude.ai や ChatGPT のユーザーにはこのページは不要です — 代わりに Quickstart をご覧ください。

実装している標準

mcp-telegram.com は MCP エコシステムが依存する OAuth 仕様に完全準拠しています — 独自拡張も、クライアントに埋め込まれた共有シークレットもありません。

エンドポイント

Authorization server メタデータ (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 リテラルかどうかに依存します。

ループバック (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_token はこれを緩和するために特別に TTL 10 年に設定されていますが、クライアント側でより短い期間でトークンを期限切れにする場合は、refresh_token を永続化するか、必要に応じて /oauth/revoke + 再認証を呼び出す必要があります。

テスト済みクライアント

サーバーとの相互運用が確認されています。新しいものを構築して動作したら、PR を送ってここに追加してください。

1 つの OAuth 接続で複数の Telegram アカウントを管理

v2.32.0 以降、1 つの OAuth 接続で複数の Telegram アイデンティティを保持し、ツール呼び出し 1 回で切り替えられるようになりました。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 を使用してください。