curl --request POST 'https://api.voicecheap.ai/oauth/register' \
--header 'Content-Type: application/json' \
--data '{"client_name":"Acme assistant","redirect_uris":["https://assistant.example.com/oauth/callback"],"token_endpoint_auth_method":"none","grant_types":["authorization_code","refresh_token"],"response_types":["code"],"scope":"account:read projects:read offline_access"}'
const input = {
client_name: 'Acme assistant',
redirect_uris: ['https://assistant.example.com/oauth/callback'],
token_endpoint_auth_method: 'none',
grant_types: ['authorization_code', 'refresh_token'],
response_types: ['code'],
scope: 'account:read projects:read offline_access',
};
const response = await fetch('https://api.voicecheap.ai/oauth/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
redirect: 'manual',
});
console.log(response.status, await response.text());
import os
import requests
response = requests.request(
"POST",
"https://api.voicecheap.ai/oauth/register",
headers={"Content-Type":"application/json"},
json={"client_name": "Acme assistant", "redirect_uris": ["https://assistant.example.com/oauth/callback"], "token_endpoint_auth_method": "none", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "scope": "account:read projects:read offline_access"},
timeout=120,
allow_redirects=False,
)
print(response.status_code, response.text)
OAuth e protocollo MCP
Registra un client OAuth MCP
Registra un client pubblico con URL di callback esatti e un insieme limitato di autorizzazioni del prodotto.
POST
/
oauth
/
register
curl --request POST 'https://api.voicecheap.ai/oauth/register' \
--header 'Content-Type: application/json' \
--data '{"client_name":"Acme assistant","redirect_uris":["https://assistant.example.com/oauth/callback"],"token_endpoint_auth_method":"none","grant_types":["authorization_code","refresh_token"],"response_types":["code"],"scope":"account:read projects:read offline_access"}'
const input = {
client_name: 'Acme assistant',
redirect_uris: ['https://assistant.example.com/oauth/callback'],
token_endpoint_auth_method: 'none',
grant_types: ['authorization_code', 'refresh_token'],
response_types: ['code'],
scope: 'account:read projects:read offline_access',
};
const response = await fetch('https://api.voicecheap.ai/oauth/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
redirect: 'manual',
});
console.log(response.status, await response.text());
import os
import requests
response = requests.request(
"POST",
"https://api.voicecheap.ai/oauth/register",
headers={"Content-Type":"application/json"},
json={"client_name": "Acme assistant", "redirect_uris": ["https://assistant.example.com/oauth/callback"], "token_endpoint_auth_method": "none", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "scope": "account:read projects:read offline_access"},
timeout=120,
allow_redirects=False,
)
print(response.status_code, response.text)
Registra un client pubblico con URL di callback esatti e un insieme limitato di autorizzazioni del prodotto.
POST https://api.voicecheap.ai/oauth/register
Autenticazione
Nessuna. La registrazione non esegue l’accesso di un utente né autorizza una connessione all’account.Corpo della richiesta
array
obbligatorio
Da 1 a 10 callback prima della rimozione dei duplicati.Numero minimo di elementi: 1. Numero massimo di elementi: 10.
string
Etichetta facoltativa del client; gli spazi iniziali e finali vengono rimossi prima del salvataggio e il valore deve rimanere non vuoto.Lunghezza minima: 1. Lunghezza massima: 120. Pattern:
^(?=.*\S)[^\u0000-\u001F\u007F]+$. Valore predefinito: “MCP client”.field
Solo client pubblici.Valore obbligatorio: “none”. Valore predefinito: “none”.
union
Deve includere authorization_code; refresh_token è facoltativo. Se omesso o null, seleziona entrambi. I valori duplicati vengono rimossi.Valore predefinito: [“authorization_code”,“refresh_token”].
array
Elenco di valori. Consulta lo schema di input completo per la struttura degli elementi.Numero minimo di elementi: 1. Numero massimo di elementi: 1. Valore predefinito: [“code”].
string
Autorizzazioni di scopes_supported separate da spazi, che possono includere offline_access. I nomi non supportati e i valori composti solo da spazi vengono rifiutati; i duplicati vengono rimossi. Omettere scope o non indicare autorizzazioni di prodotto, ad esempio solo openid o solo offline_access, registra tutti gli scope di prodotto supportati. email richiede openid; email da solo viene rifiutato. Quando OpenID Connect è disponibile, la registrazione include openid ed email come capacità del client anche se scope è omesso. La registrazione non concede accesso; le autorizzazioni di identità richiedono una richiesta di autorizzazione esplicita e il consenso dell’utente.Lunghezza minima: 1. Lunghezza massima: 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))* *$.Schema tecnico
Schema tecnico
{
"type": "object",
"properties": {
"redirect_uris": {
"type": "array",
"minItems": 1,
"maxItems": 10,
"items": {
"type": "string",
"minLength": 1,
"maxLength": 2048,
"pattern": "^[^\\s\\u0000-\\u001F\\u007F-\\u009F#\\\\]+$",
"format": "uri",
"anyOf": [
{
"pattern": "^[Hh][Tt][Tt][Pp][Ss]://"
},
{
"pattern": "^http://(?:localhost|127\\.0\\.0\\.1|\\[::1\\])(?::[0-9]{1,5})?(?:/|\\?|$)"
},
{
"const": "cursor://anysphere.cursor-mcp/oauth/callback"
}
],
"description": "An absolute HTTPS callback, an HTTP callback using the exact lowercase loopback spelling localhost, 127.0.0.1, or [::1], or exactly cursor://anysphere.cursor-mcp/oauth/callback. Must parse as a URL with no username/password, whitespace, control characters, backslashes, or fragment. A loopback port must be a valid URL port. The exact spelling is retained."
},
"description": "Between 1 and 10 callbacks before duplicates are removed."
},
"client_name": {
"type": "string",
"minLength": 1,
"maxLength": 120,
"pattern": "^(?=.*\\S)[^\\u0000-\\u001F\\u007F]+$",
"default": "MCP client",
"description": "Optional client label; trimmed before saving and must remain nonempty."
},
"token_endpoint_auth_method": {
"const": "none",
"default": "none",
"description": "Public clients only."
},
"grant_types": {
"anyOf": [
{
"type": "array",
"minItems": 1,
"items": {
"enum": [
"authorization_code",
"refresh_token"
]
},
"contains": {
"const": "authorization_code"
}
},
{
"type": "null"
}
],
"default": [
"authorization_code",
"refresh_token"
],
"description": "Must include authorization_code; refresh_token is optional. Omitted or null selects both. Duplicate values are removed."
},
"response_types": {
"type": "array",
"minItems": 1,
"maxItems": 1,
"items": {
"const": "code"
},
"default": [
"code"
]
},
"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, registers all supported product scopes. email requires openid; email alone is rejected. When OpenID Connect is available, registration includes openid and email as client capabilities even when scope is omitted. Registration grants no access; identity permissions require an explicit authorization request and user consent.",
"examples": [
"account:read projects:read offline_access"
]
}
},
"required": [
"redirect_uris"
],
"additionalProperties": true
}
Esempi di richiesta
Segui la codifica e l’autenticazione documentate per questa route. L’involucro e le regole di idempotenza dell’API delle azioni si applicano solo alle invocazioni di azioni.curl --request POST 'https://api.voicecheap.ai/oauth/register' \
--header 'Content-Type: application/json' \
--data '{"client_name":"Acme assistant","redirect_uris":["https://assistant.example.com/oauth/callback"],"token_endpoint_auth_method":"none","grant_types":["authorization_code","refresh_token"],"response_types":["code"],"scope":"account:read projects:read offline_access"}'
const input = {
client_name: 'Acme assistant',
redirect_uris: ['https://assistant.example.com/oauth/callback'],
token_endpoint_auth_method: 'none',
grant_types: ['authorization_code', 'refresh_token'],
response_types: ['code'],
scope: 'account:read projects:read offline_access',
};
const response = await fetch('https://api.voicecheap.ai/oauth/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
redirect: 'manual',
});
console.log(response.status, await response.text());
import os
import requests
response = requests.request(
"POST",
"https://api.voicecheap.ai/oauth/register",
headers={"Content-Type":"application/json"},
json={"client_name": "Acme assistant", "redirect_uris": ["https://assistant.example.com/oauth/callback"], "token_endpoint_auth_method": "none", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "scope": "account:read projects:read offline_access"},
timeout=120,
allow_redirects=False,
)
print(response.status_code, response.text)
Risposta
Metadati del client pubblico registrato. Salva client_id e usalo con il redirect_uri registrato esatto. Non viene emesso alcun client_secret.HTTP 201
{
"client_id": "mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"client_id_issued_at": 1792152000,
"client_name": "Acme assistant",
"redirect_uris": ["https://assistant.example.com/oauth/callback"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"scope": "account:read projects:read offline_access"
}
Intestazioni della risposta
{
"Cache-Control": "no-store",
"Pragma": "no-cache"
}
Note sull’operazione
- I parametri scalari riconosciuti devono essere forniti una sola volta come stringhe non vuote, senza caratteri di controllo ASCII o DEL. I campi ripetuti nella query o nel modulo vengono decodificati come array e rifiutati quando vengono letti come scalari.
- Usa Content-Type application/json. Un corpo di registrazione con codifica URL viene rifiutato con la risposta OAuth invalid_request; i tipi multimediali non supportati possono essere rifiutati prima dal parser dell’integrazione.
- Gli URI di reindirizzamento vengono conservati e confrontati esattamente. Le modifiche a maiuscole e minuscole, rappresentazione della porta, percorso, query o barra finale richiedono la registrazione di quell’URI esatto.
- I callback HTTP accettano solo i nomi loopback letterali localhost, 127.0.0.1 e [::1]. Gli host di reti private, le grafie IP alternative, *.localhost e LOCALHOST in maiuscolo non sono ammessi.
- L’unico callback con schema URI personalizzato accettato è esattamente cursor://anysphere.cursor-mcp/oauth/callback.
- Ogni callback deve superare la convalida; un solo callback non valido comporta il rifiuto dell’intera registrazione. Sono rifiutati credenziali negli URL, spazi bianchi, caratteri di controllo, frammenti e barre rovesciate.
- Il client può registrare qualsiasi ambito del prodotto supportato, ma l’utente deve approvare separatamente il sottoinsieme richiesto durante l’autorizzazione. La sola registrazione non concede accesso.
- Sono supportati solo il grant authorization_code e il grant facoltativo refresh_token. Un client registrato senza refresh_token non riceve alcun refresh token.
- I campi di metadati di primo livello sconosciuti vengono ignorati dall’implementazione corrente. I campi noti mantengono i vincoli indicati nello schema.
- Il limite pubblico di registrazione è di 10 richieste ogni 10 minuti per IP del client, condiviso tra i worker. I corpi JSON sono limitati a 1 MiB.
- Una registrazione riuscita restituisce HTTP 201.
- openid ed email sono autorizzazioni di identità, separate da quelle del prodotto, accettate solo se dichiarate. email richiede openid. Durante l’autorizzazione iniziale, una richiesta con soli ambiti di identità usa le autorizzazioni di prodotto predefinite mostrate nella schermata di consenso.
Errori
| Stato HTTP | Codice | Significato o risoluzione |
|---|---|---|
| 400 | invalid_request | Il corpo o un parametro riconosciuto non è valido, è mancante, è duplicato oppure ha una codifica errata. |
| 400 | invalid_client_metadata | Numero di callback non valido, etichetta del client vuota, autenticazione del client, tipi di concessione o tipi di risposta non supportati. |
| 400 | invalid_redirect_uri | Un URL di callback utilizza una forma non supportata o non sicura. |
| 400 | invalid_scope | La stringa scope contiene un’autorizzazione non supportata oppure nessuno scope richiesto. |
| 413 | REQUEST_TOO_LARGE | La richiesta supera la dimensione consentita per il corpo. JSON è limitato a 1 MiB e i moduli con codifica URL a 32 KiB. |
| 415 | UNSUPPORTED_CONTENT_TYPE | Il parser del corpo dell’integrazione accetta solo JSON o moduli con codifica URL. La route può richiedere specificamente una di queste codifiche. |
| 429 | temporarily_unavailable | È stato raggiunto il limite di frequenza delle richieste OAuth pubbliche. Attendi il termine della finestra corrente prima di riprovare. |
| 500 | server_error | L’autorizzazione è temporaneamente non disponibile. Riprova più tardi. |
Questa pagina è stata utile?

