Open in
OAuth で接続
API キーを共有せずに、MCP クライアントと ThunderPhone CLI を認可します。
OAuth を使用すると、承認した権限でアプリを 1 つの ThunderPhone 組織に接続できます。ディレクトリクライアントでは、デフォルトで OAuth を使用してください。手動で設定する Bearer トークンが必要なクライアント向けには、組織 API キーも引き続き利用できます。
接続を承認する
MCP クライアントで接続を開始します。ThunderPhone にログインし、アプリ名と要求された権限を確認して、組織を選択し、承認を選択します。接続を開始していない場合やアプリを信頼できない場合は、拒否を選択します。アプリ名は開発者によって提供されるものであり、認証バッジではありません。
読み取り権限では、calls:read が要求された場合の録音や文字起こしを含め、指定されたデータにアクセスできます。書き込み権限ではリソースを変更または削除できます。通話、キャンペーン、電話番号の購入、デプロイは、費用の発生や本番環境への影響を伴う可能性があります。組織でのロールも引き続き適用されます。
CLI 接続では、ターミナルに表示される認証リンクを開き、8 文字のコードを照合して、組織を選択し、承認します。リンクを開くだけではアクセスは付与されません。コードは 15 分後に失効します。
アプリの接続を解除する
ダッシュボードで 組織 → API キー → 承認済みアプリ を開き、取り消すを選択します。これにより、アクセス トークンと更新トークンを含む、現在の組織に対する選択した認可が取り消されます。再度認可する場合は、アプリから再接続してください。
MCP クライアント向けディスカバリー
サーバー URL https://api.thunderphone.com/v1/mcp を使用します。有効な認証なしのリクエストは、次の内容で 401 を受け取ります。
WWW-Authenticate: Bearer resource_metadata="https://api.thunderphone.com/.well-known/oauth-protected-resource"このドキュメントを取得してから、https://api.thunderphone.com/.well-known/oauth-authorization-server にある認可サーバーのメタデータを取得します。リソースメタデータは /.well-known/oauth-protected-resource/v1/mcp でも利用できます。エンドポイントを組み立てるのではなく、返されたエンドポイントを使用してください。リソース識別子は https://api.thunderphone.com/v1/mcp です。
サーバーは S256 PKCE を使用した認可コード、ローテーションするリフレッシュトークン、公開動的クライアント登録、失効、およびデバイス認可グラントをサポートします。クライアントシークレットおよび暗黙的グラントはありません。OpenID ディスカバリーは /.well-known/openid-configuration でも利用でき、同じ認可サーバーフィールドに加えて subject_types_supported: ["public"] と userinfo エンドポイントを含みます。ID トークンおよびクライアント ID メタデータドキュメント(CIMD)はサポートされません。
公開クライアントを登録する
JSON を POST /v1/oauth/register に送信します。
{
"client_name": "My MCP client",
"redirect_uris": ["http://127.0.0.1:8765/callback"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"]
}返された client_id を保存します。リダイレクトには HTTPS、または 127.0.0.1 か localhost 上の HTTP を使用する必要があります。ポートとパスを含む正確なコールバック URI を登録してください。フラグメントおよび埋め込み認証情報は拒否されます。任意の client_uri および logo_uri には HTTPS を使用する必要があります。ThunderPhone は登録時にこれらを取得しません。登録にはレート制限があります。登録済みクライアントは期限切れにならず、接続が失効しても登録されたままです。HTTPS コールバックには https://chatgpt.com/connector/oauth/<id> および https://chatgpt.com/connector_platform_oauth_redirect が含まれます。各接続で独自のクライアントを登録できます。
認可コード
検出された認可エンドポイントを、client_id、正確に登録された redirect_uri、response_type=code、ランダムな state、scope、code_challenge、code_challenge_method=S256、および resource=https://api.thunderphone.com/v1/mcp を指定して開きます。新しく生成した高エントロピーの PKCE ベリファイアの、パディングなし base64url SHA-256 ダイジェストとしてチャレンジを計算します。コードを交換する前に、返された state と iss を確認してください。拒否およびプロトコルエラーを含むすべての認可レスポンスは、検出された issuer と完全に一致する iss で発行者を識別します。無効なクライアントまたはコールバックに対するエラーは、そのコールバックにリダイレクトせずローカルで返されます。
フォームエンコーディングを使用して POST /v1/oauth/token で交換します(JSON も受け付けます)。
grant_type=authorization_code
client_id=<your client id>
code=<single-use authorization code>
redirect_uri=<exact registered redirect URI>
code_verifier=<original PKCE verifier>
resource=https://api.thunderphone.com/v1/mcp任意の resource パラメータは、認可リクエストとトークンリクエストの両方で受け付けられます(リフレッシュおよびデバイス交換を含む)。省略した場合、検出された MCP リソースがデフォルトになります。指定する場合は、そのリソースと完全に一致する必要があります。それ以外の値は invalid_target を返します。アクセストークンにはそのオーディエンスが含まれ、MCP はオーディエンスがない、または異なるトークンをディスカバリーチャレンジ付きの 401 で拒否します。
認可リクエストとコードは 10 分後に期限切れになります。すべてのトークンレスポンスには、access_token、token_type(Bearer)、expires_in(デフォルトで 3600 秒)、refresh_token、scope、organization_id、および organization_name が含まれます。アクセストークンは Authorization: Bearer ヘッダーを通じてのみ送信してください。トークンを URL、ログ、ソース管理、またはチャットに置かないでください。
リフレッシュと失効
トークンエンドポイントで、grant_type=refresh_token、client_id、refresh_token、および resource を使用してリフレッシュします。新しいリフレッシュトークンをアトミックに保存し、古いトークンの使用を停止してください。リフレッシュトークンは、正常なリフレッシュがない状態で 30 日後に期限切れになります。任意の scope で付与された権限を制限できます。offline_access は常に含まれ、リフレッシュトークンは常に発行されます。scope のない初回リクエストでは offline_access のみが付与されるため、クライアントは必要な権限をリクエストする必要があります。
コードの再利用およびローテーション済みリフレッシュトークンの再利用により、認可全体が失効します。クライアント内のリフレッシュは直列化してください。正常に交換された認証情報の再送は、安全な再試行方法ではありません。
切断するには、token と client_id を POST /v1/oauth/revoke に送信します。いずれかのトークンを失効すると、そこから発行されたすべてのトークンを含む認可が失効します。不明なトークンは、存在するかどうかを開示せずに成功を返します。ダッシュボードセッションでは、GET /v1/oauth/grants で自身の認可を一覧表示し、DELETE /v1/oauth/grants/<id> で認可を失効できます。X-ThunderPhone-Org で組織を選択します。
デバイス認可
デバイス認可は事前登録済みクライアントに限定されます。動的に登録されたクライアントは unauthorized_client を受け取ります。事前登録済みの公開クライアント thunderphone-cli は、デバイス認可とリフレッシュをサポートします。client_id=thunderphone-cli と scope を POST /v1/oauth/device/code に送信します。user_code と verification_uri をユーザーに表示するか、verification_uri_complete を開きます。
grant_type=urn:ietf:params:oauth:grant-type:device_code、client_id、および device_code を使用してトークンエンドポイントをポーリングし、返された interval(5 秒)以上待機します。authorization_pending では継続します。slow_down では、以降のすべてのリクエストに対して、レスポンスで返された新しい interval(5 秒増加)を使用します。access_denied、expired_token、またはその他のエラーで停止します。デバイスコードを自動承認しないでください。
事前登録済みの thunderphone-mcp クライアントは、任意のポートの http://127.0.0.1/callback および http://localhost/callback を受け付けます。スキーム、ホスト、パス、クエリは一致する必要があります。トークン交換では、認可で使用した正確なリダイレクト URI(ポートを含む)を使用する必要があります。動的に登録されたクライアントでは、ポートを含む正確なリダイレクト URI の一致が必要です。別のパスが必要な場合は、異なるコールバックを動的に登録してください。
アカウント ID とワークスペースドメインの確認
クライアントに必要な操作スコープとともに、openid email の両方をリクエストします。Bearer ヘッダー内のアクセストークンを使用して、検出された userinfo_endpoint(GET /v1/oauth/userinfo)を呼び出します。成功レスポンスには次が含まれます。
{
"sub": "123",
"email": "person@example.com",
"email_verified": true,
"name": "Example User",
"org_id": 456
}sub は安定したユーザー識別子であり、org_id は同意中に選択された組織です。このエンドポイントには両方の ID スコープが必要で、いずれかが欠けている場合は 403 を返します。アカウントに確認済みメールプロファイルがない場合は、未確認メールが信頼されていると主張するのではなく、error=access_denied を含む 403 を返します。無効、期限切れ、失効済み、またはオーディエンスが異なるトークンは 401 を返します。ユーザーセッショントークンおよび組織 API キーでは userinfo を呼び出せません。ID トークンは発行されません。
利用可能な権限
| ファミリー | スコープ |
|---|---|
| エージェントとエージェントのインポート | agents:read, agents:write |
| 通話 | calls:read, calls:write |
| 電話番号、ブロックされた発信者、VoIP | numbers:read, numbers:write |
| ナレッジ | knowledge:read, knowledge:write |
| キャンペーン | campaigns:read, campaigns:write |
| 連携、Webhook エンドポイント、MCP サーバー | integrations:read, integrations:write |
| 音声 | voices:read |
| テストシナリオ、テスト実行、検証 | testing:read, testing:write |
| 請求 | billing:read |
| アカウント ID と確認済みメールアドレス | openid, email(userinfo には両方必須) |
| 永続的な接続 | offline_access(常に含まれる) |
GET、HEAD、OPTIONSは読み取りスコープを使用し、その他のメソッドは書き込みスコープを使用します。音声および請求の変更操作はOAuthでは利用できません。POST /v1/voices/preview は設定を変更せずに音声をプレビューするため、voices:read を使用します。MCPツールは、基盤となるREST操作のスコープを適用します。認可するユーザーが両方の組織に所属している場合でも、組織間の移行は拒否されます。APIキー管理や人間のアカウント設定を含むその他のAPIファミリーは、OAuthでは利用できません。REST操作で権限が不足している場合は、WWW-Authenticate: Bearer error="insufficient_scope", scope="..." とともに 403 が返されます。無効または期限切れのアクセストークンでは 401 が返されます。
MCPツールの認証シグナル
tools/list 内のすべてのツールには、そのツールのREST操作のスコープを含む securitySchemes: [{"type": "oauth2", "scopes": ["agents:read"]}] が含まれます。公開ドキュメント用ツールは空のスコープリストを使用しますが、認証済み接続が必要です。
有効なトークンにツールに必要なスコープがない場合、HTTP 200 と、isError: true、content 内の説明テキスト、および _meta["mcp/www_authenticate"] を含むJSON-RPC result が返されます。後者は、resource_metadata、error="insufficient_scope"、error_description、および必要な scope を含むBearerチャレンジを格納した配列です。ツールは実行されません。このチャレンジを使用して、拡張された同意をリクエストしてください。認証がない場合または無効な場合は、引き続き WWW-Authenticate とともにHTTP 401 が返されます。RESTスコープの失敗では、引き続きHTTP 403 が返されます。
認証情報の保持
APIは、ステージング環境と本番環境で毎時 python manage.py oauth_cleanup を実行します。期限切れの認可リクエストとデバイスコードを削除します。期限切れのアクセストークン、認可コード、リフレッシュトークンハッシュは、そのグラントが失効するか、ファミリー全体が無効になった後にのみ削除されます。使用済みハッシュは、ファミリーに使用可能なリフレッシュトークン、認可コード、承認済みデバイスコード、またはアクセストークンが存在する間保持されるため、クリーンアップによってリプレイ検出が無効になることはありません。