For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navegação principal
Theme
Visão geral Documentação para usuários do ChatGPT e do Codex Casos de uso

Autenticação

Padrões de autenticação para servidores MCP de plugins.

Autentique os usuários

Muitos servidores MCP de plugins podem operar em modo anônimo e somente leitura. Se o servidor expõe dados específicos de clientes ou permite operações de escrita, ele deve autenticar os usuários.

Os plugins publicados podem ser executados no ChatGPT e no Codex. O contrato de autorização do MCP se aplica aos dois produtos. Este guia destaca os detalhes específicos do cliente ChatGPT quando o callback, o documento de metadados ou a interface de vinculação varia de um produto para o outro.

Você pode integrar seu próprio servidor de autorização quando precisar se conectar a um aplicativo existente que é executado no servidor ou compartilhar dados entre usuários.

Autenticação personalizada com OAuth 2.1

Para um servidor MCP com autenticação, implemente um fluxo OAuth 2.1 em conformidade com a especificação de autorização do MCP.

Componentes

  • Servidor de recursos: seu servidor MCP, que disponibiliza ferramentas e verifica os tokens de acesso a cada requisição.
  • Servidor de autorização: seu provedor de identidade ou uma implementação personalizada que emite tokens e publica metadados de descoberta.
  • Cliente: o host da OpenAI, como o ChatGPT ou o Codex, que atua em nome do usuário. Os clientes compatíveis usam documentos de metadados de ID do cliente (CIMD), registro dinâmico de clientes (DCR), clientes OAuth predefinidos e PKCE.

Requisitos da especificação de autorização do MCP

  • Hospede os metadados do recurso protegido no servidor MCP
  • Publique os metadados OAuth no servidor de autorização
  • Repasse o parâmetro resource ao longo de todo o fluxo OAuth
  • Escolha como o host da OpenAI identifica ou registra seu cliente OAuth: CIMD, DCR ou um cliente OAuth predefinido
  • Publique os métodos de autenticação aceitos pelo endpoint de token do servidor de autorização

Veja o que cada requisito significa na prática.

Hospede os metadados do recurso protegido no servidor MCP

  • Disponibilize um endpoint HTTPS como GET https://your-mcp.example.com/.well-known/oauth-protected-resource (ou informe a mesma URL no cabeçalho WWW-Authenticate das respostas 401 Unauthorized) para que o ChatGPT saiba onde buscar os metadados.
  • Esse endpoint retorna um documento JSON que descreve o servidor de recursos e os servidores de autorização disponíveis:
{
  "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"
}
  • Preencha os campos principais conforme indicado:
    • resource: identificador HTTPS canônico do servidor MCP. O ChatGPT envia exatamente esse valor no parâmetro de consulta resource durante o fluxo OAuth.
    • authorization_servers: uma ou mais URLs base de emissores que apontam para o provedor de identidade. O ChatGPT consulta cada uma delas até encontrar os metadados OAuth.
    • scopes_supported: lista opcional que ajuda o ChatGPT a explicar quais permissões vai solicitar ao usuário.
    • Campos opcionais da RFC 9728, como resource_documentation, resource_policy_uri ou resource_tos_uri, ajudam clientes e administradores a entender a configuração.

Quando bloquear uma requisição por falta de autenticação, retorne um desafio como este:

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

Esse cabeçalho basta para que o ChatGPT descubra a URL dos metadados, mesmo no primeiro acesso.

Publique os metadados OAuth no servidor de autorização

  • Seu provedor de identidade deve disponibilizar um dos documentos de descoberta em um endereço padronizado para que o ChatGPT possa ler a configuração:
    • Metadados OAuth 2.0 em https://auth.yourcompany.com/.well-known/oauth-authorization-server
    • Metadados OpenID Connect em https://auth.yourcompany.com/.well-known/openid-configuration
  • Cada documento informa ao host da OpenAI para onde encaminhar o usuário, como trocar códigos por tokens e como se identificar. Veja uma resposta 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"]
}
  • Configure corretamente os seguintes campos:
    • issuer: identificador canônico do servidor de autorização. Use exatamente esse valor na lista authorization_servers dos metadados do recurso protegido.
    • authorization_response_iss_parameter_supported: defina como true somente se o servidor de autorização retornar o parâmetro iss em todas as respostas de autorização, inclusive nas de erro.
    • authorization_endpoint, token_endpoint: URLs que o ChatGPT usa para executar todo o fluxo OAuth de código de autorização com PKCE.
    • client_id_metadata_document_supported: defina como true se quiser que o ChatGPT use CIMD para registrar o cliente. O ChatGPT prioriza CIMD quando disponível, mas quem cria o plugin pode optar por DCR se ambos estiverem disponíveis.
    • token_endpoint_auth_methods_supported: inclua os métodos de autenticação aceitos pelo endpoint de token do servidor de autorização. Isso vale para CIMD, DCR e clientes OAuth predefinidos. Com CIMD, o ChatGPT aceita none para a troca de código por token em clientes públicos e private_key_jwt para a troca com uma asserção assinada do cliente. Outros clientes OAuth costumam usar none, client_secret_post ou client_secret_basic.
    • registration_endpoint: inclua esse campo se oferecer registro dinâmico de clientes (DCR). Com ele, o ChatGPT pode criar e reutilizar um client_id exclusivo para a conexão com o servidor MCP.
    • code_challenge_methods_supported: deve incluir S256. Não há suporte a servidores MCP quando os metadados do servidor de autorização omitem esse campo ou não declaram S256, conforme exige a especificação de autorização do MCP.
    • Os campos opcionais seguem a RFC 8414 e a especificação de descoberta do OpenID. Inclua os que ajudarem os administradores a configurar políticas.

Escopos OIDC

  • Se o provedor declarar escopos OIDC (como openid, email e profile) em scopes_supported no documento .well-known/oauth-authorization-server ou .well-known/openid-configuration, o ChatGPT solicitará esses escopos por padrão durante o fluxo OAuth.
  • Alguns provedores de identidade não habilitam por padrão os escopos OIDC que declaram. Verifique as configurações do provedor e confirme que todos os escopos declarados estão habilitados para o cliente OAuth, seja ele identificado por CIMD, criado manualmente ou registrado via DCR.

Ofereça suporte às restrições de domínio do espaço de trabalho

Os espaços de trabalho do ChatGPT Enterprise podem verificar a propriedade de domínios de e-mail. Quando um plugin vinculado via OAuth fornece o endereço de e-mail verificado do usuário, o ChatGPT pode usar o domínio desse endereço para impedir que o usuário vincule o plugin com essa identidade corporativa em um espaço de trabalho pessoal ou em outro espaço de trabalho fora da organização.

Para oferecer essa proteção, configure o servidor de autorização para:

  • Publicar os metadados de descoberta do OpenID Connect.
  • Declarar e habilitar os escopos openid e email.
  • Divulgar um endpoint UserInfo que retorne a declaração email do usuário e email_verified: true.

Você também pode retornar essas declarações em um token de ID durante o fluxo OAuth, mas as restrições de domínio do espaço de trabalho exigem o endpoint UserInfo.

O espaço de trabalho Enterprise também precisa verificar a propriedade do domínio. O servidor de autorização fornece a identidade do usuário para que o ChatGPT a compare com os domínios verificados configurados no espaço de trabalho. A verificação da propriedade do domínio cabe ao espaço de trabalho.

Preserve o contexto de login durante a reautorização

Quando o ChatGPT reautoriza um vínculo existente, inclusive para solicitar escopos OAuth adicionais, ele pode incluir o token de ID OIDC anterior na requisição de autorização por meio do parâmetro padrão id_token_hint. Para que os usuários possam conceder escopos adicionais sem refazer o login, configure o servidor de autorização para emitir um token de ID durante o fluxo OAuth original e levar em conta id_token_hint durante a autorização.

Essa otimização é opcional. A reautorização funciona mesmo quando o token de ID está indisponível ou o servidor de autorização não usa essa indicação.

Proteja os callbacks com a identificação do emissor

Os hosts da OpenAI usam a identificação do emissor definida na RFC 9207 para proteger os callbacks OAuth contra ataques que confundem um servidor de autorização com outro. Para permitir que o ChatGPT e o Codex usem um URI de redirecionamento estável ao criar um cliente OAuth elegível:

  • Defina authorization_response_iss_parameter_supported: true nos metadados do servidor de autorização.
  • Use exatamente o mesmo identificador de emissor no campo issuer dos metadados e na lista authorization_servers dos metadados do recurso protegido.
  • Retorne iss em todas as respostas de autorização, tanto nas de sucesso quanto nas de erro. O valor deve corresponder exatamente a issuer nos metadados. Os clientes comparam as strings literalmente, sem normalizar barras finais, caminhos, portas ou diferenças entre maiúsculas e minúsculas.

O ChatGPT e o Codex registram o valor de issuer dos metadados selecionados antes de redirecionar o usuário e verificam o iss retornado antes de trocar o código de autorização por um token. Se o servidor declarar que identifica o emissor, mas omitir iss ou retornar um valor diferente, o ChatGPT e o Codex rejeitarão a resposta. Esses requisitos seguem as regras do MCP para validação de respostas de autorização.

URL de redirecionamento

Copie o URI de redirecionamento de produção exatamente como aparece na página de gerenciamento do servidor MCP e adicione-o à lista de permissões do servidor de autorização.

  • Se o servidor de autorização não atender aos requisitos de identificação do emissor descritos acima, o ChatGPT usará o URI de redirecionamento específico do ID de callback https://chatgpt.com/connector/oauth/{callback_id}.
  • Se o servidor de autorização atender a esses requisitos, o ChatGPT usará o URI de redirecionamento estável https://chatgpt.com/connector_platform_oauth_redirect.

Os servidores MCP publicados antes de o ChatGPT adotar redirecionamentos específicos por ID de callback também continuam a usar o URI de redirecionamento estável.

Repasse o parâmetro resource ao longo de todo o fluxo OAuth

  • O ChatGPT acrescenta resource=https%3A%2F%2Fyour-mcp.example.com tanto à requisição de autorização quanto à de token. Isso vincula o token aos metadados do recurso protegido mostrados acima.
  • Configure o servidor de autorização para copiar esse valor para o token de acesso (geralmente na declaração aud). Assim, o servidor MCP pode verificar se o token foi emitido exclusivamente para ele.
  • Se receber um token sem o destinatário ou os escopos esperados, rejeite-o e use o desafio WWW-Authenticate para solicitar que o ChatGPT refaça a autorização com os parâmetros corretos.

Ofereça suporte ao fluxo de código de autorização

  • Como cliente MCP, o ChatGPT executa o fluxo de código de autorização com PKCE usando o desafio de código S256 para impedir que um invasor reutilize códigos de autorização interceptados.
  • O servidor de autorização deve publicar code_challenge_methods_supported com S256 para que os clientes possam confirmar o suporte a PKCE nos metadados.

Fluxo OAuth

Depois que você implementar a especificação de autorização do MCP descrita acima, o fluxo OAuth seguirá estas etapas:

  1. O ChatGPT consulta o servidor MCP para obter os metadados do recurso protegido.

  1. O ChatGPT se identifica como cliente OAuth. Quando o servidor MCP usa CIMD, o ChatGPT pula o registro dinâmico de clientes e envia a URL de um documento CIMD como client_id. Para servidores de autorização que atendem aos requisitos de identificação do emissor descritos acima, o ChatGPT usa a URL estável https://chatgpt.com/oauth/client.json. Para os demais, usa a URL específica do ID de callback https://chatgpt.com/oauth/{callback_id}/client.json. A página de gerenciamento do servidor MCP mostra o documento de metadados do cliente e o URI de redirecionamento exatos para o modo de callback da conexão. Quando o servidor MCP usa DCR, o ChatGPT chama o registration_endpoint do servidor de autorização uma única vez para a conexão com o servidor MCP, recebe o client_id gerado e reutiliza esse cliente na conexão.

Com CIMD, não há etapa de registro do cliente. A tela a seguir mostra o fluxo com DCR:

  1. Na primeira vez que o usuário chama uma ferramenta, o cliente ChatGPT inicia o fluxo OAuth de código de autorização com PKCE. O usuário se autentica e consente com os escopos solicitados.

  1. O ChatGPT troca o código de autorização por um token de acesso e o inclui nas requisições MCP seguintes (Authorization: Bearer <token>).

  1. A cada requisição, o servidor verifica o token (emissor, destinatário, validade e escopos) antes de executar a ferramenta.

Registro de clientes

Use documentos de metadados de ID do cliente (CIMD) como método preferencial de registro quando o servidor de autorização oferecer suporte a CIMD e quem cria o plugin escolher esse método. Com CIMD, o ChatGPT usa a URL HTTPS de um documento de metadados como client_id. O servidor de autorização busca o documento, valida os metadados publicados do cliente e os identificadores de recurso de redirecionamento e usa a URL como identidade estável do cliente ChatGPT.

Se oferecer suporte a CIMD, defina client_id_metadata_document_supported: true nos metadados do servidor de autorização. Assim, o ChatGPT pode usar uma única identidade de cliente estável nos servidores MCP que optam por CIMD. O servidor de autorização pode usar essa identidade em listas de URIs de redirecionamento permitidos, limites de taxa e outras políticas.

O ChatGPT está adotando a mudança no CIMD proposta no MCP SEP-3149. O documento CIMD de produção publica token_endpoint_auth_methods_supported como um array dos métodos que o ChatGPT pode usar, sem ordem de preferência. Durante a transição, o documento também publica o campo legado no singular token_endpoint_auth_method para indicar uma preferência:

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

O campo no plural tem um significado diferente em cada documento. Nos metadados do servidor de autorização, ele lista os métodos que o endpoint de token aceita. No documento CIMD do ChatGPT, lista os métodos que o ChatGPT pode usar. O ChatGPT seleciona um método presente nas duas listas. Se o método preferido indicado no campo legado estiver nas duas listas, o ChatGPT o usará para manter a compatibilidade com servidores de autorização que ainda tratam o valor do campo no singular como obrigatório. Caso contrário, o ChatGPT poderá usar outro método comum às duas listas.

Os servidores de autorização que leem o campo CIMD no plural devem aceitar qualquer método presente nas duas listas, a menos que a política de segurança local proíba esse método para o cliente. Eles devem rejeitar os métodos fora dessa interseção. A URL de client_id permanece estável e não usa parâmetros de consulta para selecionar um documento específico de cada método.

Os métodos compatíveis são:

  • none: use esse fluxo para clientes públicos quando o endpoint de token aceitar a troca de código de autorização por token com PKCE sem autenticação do cliente. O ChatGPT não armazena um segredo por cliente.
  • private_key_jwt: use esse fluxo de asserção assinada do cliente quando o endpoint de token exigir autenticação do cliente. O ChatGPT publica a URL de um JWKS público nos metadados CIMD. O JWKS fica disponível em /oauth/jwks.json, na mesma origem dos metadados. O ChatGPT assina as requisições de token no servidor com uma chave privada gerenciada e indica a chave pelo kid. O servidor de autorização verifica a asserção usando o JWKS público.

O ChatGPT continua oferecendo suporte a DCR. Se você incluir registration_endpoint, o ChatGPT poderá se registrar dinamicamente quando quem cria o plugin optar por DCR ou quando CIMD estiver indisponível. O ChatGPT executa o DCR uma vez por conexão com o servidor MCP e mantém o cliente OAuth registrado para reutilizá-lo nessa conexão. Como o DCR pode criar muitos registros de clientes quando há muitas conexões distintas, o CIMD costuma ser mais fácil de administrar em escala.

Mantenha o registro do cliente OAuth e qualquer segredo do cliente válidos enquanto a conexão com o servidor MCP estiver em uso. Se o servidor de autorização fizer uma dessas credenciais expirar, excluí-la ou substituí-la, usuários e revisores poderão receber um erro invalid_client ao se conectar. Os tokens de acesso e de atualização podem continuar a expirar ou ser rotacionados normalmente.

Identificação do cliente

Uma dúvida comum é como o servidor MCP pode confirmar que uma requisição realmente vem do ChatGPT. Ao se conectar a servidores MCP, o ChatGPT apresenta um certificado de cliente gerenciado pela OpenAI. Assim, você pode verificar o cliente na camada de transporte com mTLS. Você também pode adicionar à lista de permissões as faixas de IP de saída publicadas pelo ChatGPT. O ChatGPT não oferece suporte a concessões OAuth entre máquinas, como credenciais de cliente, contas de serviço ou asserções JWT do tipo bearer. Também não pode apresentar chaves de API personalizadas ou certificados mTLS fornecidos pelo cliente.

O CIMD reforça a identificação do cliente ao fornecer ao servidor de autorização uma declaração estável da identidade do ChatGPT hospedada via HTTPS. Ao usar private_key_jwt, verifique a asserção de cliente apresentada pelo ChatGPT ao endpoint de token usando o JWKS público divulgado nos metadados CIMD.

TLS mútuo (mTLS)

O ChatGPT agora apresenta um certificado de cliente gerenciado pela OpenAI ao estabelecer conexões TLS com servidores MCP. Se o seu aplicativo valida certificados de cliente, configure-o para confiar na cadeia de certificados da OpenAI indicada abaixo.

Para validar o certificado do cliente ao estabelecer a conexão TLS com o servidor MCP:

  • Verifique se há um certificado final e se sua cadeia leva à autoridade certificadora intermediária de mTLS dos conectores da OpenAI.
  • Verifique se o certificado final é válido para autenticação de cliente.
  • Verifique se o campo dnsName do SAN do certificado final tem o valor mtls.prod.connectors.openai.com.
  • Evite fixar a impressão digital de um certificado final. A OpenAI pode rotacionar esse certificado e mantê-lo na cadeia de autoridades certificadoras publicada.

Use mTLS para autenticar o ChatGPT como cliente MCP. Continue usando OAuth 2.1 para autenticar o usuário final e autorizar o acesso às ferramentas.

Escolha de um provedor de identidade

A maioria dos provedores de identidade OAuth 2.1 consegue atender aos requisitos de autorização do MCP desde que disponibilize um documento de descoberta, ofereça suporte a CIMD com none ou private_key_jwt, aceite DCR quando necessário e inclua o valor do parâmetro resource nos tokens emitidos. Dê preferência a provedores que aceitem CIMD para o registro de clientes.

Recomendamos fortemente usar um provedor de identidade consolidado em vez de implementar a autenticação do zero.

Consulte as instruções para alguns dos provedores de identidade mais usados.

Auth0

O Auth0 permite que clientes MCP se conectem com segurança a servidores MCP. Ele oferece descoberta de metadados, registro via CIMD, segurança de API e troca de tokens para chamadas a ferramentas próprias e de terceiros.

Exemplo de provedor hospedado (Stytch)

Implemente a verificação de tokens

Ao concluir o fluxo OAuth, o ChatGPT inclui o token de acesso recebido diretamente nas requisições MCP seguintes (Authorization: Bearer …). Quando uma requisição chegar ao servidor MCP, trate o token como não confiável e execute todas as verificações que cabem ao servidor de recursos: valide a assinatura, confira o emissor e o destinatário, verifique o prazo de validade, avalie o risco de ataques de repetição e exija os escopos necessários. Cabe a você realizar essas verificações no servidor.

Na prática:

  • Busque as chaves de assinatura publicadas pelo servidor de autorização (geralmente via JWKS) e verifique a assinatura do token e o valor de iss.
  • Rejeite tokens expirados ou que ainda não entraram em vigor (exp/nbf).
  • Confirme que o token foi emitido para o seu servidor (aud ou a declaração resource) e contém os escopos que você definiu como obrigatórios.
  • Aplique as verificações de política específicas do servidor. Em seguida, associe a identidade obtida ao contexto da requisição ou retorne 401 com um desafio WWW-Authenticate.

Se a verificação falhar, responda com 401 Unauthorized e um cabeçalho WWW-Authenticate que aponte para os metadados do recurso protegido. Isso indica ao cliente que ele deve repetir o fluxo OAuth.

Recursos dos SDKs para verificação de tokens

Os SDKs do MCP para Python e TypeScript incluem funções auxiliares para que você não precise implementar toda a verificação do zero.

Ofereça suporte a várias contas

O suporte a várias contas permite que o usuário conecte mais de uma conta ao mesmo plugin, como uma conta pessoal e outra profissional. A OpenAI encaminha cada chamada de ferramenta usando as credenciais autenticadas da conexão selecionada. Os usuários podem conectar várias contas mesmo sem uma ferramenta de perfil. Para ajudá-los a distinguir as conexões e reconhecer o mesmo perfil após uma reconexão, disponibilize uma ferramenta de perfil autenticada que forneça um ID estável e metadados de exibição úteis.

Como os usuários acessam várias contas

Os usuários podem conectar outras contas na página de configurações do plugin. O modelo tem acesso a todas as contas conectadas e, ao chamar ferramentas, seleciona uma ou mais contas conforme a solicitação do usuário. Cada chamada de ferramenta usa as credenciais e permissões da conta selecionada.

Melhore a identificação das contas

Para ajudar a OpenAI a reconhecer perfis conectados e mostrar rótulos úteis:

  • Disponibilize uma ferramenta de perfil autenticada que retorne um ID opaco, único e estável para o perfil representado pelas credenciais da requisição. Assim, a OpenAI pode reconhecer o mesmo perfil em reconexões e distingui-lo dos demais. Um campo chamado id só serve para esse fim se o valor oferecer essas garantias.
  • Indique a ferramenta de perfil nos metadados MCP para que a OpenAI possa descobrir qual ferramenta chamar para obter informações sobre o perfil autenticado.

Quando precisa de informações de perfil, a OpenAI descobre a ferramenta indicada em tempo de execução, chama essa ferramenta com as credenciais da conexão e valida a resposta antes de usar os dados do perfil. Sem uma ferramenta de perfil, os usuários ainda podem conectar contas, mas os rótulos das contas, o reconhecimento de perfis ou a detecção de duplicatas podem ser menos confiáveis. Se declarar uma ferramenta de perfil, retorne uma identidade válida. Uma resposta inválida pode impedir a conexão da conta.

Defina uma identidade estável para o perfil

O perfil corresponde à identidade representada pelas credenciais autenticadas da requisição. Seu serviço define quais perfis podem ser conectados de forma independente. Esse contrato não impõe um modelo de organização ou de autorização ao serviço.

Retorne um ID de perfil opaco e exclusivo dentro do aplicativo. O mesmo perfil deve manter seu ID após a atualização do token ou a reconexão. Perfis distintos devem ter IDs distintos. A OpenAI compara esses IDs sem interpretar seu conteúdo.

Use um ID opaco e imutável já fornecido pelo provedor se ele identificar o perfil completo. Caso contrário, atribua um ID opaco uma única vez, armazene a associação com o perfil e recupere o mesmo ID nas requisições futuras. Mantenha os relacionamentos internos no seu serviço. Não codifique nomes, endereços de e-mail ou relações organizacionais no ID retornado.

O id deve atender a estes requisitos:

  • Ser uma string não vazia que contenha pelo menos um caractere que não seja espaço em branco. Serialize os IDs numéricos do provedor como strings.
  • Permanecer o mesmo para o perfil após a atualização do token, a reconexão ou a ampliação dos escopos.
  • Ser diferente para cada perfil distinto que possa se conectar pelo aplicativo.
  • Permanecer inalterado quando o e-mail, o nome ou o rótulo de exibição do perfil mudar.
  • Nunca ser reatribuído a outro perfil após a exclusão.

Não gere um novo ID a cada login, token, sessão ou chamada de ferramenta. Mantenha o e-mail e os nomes editáveis nos metadados de exibição. Um endereço de e-mail que pode mudar ou ser reatribuído não serve como ID estável do perfil. No OIDC do Google, use o identificador estável sub em vez da declaração de e-mail. Segundo a documentação do Google, o e-mail pode mudar, enquanto sub permanece inalterado e nunca é reutilizado. Consulte a documentação de identidade do Google.

Preserve os IDs de perfil existentes ao atualizar a integração. Uma mudança no nome de exibição, um novo token ou uma nova conexão não deve gerar uma nova identidade de perfil.

Implemente e declare a ferramenta de perfil

Disponibilize uma ferramenta autenticada e somente leitura que aceite um objeto de argumentos vazio e retorne o perfil atual. A ferramenta pode se chamar get_profile, whoami ou ter outro nome. São os metadados que a identificam como ferramenta de perfil para descoberta em tempo de execução. A resposta deve atender aos requisitos de identidade abaixo para que a OpenAI possa usá-la corretamente.

  • Determine a identidade a partir das credenciais validadas da requisição.
  • Garanta que a operação seja somente leitura e esteja disponível com as permissões normais da conexão.
  • Retorne exatamente um perfil: aquele representado pelas credenciais da requisição atual.
  • Não exija que quem chama a ferramenta forneça um ID de usuário, um e-mail ou um seletor de conta.
  • Se a autenticação falhar, retorne o erro de autenticação apropriado em vez de um ID provisório ou do perfil de outra conta.

A resposta de perfil deve seguir este JSON Schema:

{
  "$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
}

A resposta deve conter uma string id que não esteja vazia nem contenha apenas espaços em branco. Os campos de exibição são opcionais. Os metadados da ferramenta indicam à OpenAI onde buscar as informações de perfil. A resposta identifica o perfil representado pelas credenciais atuais.

A validação do schema verifica se a resposta tem a estrutura e os tipos de campo necessários para processar o perfil. Seu serviço também deve garantir que os IDs sejam únicos e estáveis e que cada requisição acesse apenas o perfil correspondente às credenciais. Nem os metadados nem a aprovação na validação do schema comprovam essas garantias de comportamento.

Inclua name, email e/ou nickname quando disponíveis para que os usuários possam distinguir os perfis. Omita valores opcionais indisponíveis. Não invente valores nem acrescente dados pessoais sem relação com o perfil. Coloque informações úteis e legíveis em nickname, em vez de incluí-las no ID.

Marque a ferramenta com _meta["openai/profile"]: true e publique o schema da resposta de perfil em outputSchema. O marcador informa à OpenAI qual ferramenta fornece os dados de perfil. Ele não habilita o recurso nem torna a ferramenta elegível. Se o marcador estiver ausente ou for falso, a ferramenta não estará designada como fonte de perfis por esse mecanismo. Strings, números e null são valores inválidos para o 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
  }
}

Se o acesso ao perfil exigir escopos OAuth, use os escopos reais da integração. A declaração não implementa a autenticação. O servidor deve validar as credenciais e aplicar as permissões. Consulte Implemente a verificação de tokens e a referência de ferramentas.

Retorne o perfil em structuredContent para que ele possa ser validado com base em outputSchema. Para manter a compatibilidade, inclua também o mesmo perfil serializado como JSON em um item de conteúdo 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
}

Use um único objeto JSON com os campos de perfil no nível superior.

Já tem uma ferramenta de perfil? Mantenha o nome, adicione a declaração de metadados de perfil e retorne a resposta de perfil padrão. Se a resposta atual tiver outra estrutura, adapte-a no servidor ou disponibilize uma pequena ferramenta que chame a existente e retorne uma resposta compatível com o schema. A integração padrão usa a mesma declaração e a mesma estrutura de resposta em todos os aplicativos.

Exemplo prático: perfis persistentes no Moonwaffle

Imagine que o Moonwaffle, um serviço fictício, permita que Alex conecte dois perfis de forma independente. O Moonwaffle armazena um ID opaco diferente para cada perfil. As credenciais da requisição identificam um dos perfis armazenados, e a ferramenta de perfil retorna o ID já atribuído a ele.

Exemplos de perfis armazenados. Os rótulos podem mudar, mas os identificadores permanecem os mesmos:

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

Os IDs do exemplo não codificam rótulos de perfil nem relacionamentos internos. Cada ID é armazenado uma única vez por perfil e reutilizado após reconexões, atualizações de token e mudanças de e-mail ou nome de exibição.

Monte a resposta a partir do perfil autenticado. Este exemplo em JavaScript mostra a lógica de uma função de tratamento que você pode integrar ao SDK do MCP. loadAuthenticatedProfile faz parte do código de integração do seu aplicativo. Essa função valida as credenciais da requisição, aplica as permissões correspondentes e recupera o ID armazenado e os metadados de exibição do perfil. requestContext vem do processamento da requisição no servidor. O modelo não o fornece como argumento da ferramenta.

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) }],
  };
}

Registre essa função com a declaração de metadados e os schemas de entrada e saída mostrados acima. loadAuthenticatedProfile deve recuperar o mesmo perfil armazenado para credenciais equivalentes e após uma reconexão. A função não deve criar um novo ID de perfil para cada concessão OAuth ou sessão. Todas as outras ferramentas devem usar as credenciais da requisição para aplicar as permissões desse mesmo perfil.

Verifique o comportamento da identidade:

Teste Resultado esperado
Chamadas repetidas com o perfil profissional do Moonwaffle prf_8d7e4b19 em todas as chamadas
Mesmo perfil após atualização do token, reconexão ou ampliação de escopos prf_8d7e4b19
Mesmo perfil após mudança de e-mail ou de rótulo de exibição prf_8d7e4b19, mesmo que os rótulos mudem
Perfil pessoal do Moonwaffle prf_42a9c6e0, diferente do ID do perfil profissional
ID armazenado do perfil ausente ou em branco Resultado de erro, sem inventar uma identidade nem recorrer a outro perfil

Essa garantia de identidade deve valer para todos os perfis, inclusive após mudanças futuras na integração. Preserve-a independentemente dos metadados de exibição, do conteúdo dos tokens e dos eventos do ciclo de vida da conexão.

Testes e lançamento

  • Testes locais: comece com um tenant de desenvolvimento que emita tokens de curta duração para agilizar os ciclos de teste.
  • Testes internos: quando a autenticação estiver funcionando, restrinja o acesso a pessoas de confiança para testar a integração antes do lançamento geral. Você pode exigir a vinculação de conta para ferramentas específicas ou para todo o servidor MCP.
  • Rotação: planeje como lidar com a revogação e a atualização de tokens, além de mudanças nos escopos. Quando o token estiver ausente ou desatualizado, o servidor deve tratar a requisição como não autenticada e retornar uma mensagem de erro que ajude a resolver o problema.
  • Depuração de OAuth: use as configurações de autenticação (Auth) do MCP Inspector para percorrer cada etapa do OAuth e identificar onde o fluxo falha antes do lançamento.

Com a autenticação implementada, você pode disponibilizar dados específicos de cada usuário e operações de escrita para usuários do ChatGPT e do Codex.

Acione a interface de autenticação

O ChatGPT só exibe a interface de vinculação de conta via OAuth quando o servidor MCP indica que o OAuth está disponível ou é necessário.

Para acionar o fluxo OAuth de uma ferramenta, são necessários metadados (securitySchemes e o documento de metadados do recurso) e erros em tempo de execução que incluam _meta["mcp/www_authenticate"]. Sem esses dois elementos, o ChatGPT não exibe a interface de vinculação para a ferramenta.

  1. Publique os metadados do recurso. O servidor MCP deve disponibilizar a configuração OAuth em uma URL padronizada, como https://your-mcp.example.com/.well-known/oauth-protected-resource.

  2. Descreva a política de autenticação de cada ferramenta com securitySchemes. Declarar securitySchemes por ferramenta informa ao ChatGPT quais ferramentas exigem OAuth e quais podem ser executadas anonimamente. Mantenha as declarações por ferramenta mesmo que todo o servidor use a mesma política. Usar apenas os padrões do servidor dificulta a alteração de ferramentas individuais no futuro.

    Atualmente há dois tipos de esquema. Você pode listar mais de um para indicar que a autenticação é opcional:

    • noauth: a ferramenta aceita chamadas anônimas, e o ChatGPT pode executá-la imediatamente.
    • oauth2: a ferramenta exige um token de acesso OAuth 2.0. Inclua os escopos que você vai solicitar para que a tela de consentimento mostre as permissões corretas.

    Se você omitir o array por completo, a ferramenta herdará o padrão declarado pelo servidor. Declarar tanto noauth quanto oauth2 informa ao ChatGPT que ele pode começar com chamadas anônimas e que a vinculação de conta permite operações que exigem privilégios. Independentemente do que você indicar ao cliente, o servidor deve verificar o token, os escopos e o destinatário a cada chamada.

    Exemplo de ferramenta pública com autenticação opcional no SDK para 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: {},
        };
      }
    );

    Exemplo de ferramenta com autenticação obrigatória no SDK para 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. Verifique os tokens na função que processa a chamada da ferramenta e retorne _meta["mcp/www_authenticate"] quando quiser que o ChatGPT acione a interface de autenticação. Inspecione o token e verifique o emissor, o destinatário, a validade e os escopos. Se não houver um token válido, retorne um resultado de erro que inclua _meta["mcp/www_authenticate"] e confira se o valor contém tanto o parâmetro error quanto o parâmetro error_description. Depois de implementar as etapas 1 e 2, é esse conteúdo de WWW-Authenticate que aciona a interface OAuth da ferramenta. Quando um desafio solicitar a reautorização, o provedor poderá preservar o contexto de login do usuário durante o fluxo.

    Exemplo

    {
      "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
      }
    }