O cliente diz “conectado”, o tools/list responde, e toda ferramenta de
conta devolve 401 para sempre. Não há erro para pesquisar — este artigo é a mensagem
que faltava.
mcp login <servidor> (ou o botão
“conectar/autenticar”) termina com algo como “o servidor respondeu, mas nenhum token OAuth foi
obtido”.*.client.json (resultado do registro dinâmico) e não o *.json
com access_token.401.A especificação de autorização do MCP faz o cliente começar o fluxo de forma reativa: ele só descobre o servidor de autorização e começa o OAuth quando recebe de volta
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://<host>/.well-known/oauth-protected-resource"
Um servidor que responde initialize e tools/list sem exigir
autenticação (200) e só desafia 401 nas chamadas de conta nunca dispara esse gatilho durante
a sondagem de login. A sondagem vê “conectado” e para — e o cliente encerra sem URL, sem
consentimento e sem token.
Isso é uma escolha de desenho do servidor (superfície pública + ferramentas de conta privadas), não um servidor quebrado nem um cliente quebrado: o que falha é a interação entre os dois.
401 + WWW-Authenticate com resource_metadata=. Se vier
200, a ferramenta é pública: escolha outra (perfil / biblioteca / créditos / pedidos).
curl -sS -i -m 20 -X POST "$MCP_URL" -H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"<ferramenta_de_conta>","arguments":{}}}' | head -30authorization_servers[] e scopes_supported[].
curl -sS -m 20 "$MCP_URL_ORIGIN/.well-known/oauth-protected-resource"registration_endpoint
(você não precisa registrar cliente à mão), authorization_endpoint,
token_endpoint, code_challenge_methods_supported: S256 e
token_endpoint_auth_methods_supported: none (cliente público + PKCE).
curl -sS -m 20 "$AUTH_SERVER/.well-known/oauth-authorization-server"*.client.json significa OAuth não concluído.
ls -la "$TOKEN_DIR" # ~/.config/<cliente>/mcp-tokens/, ~/.mcp/tokens/Leitura: (1) 401 com WWW-Authenticate = servidor corretamente configurado,
o cliente é que nunca perguntou; (3) com registration_endpoint = o fluxo é automático e
não existe cliente para registrar à mão — seja qual for a sugestão do erro do cliente.
<servidor>.auth: oauth com um bloco
oauth (flow: browser ou device, timeout).registration_endpoint (JSON com redirect_uris, client_name,
grant_types:["authorization_code","refresh_token"],
response_types:["code"], token_endpoint_auth_method:"none"), abra o
authorization_endpoint com response_type=code, code_challenge
(S256) e state, capture o code no redirect de loopback, troque no
token_endpoint com o code_verifier e grave o token no formato que o
cliente espera.registration_endpoint presente, token ausenteO arquivo de registro
prova só o registro dinâmico. Confira se existe access_token.refresh_token e
releia o arquivo de token quando o access token expirar, em vez de repetir o fluxo interativo.CAUSE: <uma frase: qual passo do fluxo nunca aconteceu>
EVIDENCE: <a linha do 401 + WWW-Authenticate, a linha do registration_endpoint, o caminho do token>
FIX APPLIED: <A | B | C + o que mudou>
VERIFIED: <a chamada de conta exata e o texto devolvido, ou "NOT VERIFIED: <por quê>">
NEXT: <uma única próxima ação>
A última linha é a que mais importa: VERIFIED com a saída crua, ou a confissão de
que não deu para verificar. “Conectado” não é evidência.
A skill MCP OAuth Debug traz o diagnóstico completo, o checklist de uma página e a
implementação de referência do fix B (scripts/force-oauth-challenge.py), para qualquer
cliente MCP e qualquer servidor protegido por OAuth.
Ver a skill MCP OAuth Debug Ver todas as skills
Precisa resolver isso no seu projeto? Setup guiado a partir de R$ 1.500, com o primeiro ciclo rodado junto.