Referência · Agentes de IA nas redes sociais

OAuth em servidor MCP: como ele autentica um agente e o que quebra

Por Antoine Blanco··7 min de leitura

Um servidor MCP remoto autentica um agente como servidor de recursos OAuth 2.1. Ele responde a uma chamada sem token com 401 e um cabeçalho WWW-Authenticate, o cliente segue esse caminho até os metadados do servidor, roda um fluxo de código de autorização com PKCE e envia o token como cabeçalho bearer em cada requisição. Aqui vai cada passo, executado ao vivo hoje.

A autorização é opcional no MCP, e só para transportes HTTP: um servidor stdio local lê as credenciais do ambiente. Tudo o que vem abaixo é da revisão atual da especificação, 2026-07-28, e cada resposta é uma chamada real para https://api.plugkit.co/mcp feita em 16 de outubro de 2026.

O aperto de mão, em quatro respostas

Passo 1. Chamar sem token e ler o desafio. O servidor precisa devolver um 401 com um cabeçalho WWW-Authenticate apontando para os metadados dele.

curl -i -X POST https://api.plugkit.co/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
HTTP/2 401
www-authenticate: Bearer resource_metadata="https://api.plugkit.co/.well-known/oauth-protected-resource", scope="mcp:read mcp:write"
{"error":"Missing credentials. Send `Authorization: Bearer <api key or session token>`.","type":"authentication_error","code":"unauthorized"}

A dica de scope é um SHOULD na especificação, não um MUST, e é a diferença entre um cliente que pede as permissões certas de primeira e um que adivinha. Os clientes precisam tratar os escopos do desafio como autoridade para a operação.

Passo 2. Buscar os metadados do recurso protegido. É a RFC 9728, e é um MUST para todo servidor MCP.

{"resource":"https://api.plugkit.co/mcp",
 "authorization_servers":["https://api.plugkit.co"],
 "scopes_supported":["mcp:read","mcp:write"],
 "bearer_methods_supported":["header"],
 "resource_documentation":"https://docs.plugkit.co"}

Passo 3. Buscar os metadados do servidor de autorização. RFC 8414, ou OpenID Connect Discovery; o servidor precisa oferecer pelo menos um, e o cliente precisa suportar os dois.

{"issuer":"https://api.plugkit.co",
 "authorization_endpoint":"https://api.plugkit.co/oauth/authorize",
 "token_endpoint":"https://api.plugkit.co/oauth/token",
 "registration_endpoint":"https://api.plugkit.co/oauth/register",
 "revocation_endpoint":"https://api.plugkit.co/oauth/revoke",
 "code_challenge_methods_supported":["S256"],
 "token_endpoint_auth_methods_supported":["none"],
 "client_id_metadata_document_supported":true,
 "authorization_response_iss_parameter_supported":true}

Passo 4. Rodar o fluxo de código e chamar de novo com o token. Código de autorização com PKCE, o parâmetro resource nas duas requisições, e depois Authorization: Bearer <token> em absolutamente toda requisição HTTP, inclusive nas da mesma sessão.

Autenticação de um servidor MCP: de onde vem o client ID

Essa é a parte que mudou, e a parte que a maioria dos tutoriais ainda conta errado. A revisão atual lista três mecanismos e os ordena.

Mecanismo Status na revisão 2026-07-28 O que o cliente envia como client_id
Client ID Metadata Documents SHOULD support Uma URL HTTPS que o servidor busca para ler os metadados do cliente
Registro prévio Permitido Um client ID que te entregaram por fora
Dynamic Client Registration (RFC 7591) MAY support, obsoleto Um client ID vindo de POST /register

O registro dinâmico era um SHOULD na revisão 2025-06-18. Agora é explicitamente “deprecated and retained for backwards compatibility with authorization servers that do not support Client ID Metadata Documents”. O CIMD substitui isso por algo mais simples: o cliente usa uma URL como identificador, o servidor de autorização busca essa URL, lê os metadados e valida as redirect URIs. Sem chamada de registro e sem um cadastro de cliente guardado por cliente.

O servidor do PlugKit acima anuncia as duas coisas, client_id_metadata_document_supported: true e um registration_endpoint ativo, que é a postura correta enquanto os clientes se atualizam.

OAuth 2.1 no MCP: PKCE, o parâmetro resource e a vinculação de audiência

Três exigências fazem o trabalho de segurança, e as três são MUST para os clientes.

  1. PKCE. Obrigatório em todos os clientes. S256 é o método que o servidor acima publica. Ele impede que um código de autorização interceptado seja trocado por qualquer cliente que não seja o que iniciou o fluxo.
  2. O parâmetro resource. RFC 8707, tanto na requisição de autorização quanto na de token, levando a URI canônica do servidor MCP: &resource=https%3A%2F%2Fapi.plugkit.co%2Fmcp. Os clientes devem enviá-lo, com ou sem suporte do servidor.
  3. Validação da audiência. O servidor precisa verificar que o token foi emitido para ele, e precisa recusar qualquer outro. A especificação é categórica: um servidor MCP “MUST NOT accept or transit any other tokens”.

Essa última tem nome. Se um servidor pega um token destinado a outro e repassa para cima, aparece o problema do delegado confuso: a API de destino confia na chamada porque ela veio do servidor. O passthrough de token é proibido, e é por isso que um servidor que chama uma API externa precisa ter o próprio token separado para ela. Essa é a metade “servidor para plataforma” do problema, e ela tem as próprias falhas, tratadas em os tokens de acesso das redes sociais.

O que quebra

Cinco falhas, na ordem em que você provavelmente vai encontrá-las.

Sintoma Status Causa Correção
O cliente nunca inicia o fluxo 401 Sem cabeçalho WWW-Authenticate, ou sem metadados de recurso Implemente a RFC 9728 e devolva o cabeçalho em cada 401
Chamada de ferramenta recusada, e o token parece certo 403 Falta ao token um escopo de que a operação precisa Devolva error="insufficient_scope" com scope, e deixe o cliente elevar os escopos
Loop de pedidos de consentimento no navegador 401 Refresh token expirado ou revogado, com um cliente que tenta de novo às cegas Limite as tentativas e trate a falha repetida como definitiva
Token recusado por um segundo servidor 401 Token enviado a um servidor para o qual não foi emitido Envie o parâmetro resource e valide a audiência
O fluxo termina contra o servidor errado nenhum Ataque de confusão de servidores, iss não verificado Guarde o emissor antes de redirecionar e compare na volta

A dos escopos merece detalhe, porque é nova e fácil de errar. Quando um token é válido mas estreito demais, o servidor deve responder 403 com error="insufficient_scope" e os escopos de que a operação precisa. O cliente então reautoriza com a união do que já tinha e do que acabou de ser pedido, não só o escopo novo, ou perde as permissões que estava usando antes. Os servidores deveriam enviar todos os escopos de que a operação precisa num único desafio, em vez de pingar um por ida e volta.

A verificação do iss é a mais silenciosa das cinco, porque nada falha de forma visível. O cliente precisa guardar o emissor dos metadados validados antes de abrir o navegador, e depois comparar o iss que volta no callback, sem nenhuma normalização: sem igualar maiúsculas, sem barra final, sem limpar o percent-encoding. O servidor acima define authorization_response_iss_parameter_supported: true, então um iss ausente na resposta precisa ser recusado de imediato.

Auth de servidor MCP remoto: OAuth ou chave de API?

As duas funcionam, e a escolha é sobre escopos e revogação, não sobre teatro de segurança.

OAuth 2.1 Chave de API
Granularidade Escopos, só leitura é possível Acesso total, nenhum escopo
Quem guarda o segredo O cliente, renovável Você, num arquivo de configuração ou variável de ambiente
Revogação Por aplicativo conectado, pelo usuário Rode a chave, e quebra todos os consumidores
Serve para Clientes interativos, terceiros Scripts, cron, seu próprio backend

No servidor acima, os dois escopos se separam com clareza: mcp:read cobre perfis, contas, posts, conversas e analytics; mcp:write acrescenta publicar, enviar mensagens, responder comentários e conectar ou desconectar contas. Uma chave de API carrega acesso total e nenhum escopo, que é a razão honesta para preferir OAuth em tudo que um modelo conduz de forma interativa. Deixe um agente em mcp:read por uma semana antes de permitir que ele escreva, como em Claude como seu gestor de redes sociais.

O mesmo servidor é acessível no Claude, no ChatGPT, no Claude Code, no Cursor e no VS Code, e custa US$ 49 por mês para 5 contas conectadas, cancela quando quiser, com 7 dias grátis e sem cartão. Se um servidor MCP é a forma certa para a sua integração é outra pergunta, respondida em MCP ou API REST para o seu agente; para um exemplo real dentro de um cliente, veja o servidor MCP do Instagram.

Texto normativo completo: a especificação de autorização do MCP, lida em 16 de outubro de 2026.

Perguntas frequentes

Um servidor MCP precisa de OAuth?

Só se ele for remoto e você quiser autorização por usuário. A autorização é opcional na especificação, e servidores stdio locais não deveriam usá-la de jeito nenhum, e sim pegar as credenciais do ambiente. Um servidor HTTP que atende vários usuários deveria implementá-la, porque uma chave de API dá o mesmo acesso total a quem a tiver.

Qual versão do OAuth o MCP usa?

OAuth 2.1, com PKCE obrigatório em todos os clientes, metadados de recurso protegido (RFC 9728) obrigatórios em todos os servidores, e o parâmetro resource da RFC 8707 obrigatório nas requisições de autorização e de token. A revisão atual é a 2026-07-28, que também traz a identificação do emissor da RFC 9207.

O registro dinâmico de cliente ainda é obrigatório no MCP?

Não. Passou de SHOULD na revisão 2025-06-18 para MAY na atual, e a especificação chama isso de obsoleto, mantido para servidores que não suportam Client ID Metadata Documents. O CIMD é o caminho recomendado: o cliente usa uma URL HTTPS como client ID e o servidor de autorização lê os metadados ali.

Por que meu cliente MCP fica pedindo que eu entre de novo?

Normalmente um refresh token expirado ou revogado com um cliente que repete o fluxo em vez de parar. A especificação manda os clientes limitarem as tentativas e tratarem a falha repetida como definitiva. Verifique se o usuário revogou o app, e se o seu servidor de autorização rotaciona os refresh tokens, o que ele precisa fazer para clientes públicos.

O que significa um 403 de um servidor MCP?

O token é válido mas falta um escopo de que a operação precisa. O servidor deveria devolver error="insufficient_scope" junto com os escopos exigidos, e o cliente deveria reautorizar pedindo esses mais tudo que já tinha. Um 401 quer dizer credenciais ausentes ou inválidas, e um 400 quer dizer que a própria requisição de autorização estava malformada.

AB
Antoine BlancoFundador da PlugKit. Gerencia as próprias contas de Instagram, YouTube e X pela API e pelo servidor MCP descritos aqui.

Um plug para cada plataforma que seu agente usa

$49 por mês para 5 contas conectadas, cancele quando quiser. Todos os recursos em todos os planos.

Pegue sua chave de API →
Português ▾