Voltar as noticias
Como um CLI sem cabeça faz login: implementando o Fluxo de Código de Dispositivo OAuth para um cliente MCP
MCP ProtocolMediaEN

Como um CLI sem cabeça faz login: implementando o Fluxo de Código de Dispositivo OAuth para um cliente MCP

Dev.to - MCP·9 de junho de 2026

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:

  1. O CLI chama /oauth/device/authorize e recebe de volta um device_code (o segredo da máquina) e um user_code (um código curto que um humano digita).
  2. O CLI mostra ao usuário "abra esta URL e digite ABCD-EFGH", então começa a consultar /oauth/device/token em segundo plano.
  3. O usuário abre a página de verificação em seu navegador normal, já logado, digita o user_code e aprova.
  4. 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["
Contexto Triplo Up

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

Gostou do conteudo?

Receba toda semana as principais novidades sobre WebMCP.