For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navegación principal
Theme
Descripción general Documentación para usuarios de ChatGPT y Codex Casos de uso

Autenticación

Patrones de autenticación para servidores MCP de complementos.

Autentica a tus usuarios

Muchos servidores MCP de complementos pueden funcionar en modo anónimo y de solo lectura, pero cualquier servidor que dé acceso a datos específicos de un cliente o permita operaciones de escritura debería autenticar a los usuarios.

Los complementos publicados pueden ejecutarse en ChatGPT y Codex. El contrato de autorización de MCP se aplica a ambos productos. Esta guía señala los detalles específicos del cliente de ChatGPT cuando la devolución de llamada, el documento de metadatos o la interfaz de vinculación difieren entre productos.

Puedes integrar tu propio servidor de autorización si necesitas conectarte a una aplicación existente del lado del servidor o compartir datos entre usuarios.

Autenticación personalizada con OAuth 2.1

Para un servidor MCP que requiere autenticación, debes implementar un flujo de OAuth 2.1 que cumpla con la especificación de autorización de MCP.

Componentes

  • Servidor de recursos: tu servidor MCP, que ofrece herramientas y verifica los tokens de acceso en cada solicitud.
  • Servidor de autorización: tu proveedor de identidad o tu implementación personalizada, que emite tokens y publica metadatos de descubrimiento.
  • Cliente: el host de OpenAI, como ChatGPT o Codex, que actúa en nombre del usuario. Los clientes compatibles usan documentos de metadatos de ID de cliente (CIMD), registro dinámico de clientes (DCR), clientes OAuth predefinidos y PKCE.

Requisitos de la especificación de autorización de MCP

  • Aloja los metadatos del recurso protegido en tu servidor MCP
  • Publica los metadatos de OAuth desde tu servidor de autorización
  • Reproduce el valor del parámetro resource a lo largo del flujo de OAuth
  • Elige cómo el host de OpenAI identifica o registra su cliente OAuth: mediante CIMD, DCR o un cliente OAuth predefinido
  • Publica los métodos de autenticación que tu servidor de autorización acepta en el punto de acceso de tokens

En términos prácticos, la especificación establece los siguientes requisitos.

Aloja los metadatos del recurso protegido en tu servidor MCP

  • Necesitas un punto de acceso HTTPS como GET https://your-mcp.example.com/.well-known/oauth-protected-resource para que ChatGPT sepa dónde obtener tus metadatos. También puedes indicar esa misma URL en el encabezado WWW-Authenticate de las respuestas 401 Unauthorized.
  • Ese punto de acceso devuelve un documento JSON que describe el servidor de recursos y los servidores de autorización disponibles:
{
  "resource": "https://your-mcp.example.com",
  "authorization_servers": ["https://auth.yourcompany.com"],
  "scopes_supported": ["files:read", "files:write"],
  "resource_documentation": "https://yourcompany.com/docs/mcp"
}
  • Campos principales que debes configurar:
    • resource: el identificador HTTPS canónico de tu servidor MCP. ChatGPT envía este valor exacto como parámetro de consulta resource durante el flujo de OAuth.
    • authorization_servers: una o más URL base de emisores que apuntan a tu proveedor de identidad. ChatGPT probará cada una para encontrar los metadatos de OAuth.
    • scopes_supported: lista opcional que ayuda a ChatGPT a explicar al usuario qué permisos le solicitará.
    • Los campos opcionales de RFC 9728, como resource_documentation, resource_policy_uri o resource_tos_uri, ayudan a los clientes y administradores a entender tu configuración.

Si bloqueas una solicitud porque no está autenticada, devuelve un desafío como el siguiente:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://your-mcp.example.com/.well-known/oauth-protected-resource",
                         scope="files:read"

Con ese único encabezado, ChatGPT puede descubrir la URL de los metadatos incluso si nunca la ha visto.

Publica los metadatos de OAuth desde tu servidor de autorización

  • Tu proveedor de identidad debe ofrecer uno de los documentos de descubrimiento en una ubicación estándar para que ChatGPT pueda leer su configuración:
    • Metadatos de OAuth 2.0 en https://auth.yourcompany.com/.well-known/oauth-authorization-server
    • Metadatos de OpenID Connect en https://auth.yourcompany.com/.well-known/openid-configuration
  • Cada documento le indica al host de OpenAI adónde dirigir al usuario, cómo intercambiar códigos y cómo identificarse. Esta es una respuesta típica:
{
  "issuer": "https://auth.yourcompany.com",
  "authorization_response_iss_parameter_supported": true,
  "authorization_endpoint": "https://auth.yourcompany.com/oauth2/v1/authorize",
  "token_endpoint": "https://auth.yourcompany.com/oauth2/v1/token",
  "client_id_metadata_document_supported": true,
  "token_endpoint_auth_methods_supported": ["none", "private_key_jwt"],
  "registration_endpoint": "https://auth.yourcompany.com/oauth2/v1/register",
  "code_challenge_methods_supported": ["S256"],
  "scopes_supported": ["files:read", "files:write"]
}
  • Campos que deben estar configurados correctamente:
    • issuer: el identificador canónico del servidor de autorización. Usa este valor exacto en la lista authorization_servers de los metadatos del recurso protegido.
    • authorization_response_iss_parameter_supported: establece este campo en true solo si tu servidor de autorización devuelve el parámetro iss en todas las respuestas de autorización, incluidas las de error.
    • authorization_endpoint, token_endpoint: las URL que ChatGPT necesita para completar el flujo de OAuth con código de autorización y PKCE.
    • client_id_metadata_document_supported: establece este campo en true si quieres que ChatGPT use CIMD para el registro de clientes. ChatGPT da prioridad a CIMD cuando está disponible, pero quien crea el complemento puede elegir DCR si ambos métodos están disponibles.
    • token_endpoint_auth_methods_supported: incluye los métodos de autenticación que tu servidor de autorización acepta en el punto de acceso de tokens. Esto se aplica a CIMD, DCR y los clientes OAuth predefinidos. Con CIMD, ChatGPT admite none para el intercambio de tokens de clientes públicos y private_key_jwt para el intercambio de tokens con una aserción de cliente firmada. Otros clientes OAuth suelen usar none, client_secret_post o client_secret_basic.
    • registration_endpoint: incluye este campo si admites el registro dinámico de clientes (DCR), que permite a ChatGPT crear y reutilizar un client_id exclusivo para la conexión con el servidor MCP.
    • code_challenge_methods_supported: debe incluir S256. Los servidores MCP no son compatibles si los metadatos de su servidor de autorización omiten este campo o no anuncian S256, tal como exige la especificación de autorización de MCP.
    • Los campos opcionales siguen RFC 8414 y la especificación de descubrimiento de OpenID. Incluye los que ayuden a tus administradores a configurar las políticas.

Alcances de OIDC

  • Si tu proveedor anuncia alcances de OIDC (por ejemplo, openid, email, profile) en el campo scopes_supported de su documento .well-known/oauth-authorization-server o .well-known/openid-configuration, ChatGPT los solicita de forma predeterminada durante el flujo de OAuth.
  • Es posible que algunos proveedores de identidad no habiliten de forma predeterminada los alcances de OIDC que anuncian. Revisa la configuración de tu proveedor y comprueba que todos los alcances anunciados estén habilitados para el cliente OAuth, tanto si usa CIMD como si se creó de forma manual o mediante DCR.

Habilita las restricciones de dominio del espacio de trabajo

Los espacios de trabajo de ChatGPT Enterprise pueden verificar la titularidad de los dominios de correo electrónico. Cuando un complemento vinculado mediante OAuth proporciona la dirección de correo electrónico verificada del usuario, ChatGPT puede usar el dominio del correo para impedir que esa identidad corporativa vincule el complemento en un espacio de trabajo personal o en otro ajeno a la organización.

Para habilitar esta protección, configura tu servidor de autorización para que realice las siguientes acciones:

  • Publicar metadatos de descubrimiento de OpenID Connect.
  • Anunciar y habilitar los alcances openid y email.
  • Anunciar un punto de acceso UserInfo que devuelva la declaración email del usuario y email_verified: true.

También puedes devolver estas declaraciones en un token de ID durante el flujo de OAuth, pero las restricciones de dominio del espacio de trabajo requieren el punto de acceso UserInfo.

El espacio de trabajo Enterprise también debe verificar su dominio. Tu servidor de autorización proporciona la identidad del usuario que ChatGPT compara con los dominios verificados configurados para el espacio de trabajo. La verificación de la titularidad del dominio le corresponde al espacio de trabajo.

Conserva el contexto de inicio de sesión durante la reautorización

Cuando ChatGPT vuelve a autorizar una vinculación existente, incluso para solicitar alcances adicionales de OAuth, puede incluir el token de ID de OIDC anterior en la solicitud de autorización mediante el parámetro estándar id_token_hint. Para que los usuarios puedan conceder alcances adicionales sin volver a iniciar sesión desde cero, configura tu servidor de autorización para que emita un token de ID durante el flujo original de OAuth y tenga en cuenta id_token_hint durante la autorización.

Esta optimización es opcional. La reautorización sigue funcionando aunque no haya un token de ID disponible o tu servidor de autorización no use esa indicación.

Protege las devoluciones de llamada mediante la identificación del emisor

Los hosts de OpenAI usan la identificación del emisor definida en RFC 9207 para proteger las devoluciones de llamada de OAuth contra ataques de confusión entre servidores de autorización. Para que ChatGPT y Codex puedan usar un URI de redirección estable al crear un cliente OAuth que cumpla los requisitos:

  • Establece authorization_response_iss_parameter_supported: true en los metadatos de tu servidor de autorización.
  • Usa exactamente el mismo identificador de emisor en el campo issuer de los metadatos y en la lista authorization_servers de los metadatos del recurso protegido.
  • Devuelve iss en todas las respuestas de autorización, tanto las exitosas como las de error. Su valor debe coincidir exactamente con el campo issuer de los metadatos. Los clientes comparan las cadenas de forma exacta, sin normalizar las barras finales, las rutas, los puertos ni el uso de mayúsculas y minúsculas.

ChatGPT y Codex registran el valor de issuer de los metadatos seleccionados antes de redirigir al usuario y comprueban el iss recibido antes de intercambiar el código de autorización. Si el servidor anuncia la identificación del emisor, pero omite iss o devuelve un valor que no coincide, ChatGPT y Codex rechazan la respuesta. Estos requisitos siguen las reglas de validación de respuestas de autorización de MCP.

URL de redirección

Copia el URI de redirección de producción que aparece en la página de administración del servidor MCP, sin modificarlo, en la lista de URI permitidos de tu servidor de autorización.

  • Si tu servidor de autorización no cumple con los requisitos de identificación del emisor descritos anteriormente, ChatGPT usa el URI de redirección específico del ID de devolución de llamada https://chatgpt.com/connector/oauth/{callback_id}.
  • Si tu servidor de autorización cumple con esos requisitos, ChatGPT usa el URI de redirección estable https://chatgpt.com/connector_platform_oauth_redirect.

Los servidores MCP publicados antes de que ChatGPT incorporara las redirecciones específicas del ID de devolución de llamada también siguen usando el URI de redirección estable.

Reproduce el valor del parámetro resource a lo largo del flujo de OAuth

  • ChatGPT agrega resource=https%3A%2F%2Fyour-mcp.example.com tanto a las solicitudes de autorización como a las de tokens. Esto vincula el token con los metadatos del recurso protegido que se mostraron anteriormente.
  • Configura tu servidor de autorización para que copie ese valor en el token de acceso (por lo general, en la declaración aud). Así, tu servidor MCP puede verificar que el token se emitió exclusivamente para él.
  • Si recibes un token sin la audiencia o los alcances esperados, recházalo y usa el desafío WWW-Authenticate para indicar a ChatGPT que repita la autorización con los parámetros correctos.

Admite el flujo con código de autorización

  • ChatGPT actúa como cliente MCP y ejecuta el flujo con código de autorización y PKCE usando el desafío de código S256, para que un atacante no pueda reutilizar un código de autorización interceptado.
  • Tu servidor de autorización debe publicar code_challenge_methods_supported con S256 para que los clientes puedan confirmar la compatibilidad con PKCE a partir de los metadatos.

Flujo de OAuth

Una vez que implementes la especificación de autorización de MCP descrita anteriormente, el flujo de OAuth seguirá estos pasos:

  1. ChatGPT solicita a tu servidor MCP los metadatos del recurso protegido.

  1. ChatGPT se identifica como cliente OAuth. Cuando el servidor MCP usa CIMD, ChatGPT omite el registro dinámico de clientes y envía la URL de un documento CIMD como client_id. Para los servidores de autorización que cumplen con los requisitos de identificación del emisor descritos anteriormente, ChatGPT usa la URL estable https://chatgpt.com/oauth/client.json. Para los demás, usa la URL específica del ID de devolución de llamada https://chatgpt.com/oauth/{callback_id}/client.json. La página de administración del servidor MCP muestra el documento de metadatos del cliente y el URI de redirección exactos que corresponden al modo de devolución de llamada de la conexión. Cuando el servidor MCP usa DCR, ChatGPT llama una sola vez al registration_endpoint de tu servidor de autorización para esa conexión con el servidor MCP, recibe un client_id generado y reutiliza ese cliente para la misma conexión.

Con CIMD no hay un paso de registro del cliente. La siguiente pantalla muestra el proceso con DCR:

  1. La primera vez que el usuario invoca una herramienta, el cliente de ChatGPT inicia el flujo de OAuth con código de autorización y PKCE. El usuario se autentica y da su consentimiento para los alcances solicitados.

  1. ChatGPT intercambia el código de autorización por un token de acceso y lo adjunta a las solicitudes MCP posteriores (Authorization: Bearer <token>).

  1. Tu servidor verifica el token en cada solicitud (emisor, audiencia, vencimiento y alcances) antes de ejecutar la herramienta.

Registro de clientes

Usa los documentos de metadatos de ID de cliente (CIMD) como método preferido de registro de clientes cuando tu servidor de autorización lo admita y quien crea el complemento lo elija. Con CIMD, ChatGPT usa la URL HTTPS de un documento de metadatos como client_id. Tu servidor de autorización obtiene ese documento, valida los metadatos publicados del cliente y los identificadores de recursos de redirección, y usa la URL como identidad estable del cliente de ChatGPT.

Si admites CIMD, establece client_id_metadata_document_supported: true en los metadatos de tu servidor de autorización. Así, ChatGPT puede usar una única identidad de cliente estable para los servidores MCP que elijan CIMD. Tu servidor de autorización puede usar esa identidad para gestionar listas de URI de redirección permitidos, límites de solicitudes y otras políticas.

ChatGPT está adoptando la transición de CIMD propuesta en MCP SEP-3149. Su documento CIMD de producción publica token_endpoint_auth_methods_supported como un arreglo de métodos que ChatGPT puede usar, sin orden de preferencia. Durante la transición, también publica el campo anterior en singular, token_endpoint_auth_method, para indicar una preferencia:

{
  "token_endpoint_auth_methods_supported": ["none", "private_key_jwt"],
  "token_endpoint_auth_method": "private_key_jwt"
}

El significado del campo en plural depende del documento. En los metadatos del servidor de autorización, enumera los métodos que acepta tu punto de acceso de tokens. En el documento CIMD de ChatGPT, enumera los métodos que ChatGPT puede usar. ChatGPT elige un método común a ambos conjuntos. Si la preferencia indicada en el campo anterior en singular está en ambos conjuntos, ChatGPT la usa por compatibilidad con los servidores de autorización que aún consideran obligatorio el método indicado en ese campo. En caso contrario, ChatGPT puede usar otro método común.

Los servidores de autorización que leen el campo CIMD en plural deben aceptar cualquier método común a ambos conjuntos, salvo que la política de seguridad local lo prohíba para ese cliente. Deben rechazar cualquier método que falte en uno o en ambos conjuntos. La URL de client_id se mantiene estable y no usa parámetros de consulta para seleccionar un documento específico de un método.

Los métodos compatibles son:

  • none: usa este flujo de cliente público si tu punto de acceso de tokens admite el intercambio de códigos de autorización con PKCE sin autenticar al cliente. ChatGPT no almacena un secreto por cliente.
  • private_key_jwt: usa este flujo de aserción de cliente firmada si tu punto de acceso de tokens requiere autenticar al cliente. ChatGPT publica una URL pública de JWKS en sus metadatos CIMD. El JWKS está disponible en /oauth/jwks.json, en el mismo origen que los metadatos. ChatGPT firma las solicitudes de tokens del lado del servidor con una clave privada administrada e incluye el kid. Tu servidor de autorización verifica la aserción con el JWKS público.

ChatGPT sigue admitiendo DCR. Si incluyes registration_endpoint, ChatGPT puede registrarse dinámicamente cuando quien crea el complemento elige DCR o cuando CIMD no está disponible. ChatGPT ejecuta DCR una vez por conexión con el servidor MCP y conserva el cliente OAuth registrado para reutilizarlo en esa conexión. Con DCR, muchas conexiones independientes pueden dar lugar a un gran número de clientes registrados, por lo que CIMD suele ser más fácil de administrar a gran escala.

Mantén la validez del cliente OAuth registrado y de cualquier secreto de cliente mientras la conexión con el servidor MCP esté en uso. Si tu servidor de autorización deja vencer, elimina o reemplaza alguna de esas credenciales, los usuarios y revisores pueden recibir un error invalid_client al conectarse. Los tokens de acceso y de actualización pueden seguir venciendo o rotando con normalidad.

Identificación del cliente

Una pregunta frecuente es cómo puede tu servidor MCP confirmar que una solicitud realmente proviene de ChatGPT. Al conectarse a servidores MCP, ChatGPT presenta un certificado de cliente administrado por OpenAI, por lo que puedes verificar el cliente en la capa de transporte con mTLS. También puedes agregar los rangos de IP de salida publicados por ChatGPT a tu lista de direcciones permitidas. ChatGPT no admite concesiones OAuth entre máquinas, como credenciales de cliente, cuentas de servicio o aserciones JWT de portador. Tampoco puede presentar claves de API personalizadas ni certificados mTLS proporcionados por el cliente.

CIMD refuerza la identificación del cliente al proporcionar a tu servidor de autorización una declaración estable de la identidad de ChatGPT, alojada en HTTPS. Si usas private_key_jwt, verifica la aserción de cliente que ChatGPT envía al punto de acceso de tokens con el JWKS público que figura en los metadatos CIMD.

TLS mutuo (mTLS)

ChatGPT ahora presenta un certificado de cliente administrado por OpenAI al establecer conexiones TLS con servidores MCP. Si tu aplicación valida certificados de cliente, configúrala para que confíe en la siguiente cadena de certificados de OpenAI.

Para validar el certificado de cliente al establecer la conexión TLS con tu servidor MCP:

  • Comprueba que haya un certificado final y que su cadena de certificación lo vincule con la CA intermedia de mTLS de OpenAI Connectors.
  • Comprueba que el certificado final sea válido para la autenticación de clientes.
  • Comprueba que el valor de dnsName en el SAN del certificado final sea mtls.prod.connectors.openai.com.
  • Evita fijar la huella digital del certificado final. OpenAI puede rotar ese certificado sin cambiar la cadena de CA publicada.

Usa mTLS para autenticar a ChatGPT como cliente MCP. Sigue usando OAuth 2.1 para autenticar al usuario final y autorizar el acceso a las herramientas.

Elección de un proveedor de identidad

La mayoría de los proveedores de identidad de OAuth 2.1 pueden cumplir con los requisitos de autorización de MCP si ofrecen un documento de descubrimiento, admiten CIMD con none o private_key_jwt, admiten DCR cuando es necesario y copian el valor del parámetro resource en los tokens que emiten. Da preferencia a los proveedores que admitan CIMD para el registro de clientes.

Te recomendamos encarecidamente que uses un proveedor de identidad consolidado en lugar de implementar la autenticación desde cero.

A continuación encontrarás instrucciones para algunos proveedores de identidad populares.

Auth0

Auth0 permite que los clientes MCP se conecten de forma segura a servidores MCP. Ofrece descubrimiento de metadatos, registro mediante CIMD, seguridad de API e intercambio de tokens para llamadas a herramientas propias y de terceros.

Ejemplo de proveedor alojado (Stytch)

Implementación de la verificación de tokens

Una vez que finaliza el flujo de OAuth, ChatGPT adjunta directamente el token de acceso recibido a las solicitudes MCP posteriores (Authorization: Bearer …). Cuando una solicitud llega a tu servidor MCP, debes tratar el token como no confiable y realizar todas las comprobaciones que le corresponden al servidor de recursos: validar la firma, comprobar que el emisor y la audiencia coincidan con los valores esperados, verificar el vencimiento, tener en cuenta el riesgo de reutilización del token y hacer cumplir los alcances. Estas comprobaciones son responsabilidad tuya y no de ChatGPT.

En la práctica, debes hacer lo siguiente:

  • Obtén las claves de firma publicadas por tu servidor de autorización (normalmente mediante JWKS) y verifica la firma del token y su iss.
  • Rechaza los tokens que hayan vencido o que aún no sean válidos (exp/nbf).
  • Confirma que el token se haya emitido para tu servidor (aud o la declaración resource) y que contenga los alcances que marcaste como obligatorios.
  • Ejecuta las comprobaciones de políticas específicas del servidor. Luego, adjunta la identidad determinada al contexto de la solicitud o devuelve un 401 con un desafío WWW-Authenticate.

Si la verificación falla, responde con 401 Unauthorized y un encabezado WWW-Authenticate que apunte a los metadatos de tu recurso protegido. Esto indica al cliente que debe ejecutar de nuevo el flujo de OAuth.

Funciones de los SDK para verificar tokens

Los kits de desarrollo de software de MCP para Python y TypeScript incluyen funciones auxiliares para que no tengas que implementar esta lógica desde cero.

Admite varias cuentas

La compatibilidad con varias cuentas permite a los usuarios conectar más de una cuenta al mismo complemento, por ejemplo, una personal y otra de trabajo. OpenAI dirige cada llamada a una herramienta usando las credenciales autenticadas de la conexión seleccionada. Los usuarios pueden conectar varias cuentas sin una herramienta de perfil. Para ayudarlos a distinguir las conexiones y reconocer el mismo perfil al volver a conectarse, ofrece una herramienta de perfil que requiera autenticación y proporcione un ID estable y metadatos de visualización útiles.

Cómo usan varias cuentas los usuarios

Los usuarios pueden conectar cuentas adicionales desde la página de configuración del complemento. El modelo tiene acceso a todas las cuentas conectadas y, cuando invoca herramientas, selecciona la cuenta o las cuentas pertinentes según la solicitud del usuario. Cada llamada a una herramienta usa las credenciales y los permisos de la cuenta seleccionada.

Mejora la identificación de cuentas

Para ayudar a OpenAI a reconocer los perfiles conectados y mostrar etiquetas útiles:

  • Ofrece una herramienta de perfil que requiera autenticación y devuelva un ID opaco que identifique de forma única y estable el perfil representado por las credenciales de la solicitud. Así, OpenAI puede reconocer el mismo perfil al restablecer la conexión y distinguirlo de otros perfiles. Un campo llamado id solo sirve para este fin si su valor cumple con esas garantías.
  • Designa la herramienta de perfil en los metadatos de MCP para que OpenAI pueda descubrir a qué herramienta llamar para obtener información del perfil autenticado.

Cuando OpenAI necesita información del perfil, descubre la herramienta designada en tiempo de ejecución, la llama con las credenciales de la conexión y valida la respuesta antes de usar los datos del perfil. Sin una herramienta de perfil, los usuarios aún pueden conectar cuentas, pero las etiquetas de las cuentas, su reconocimiento o la detección de duplicados pueden ser menos confiables. Si declaras una herramienta de perfil, devuelve una identidad válida. Una respuesta no válida puede impedir que se conecte la cuenta.

Define una identidad de perfil estable

Un perfil identifica a la entidad representada por las credenciales autenticadas de la solicitud. Tu servicio define qué perfiles se pueden conectar de forma independiente. Este contrato no impone una estructura organizativa ni un modelo de autorización para tu servicio.

Devuelve un ID de perfil opaco que sea único dentro de tu app. El mismo perfil debe conservar su ID al actualizar el token y al restablecer la conexión. Los perfiles distintos deben tener ID distintos. OpenAI compara estos ID sin interpretar su contenido.

Usa un ID opaco e inmutable que ya exista en el proveedor si identifica el perfil completo. De lo contrario, asigna un ID opaco una sola vez, guarda su asociación con ese perfil y recupera el mismo ID en las solicitudes futuras. Mantén las relaciones internas en tu servicio. No codifiques nombres, direcciones de correo electrónico ni relaciones organizativas en el ID que devuelvas.

Tu id debe cumplir estas condiciones:

  • Ser una cadena que no esté vacía ni contenga únicamente espacios en blanco. Serializa los ID numéricos del proveedor como cadenas.
  • Mantenerse igual para el mismo perfil al actualizar el token, restablecer la conexión o ampliar los alcances.
  • Ser diferente para cada perfil distinto que pueda conectarse a través de la app.
  • Mantenerse sin cambios cuando cambie el correo electrónico, el nombre o la etiqueta visible del perfil.
  • No reasignarse nunca a otro perfil después de eliminar el perfil original.

No generes un ID nuevo por cada inicio de sesión, token, sesión o llamada a una herramienta. Guarda el correo electrónico y los nombres editables en los metadatos de visualización. Una dirección de correo electrónico que puede cambiar o reasignarse no sirve como ID de perfil estable. Para OIDC de Google, usa el valor estable de sub en lugar de la declaración de correo electrónico. Google indica que el correo electrónico puede cambiar, mientras que sub permanece sin cambios y nunca se reutiliza. Consulta la documentación de identidad de Google.

Conserva los ID de perfil existentes cuando actualices tu integración. Un cambio de nombre visible, un token nuevo o una conexión nueva no deben crear una identidad de perfil nueva.

Implementa y declara tu herramienta de perfil

Ofrece una herramienta de solo lectura que requiera autenticación, acepte un objeto de argumentos vacío y devuelva el perfil actual. La herramienta puede llamarse get_profile, whoami o tener otro nombre. Sus metadatos la identifican como herramienta de perfil para que pueda descubrirse en tiempo de ejecución. La respuesta debe cumplir con los requisitos de identidad que se indican a continuación para que OpenAI pueda usarla correctamente.

  • Determina la identidad a partir de las credenciales validadas de la solicitud.
  • Asegúrate de que la operación sea de solo lectura y esté disponible con los permisos habituales de la conexión.
  • Devuelve exactamente un perfil: el que representan las credenciales de la solicitud actual.
  • No exijas que quien llama a la herramienta proporcione un ID de usuario, un correo electrónico o un selector de cuenta.
  • Si falla la autenticación, devuelve el error de autenticación correspondiente en lugar de un ID provisional o el perfil de otra cuenta.

La respuesta de perfil debe ajustarse al siguiente esquema JSON:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1,
      "pattern": "\\S",
      "description": "Opaque profile identifier, unique within this app and unchanged across token refresh, reconnection, and display-metadata changes. Never reassigned to another profile."
    },
    "name": {
      "type": "string",
      "description": "Display name for the authenticated profile."
    },
    "email": {
      "type": "string",
      "description": "Email address for display; not used as the profile identity."
    },
    "nickname": {
      "type": "string",
      "description": "A useful label that helps users distinguish connected profiles."
    }
  },
  "required": ["id"],
  "additionalProperties": false
}

La respuesta debe contener un id de tipo cadena que no esté vacío ni contenga únicamente espacios en blanco. Los campos de visualización son opcionales. Los metadatos de la herramienta indican a OpenAI dónde obtener la información del perfil. La respuesta identifica el perfil representado por las credenciales actuales.

La validación del esquema comprueba si la respuesta tiene la estructura y los tipos de campo necesarios para gestionar el perfil. Tu servicio también debe garantizar que el ID sea único, se mantenga estable y corresponda al perfil de las credenciales. Ni los metadatos ni una validación correcta del esquema demuestran que se cumplan esas condiciones.

Incluye name, email o nickname, o una combinación de estos campos, cuando estén disponibles para que los usuarios puedan distinguir los perfiles. Omite los valores opcionales que no estén disponibles. No los inventes ni agregues datos personales ajenos al perfil. Coloca la información de contexto que resulte útil y fácil de entender en nickname en lugar de incluirla en el ID.

Marca la herramienta con _meta["openai/profile"]: true y publica el esquema de la respuesta de perfil como su outputSchema. El marcador indica a OpenAI qué herramienta proporciona la información del perfil. No habilita la función ni concede acceso a ella. Si el marcador está ausente o es falso, la herramienta no está designada como fuente de perfiles mediante este mecanismo. Las cadenas, los números y el valor nulo no son valores válidos para el marcador.

{
  "name": "get_profile",
  "description": "Return the profile represented by this request's authenticated credentials. The opaque id is unique within this app and remains unchanged across token refresh, reconnection, and display-metadata changes.",
  "inputSchema": {
    "type": "object",
    "properties": {},
    "additionalProperties": false
  },
  "outputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "id": {
        "type": "string",
        "minLength": 1,
        "pattern": "\\S",
        "description": "Opaque profile identifier, unique within this app and unchanged across token refresh, reconnection, and display-metadata changes. Never reassigned to another profile."
      },
      "name": {
        "type": "string",
        "description": "Display name for the authenticated profile."
      },
      "email": {
        "type": "string",
        "description": "Email address for display; not used as the profile identity."
      },
      "nickname": {
        "type": "string",
        "description": "A useful label that helps users distinguish connected profiles."
      }
    },
    "required": ["id"],
    "additionalProperties": false
  },
  "annotations": {
    "readOnlyHint": true,
    "destructiveHint": false,
    "openWorldHint": false
  },
  "securitySchemes": [
    {
      "type": "oauth2",
      "scopes": []
    }
  ],
  "_meta": {
    "openai/profile": true
  }
}

Usa los alcances de OAuth de tu integración si el acceso al perfil los requiere. La declaración no implementa la autenticación. El servidor debe validar las credenciales y hacer cumplir los permisos. Consulta la sección sobre la implementación de la verificación de tokens y la referencia de herramientas.

Devuelve el perfil en structuredContent para que pueda validarse con outputSchema. Por compatibilidad, incluye también el mismo perfil serializado como JSON en un elemento de contenido de texto:

{
  "content": [
    {
      "type": "text",
      "text": "{\"id\":\"prf_8d7e4b19\",\"name\":\"Alex Chen\",\"email\":\"alex@example.com\",\"nickname\":\"Alex — Moonwaffle work\"}"
    }
  ],
  "structuredContent": {
    "id": "prf_8d7e4b19",
    "name": "Alex Chen",
    "email": "alex@example.com",
    "nickname": "Alex — Moonwaffle work"
  },
  "isError": false
}

Usa un único objeto JSON con los campos del perfil en el nivel superior.

¿Ya tienes una herramienta de perfil? Conserva su nombre, agrega la declaración de metadatos de perfil y devuelve la respuesta de perfil estándar. Si la respuesta existente tiene otra estructura, adáptala en tu servidor u ofrece una pequeña herramienta que llame a la original y se ajuste al esquema. El procedimiento de integración estándar usa la misma declaración y estructura de respuesta para todas las apps.

Ejemplo concreto: perfiles persistentes de Moonwaffle

Supongamos que Moonwaffle, un servicio ficticio, permite a Alex conectar dos perfiles de forma independiente. Moonwaffle almacena un ID opaco distinto para cada perfil. Las credenciales de la solicitud identifican uno de esos perfiles almacenados y la herramienta de perfil devuelve su ID existente.

Ejemplo de perfiles almacenados. Las etiquetas pueden cambiar, pero los identificadores se mantienen:

Alex — Moonwaffle personal: prf_42a9c6e0
Alex — Moonwaffle work:     prf_8d7e4b19

Estos ID de ejemplo no codifican etiquetas de perfil ni relaciones internas. Se guardan una sola vez por perfil y se reutilizan al restablecer la conexión, actualizar el token o cambiar el correo electrónico o el nombre visible.

Construye la respuesta a partir del perfil autenticado. Este ejemplo de JavaScript muestra la lógica de un controlador que puedes conectar a tu SDK de MCP. loadAuthenticatedProfile es el código de integración de tu aplicación: valida las credenciales de la solicitud, hace cumplir sus permisos y recupera el ID almacenado y los metadatos de visualización del perfil correspondiente. requestContext proviene del procesamiento de solicitudes de tu servidor. El modelo no lo proporciona como argumento de la herramienta.

async function getProfile(requestContext) {
  // Your auth/provider integration validates credentials and loads
  // the existing profile. Auth failures use normal MCP auth handling.
  const account = await loadAuthenticatedProfile(requestContext);
  const id = account.profileId;

  if (typeof id !== "string" || id.trim().length === 0) {
    return {
      isError: true,
      content: [{ type: "text", text: "Profile identity unavailable." }],
    };
  }

  // Return the persisted ID unchanged; do not generate an ID per call.
  const profile = {
    id,
    ...(typeof account.name === "string" ? { name: account.name } : {}),
    ...(typeof account.email === "string" ? { email: account.email } : {}),
    ...(typeof account.nickname === "string"
      ? { nickname: account.nickname }
      : {}),
  };

  return {
    isError: false,
    structuredContent: profile,
    content: [{ type: "text", text: JSON.stringify(profile) }],
  };
}

Registra este controlador con la declaración de metadatos y los esquemas de entrada y salida anteriores. loadAuthenticatedProfile debe recuperar el mismo perfil almacenado si las credenciales son equivalentes y también después de restablecer la conexión. No debe crear un ID de perfil nuevo por cada concesión de OAuth o sesión. Todas las demás herramientas deben usar las credenciales de la solicitud para hacer cumplir los permisos de ese mismo perfil.

Verifica el comportamiento de la identidad:

Prueba Resultado esperado
Llamadas repetidas con el perfil de trabajo de Moonwaffle prf_8d7e4b19 en cada llamada
El mismo perfil después de actualizar el token, restablecer la conexión o ampliar los alcances prf_8d7e4b19
El mismo perfil después de cambiar el correo electrónico o la etiqueta visible prf_8d7e4b19, aunque las etiquetas cambien
Perfil personal de Moonwaffle prf_42a9c6e0, distinto del ID del perfil de trabajo
El ID de perfil almacenado falta o está en blanco Un resultado de error, sin inventar una identidad ni recurrir a otro perfil

La garantía de identidad debe mantenerse para todos los perfiles y ante futuros cambios en tu integración. Consérvala independientemente de los metadatos de visualización, del contenido del token y de los eventos del ciclo de vida de la conexión.

Pruebas y lanzamiento

  • Pruebas locales: comienza con una instancia de desarrollo que emita tokens de corta duración para que puedas iterar rápidamente.
  • Pruebas internas: una vez que la autenticación funcione, limita el acceso a personas de confianza que puedan probarla antes del lanzamiento general. Puedes exigir la vinculación para herramientas específicas o para todo el servidor MCP.
  • Rotación: planifica la revocación y la actualización de tokens, así como los cambios de alcance. Tu servidor debe tratar como no autenticadas las solicitudes con tokens ausentes o desactualizados y devolver un mensaje de error útil.
  • Depuración de OAuth: usa la configuración de autenticación de MCP Inspector para recorrer cada paso de OAuth e identificar dónde falla el flujo antes del lanzamiento.

Una vez implementada la autenticación, puedes ofrecer a los usuarios de ChatGPT y Codex acceso a datos específicos de cada usuario y a operaciones de escritura.

Activación de la interfaz de autenticación

ChatGPT solo muestra su interfaz de vinculación de OAuth cuando tu servidor MCP indica que OAuth está disponible o es necesario.

Para activar el flujo de OAuth de una herramienta, se necesitan tanto los metadatos (securitySchemes y el documento de metadatos del recurso) como los errores en tiempo de ejecución que incluyan _meta["mcp/www_authenticate"]. Si falta alguno de estos elementos, ChatGPT no mostrará la interfaz de vinculación para esa herramienta.

  1. Publica los metadatos del recurso. El servidor MCP debe ofrecer su configuración de OAuth en una URL estándar, como https://your-mcp.example.com/.well-known/oauth-protected-resource.

  2. Describe la política de autenticación de cada herramienta con securitySchemes. Al declarar securitySchemes para cada herramienta, indicas a ChatGPT cuáles requieren OAuth y cuáles pueden ejecutarse de forma anónima. Usa declaraciones por herramienta aunque todo el servidor aplique la misma política. Los valores predeterminados del servidor dificultan modificar cada herramienta por separado más adelante.

    Actualmente hay dos tipos de esquemas disponibles. Puedes indicar más de uno para expresar que la autenticación es opcional:

    • noauth: la herramienta admite llamadas anónimas y ChatGPT puede ejecutarla de inmediato.
    • oauth2: la herramienta necesita un token de acceso de OAuth 2.0. Incluye los alcances que solicitarás para que la pantalla de consentimiento los muestre correctamente.

    Si omites el arreglo por completo, la herramienta hereda el valor predeterminado que anuncie el servidor. Si declaras tanto noauth como oauth2, le indicas a ChatGPT que puede comenzar con llamadas anónimas y que la vinculación habilita operaciones que requieren privilegios. Independientemente de lo que le indiques al cliente, tu servidor debe verificar el token, los alcances y la audiencia en cada llamada.

    Ejemplo de acceso público con autenticación opcional en el SDK de TypeScript

    import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
    import { z } from "zod";
    
    const server = new McpServer({ name: "auth-example", version: "1.0.0" });
    
    server.registerTool(
      "search",
      {
        title: "Public Search",
        description: "Search public documents.",
        inputSchema: {
          q: z.string(),
        },
        outputSchema: {},
        _meta: {
          securitySchemes: [
            { type: "noauth" },
            { type: "oauth2", scopes: ["search.read"] },
          ],
        },
      },
      async ({ q }) => {
        return {
          content: [{ type: "text", text: `Results for ${q}` }],
          structuredContent: {},
        };
      }
    );

    Ejemplo de autenticación obligatoria en el SDK de TypeScript

    import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
    import { z } from "zod";
    
    const server = new McpServer({ name: "auth-example", version: "1.0.0" });
    
    server.registerTool(
      "create_doc",
      {
        title: "Create Document",
        description: "Make a new doc in your account.",
        inputSchema: {
          title: z.string(),
        },
        outputSchema: {},
        _meta: {
          securitySchemes: [{ type: "oauth2", scopes: ["docs.write"] }],
        },
      },
      async ({ title }) => {
        return {
          content: [{ type: "text", text: `Created doc: ${title}` }],
          structuredContent: {},
        };
      }
    );
  3. Comprueba los tokens en el controlador de la herramienta y devuelve _meta["mcp/www_authenticate"] cuando quieras que ChatGPT active la interfaz de autenticación. Examina el token y verifica el emisor, la audiencia, el vencimiento y los alcances. Si no hay un token válido, devuelve un resultado de error que incluya _meta["mcp/www_authenticate"] y comprueba que el valor contenga tanto el parámetro error como el parámetro error_description. Una vez completados los pasos 1 y 2, el contenido de WWW-Authenticate es lo que activa la interfaz de OAuth de la herramienta. Cuando un desafío solicita una nueva autorización, tu proveedor puede conservar el contexto de inicio de sesión del usuario durante ese flujo.

    Ejemplo

    {
      "jsonrpc": "2.0",
      "id": 4,
      "result": {
        "content": [
          {
            "type": "text",
            "text": "Authentication required: no access token provided."
          }
        ],
        "_meta": {
          "mcp/www_authenticate": [
            "'Bearer resource_metadata=\"https://your-mcp.example.com/.well-known/oauth-protected-resource\", error=\"insufficient_scope\", error_description=\"You need to login to continue\"'"
          ]
        },
        "isError": true
      }
    }