OAuth 2.1
OAuth 2.1 con PKCE y registro dinámico de clientes, para que un cliente MCP pueda conectarse a LLM Pulse sin que el usuario tenga que pegar una clave de API.
OAuth 2.1 (ChatGPT Apps SDK, clientes MCP)
Servidor de autorización OAuth 2.1 con PKCE-S256, registro dinámico de clientes (RFC 7591) y metadatos de descubrimiento (RFC 8414 + RFC 9728). Lo usan el SDK de ChatGPT Apps y cualquier otro cliente MCP compatible con OAuth. Disponible en todos los planes para el recurso MCP en /api/v1/mcp. Los tokens de acceso JWT firmados con RS256 y el refresh token reutilizable comparten una fecha límite de autorización fija de un año.
Resumen de OAuth 2.1
Usa OAuth 2.1 cuando tu cliente necesite acceso delegado por usuario al endpoint MCP y no puedas distribuir una API key (por ejemplo, un asistente de IA multiinquilino). Usa API keys cuando controles ambos extremos y quieras una integración más simple (plan Scale o superior). El MCP vía OAuth está disponible en todos los planes, incluida la prueba gratuita.
Endpoints: /oauth/authorize, /oauth/token, /oauth/register, /oauth/jwks.json, /.well-known/oauth-authorization-server, /.well-known/oauth-protected-resource.
GET/.well-known/oauth-authorization-server
Metadatos del servidor de autorización en /.well-known/oauth-authorization-server (RFC 8414) y metadatos del recurso protegido en /.well-known/oauth-protected-resource (RFC 9728). Las JWKS que se usan para verificar las firmas de los tokens de acceso se encuentran en /oauth/jwks.json. Los clientes deben consultarlos para descubrir los endpoints authorize, token y registration, y nunca fijarlos en el código.
Sin parámetros. Devuelve JSON con issuer, authorization_endpoint, token_endpoint, registration_endpoint, jwks_uri, scopes_supported, code_challenge_methods_supported y metadatos relacionados.
POST/oauth/register
Registro dinámico de clientes según RFC 7591. Sin autenticación y con un límite de 5 solicitudes por hora por IP. Solo se persisten los campos RFC 7591 (los campos adicionales se descartan). Las redirect URIs deben ser HTTPS (cualquier host) o loopback HTTP (localhost / 127.0.0.1); los esquemas personalizados como javascript:, data:, file: se rechazan. Máximo 10 redirect URIs por cliente; client_name limitado a 200 caracteres; URIs limitadas a 2048 caracteres.
Cuerpo JSON: redirect_uris (array obligatorio), client_name, grant_types (por defecto, authorization_code refresh_token), token_endpoint_auth_method (none para clientes PKCE públicos, client_secret_post para confidenciales), scope.
GET/oauth/authorize
Muestra una pantalla de consentimiento integrada en la app. Tras la aprobación, redirige al usuario de vuelta a redirect_uri con un code de un solo uso (TTL de 10 minutos) y el state original. PKCE-S256 es obligatorio; los desafíos plain se rechazan.
Parámetros: response_type=code (obligatorio), client_id (obligatorio), redirect_uri (obligatorio, debe coincidir exactamente con una URI registrada), code_challenge (obligatorio), code_challenge_method=S256 (obligatorio), scope (separado por espacios: mcp:read mcp:write), state, resource (indicador de recurso RFC 8707).
POST/oauth/token
Intercambia un código de autorización por un access token + refresh token, o renueva un access token. Usa application/x-www-form-urlencoded. Límite de 60 solicitudes por minuto por IP. Las respuestas de renovación devuelven el mismo refresh token reutilizable, y todas las credenciales caducan en la fecha límite de autorización fija de un año.
Cuerpo: grant_type (authorization_code o refresh_token), client_id (obligatorio), client_secret (obligatorio para clientes confidenciales) y o bien {code, code_verifier, redirect_uri} o bien {refresh_token, scope opcional para reducir el alcance}.
Scopes y verificación de la audiencia
Se definen dos scopes. mcp:read concede acceso a todas las herramientas de lectura (list_*, get_*). mcp:write concede además las herramientas de escritura (create_prompts, create_competitor, create_collection, assign_prompt_tags, create_annotation, create_intelligence_task, launch_recommendations, create_technical_geo_report). Un token emitido solo con mcp:read no puede invocar herramientas de escritura: tanto tools/list las oculta como una llamada directa a tools/call devuelve un error. La claim aud del JWT debe coincidir con la URL del servidor de recursos; los tokens con una audiencia distinta se rechazan en /api/v1/mcp.
Al renovar un token, puedes pasar un scope más restringido; cualquier alcance más amplio que la concesión original devuelve invalid_grant.