curl --request GET 'https://api.voicecheap.ai/oauth/authorize?client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&redirect_uri=https%3A%2F%2Fassistant.example.com%2Foauth%2Fcallback&response_type=code&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&resource=https%3A%2F%2Fapi.voicecheap.ai%2Fmcp&scope=account%3Aread+projects%3Aread+offline_access&state=example-client-csrf-state'
const input = {
client_id: 'mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
redirect_uri: 'https://assistant.example.com/oauth/callback',
response_type: 'code',
response_mode: 'query',
code_challenge: 'E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM',
code_challenge_method: 'S256',
resource: 'https://api.voicecheap.ai/mcp',
scope: 'account:read projects:read offline_access',
state: 'example-client-csrf-state',
};
const response = await fetch(
'https://api.voicecheap.ai/oauth/authorize?client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&redirect_uri=https%3A%2F%2Fassistant.example.com%2Foauth%2Fcallback&response_type=code&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&resource=https%3A%2F%2Fapi.voicecheap.ai%2Fmcp&scope=account%3Aread+projects%3Aread+offline_access&state=example-client-csrf-state',
{
method: 'GET',
headers: {},
redirect: 'manual',
},
);
console.log(response.status, await response.text());
import os
import requests
response = requests.request(
"GET",
"https://api.voicecheap.ai/oauth/authorize?client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&redirect_uri=https%3A%2F%2Fassistant.example.com%2Foauth%2Fcallback&response_type=code&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&resource=https%3A%2F%2Fapi.voicecheap.ai%2Fmcp&scope=account%3Aread+projects%3Aread+offline_access&state=example-client-csrf-state",
headers={},
timeout=120,
allow_redirects=False,
)
print(response.status_code, response.text)
OAuth- und MCP-Protokoll
MCP-Kontoautorisierung starten
Erstellen Sie eine kurzlebige Autorisierungsanfrage und leiten Sie den Benutzer zur VoiceCheap-Seite für Anmeldung und Zustimmung zu Berechtigungen weiter.
GET
/
oauth
/
authorize
curl --request GET 'https://api.voicecheap.ai/oauth/authorize?client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&redirect_uri=https%3A%2F%2Fassistant.example.com%2Foauth%2Fcallback&response_type=code&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&resource=https%3A%2F%2Fapi.voicecheap.ai%2Fmcp&scope=account%3Aread+projects%3Aread+offline_access&state=example-client-csrf-state'
const input = {
client_id: 'mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
redirect_uri: 'https://assistant.example.com/oauth/callback',
response_type: 'code',
response_mode: 'query',
code_challenge: 'E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM',
code_challenge_method: 'S256',
resource: 'https://api.voicecheap.ai/mcp',
scope: 'account:read projects:read offline_access',
state: 'example-client-csrf-state',
};
const response = await fetch(
'https://api.voicecheap.ai/oauth/authorize?client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&redirect_uri=https%3A%2F%2Fassistant.example.com%2Foauth%2Fcallback&response_type=code&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&resource=https%3A%2F%2Fapi.voicecheap.ai%2Fmcp&scope=account%3Aread+projects%3Aread+offline_access&state=example-client-csrf-state',
{
method: 'GET',
headers: {},
redirect: 'manual',
},
);
console.log(response.status, await response.text());
import os
import requests
response = requests.request(
"GET",
"https://api.voicecheap.ai/oauth/authorize?client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&redirect_uri=https%3A%2F%2Fassistant.example.com%2Foauth%2Fcallback&response_type=code&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&resource=https%3A%2F%2Fapi.voicecheap.ai%2Fmcp&scope=account%3Aread+projects%3Aread+offline_access&state=example-client-csrf-state",
headers={},
timeout=120,
allow_redirects=False,
)
print(response.status_code, response.text)
Erstellen Sie eine kurzlebige Autorisierungsanfrage und leiten Sie den Benutzer zur VoiceCheap-Seite für Anmeldung und Zustimmung zu Berechtigungen weiter.
GET https://api.voicecheap.ai/oauth/authorize
Authentifizierung
Keine auf dieser Route. Der anschließende Zustimmungsablauf im Browser erfordert die Anmeldung des Benutzers, und die Genehmigung erfordert Zugriff auf ein berechtigtes kostenpflichtiges Konto.Abfrageparameter
string
erforderlich
Die von der dynamischen Registrierung zurückgegebene client_id oder die exakte öffentliche HTTPS-URL des Client-Metadatendokuments.Mindestlänge: 1. Höchstlänge: 2048. Muster:
^[^\u0000-\u001F\u007F]+$.string
erforderlich
Muss exakt mit einem der für diesen Client registrierten redirect_uris übereinstimmen.Mindestlänge: 1. Höchstlänge: 2048. Muster:
^[^\u0000-\u001F\u007F]+$.field
erforderlich
Wert gemäß dem vollständigen Eingabeschema.Erforderlicher Wert: “code”.
field
Wert gemäß dem vollständigen Eingabeschema.Erforderlicher Wert: “query”. Standardwert: “query”.
string
erforderlich
Base64url-SHA-256-Digest des ursprünglichen code_verifier ohne Padding.Mindestlänge: 43. Höchstlänge: 43. Muster:
^[A-Za-z0-9_-]{43}$.field
erforderlich
Wert gemäß dem vollständigen Eingabeschema.Erforderlicher Wert: “S256”.
string
erforderlich
Erforderliche exakte Ressourcen-Audience: Verwenden Sie den Wert resource aus den Metadaten der geschützten Ressource dieser Umgebung. In der Produktion ist dies https://api.voicecheap.ai/mcp. Ein anderer Origin, Pfad oder ein abschließender Schrägstrich wird abgelehnt.Format: “uri”.
string
Durch Leerzeichen getrennte Berechtigungen aus scopes_supported, optional einschließlich offline_access. Nicht unterstützte Namen und Werte, die nur aus Leerraum bestehen, werden abgelehnt; Duplikate werden entfernt. Wird scope weggelassen oder werden keine Produktberechtigungen angegeben, etwa nur openid oder nur offline_access, wird die Schnittmenge der standardmäßigen Leseberechtigungen und der registrierten Produktberechtigungen dieses Clients gewählt. email erfordert openid; email allein wird abgelehnt. Angeforderte Produktberechtigungen müssen für diesen Client registriert sein. Identitätsberechtigungen müssen ausdrücklich angefordert und vom Benutzer genehmigt werden; ohne scope werden keine Identitätsberechtigungen angefordert.Mindestlänge: 1. Höchstlänge: 2048. Muster:
^ *(?:account:read|usage:read|settings:read|settings:write|team:read|team:write|projects:read|projects:write|projects:delete|translations:write|transcription:read|transcription:write|subtitles:read|subtitles:write|tts:read|tts:write|voices:read|voices:write|images:read|images:write|thumbnails:read|thumbnails:write|folders:read|folders:write|glossary:read|glossary:write|webhooks:read|webhooks:write|publishing:read|publishing:write|offline_access|openid|email)(?: +(?:account:read|usage:read|settings:read|settings:write|team:read|team:write|projects:read|projects:write|projects:delete|translations:write|transcription:read|transcription:write|subtitles:read|subtitles:write|tts:read|tts:write|voices:read|voices:write|images:read|images:write|thumbnails:read|thumbnails:write|folders:read|folders:write|glossary:read|glossary:write|webhooks:read|webhooks:write|publishing:read|publishing:write|offline_access|openid|email))* *$.string
Optionaler opaker Wert, der beim abschließenden Callback zurückgegeben wird. Verwenden Sie einen neuen, nicht vorhersagbaren Wert und prüfen Sie ihn im Client.Mindestlänge: 1. Höchstlänge: 2048. Muster:
^[^\u0000-\u001F\u007F]+$.string
Optionaler undurchsichtiger nonce-Wert, der bei gewährtem openid im ID-Token zurückgegeben wird. Prüfen Sie ihn im Client.Mindestlänge: 1. Höchstlänge: 2048. Muster:
^[^\u0000-\u001F\u007F]+$.string
Textwert.Erforderlicher Wert: “consent”.
Technisches Schema
Technisches Schema
{
"type": "object",
"properties": {
"client_id": {
"type": "string",
"minLength": 1,
"maxLength": 2048,
"pattern": "^[^\\u0000-\\u001F\\u007F]+$",
"description": "The client_id returned by dynamic registration, or the exact public HTTPS URL of the client metadata document."
},
"redirect_uri": {
"type": "string",
"minLength": 1,
"maxLength": 2048,
"pattern": "^[^\\u0000-\\u001F\\u007F]+$",
"description": "Must exactly match one of this client's registered redirect_uris."
},
"response_type": {
"const": "code"
},
"response_mode": {
"const": "query",
"default": "query"
},
"code_challenge": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^[A-Za-z0-9_-]{43}$",
"description": "Base64url SHA-256 digest of the original code_verifier, without padding."
},
"code_challenge_method": {
"const": "S256"
},
"resource": {
"type": "string",
"format": "uri",
"description": "Required exact resource audience: use the resource value from this environment's protected-resource metadata. In production this is https://api.voicecheap.ai/mcp. A different origin, path, or trailing slash is rejected.",
"examples": [
"https://api.voicecheap.ai/mcp"
]
},
"scope": {
"type": "string",
"minLength": 1,
"maxLength": 2048,
"pattern": "^ *(?:account:read|usage:read|settings:read|settings:write|team:read|team:write|projects:read|projects:write|projects:delete|translations:write|transcription:read|transcription:write|subtitles:read|subtitles:write|tts:read|tts:write|voices:read|voices:write|images:read|images:write|thumbnails:read|thumbnails:write|folders:read|folders:write|glossary:read|glossary:write|webhooks:read|webhooks:write|publishing:read|publishing:write|offline_access|openid|email)(?: +(?:account:read|usage:read|settings:read|settings:write|team:read|team:write|projects:read|projects:write|projects:delete|translations:write|transcription:read|transcription:write|subtitles:read|subtitles:write|tts:read|tts:write|voices:read|voices:write|images:read|images:write|thumbnails:read|thumbnails:write|folders:read|folders:write|glossary:read|glossary:write|webhooks:read|webhooks:write|publishing:read|publishing:write|offline_access|openid|email))* *$",
"description": "Space-delimited permissions from scopes_supported, optionally including offline_access. Unsupported names and whitespace-only values are rejected; duplicates are removed. Omitting scope or supplying no product scopes, such as openid alone or offline_access alone, selects the default read scopes intersected with this client's registered product scopes. email requires openid; email alone is rejected. Requested product permissions must be registered for this client. Identity permissions must be explicitly requested and approved by the user; omitting scope requests no identity permissions.",
"examples": [
"account:read projects:read offline_access"
]
},
"state": {
"type": "string",
"minLength": 1,
"maxLength": 2048,
"pattern": "^[^\\u0000-\\u001F\\u007F]+$",
"description": "Optional opaque value echoed on the final callback. Use a fresh unpredictable value and verify it in the client."
},
"nonce": {
"type": "string",
"minLength": 1,
"maxLength": 2048,
"pattern": "^[^\\u0000-\\u001F\\u007F]+$",
"description": "Optional opaque nonce echoed in the ID token when openid is granted. Verify it in the client."
},
"prompt": {
"type": "string",
"const": "consent"
}
},
"required": [
"client_id",
"redirect_uri",
"response_type",
"code_challenge",
"code_challenge_method",
"resource"
],
"additionalProperties": true
}
Anfragebeispiele
Beachten Sie die für diese Route dokumentierte Kodierung und Authentifizierung. Die Antwortstruktur und Idempotenzregeln der Aktions-API gelten nur für Aktionsaufrufe.curl --request GET 'https://api.voicecheap.ai/oauth/authorize?client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&redirect_uri=https%3A%2F%2Fassistant.example.com%2Foauth%2Fcallback&response_type=code&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&resource=https%3A%2F%2Fapi.voicecheap.ai%2Fmcp&scope=account%3Aread+projects%3Aread+offline_access&state=example-client-csrf-state'
const input = {
client_id: 'mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
redirect_uri: 'https://assistant.example.com/oauth/callback',
response_type: 'code',
response_mode: 'query',
code_challenge: 'E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM',
code_challenge_method: 'S256',
resource: 'https://api.voicecheap.ai/mcp',
scope: 'account:read projects:read offline_access',
state: 'example-client-csrf-state',
};
const response = await fetch(
'https://api.voicecheap.ai/oauth/authorize?client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&redirect_uri=https%3A%2F%2Fassistant.example.com%2Foauth%2Fcallback&response_type=code&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&resource=https%3A%2F%2Fapi.voicecheap.ai%2Fmcp&scope=account%3Aread+projects%3Aread+offline_access&state=example-client-csrf-state',
{
method: 'GET',
headers: {},
redirect: 'manual',
},
);
console.log(response.status, await response.text());
import os
import requests
response = requests.request(
"GET",
"https://api.voicecheap.ai/oauth/authorize?client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&redirect_uri=https%3A%2F%2Fassistant.example.com%2Foauth%2Fcallback&response_type=code&response_mode=query&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&resource=https%3A%2F%2Fapi.voicecheap.ai%2Fmcp&scope=account%3Aread+projects%3Aread+offline_access&state=example-client-csrf-state",
headers={},
timeout=120,
allow_redirects=False,
)
print(response.status_code, response.text)
Antwort
HTTP-Weiterleitung zur VoiceCheap-Einwilligungsseite. Es gibt keinen JSON-Ergebnistext. Location enthält einen opaken request-Wert; anschließend meldet sich der Nutzer an und wählt Berechtigungen aus.HTTP/1.1 302 Found
Cache-Control: no-store
Pragma: no-cache
Referrer-Policy: no-referrer
Location: https://app.voicecheap.ai/mcp/authorize?request=mcp_req_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
Antwortheader
{
"Cache-Control": "no-store",
"Pragma": "no-cache",
"Referrer-Policy": "no-referrer",
"Location": "https://app.voicecheap.ai/mcp/authorize?request=mcp_req_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
}
Hinweise zur Operation
- Erkannte skalare Parameter müssen genau einmal als nicht leere Zeichenfolgen ohne ASCII-Steuerzeichen oder DEL übergeben werden. Wiederholte Abfrage- oder Formularfelder werden als Arrays dekodiert und beim Lesen als Skalare abgelehnt.
- Verwenden Sie für jeden Abfragewert URL-Kodierung. redirect_uri muss genau die für diesen Client registrierte Schreibweise verwenden.
- Verwenden Sie ausschließlich S256; plain-PKCE und implicit/token-Antworten werden nicht unterstützt. Bewahren Sie den ursprünglichen code_verifier mit 43–128 Zeichen für den Tokenaustausch auf.
- Der Parameter resource ist erforderlich und muss exakt der MCP-Ressourcen-URL der ausgewählten Umgebung entsprechen.
- Der Standardsatz von Produktberechtigungsbereichen ist account:read usage:read projects:read transcription:read subtitles:read tts:read voices:read images:read thumbnails:read. Eine Anfrage mit Standardwerten wird auf die vom Client registrierten Berechtigungsbereiche eingeschränkt; wenn keine Produktberechtigungsbereiche übrig bleiben, schlägt die Autorisierung fehl.
- Ein Scope, der nur aus offline_access besteht, verwendet die standardmäßige Auswahl der Produkt-Scopes. offline_access wird entfernt, bevor Produktberechtigungen angezeigt oder gewährt werden.
- Zustimmungsanfragen laufen nach 10 Minuten ab und können einmal beantwortet werden. Der Benutzer darf nur eine nichtleere Teilmenge der angefragten Produktberechtigungen genehmigen.
- Nach der Genehmigung erhält der Client-Callback code, iss und, sofern angegeben, den ursprünglichen state. Der Autorisierungscode läuft nach 2 Minuten ab und kann einmal eingelöst werden.
- Nach einer Ablehnung erhält der Client-Callback error=access_denied, error_description, iss und den ursprünglichen state, sofern angegeben; es wird kein code ausgegeben.
- Ungültige Client-Metadaten, abweichende Weiterleitungen, PKCE, Scopes oder resource erzeugen direkt OAuth-JSON-Fehler; sie werden nicht an einen ungeprüften Callback weitergeleitet.
- Die öffentliche Autorisierungsgrenze beträgt 30 Anfragen pro Minute und Client-IP und wird workerübergreifend geteilt.
- openid und email sind Identitätsberechtigungen, getrennt von Produktberechtigungen, und werden nur akzeptiert, wenn sie angekündigt werden. email erfordert openid. Bei der ersten Autorisierung verwendet eine Anfrage nur mit Identitäts-Scopes die auf dem Zustimmungsbildschirm angezeigten Standard-Produktberechtigungen.
- Die von der dynamischen Registrierung zurückgegebene client_id oder die exakte öffentliche HTTPS-URL des Client-Metadatendokuments.
- Für OpenID Connect wird prompt=consent unterstützt. Andere prompt-Werte und max_age werden abgelehnt; stille Autorisierung und erzwungene erneute Anmeldung werden nicht unterstützt.
Fehler
| HTTP-Status | Code | Bedeutung oder Behebung |
|---|---|---|
| 400 | invalid_request | Der Anfragetext oder ein erkannter Parameter ist ungültig, fehlt, ist doppelt vorhanden oder hat die falsche Kodierung. |
| 400 | invalid_client | Die client_id ist unbekannt oder ihr Client-Metadatendokument kann nicht abgerufen oder validiert werden. |
| 400 | unsupported_response_type | response_type ist nicht code. |
| 400 | invalid_target | resource fehlt oder entspricht nicht exakt der MCP-URL der Umgebung. |
| 400 | invalid_scope | Ein angefragter Produkt-Scope wird nicht unterstützt, ist nicht registriert oder lässt keine nutzbare Berechtigung übrig. |
| 429 | temporarily_unavailable | Das öffentliche Anfrageratenlimit für OAuth wurde erreicht. Warten Sie vor einem erneuten Versuch das aktuelle Zeitfenster ab. |
| 500 | server_error | Die Autorisierung ist vorübergehend nicht verfügbar. Versuchen Sie es später erneut. |
| 503 | temporarily_unavailable | Die Client-Metadaten sind vorübergehend nicht verfügbar. Versuchen Sie es später erneut. |
War diese Seite hilfreich?

