Open in
Verbinden met OAuth
Machtiging verlenen aan MCP-clients en de ThunderPhone CLI zonder een API-sleutel te delen.
OAuth laat een app verbinding maken met één ThunderPhone-organisatie met de machtigingen die je goedkeurt. Directory-clients moeten standaard OAuth gebruiken. Organisatie-API-sleutels blijven beschikbaar voor clients die een handmatig geconfigureerd Bearer-token vereisen.
Een verbinding goedkeuren
Start de verbinding in je MCP-client. Log in bij ThunderPhone, controleer de appnaam en aangevraagde machtigingen, kies een organisatie en selecteer Goedkeuren. Selecteer Weigeren als je de verbinding niet hebt gestart of de app niet vertrouwt. Appnamen worden door hun ontwikkelaars opgegeven en vormen geen verificatiebadge.
Leesmachtigingen geven toegang tot de genoemde gegevens, inclusief opnamen en transcripties wanneer calls:read wordt aangevraagd. Schrijfmachtigingen kunnen resources wijzigen of verwijderen; oproepen, campagnes, telefoonaankopen en implementaties kunnen kosten met zich meebrengen of invloed hebben op de productieomgeving. Je organisatierol blijft van toepassing.
Open voor een CLI-verbinding de verificatielink die in je terminal wordt weergegeven, vergelijk de achttekencode, selecteer je organisatie en keur goed. Alleen het openen van de link geeft geen toegang. Codes verlopen na 15 minuten.
De verbinding met een app verbreken
Open Organisatie → API-sleutels → Geautoriseerde apps in het dashboard en kies Intrekken. Hiermee trek je de geselecteerde autorisatie voor de huidige organisatie in, inclusief de toegangs- en vernieuwingstokens. Maak opnieuw verbinding vanuit de app als je deze opnieuw wilt autoriseren.
Detectie voor MCP-clients
Gebruik de server-URL https://api.thunderphone.com/v1/mcp. Een verzoek zonder geldige authenticatie ontvangt 401 met:
WWW-Authenticate: Bearer resource_metadata="https://api.thunderphone.com/.well-known/oauth-protected-resource"Haal dat document op en haal vervolgens de metagegevens van de autorisatieserver op via https://api.thunderphone.com/.well-known/oauth-authorization-server. Metagegevens voor resources zijn ook beschikbaar via /.well-known/oauth-protected-resource/v1/mcp. Gebruik de geretourneerde eindpunten in plaats van ze zelf samen te stellen. De resource-id is https://api.thunderphone.com/v1/mcp.
De server ondersteunt de autorisatiecodeflow met S256 PKCE, roterende refresh-tokens, openbare dynamische clientregistratie, intrekking en de apparaatautorisatiegrant. Er zijn geen clientsecrets of impliciete grants. OpenID-detectie is ook beschikbaar via /.well-known/openid-configuration; deze bevat dezelfde velden voor de autorisatieserver plus subject_types_supported: ["public"] en het userinfo-eindpunt. ID-tokens en Client ID Metadata Documents (CIMD) worden niet ondersteund.
Een openbare client registreren
Stuur JSON naar 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"]
}Sla de geretourneerde client_id op. Omleidingen moeten HTTPS gebruiken, of HTTP op 127.0.0.1 of localhost. Registreer de exacte callback-URI, inclusief poort en pad. Fragmenten en ingesloten inloggegevens worden geweigerd. Optionele client_uri en logo_uri moeten HTTPS gebruiken; ThunderPhone haalt deze niet op tijdens registratie. Registratie is onderhevig aan rate limiting. Geregistreerde clients verlopen niet en blijven geregistreerd wanneer een verbinding wordt ingetrokken. HTTPS-callbacks omvatten https://chatgpt.com/connector/oauth/<id> en https://chatgpt.com/connector_platform_oauth_redirect. Elke verbinding kan een eigen client registreren.
Autorisatiecode
Open het gedetecteerde autorisatie-eindpunt met client_id, de exact geregistreerde redirect_uri, response_type=code, een willekeurige state, scope, code_challenge, code_challenge_method=S256 en resource=https://api.thunderphone.com/v1/mcp. Bereken de challenge als de base64url SHA-256-digest zonder padding van een nieuwe PKCE-verifier met hoge entropie. Controleer de geretourneerde state en iss voordat je de code uitwisselt. Elk autorisatieantwoord, inclusief weigeringen en protocolfouten, identificeert de uitgever met iss, dat exact overeenkomt met de gedetecteerde issuer. Fouten voor een ongeldige client of callback worden lokaal geretourneerd zonder om te leiden naar die callback.
Wissel uit via POST /v1/oauth/token met formulierversleuteling (JSON wordt ook geaccepteerd):
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/mcpDe optionele parameter resource wordt geaccepteerd voor zowel autorisatie- als tokenverzoeken, inclusief refresh- en apparaatuitwisselingen. Als deze wordt weggelaten, is de standaardwaarde de gedetecteerde MCP-resource. Als deze aanwezig is, moet deze exact met die resource overeenkomen; andere waarden retourneren invalid_target. Access-tokens bevatten die doelgroep en MCP weigert tokens met een ontbrekende of afwijkende doelgroep met 401 en een detectiechallenge.
Autorisatieverzoeken en codes verlopen na 10 minuten. Elk tokenantwoord bevat access_token, token_type (Bearer), expires_in (standaard 3600 seconden), refresh_token, scope, organization_id en organization_name. Verstuur access-tokens alleen via de header Authorization: Bearer. Plaats tokens nooit in URL's, logs, broncodebeheer of chat.
Vernieuwen en intrekken
Vernieuw met grant_type=refresh_token, client_id, refresh_token en resource bij het token-eindpunt. Sla het nieuwe refresh-token atomair op en gebruik het oude niet meer. Refresh-tokens verlopen na 30 dagen zonder succesvolle vernieuwing. Een optionele scope kan de verleende machtigingen beperken. offline_access wordt altijd opgenomen en refresh-tokens worden altijd uitgegeven. Een eerste verzoek zonder scope verleent alleen offline_access, dus clients moeten de machtigingen aanvragen die ze nodig hebben.
Hergebruik van codes en hergebruik van geroteerde refresh-tokens trekken de volledige autorisatie in. Serialiseer vernieuwingen binnen een client; het opnieuw afspelen van succesvol uitgewisselde inloggegevens is geen veilige retrystrategie.
Stuur om de verbinding te verbreken token en client_id naar POST /v1/oauth/revoke. Het intrekken van een van beide tokens trekt de bijbehorende autorisatie in, inclusief alle daaruit uitgegeven tokens. Een onbekend token retourneert succes zonder te onthullen of het bestaat. Dashboardsessies kunnen hun eigen autorisaties weergeven via GET /v1/oauth/grants en er één intrekken via DELETE /v1/oauth/grants/<id>, waarbij X-ThunderPhone-Org de organisatie selecteert.
Apparaatautorisatie
Apparaatautorisatie is beperkt tot vooraf geregistreerde clients; dynamisch geregistreerde clients ontvangen unauthorized_client. De vooraf geregistreerde openbare client thunderphone-cli ondersteunt apparaatautorisatie en vernieuwing. Stuur client_id=thunderphone-cli en scope naar POST /v1/oauth/device/code. Toon user_code en verification_uri aan de gebruiker, of open verification_uri_complete.
Poll het token-eindpunt met grant_type=urn:ietf:params:oauth:grant-type:device_code, client_id en device_code, en wacht ten minste het geretourneerde interval (5 seconden). Ga door bij authorization_pending. Gebruik bij slow_down het nieuwe interval dat in het antwoord wordt geretourneerd (met 5 seconden verhoogd) voor elk volgend verzoek. Stop bij access_denied, expired_token of een andere fout. Keur een apparaatcode nooit automatisch goed.
De vooraf geregistreerde client thunderphone-mcp accepteert http://127.0.0.1/callback en http://localhost/callback op elke poort. Schema, host, pad en query moeten overeenkomen; de tokenuitwisseling moet de exacte omleidings-URI gebruiken, inclusief poort, uit de autorisatie. Dynamisch geregistreerde clients vereisen een exacte overeenkomst met de omleidings-URI, inclusief de poort. Registreer dynamisch een andere callback als je een ander pad nodig hebt.
Accountidentiteit en controles van werkruimtedomeinen
Vraag zowel openid email aan naast de bewerkingsscopes die je client nodig heeft. Roep het gedetecteerde userinfo_endpoint (GET /v1/oauth/userinfo) aan met het access-token in de Bearer-header. Een succesvol antwoord bevat:
{
"sub": "123",
"email": "person@example.com",
"email_verified": true,
"name": "Example User",
"org_id": 456
}sub is de stabiele gebruikers-id; org_id is de organisatie die tijdens toestemming is geselecteerd. Het eindpunt vereist beide identiteitsscopes en retourneert 403 als een van beide ontbreekt. Het retourneert 403 met error=access_denied als het account geen geverifieerd e-mailprofiel heeft, in plaats van te stellen dat een niet-geverifieerd e-mailadres vertrouwd is. Ongeldige, verlopen, ingetrokken tokens of tokens met een verkeerde doelgroep retourneren 401. Tokens voor menselijke sessies en API-sleutels van organisaties kunnen userinfo niet aanroepen. Er wordt geen ID-token uitgegeven.
Beschikbare machtigingen
| Familie | Scopes |
|---|---|
| Agenten en agentimporten | agents:read, agents:write |
| Oproepen | calls:read, calls:write |
| Telefoonnummers, geblokkeerde bellers en VoIP | numbers:read, numbers:write |
| Kennis | knowledge:read, knowledge:write |
| Campagnes | campaigns:read, campaigns:write |
| Integraties, webhookeindpunten, MCP-servers | integrations:read, integrations:write |
| Stemmen | voices:read |
| Testscenario's, testruns, validatie | testing:read, testing:write |
| Facturering | billing:read |
| Accountidentiteit en geverifieerd e-mailadres | openid, email (beide vereist voor userinfo) |
| Permanente verbinding | offline_access (altijd inbegrepen) |
GET, HEAD en OPTIONS gebruiken leesscopes; andere methoden gebruiken schrijfscope. Mutaties van stemmen en facturering zijn niet beschikbaar via OAuth; POST /v1/voices/preview gebruikt voices:read omdat hiermee een stem wordt beluisterd zonder de configuratie te wijzigen. MCP-tools handhaven de scope van de onderliggende REST-bewerking. Overdrachten tussen organisaties worden geweigerd, zelfs wanneer de autoriserende gebruiker bij beide organisaties hoort. Andere API-families, waaronder API-sleutelbeheer en instellingen voor menselijke accounts, zijn niet beschikbaar via OAuth. Een ontbrekende machtiging voor een REST-bewerking retourneert 403 met WWW-Authenticate: Bearer error="insufficient_scope", scope="...". Ongeldige of verlopen toegangstokens retourneren 401.
MCP-toolverificatiesignalen
Elke tool in tools/list bevat securitySchemes: [{"type": "oauth2", "scopes": ["agents:read"]}], met de scope van de REST-bewerking van die tool. Openbare documentatietools gebruiken een lege scopelijst en vereisen nog steeds een geverifieerde verbinding.
Een geldig token zonder de scope van een tool ontvangt HTTP 200 met een JSON-RPC-result dat isError: true, toelichtende tekst in content en _meta["mcp/www_authenticate"] bevat. Dit laatste is een array met een Bearer-challenge met resource_metadata, error="insufficient_scope", error_description en de vereiste scope. De tool wordt niet uitgevoerd. Gebruik deze challenge om uitgebreide toestemming aan te vragen. Ontbrekende of ongeldige verificatie blijft HTTP 401 met WWW-Authenticate retourneren; REST-scopefouten blijven HTTP 403 retourneren.
Bewaren van referenties
De API voert elk uur python manage.py oauth_cleanup uit in staging en productie. Hiermee worden verlopen autorisatieverzoeken en apparaatcodes verwijderd. Verlopen toegangstokens, autorisatiecodes en refresh-tokenhashes worden pas verwijderd nadat hun toekenning is ingetrokken of de volledige familie niet meer actief is. Gebruikte hashes blijven bewaard zolang de familie een bruikbaar refresh-token, autorisatiecode, goedgekeurde apparaatcode of toegangstoken heeft, zodat opschoning replaydetectie niet kan uitschakelen.