Claude Code ou OpenCode via SSH: qual agente de IA roda melhor em servidor remoto?

Claude Code ou OpenCode via SSH rodando em terminal de servidor remoto
Resposta rápida

Claude Code ou OpenCode via SSH? A resposta depende de como você usa o servidor. O Claude Code tem instalador nativo para macOS, Linux e WSL, várias saídas de autenticação sem navegador (colar o código, ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN e o token de um ano do claude setup-token) e controles como CLAUDE_CODE_TOOL_MEMORY_LIMIT. O OpenCode instala por script, npm ou brew, guarda credencial em ~/.local/share/opencode/auth.json, roda sem TUI com opencode run e sobe servidor com API via opencode serve, que pede OPENCODE_SERVER_PASSWORD ao expor na rede. E é open source sob licença MIT

Fala aí, beleza? Rodar agente de IA no notebook é moleza: instala, o navegador abre sozinho, você clica em autorizar e pronto

Aí você faz a mesma coisa numa VPS acessada por SSH e a brincadeira trava logo no login

A máquina não tem tela, não tem navegador, e o servidor de callback local que o fluxo de login espera simplesmente não é alcançado por ninguém

Esse é o cenário real de muita gente: VPS, container de build, servidor sem interface gráfica, aquela caixa Linux que você só conhece pelo prompt

E nesse cenário a escolha entre Claude Code ou OpenCode via SSH não se decide por hype, se decide em três pontos bem chatos: como instala, como autentica sem navegador e como roda sem ficar preso numa sessão interativa

Se o que você quer é a comparação geral dos dois agentes no dia a dia, já tem post sobre isso aqui no blog

Aqui a gente olha só pro servidor, e só com o que a documentação oficial de cada um garante 🙂

Claude Code x OpenCode em servidor remoto: comparação item a item

Item Claude Code OpenCode
Instalação Instalador nativo para macOS, Linux e WSL: `curl -fsSL https://claude.ai/install.sh \ bash` Script oficial: `curl -fsSL https://opencode.ai/install \ bash, ou npm install -g opencode-ai (também bun, pnpm e yarn), ou brew install sst/tap/opencode` no macOS e Linux
Sistemas suportados macOS 13.0+, Windows 10 1809+ ou Windows Server 2019+, Ubuntu 20.04+, Debian 10+ e Alpine Linux 3.19+ (no Windows, o instalador documentado é o de WSL) No Windows a instalação automática não é suportada: a doc recomenda WSL e oferece o binário na página de Releases
Requisitos declarados 4 GB+ de RAM, processador x64 ou ARM64, conexão com internet, cerca de 512 MB livres pra instalar Sem requisitos mínimos publicados na documentação
Autenticação sem navegador Colar o código do navegador no prompt, ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN ou o token de um ano do claude setup-token opencode auth login, com credenciais gravadas em ~/.local/share/opencode/auth.json
Variáveis de ambiente ANTHROPIC_API_KEY (header X-Api-Key), ANTHROPIC_AUTH_TOKEN (header Authorization: Bearer), CLAUDE_CODE_OAUTH_TOKEN Precedência: credencial armazenada, depois a primeira variável de ambiente não vazia, depois settings.apiKey
Atualização Instalações nativas se atualizam sozinhas em segundo plano, e a atualização vale no próximo start Sem dado oficial sobre auto-update
Modo não interativo Modo -p opencode run, com o prompt direto na linha de comando
Modo servidor / API Sem dado oficial opencode serve, com --hostname e --port, bind padrão em 127.0.0.1
Licença Sem dado oficial MIT, no repositório sst/opencode
Formação Claude Code
Formação Recomendada

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 120 aulas
  • 4 projetos
  • 9h 45min

O que muda em cada cenário: VPS, container e Alpine

VPS acessada por SSH:

O problema aqui não é o agente, é o login

O navegador da sua máquina não alcança o servidor de callback local que roda lá no servidor, e isso é comum em sessão SSH, WSL2 e container

A documentação do Claude Code prevê exatamente essa situação: você pega o código no navegador e cola no terminal, no prompt Paste code here if prompted

Simples assim, sem gambiarra de túnel

Container e imagem enxuta:

Aqui mora o detalhe que derruba build

Em Alpine e outras bases musl ou uClibc, o Claude Code exige dependências extras em runtime: bash, curl, libgcc, libstdc++ e ripgrep

E mais uma variável de ambiente:

export USE_BUILTIN_RIPGREP=0

Tome cuidado com isso: imagem enxuta é justamente a que não traz esses pacotes por padrão, então o erro aparece depois que tudo parecia instalado

Rede corporativa com proxy:

Se a máquina remota vive atrás de proxy e certificado interno, o OpenCode documenta suporte a variáveis de ambiente de proxy padrão e a certificados customizados

É o tipo de coisa que ninguém lembra de checar antes, e que trava tudo no primeiro request

Windows:

No OpenCode a instalação automática não é suportada no Windows

O caminho recomendado pela doc é WSL, e existe binário na página de Releases pra quem prefere

No Claude Code, o Windows 10 1809+ e o Windows Server 2019+ aparecem na lista de sistemas suportados, e o instalador nativo documentado é o de macOS, Linux e WSL

Ou seja, nos dois casos o caminho de instalação que a documentação descreve pra Windows passa pelo WSL

E se o teu caso é o oposto, uma máquina com tela onde você quer o agente mexendo na interface, o assunto é outro: dá uma olhada em como ativar o agente que controla a tela

Autenticação sem navegador: as opções de cada ferramenta

Essa é A dor do cenário remoto, então vale destrinchar

Claude Code: quatro saídas documentadas

  • Colar o código: o fluxo do navegador entrega um código e você cola no prompt Paste code here if prompted, previsto justamente pra WSL2, SSH e container
  • ANTHROPIC_API_KEY: se a variável estiver definida, o Claude Code pula o prompt de login e pede aprovação da chave, que é criada no Claude Console e enviada no header X-Api-Key
  • ANTHROPIC_AUTH_TOKEN: pra quem passa por gateway ou proxy de LLM, enviada no header Authorization: Bearer
  • claude setup-token: gera um token OAuth de um ano, usado como CLAUDE_CODE_OAUTH_TOKEN, pensado pra ambientes sem login por navegador
claude setup-token
# o token gerado vira a variável CLAUDE_CODE_OAUTH_TOKEN na máquina remota

Um detalhe que muda a rotina de automação: no modo -p, o não interativo, a ANTHROPIC_API_KEY é sempre usada quando está presente

Ou seja, se ela ficou setada no perfil do servidor, é ela que manda no script, mesmo que você tenha logado de outro jeito

OpenCode: auth login e ordem de precedência

O OpenCode resolve credencial por comando próprio, com a lista de provedores vinda do Models.dev:

opencode auth login
opencode auth list

O resultado fica guardado em ~/.local/share/opencode/auth.json, e o auth list mostra os provedores já autenticados

Quando existe mais de uma fonte de credencial, a ordem é essa: primeiro a credencial armazenada, depois a primeira variável de ambiente não vazia, e por último settings.apiKey

Saber essa ordem evita aquele debug bizarro de "mas eu troquei a chave e ele continua usando a antiga"

E a doc é explícita sobre não commitar chave: em vez do valor literal, use substituição por variável de ambiente na config

"apiKey": "{env:ACME_API_KEY}"

Provedores customizados declaram em env quais variáveis aceitam, então dá pra manter tudo fora do repositório

Rodar sem TUI: automação, script e servidor headless

Sessão interativa por SSH é ótima até a conexão cair

Por isso vale saber como cada um roda sem interface

No Claude Code o caminho é o modo não interativo:

claude -p "sua instrução aqui"

No OpenCode, o equivalente recebe o prompt direto na linha de comando, feito pra script e automação:

opencode run "sua instrução aqui"

E aí vem a diferença que pesa em servidor: o OpenCode sobe um servidor headless com acesso via API, sem a TUI

opencode serve --hostname 0.0.0.0 --port <porta>

Por padrão o bind é 127.0.0.1, ou seja, só local

No momento em que você troca pra 0.0.0.0 a coisa muda de figura, e a documentação é clara: defina OPENCODE_SERVER_PASSWORD, porque sem essa variável o servidor fica desprotegido

export OPENCODE_SERVER_PASSWORD="sua-senha"
opencode serve --hostname 0.0.0.0 --port <porta>

Existe também o opencode web, que sobe servidor local em 127.0.0.1 numa porta disponível aleatória e abre o navegador padrão

Adivinha qual é o modo que menos serve numa máquina sem interface gráfica? Esse aí haha

Vale lembrar que a opção server da config vale tanto pro opencode serve quanto pro opencode web

Permissões e segredos: onde a rotina emperra no servidor

Essa parte quase ninguém comenta, porque quem testa só no notebook não esbarra nela

Costume de container é rodar tudo como root, né? Pois é: o Claude Code bloqueia a flag --dangerously-skip-permissions quando executado como root ou via sudo em Linux e macOS

A orientação da doc é rodar o container, a VM ou o sandbox como usuário não-root, o contrário do hábito de muita imagem por aí

Outro ponto sério: as credenciais do Claude Code ficam em ~/.claude

E a própria documentação avisa que dev container com permissões puladas não impede exfiltração do que está acessível dentro do container, credenciais incluídas

Por isso a recomendação de evitar montar segredos do host, tipo ~/.ssh, e preferir tokens de escopo restrito ou de curta duração

Pra quem administra a máquina, tem dois controles bem úteis:

  • permissions.disableBypassPermissionsMode com valor "disable" nas managed settings, que desliga de vez o modo que pula permissões
  • CLAUDE_CODE_TOOL_MEMORY_LIMIT em Linux e WSL, pra limitar a memória usada pelos comandos das ferramentas Bash e PowerShell
export CLAUDE_CODE_TOOL_MEMORY_LIMIT=4G

Num servidor compartilhado, esse limite de memória é o tipo de guardrail que você agradece depois

Veredito: qual escolher para o seu servidor

Sem enrolação e sem fingir que testei os dois na sua máquina: a escolha segue o modo de uso

Claude Code se o teu cenário é sessão interativa por SSH em máquina que você administra

Ele tem instalador nativo pra macOS, Linux e WSL, auto-update em background aplicado no próximo start, requisitos publicados (4 GB+ de RAM, x64 ou ARM64), token de longa duração via claude setup-token pra ambiente sem navegador, e controles prontos de permissão e memória do lado do servidor

OpenCode se o teu cenário é headless de verdade: servidor com API pelo opencode serve, script sem TUI pelo opencode run, escolha de provedor pelo opencode auth login e código aberto sob MIT no repositório sst/opencode

Em rede corporativa com proxy e certificado customizado ele também tem suporte documentado

E os dois convivem numa boa, viu?

Nada impede sessão interativa numa ferramenta e automação por API na outra, já que cada uma resolve credencial por variável de ambiente própria

Agora, o que EU não vou afirmar: não existe documentação oficial sobre requisitos mínimos do OpenCode, sobre auto-update dele, sobre um equivalente ao token de um ano pra ambiente headless, nem sobre latência de TUI e persistência de sessão com tmux ou screen

Preço, plano e limite também ficam de fora aqui, porque dado não checado eu não coloco

Conclusão

A decisão entre Claude Code ou OpenCode via SSH fica bem mais fácil quando você para de perguntar "qual é o melhor" e pergunta "como eu vou usar essa máquina"

Sessão interativa por SSH puxa pra um lado, API headless e script puxam pro outro

O roteiro prático é curto:

  1. Escolha pelo modo de uso: sessão interativa ou servidor com API
  2. Prepare a autenticação por variável de ambiente ANTES de subir a máquina, seja CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY ou a config do OpenCode com {env:...}
  3. Confira os requisitos da distro antes de instalar, principalmente se for Alpine ou outra base musl, que pede as dependências extras e o USE_BUILTIN_RIPGREP=0
  4. Se for expor o opencode serve na rede, defina a senha do servidor antes, não depois

Me conta nos comentários qual é o teu cenário: VPS solta, container de CI, WSL ou servidor da empresa atrás de proxy?

Tô curioso pra saber onde a rotina de vocês trava mais…

até o próximo post! 😀

Perguntas frequentes

Dá pra rodar o Claude Code numa VPS sem navegador nem interface gráfica?

Dá sim. Quando o navegador não alcança o servidor de callback local, situação comum em SSH, WSL2 e container, o Claude Code deixa colar o código de login direto no terminal, no prompt "Paste code here if prompted". Também dá pra pular esse fluxo inteiro definindo ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN ou o token gerado por claude setup-token.

O que fazer quando o Claude Code dá erro numa imagem Docker baseada em Alpine?

Em Alpine e outras bases musl ou uClibc, o Claude Code exige bash, curl, libgcc, libstdc++ e ripgrep instalados no runtime, pacotes que imagem enxuta costuma não trazer por padrão. Também é preciso setar a variável USE_BUILTIN_RIPGREP=0, senão o erro só aparece depois que tudo parecia instalado certinho.

O OpenCode instala no Windows sem precisar de WSL?

Os métodos automáticos de instalação do OpenCode não funcionam corretamente no Windows. A documentação recomenda usar WSL, e pra quem não quer WSL existe o binário disponível na página de Releases do projeto.

Dá pra deixar o opencode serve acessível por outras máquinas da rede, não só local?

Dá, usando –hostname 0.0.0.0 na hora de subir com opencode serve. Mas a documentação é clara: nesse caso é preciso definir a variável OPENCODE_SERVER_PASSWORD, porque sem ela o servidor fica sem proteção nenhuma. Por padrão, sem mexer em nada, o bind já é só em 127.0.0.1, ou seja, local.

Qual a diferença entre ANTHROPIC_API_KEY e ANTHROPIC_AUTH_TOKEN no Claude Code?

ANTHROPIC_API_KEY é a chave criada no Claude Console e vai no header X-Api-Key; quando ela está definida, o Claude Code pula o prompt de login e pede aprovação da chave. Já ANTHROPIC_AUTH_TOKEN é pra quem passa por gateway ou proxy de LLM, e vai no header Authorization: Bearer. No modo -p, o não interativo, a ANTHROPIC_API_KEY é sempre usada quando está presente.

É seguro usar –dangerously-skip-permissions do Claude Code direto como root no servidor?

Não dá nem pra tentar: como mostrei na seção de permissões e segredos, o Claude Code bloqueia essa flag quando executado como root ou via sudo em Linux e macOS. A orientação é rodar o container, VM ou sandbox como usuário não-root, e mesmo assim evitar montar segredos do host, como ~/.ssh, dentro dele. Pra travar essa porta de vez, dá pra usar permissions.disableBypassPermissionsMode com valor "disable" nas managed settings.



Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares