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

Autenticação

Padrões de autenticação para servidores MCP de plug-ins.

Autentique seus usuários

Muitos servidores MCP de plug-ins podem operar em modo anônimo e somente leitura, mas qualquer servidor que exponha dados específicos de clientes ou ações de escrita deve autenticar os usuários.

Os plug-ins publicados podem ser executados no ChatGPT e no Codex. O contrato de autorização do MCP se aplica aos dois produtos; este guia destaca detalhes do cliente específicos do ChatGPT quando um callback, documento de metadados ou interface de vinculação varia entre as interfaces dos produtos.

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

Autenticação personalizada com OAuth 2.1

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

Componentes

  • Servidor de recursos: Seu servidor MCP, que expõe ferramentas e verifica os tokens de acesso em cada requisição.
  • Servidor de autorização: Seu provedor de identidade ou 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 seu servidor MCP
  • Publique os metadados OAuth do seu servidor de autorização
  • Reproduza 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 no endpoint de tokens aceitos pelo seu servidor de autorização

Veja o que a especificação exige, em linguagem simples.

Hospede os metadados do recurso protegido no seu servidor MCP

  • Você precisa de um endpoint HTTPS, como GET https://your-mcp.example.com/.well-known/oauth-protected-resource (ou informar a mesma URL em um cabeçalho WWW-Authenticate nas respostas 401 Unauthorized), para que o ChatGPT saiba onde buscar seus metadados.
  • Esse endpoint retorna um documento JSON que descreve o servidor de recursos e os servidores de autorização disponíveis para ele:
{
  "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"
}
  • Principais campos que você deve preencher:
    • resource: o identificador HTTPS canônico do seu servidor MCP. O ChatGPT envia exatamente esse valor como o parâmetro de consulta resource durante o fluxo OAuth.
    • authorization_servers: uma ou mais URLs base de emissores que apontam para seu provedor de identidade. O ChatGPT tentará cada uma delas para encontrar os metadados OAuth.
    • scopes_supported: lista opcional que ajuda o ChatGPT a explicar as permissões que solicitará ao usuário.
    • Campos opcionais adicionais da RFC 9728, como resource_documentation, resource_policy_uri ou resource_tos_uri, facilitam a compreensão da sua configuração por clientes e administradores.

Ao bloquear uma requisição por não estar autenticada, retorne um desafio de autenticação 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 único cabeçalho permite que o ChatGPT descubra a URL dos metadados mesmo que ainda não a conheça.

Publique os metadados OAuth do seu servidor de autorização

  • Seu provedor de identidade deve expor um dos documentos de descoberta em um endereço padronizado para que o ChatGPT possa ler sua 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 responde a três perguntas principais para o host da OpenAI: para onde direcionar o usuário, como trocar códigos e como se identificar. Uma resposta típica é assim:
{
  "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 devem estar corretos:
    • issuer: o 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 seu servidor de autorização retornar um parâmetro iss em todas as respostas de autorização, incluindo as respostas de erro.
    • authorization_endpoint, token_endpoint: as URLs de que o ChatGPT precisa para executar o fluxo OAuth de código de autorização + PKCE do início ao fim.
    • client_id_metadata_document_supported: defina como true quando quiser que o ChatGPT use CIMD para registrar o cliente. O ChatGPT prioriza CIMD quando está disponível, mas o desenvolvedor do plug-in pode escolher DCR quando ambos estão disponíveis.
    • token_endpoint_auth_methods_supported: inclua os métodos de autenticação no endpoint de tokens aceitos pelo seu servidor de autorização. Isso se aplica a CIMD, DCR e clientes OAuth predefinidos. Para CIMD, o ChatGPT oferece suporte a none para a troca de tokens por clientes públicos e a private_key_jwt para a troca de tokens com uma asserção de cliente assinada. Outros clientes OAuth costumam usar none, client_secret_post ou client_secret_basic.
    • registration_endpoint: inclua este campo se você oferecer suporte ao registro dinâmico de clientes (DCR), que permite ao ChatGPT 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 este campo ou não indicam suporte a S256, conforme exigido pela especificação de autorização do MCP.
    • Os campos opcionais seguem a RFC 8414 / OpenID Discovery; inclua o que ajudar seus administradores a configurar políticas.

Escopos OIDC

  • Se o seu provedor indicar escopos OIDC (por exemplo, openid, email, 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 podem não habilitar por padrão os escopos OIDC indicados nos metadados. Confira as configurações do seu provedor e verifique se todos os escopos indicados estão habilitados para o cliente OAuth, independentemente de ele usar CIMD, ter sido criado manualmente ou por DCR.

Ofereça suporte às restrições de domínio do workspace

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

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

  • Publicar metadados de descoberta do OpenID Connect.
  • Indicar e habilitar os escopos openid e email.
  • Indicar 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 o endpoint UserInfo é obrigatório para as restrições de domínio do workspace.

O workspace para empresas também deve verificar seu domínio. Seu servidor de autorização fornece a identidade do usuário que o ChatGPT compara com os domínios verificados configurados para o workspace; ele não verifica se um domínio pertence ao workspace.

Preserve o contexto de login durante a reautorização

Quando o ChatGPT reautoriza uma vinculação existente, inclusive para solicitar escopos OAuth adicionais, ele pode incluir o token de ID OIDC anterior na requisição de autorização como o parâmetro padrão id_token_hint. Para permitir que os usuários concedam escopos adicionais sem reiniciar o login do zero, configure seu servidor de autorização para emitir um token de ID durante o fluxo OAuth original e respeitar id_token_hint durante a autorização.

Essa otimização é opcional. A reautorização continua funcionando quando não há um token de ID disponível ou quando seu 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 da RFC 9207 para proteger os callbacks OAuth contra ataques de confusão entre servidores de autorização. 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 seu 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 de sucesso quanto de erro. Seu valor deve corresponder exatamente a issuer nos metadados; os clientes comparam as strings exatamente como estão, sem normalizar barras finais, caminhos, portas ou letras maiúsculas e minúsculas.

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

URL de redirecionamento

Copie exatamente o URI de redirecionamento de produção exibido na página de gerenciamento do servidor MCP para a lista de permissões do seu servidor de autorização.

  • Se o seu 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 seu 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 introduzir redirecionamentos específicos do ID de callback também continuam usando o URI de redirecionamento estável.

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

  • O ChatGPT acrescentará resource=https%3A%2F%2Fyour-mcp.example.com tanto às solicitações de autorização quanto às de token. Isso vincula o token aos metadados do recurso protegido mostrados acima.
  • Configure seu servidor de autorização para copiar esse valor para o token de acesso (geralmente na declaração aud), de modo que seu servidor MCP possa verificar se o token foi emitido exclusivamente para ele.
  • Se um token chegar 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

  • O ChatGPT, atuando como cliente MCP, 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.
  • Seu servidor de autorização deve publicar code_challenge_methods_supported com S256 para que os clientes possam confirmar o suporte a PKCE pelos metadados.

Fluxo OAuth

Desde que você tenha implementado a especificação de autorização MCP descrita acima, o fluxo OAuth será o seguinte:

  1. O ChatGPT consulta seu 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 https://chatgpt.com/oauth/{callback_id}/client.json, específica do ID de callback. A página de gerenciamento do servidor MCP mostra o documento exato de metadados do cliente e o URI de redirecionamento para o modo de callback da conexão. Quando o servidor MCP usa DCR, o ChatGPT chama o registration_endpoint do seu servidor de autorização uma vez para a conexão com o servidor MCP, recebe um client_id gerado e reutiliza esse cliente na conexão.

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

  1. Quando o usuário invoca uma ferramenta pela primeira vez, o cliente ChatGPT inicia o fluxo OAuth de código de autorização + 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 anexa às solicitações MCP subsequentes (Authorization: Bearer <token>).

  1. Seu servidor verifica o token em cada solicitação (emissor, destinatário, expiração 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 de clientes quando seu servidor de autorização oferecer suporte a ele e o criador do plug-in o escolher. Com CIMD, o ChatGPT usa a URL HTTPS de um documento de metadados como seu client_id. Seu servidor de autorização busca esse documento, valida os metadados publicados do cliente e os identificadores de recurso de redirecionamento e trata a URL como a identidade estável do ChatGPT como cliente.

Se você oferece suporte a CIMD, defina client_id_metadata_document_supported: true nos metadados do seu servidor de autorização. Isso permite que o ChatGPT use uma única identidade estável de cliente para servidores MCP que escolhem CIMD. Seu servidor de autorização pode usar essa identidade em listas de permissões de URIs de redirecionamento, limites de taxa e outras políticas.

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

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

O campo no plural representa perspectivas diferentes nos dois documentos: os metadados do servidor de autorização listam os métodos que seu endpoint de token aceita, enquanto o documento CIMD do ChatGPT lista os métodos que o ChatGPT pode usar. O ChatGPT seleciona um método da interseção desses conjuntos. Quando a preferência legada no singular faz parte da interseção, o ChatGPT a usa para manter a compatibilidade com servidores de autorização que ainda tratam o campo no singular como obrigatório. Caso contrário, o ChatGPT pode usar outro método da interseção.

Os servidores de autorização que leem o campo CIMD no plural devem aceitar qualquer método da interseção, a menos que a política de segurança local proíba esse método para o cliente. Eles devem rejeitar métodos fora da 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 um método.

Os métodos compatíveis são:

  • none: use esse fluxo de cliente público quando seu endpoint de token oferecer suporte à troca de código de autorização baseada em 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 seu endpoint de token exigir autenticação do cliente. O ChatGPT publica uma URL pública de JWKS em seus metadados CIMD. O JWKS é disponibilizado em /oauth/jwks.json, na origem dos metadados. O ChatGPT assina as solicitações de token no servidor com uma chave privada gerenciada e um kid; seu servidor de autorização verifica a asserção usando o JWKS público.

O DCR continua sendo compatível. Se você incluir registration_endpoint, o ChatGPT poderá se registrar dinamicamente quando o criador do plug-in escolher DCR ou quando CIMD não estiver disponível. O ChatGPT executa o DCR uma vez por conexão com o servidor MCP e, depois, mantém e reutiliza o cliente OAuth registrado para essa conexão. O DCR ainda pode criar muitos clientes registrados em várias conexões separadas, por isso o CIMD costuma ser mais fácil de administrar em escala.

Mantenha o cliente OAuth registrado e qualquer segredo do cliente válidos enquanto a conexão com o servidor MCP estiver em uso. Se o seu servidor de autorização expirar, excluir ou substituir qualquer uma dessas credenciais, usuários e revisores poderão receber um erro invalid_client ao se conectar. Os tokens de acesso e de atualização ainda podem expirar ou passar por rotação normalmente.

Identificação do cliente

Uma dúvida frequente é como seu servidor MCP pode confirmar que uma solicitação realmente vem do ChatGPT. O ChatGPT apresenta um certificado de cliente gerenciado pela OpenAI ao se conectar a servidores MCP, permitindo 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 do 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 bearer, nem pode apresentar chaves de API personalizadas ou certificados mTLS fornecidos pelo cliente.

O CIMD reforça ainda mais a identificação do cliente ao fornecer ao seu 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 que o ChatGPT envia ao endpoint de token usando o JWKS público publicado 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 seu aplicativo valida certificados de cliente, configure-o para confiar na cadeia de certificados da OpenAI abaixo.

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

  • Verifique se há um certificado folha e se sua cadeia leva à CA intermediária OpenAI Connectors mTLS.
  • Verifique se o certificado folha é válido para autenticação de cliente.
  • Verifique se o dnsName no SAN do certificado folha é mtls.prod.connectors.openai.com.
  • Evite fixar a impressão digital de um certificado folha; a OpenAI pode realizar a rotação do certificado folha mantendo-o na cadeia de CAs 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.

Como escolher um provedor de identidade

A maioria dos provedores de identidade OAuth 2.1 pode atender aos requisitos de autorização MCP desde que disponibilize um documento de descoberta, ofereça suporte a CIMD com none ou private_key_jwt, ofereça suporte a DCR quando necessário e reproduza o parâmetro resource nos tokens emitidos. Prefira provedores que ofereçam suporte a CIMD para registro de clientes.

Recomendamos fortemente que você use um provedor de identidade já consolidado em vez de implementar a autenticação do zero por conta própria.

Veja as instruções para alguns provedores de identidade populares.

Auth0

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

Exemplo de provedor hospedado

Como implementar a verificação de tokens

Quando o fluxo OAuth termina, o ChatGPT anexa diretamente o token de acesso recebido às solicitações MCP subsequentes (Authorization: Bearer …). Quando uma solicitação chega ao seu servidor MCP, você deve tratar o token como não confiável e executar por conta própria todas as verificações do servidor de recursos: validação da assinatura, correspondência de emissor e destinatário, expiração, análise de riscos de reutilização e aplicação dos escopos. Essa responsabilidade é sua, não do ChatGPT.

Na prática, você deve:

  • Buscar as chaves de assinatura publicadas pelo seu servidor de autorização (geralmente via JWKS) e verificar a assinatura e o iss do token.
  • Rejeitar tokens que expiraram ou ainda não se tornaram válidos (exp/nbf).
  • Confirmar que o token foi emitido para seu servidor (aud ou a declaração resource) e contém os escopos que você definiu como obrigatórios.
  • Executar todas as verificações de políticas específicas do servidor e, em seguida, anexar a identidade identificada ao contexto da solicitação ou retornar 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 seu recurso protegido. Isso informa ao cliente que ele deve executar o fluxo OAuth novamente.

Primitivas de verificação de tokens dos SDKs

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

Ofereça suporte a várias contas

O suporte a várias contas permite que os usuários conectem mais de uma conta ao mesmo plug-in, como contas pessoais e de trabalho. A OpenAI encaminha cada chamada de ferramenta usando as credenciais autenticadas da conexão selecionada. Os usuários podem conectar várias contas sem uma ferramenta de perfil. Para ajudar os usuários a distinguir as conexões e reconhecer o mesmo perfil após uma reconexão, forneça uma ferramenta de perfil autenticada com um ID estável e metadados de exibição úteis.

Como o suporte a várias contas funciona para os usuários

Os usuários podem conectar outras contas pela página de configurações do plug-in. Todas as contas conectadas ficam disponíveis para o modelo, que seleciona a conta ou as contas relevantes ao chamar ferramentas com base na 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 os perfis conectados e mostrar rótulos úteis:

  • Forneça uma ferramenta de perfil autenticada que retorne um ID opaco que identifique de forma única e estável o perfil representado pelas credenciais da requisição. Isso permite que a OpenAI reconheça o mesmo perfil após reconexões e o diferencie de outros perfis. Um campo chamado id só é útil para esse fim se seu valor oferecer essas garantias.
  • Designe a ferramenta de perfil nos metadados MCP para que a OpenAI possa descobrir qual ferramenta chamar para obter informações do perfil autenticado.

Quando precisa de informações do perfil, a OpenAI descobre a ferramenta designada 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 ou a detecção de duplicatas podem ser menos confiáveis. Se você declarar uma ferramenta de perfil, retorne uma identidade válida; uma resposta inválida pode impedir a conexão da conta.

Defina uma identidade de perfil estável

Um perfil identifica a identidade representada pelas credenciais autenticadas da requisição. Seu serviço define quais perfis podem ser conectados de forma independente; este contrato não determina o modelo de organização ou autorização do seu serviço.

Retorne um ID de perfil opaco e único no seu aplicativo. O mesmo perfil deve manter seu ID após a renovação do token e a reconexão; perfis distintos devem ter IDs distintos. A OpenAI compara esses IDs sem interpretar seu conteúdo.

Use um ID de provedor existente, imutável e opaco quando ele identificar o perfil completo. Caso contrário, atribua um ID opaco uma única vez, persista sua associação com esse 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 relacionamentos organizacionais no ID retornado.

Seu id deve:

  • Ser uma string não vazia que não contenha apenas espaços em branco. Serialize IDs numéricos de provedores como strings.
  • Permanecer o mesmo para o mesmo perfil após renovações de token, reconexões e ampliações de escopo.
  • Ser diferente para perfis distintos que possam 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 um perfil diferente 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 possa mudar ou ser reatribuído não pode servir como ID estável do perfil. No Google OIDC, use o valor estável de sub em vez da declaração de e-mail; a documentação do Google informa que 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 sua integração. Uma mudança no nome de exibição, um novo token ou uma nova conexão não deve criar uma nova identidade de perfil.

Implemente e declare sua ferramenta de perfil

Exponha 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; seus metadados a identificam como a 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.
  • Faça com que a operação seja somente leitura e esteja disponível com as permissões normais da conexão.
  • Retorne exatamente um perfil: o perfil representado pelas credenciais da requisição atual.
  • Não exija que quem chama a ferramenta forneça um ID de usuário, e-mail ou seletor de conta.
  • Em caso de falha na autenticação, 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 estar em conformidade com 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 um campo id do tipo string, não vazio e que não contenha apenas espaços em branco. Os campos de exibição são opcionais. Os metadados da ferramenta informam à OpenAI onde obter as informações do perfil; a resposta identifica o perfil representado pelas credenciais atuais.

A validação do esquema verifica se uma resposta tem a estrutura e os tipos de campo necessários para o tratamento de perfis. Seu serviço também deve garantir a unicidade e a estabilidade dos IDs e a delimitação correta do escopo das credenciais; nem os metadados nem a aprovação na validação do esquema comprovam essas propriedades de comportamento.

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

Marque a ferramenta com _meta["openai/profile"]: true e publique o esquema da resposta de perfil como seu outputSchema. O marcador informa à OpenAI qual ferramenta fornece as informações do perfil; ele não habilita o recurso nem concede elegibilidade. Um marcador ausente ou falso significa que essa ferramenta não está designada como fonte de perfil 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
  }
}

Use os escopos OAuth reais da sua integração se o acesso ao perfil os exigir. A declaração não implementa a autenticação; o servidor deve validar as credenciais e aplicar as permissões. Consulte Implementação da verificação de tokens e a referência de ferramentas.

Retorne o perfil em structuredContent para que ele possa ser validado de acordo com 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 dela, adicione a declaração de metadados de perfil e retorne a resposta de perfil padrão. Se a resposta existente tiver outro formato, adapte-a no seu servidor ou exponha uma pequena ferramenta que encapsule a existente e esteja em conformidade com o esquema. O fluxo de integração padrão usa a mesma declaração e o mesmo formato de resposta para todos os aplicativos.

Exemplo concreto: perfis persistentes do Moonwaffle

Suponha 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 desses perfis armazenados, e a ferramenta de perfil retorna o ID existente dele.

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

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

Esses IDs de exemplo não codificam rótulos de perfil nem relacionamentos internos. Eles são persistidos uma única vez por perfil e reutilizados após reconexões, renovações de token e alterações no e-mail ou no nome de exibição.

Crie a resposta a partir do perfil autenticado. Este exemplo em JavaScript mostra a lógica de um manipulador que você pode conectar ao seu SDK MCP. loadAuthenticatedProfile é o código de integração do seu aplicativo: ele valida as credenciais da requisição, aplica as permissões delas e recupera o ID persistido e os metadados de exibição do perfil correspondente. requestContext vem do processamento de requisições do seu servidor; não é um argumento de ferramenta fornecido pelo modelo.

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 esse manipulador com a declaração de metadados e os esquemas de entrada e saída acima. loadAuthenticatedProfile deve identificar o mesmo perfil armazenado para credenciais equivalentes e após a reconexão. Ele 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:

TesteResultado esperado
Chamadas repetidas para o perfil de trabalho do Moonwaffleprf_8d7e4b19 em todas as chamadas
O mesmo perfil após a renovação do token, reconexão ou ampliação de escopoprf_8d7e4b19
O mesmo perfil após uma alteração no e-mail ou no rótulo de exibiçãoprf_8d7e4b19; os rótulos podem mudar
Perfil pessoal do Moonwaffleprf_42a9c6e0, distinto do perfil de trabalho
O ID persistido do perfil está ausente ou em brancoUm resultado de erro; nenhuma identidade inventada nem uso de outro perfil como alternativa

A garantia de identidade deve se manter para todos os perfis e em futuras alterações na sua 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 gradual

  • Testes locais: Comece com um tenant de desenvolvimento que emita tokens de curta duração para poder iterar rapidamente.
  • Testes internos: Quando a autenticação estiver funcionando, restrinja o acesso a pessoas de confiança para testar antes de disponibilizá-lo amplamente. Você pode exigir a vinculação de contas para ferramentas específicas ou para todo o servidor MCP.
  • Rotação: Planeje a revogação e a renovação de tokens, além das alterações de escopo. Seu servidor deve tratar requisições com tokens ausentes ou desatualizados como não autenticadas e retornar uma mensagem de erro útil.
  • Depuração de OAuth: Use as configurações de autenticação do MCP Inspector para percorrer cada etapa do OAuth e identificar exatamente onde o fluxo falha antes do lançamento.

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

Acionar a interface de autenticação

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

Para acionar o fluxo OAuth de uma ferramenta, são necessários os metadados (securitySchemes e o documento de metadados do recurso) e erros em tempo de execução que contenham _meta["mcp/www_authenticate"]. Sem essas duas partes, o ChatGPT não exibirá a interface de vinculação para essa ferramenta.

  1. Publique os metadados do recurso. O servidor MCP deve expor sua 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 para cada 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; os padrões definidos no nível do servidor dificultam a evolução de ferramentas individuais no futuro.

    Atualmente, há dois tipos de esquema disponíveis, e você pode listar mais de um para indicar que a autenticação é opcional:

    • noauth: a ferramenta pode ser chamada anonimamente; o ChatGPT pode executá-la imediatamente.
    • oauth2: a ferramenta precisa de um token de acesso OAuth 2.0; inclua os escopos que você solicitará para que a tela de consentimento mostre as informações corretas.

    Se você omitir o array por completo, a ferramenta herdará o padrão informado pelo servidor. Declarar tanto noauth quanto oauth2 informa ao ChatGPT que ele pode começar com chamadas anônimas, mas que a vinculação libera funcionalidades que exigem privilégios. Independentemente do que você sinalizar ao cliente, seu servidor ainda deve verificar o token, os escopos e o destinatário em cada chamada.

    Exemplo (acesso público + autenticação opcional) — SDK para TypeScript

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

    Exemplo (autenticação obrigatória) — SDK para TypeScript

    import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
    import { z } from "zod";
    
    declare const server: McpServer;
    
    server.registerTool(
      "create_doc",
      {
        title: "Create Document",
        description: "Make a new doc in your account.",
        inputSchema: {
          title: z.string(),
        },
        outputSchema: {},
        securitySchemes: [{ type: "oauth2", scopes: ["docs.write"] }],
      },
      async ({ title }) => {
        return {
          content: [{ type: "text", text: `Created doc: ${title}` }],
          structuredContent: {},
        };
      }
    );
  3. Verifique os tokens dentro do manipulador da ferramenta e emita _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 expiração e os escopos. Se não houver um token válido, retorne um resultado de erro que inclua _meta["mcp/www_authenticate"] e garanta que o valor contenha os parâmetros error e error_description. É esse payload de WWW-Authenticate que efetivamente aciona a interface OAuth da ferramenta após a implementação das etapas 1 e 2. Quando um desafio de autenticação solicitar uma nova autorização, seu provedor poderá preservar o contexto de login existente do usuário durante esse 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
      }
    }