ThunderPhone 2.0、提供開始。セルフサービスで、1分あたり2セントから。発表内容を見る

Connect tools & data

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
電話番号、ブロックされた発信者、VoIPnumbers: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 を実行します。期限切れの認可リクエストとデバイスコードを削除します。期限切れのアクセストークン、認可コード、リフレッシュトークンハッシュは、そのグラントが失効するか、ファミリー全体が無効になった後にのみ削除されます。使用済みハッシュは、ファミリーに使用可能なリフレッシュトークン、認可コード、承認済みデバイスコード、またはアクセストークンが存在する間保持されるため、クリーンアップによってリプレイ検出が無効になることはありません。