
Como um CLI sem cabeça faz login: implementando o Fluxo de Código de Dispositivo OAuth para um cliente MCP
Quando você conecta um servidor MCP ao seu próprio serviço, um problema sem glamour aparece rapidamente: como o CLI faz login?
Um aplicativo web com um navegador pode usar o fluxo de código de autorização OAuth — redirecionar o usuário para uma página de login, trocar o código retornado por um token. Mas os clientes MCP frequentemente rodam onde não há navegador GUI: via SSH, em um contêiner CI, em uma máquina sem interface gráfica. O truque de loopback (http://localhost:random_port como o alvo de redirecionamento) também não ajuda, porque não há navegador para abrir.
OAuth tem uma resposta adequada para "autenticar um usuário onde não há navegador": RFC 8628, o Dispositivo de Autorização, também conhecido como Fluxo de Código do Dispositivo. Eu implementei isso no serviço de autenticação da Codens, então aqui está o design e o código real.
A ideia: separar onde você autentica de onde você aprova
O Fluxo de Código do Dispositivo separa o "dispositivo que mostra um código" (o CLI) do "dispositivo que aprova" (seu navegador cotidiano). É a mesma coisa que fazer login na Netflix em uma TV: um código aparece na tela, você o digita no seu telefone.
O fluxo:
- O CLI chama
/oauth/device/authorizee recebe de volta umdevice_code(o segredo da máquina) e umuser_code(um código curto que um humano digita). - O CLI mostra ao usuário "abra esta URL e digite ABCD-EFGH", então começa a consultar
/oauth/device/tokenem segundo plano. - O usuário abre a página de verificação em seu navegador normal, já logado, digita o
user_codee aprova. - No momento em que é aprovado, a consulta do CLI recebe o token.
O CLI nunca abre um navegador. O usuário aprova de qualquer navegador que já tenha — telefone, outro laptop, qualquer coisa.
Endpoint 1: device/authorize
O CLI chama isso primeiro. Ele aceita um client_id e scope e emite os dois códigos.
@router.post("/device/authorize", response_model=DeviceAuthorizationResponse)
async def device_authorize(
client_id: str = Form(...),
scope: str = Form("openid profile email"),
session: AsyncSession = Depends(get_session),
):
# Este cliente está autorizado a usar a concessão device_code?
client = await OAuthClientRepository(session).get_by_client_id(client_id)
if not client or not client.is_active:
return JSONResponse(status_code=400,
content={"error": "invalid_client", "error_description": "Cliente desconhecido"})
allowed_grants = (client.grant_types or "").split()
if _DEVICE_GRANT_TYPE not in allowed_grants:
return JSONResponse(status_code=400,
content={"error": "unauthorized_client",
"error_description": "Cliente não autorizado para a concessão device_code"})
store = get_device_code_store()
result = await store.create(client_id=client_id, scope=scope)
frontend_url = settings.FRONTEND_URL.rstrip("/")
return DeviceAuthorizationResponse(
device_code=result["device_code"],
user_code=result["user_code"],
verification_uri=f"{frontend_url}/device",
expires_in=result["expires_in"], # 900s
interval=result["A implementação do Fluxo de Código de Dispositivo pode facilitar a integração de serviços em ambientes sem GUI, como servidores e containers. Isso é crucial para empresas que utilizam MCPs em suas operações, permitindo uma autenticação mais flexível e segura.
Noticias relacionadas

Seu AI pode ler todo o seu portfólio de cripto através do MCP
O HeadlessTracker é um servidor MCP open-source que permite que assistentes de IA acessem informações sobre portfólios de cripto de forma simplificada, sem necessidade de chaves de API.

Guia de Configuração do CodeGraph 2026: Reduza Chamadas de Ferramentas do Claude Code em 58%
O CodeGraph v0.9.9 é um servidor MCP local que pré-indexa seu código, reduzindo chamadas de ferramentas e custos de API. Com benchmarks que mostram 58% menos chamadas, é ideal para usuários do Claude Code e Cursor.
MCP para Claude: a explicação para iniciantes que eu gostaria de ter tido
O MCP é mais fácil de entender se não for tratado como 'mais um plugin de IA'. É um padrão de conexão entre um cliente de IA e ferramentas externas, com vocabulário básico e permissões importantes.
Gostou do conteudo?
Receba toda semana as principais novidades sobre WebMCP.