Pular para o conteúdo principal

Documentação oficial desta página · v0.20.6

Automação de navegador

O Hermes Agent traz um conjunto completo de ferramentas de navegador, com vários backends:

  • Browser Use na nuvem, pelo Browser Use — Chromium gerenciado com furtividade, proxies residenciais, resolução de CAPTCHA e perfis reaproveitáveis
  • Browserbase na nuvem, pelo Browserbase — outro provedor de navegador na nuvem, com ferramentas anti-bot
  • Modo Browser Use, pela CLI do Browser Use 3.0 — o driver padrão, tanto para o Chrome local quanto para os navegadores na nuvem do Browser Use
  • Firecrawl na nuvem, pelo Firecrawl — navegadores na nuvem com extração embutida
  • Camofox local, pelo Camofox — navegação local anti-detecção (falsificação de impressão digital, baseada no Firefox)
  • Motor Lightpanda, pelo Lightpanda — um navegador sem interface escrito do zero em Zig, para máquinas; abre na hora, usa 16 vezes menos memória e é 9 vezes mais rápido que o Chrome, com recuo automático para o Chrome nas ações que ele ainda não faz
  • Chromium local por CDP — liga as ferramentas ao seu próprio Chrome, Brave, Chromium ou Edge, com /browser connect
  • Navegador local, pela CLI agent-browser e uma instalação local do Chromium

Em todos os modos, o agente navega em sites, interage com elementos, preenche formulários e extrai informação.

Visão geral​

As páginas são representadas como árvores de acessibilidade (retratos em texto), o que as torna ideais para agentes de modelo de linguagem. Os elementos interativos ganham identificadores (@e1, @e2), que o agente usa para clicar e digitar.

Principais capacidades:

  • Execução na nuvem, com vários provedores — Browser Use, Browserbase ou Firecrawl, sem navegador local
  • Integração com Chromium local — anexa ao seu Chrome, Brave, Chromium ou Edge por CDP, para navegação com a mão junto
  • Anti-bot na nuvem — o Browser Use Cloud inclui furtividade, proxies residenciais e resolução de CAPTCHA
  • Perfis persistentes na nuvem — o Browser Use Cloud reaproveita cookies, localStorage e senhas salvas entre sessões
  • Isolamento por sessão — cada tarefa ganha a própria sessão de navegador
  • Limpeza automática — sessões paradas são fechadas depois de um tempo
  • Análise visual — captura de tela mais análise por IA, para entendimento visual

Configuração​

Assinantes da Nous

Com uma assinatura paga do Nous Portal, dá para usar a automação de navegador pelo Tool Gateway, sem chave nenhuma. Instalações novas rodam hermes setup --portal para autenticar e ligar todas as ferramentas do gateway de uma vez; instalações existentes escolhem Nous Subscription como provedor em hermes model ou hermes tools.

Browser Use na nuvem​

# em ~/.hermes/.env
BROWSER_USE_API_KEY=***

Pegue a chave em browser-use.com.

O Browser Use Cloud roda Chromium gerenciado, com furtividade e proxies residenciais ligados por padrão, inclui resolução de CAPTCHA e suporta perfis persistentes, com cookies, localStorage e senhas salvas.

Browserbase na nuvem​

# em ~/.hermes/.env
BROWSERBASE_API_KEY=***
BROWSERBASE_PROJECT_ID=seu-id-de-projeto

Pegue as credenciais em browserbase.com.

Escolher o provedor

As chaves do .env acima fornecem só credenciais. O navegador de nuvem ativo é escolhido pelo browser.cloud_provider, gravado por hermes tools → Browser Automation (browserbase, browser-use, camofox, ou nous, para a assinatura da Nous). Feita a escolha, acrescentar ou tirar uma chave não troca de provedor — e um provedor escolhido com a chave faltando dá erro, orientando a rodar hermes tools, em vez de mudar de rota em silêncio. Instalações nunca configuradas ainda detectam pelo que houver de credencial.

Modo Browser Use (padrão)​

O modo Browser Use usa a CLI do Browser Use 3.0 no lugar das ferramentas embutidas. O agente escreve e executa Python no navegador para clicar, digitar, arrastar, extrair e interagir com as páginas.

É o modo padrão: quando o browser.backend não está definido e a CLI browser-use roda (instalada, ou disponível pelo uvx), o agente recebe a ferramenta única browser_exec. Se a CLI não rodar, o Hermes cai nas ferramentas embutidas sozinho.

O modo é um driver que se combina com o backend configurado: ele dirige o seu Chrome local, um navegador de nuvem da assinatura Nous, o Browserbase, o Firecrawl ou os navegadores do Browser Use — o que estiver escolhido em hermes tools → Browser Automation. A exceção é o Camofox, que não tem endpoint CDP para o arcabouço se anexar; instalações com Camofox mantêm as ferramentas embutidas.

Sessões simultâneas: o browser_exec aceita um argumento session=<nome>, que isola o trabalho por nome em qualquer backend. Cada nome ganha o próprio daemon (com socket, log e estado próprios) e, nos backends de nuvem, o próprio navegador — então subagentes em paralelo ou conversas simultâneas não atropelam mais uma conexão compartilhada. Omitir session usa o daemon padrão, o que basta para navegar um de cada vez.

Para desistir do modo e forçar as ferramentas embutidas, use /browser use off, ou:

# em ~/.hermes/config.yaml
browser:
backend: "off"

(backend: "browser-use" continua válido, para forçar o modo.)

Os navegadores de nuvem do próprio Browser Use precisam de browser-use auth login ou de BROWSER_USE_API_KEY; as outras fontes de navegador usam as credenciais que já têm.

observação

Como o modo Browser Use executa Python escrito pelo modelo na sua máquina, a ferramenta browser_exec só é oferecida a sessões que também têm acesso ao terminal. Plataformas configuradas sem o conjunto de terminal (uma superfície de mensagem restrita, por exemplo) ficam com as ferramentas de navegador padrão.

Firecrawl na nuvem​

# em ~/.hermes/.env
FIRECRAWL_API_KEY=fc-***

Pegue a chave em firecrawl.dev. Depois escolha o Firecrawl como provedor:

hermes setup tools
# → Browser Automation → Firecrawl

Opções:

# Instância própria do Firecrawl (padrão: https://api.firecrawl.dev)
FIRECRAWL_API_URL=http://localhost:3002

# Tempo de vida da sessão, em segundos (padrão: 300)
FIRECRAWL_BROWSER_TTL=600

Roteamento híbrido: nuvem para URLs públicas, local para a rede interna​

Com um provedor de nuvem configurado, o Hermes sobe sozinho um Chromium local auxiliar para as URLs que resolvem para endereço privado, de loopback ou de rede local (localhost, 127.0.0.1, 192.168.x.x, 10.x.x.x, 172.16-31.x.x, *.local, *.lan, *.internal, o loopback IPv6 ::1 e o link-local 169.254.x.x). As URLs públicas continuam indo para a nuvem, na mesma conversa.

Isso resolve o caso comum de "estou desenvolvendo local, mas uso o Browserbase" — o agente tira uma captura do seu painel em http://localhost:3000 E extrai dados do https://github.com, sem você trocar de provedor nem desligar a proteção contra SSRF. O provedor de nuvem nunca vê a URL privada.

O recurso vem ligado. Para desligar (todas as URLs vão para a nuvem, como antes):

# ~/.hermes/config.yaml
browser:
cloud_provider: browserbase
auto_local_for_private_urls: false

Com o roteamento desligado, URLs privadas são recusadas com "Blocked: URL targets a private or internal address", a menos que você também defina browser.allow_private_urls: true (o que deixa o provedor de nuvem tentar — em geral sem sucesso, já que o Browserbase e afins não alcançam a sua rede).

Requisitos: o Chromium auxiliar usa a mesma CLI agent-browser do modo local, então ela precisa estar instalada (o hermes setup tools → Browser Automation instala sozinho). Redirecionamentos de uma URL pública para um endereço privado continuam bloqueados depois da navegação — não dá para usar o truque do redirecionamento para alcançar a sua rede pelo caminho público.

Navegar com o seu perfil de verdade​

Por padrão, a navegação local roda num perfil limpo e descartável — o agente não está logado em nada. Ligue a navegação com perfil real para deixá-lo navegar como você, com os seus logins e cookies:

# ~/.hermes/config.yaml
browser:
use_real_profile: true

Ligado, o Hermes copia o perfil ativo do seu navegador padrão — aquele que você usa de verdade (Local State → profile.last_used), com cookies, logins salvos e preferências — para um retrato gerenciado em ~/.hermes/browser-profile/<navegador>/, e dirige esse retrato com o Chromium dele. O seu perfil vivo nunca é aberto diretamente: o retrato é um diretório separado, então ele não briga com o navegador em uso pela trava do perfil, e contorna o bloqueio do Chrome 136+ à depuração remota do diretório padrão. Os arquivos de autenticação (cookies, logins, preferências) são sincronizados de novo do seu perfil real sempre que uma sessão nova sobe, então os logins que você fizer no seu navegador aparecem na sessão do agente. Só o perfil ativo é copiado — os outros perfis do Chrome nunca são.

Ao desligar o botão, o Hermes apaga o retrato (~/.hermes/browser-profile/) no próximo uso do navegador, para as credenciais copiadas não ficarem por aí depois de você revogar o consentimento.

No Windows, o navegador precisa estar totalmente fechado

No Windows, um Chrome, Edge ou Brave em execução segura os bancos de cookie e de login com trava exclusiva, então o Hermes não consegue copiá-los com o navegador aberto — ele falha logo, com uma mensagem pedindo para fechar o navegador por completo e tentar de novo, em vez de travar ou produzir uma sessão deslogada. A navegação com perfil real no Windows exige o navegador totalmente fechado, incluindo qualquer instância em segundo plano ou na bandeja (a opção do Chrome de "continuar rodando aplicativos em segundo plano" mantém um chrome.exe vivo depois que você fecha a janela). No macOS e no Linux dá para copiar com o navegador aberto.

Defina browser.real_profile_autoclose: true para o Hermes se oferecer para fechar o navegador quando ele estiver segurando o perfil. Mesmo assim, o Hermes nunca fecha sozinho — com o perfil travado, ele sempre para e o agente pergunta antes; só com a sua aprovação ele roda o hermes browser close-profile (que encerra a árvore de processos ligada àquele perfil, perdendo abas não salvas) e tenta de novo. Se o perfil continuar travado depois disso (uma instância de bandeja que reabriu, por exemplo), o Hermes continua bloqueado e pede para você fechar o navegador — ele não repete nem mata de novo por conta própria.

  • Navegadores suportados: Chrome, Edge, Brave e Chromium (o que for o padrão do seu sistema). Um padrão que não seja da família Chromium (o Firefox, por exemplo) falha fechado, com mensagem clara, em vez de adivinhar.
  • Funciona em qualquer backend. Num backend local, é automático com o botão ligado. Sob um backend de nuvem, o agente ainda abre uma sessão local com perfil real sob demanda, pelo argumento local da ferramenta browser_exec (a ferramenta só expõe esse argumento com o botão ligado) — o backend de nuvem segue atendendo o resto.
  • Enquadramento de segurança: isto é uma conveniência com consentimento, não uma fronteira de isolamento. Uma página que o agente visita roda com os seus logins de verdade, então só ligue quando você quiser mesmo o agente agindo como você. Desligado por padrão.
  • No desktop: o botão está em Settings → Browser → Use My Real Browser Profile.

Camofox local​

O Camofox é um servidor Node.js auto-hospedado que embrulha o Camoufox (uma variante do Firefox com falsificação de impressão digital em C++). Ele dá navegação anti-detecção local, sem depender da nuvem.

# Clone o servidor primeiro
git clone https://github.com/jo-inc/camofox-browser
cd camofox-browser

# Compile e suba com Docker, nas configurações padrão
# (detecta a arquitetura: aarch64 nos M1 e M2, x86_64 nos Intel)
make up

# Para e remove o container padrão
make down

# Força uma reconstrução limpa (depois de atualizar VERSION ou RELEASE)
make reset

# Só baixa os binários, sem compilar
make fetch

# Escolhe arquitetura ou versão explicitamente
make up ARCH=x86_64
make up VERSION=135.0.1 RELEASE=beta.24

O make up sobe o container padrão na hora. Se você quiser configurações próprias, como mais memória para o Node, VNC ou um diretório de perfil persistente, compile a imagem primeiro e depois rode você mesmo:

# Compila a imagem sem subir o container padrão
make build

# Sobe com persistência, VNC ao vivo e mais memória para o Node
mkdir -p ~/.camofox-docker
docker run -d \
--name camofox-browser \
--restart unless-stopped \
-p 9377:9377 \
-p 6080:6080 \
-p 5901:5900 \
-e CAMOFOX_PORT=9377 \
-e ENABLE_VNC=1 \
-e VNC_BIND=0.0.0.0 \
-e VNC_RESOLUTION=1920x1080 \
-e MAX_OLD_SPACE_SIZE=2048 \
-v ~/.camofox-docker:/root/.camofox \
camofox-browser:135.0.1-aarch64

Com o VNC ligado, o navegador roda com janela visível e dá para acompanhar ao vivo em http://localhost:6080 (noVNC). Também dá para conectar um cliente VNC nativo em localhost:5901.

Se você já rodou o make up, pare e remova aquele container antes de subir o seu:

make down
# depois rode o docker run acima

Então defina em ~/.hermes/.env:

CAMOFOX_URL=http://localhost:9377

Se o Camofox roda em Docker e você quer que ele abra aplicações servidas pela máquina, ligue a reescrita de loopback. O CAMOFOX_URL continua apontando para a API de controle publicada no host, mas URLs de página como http://127.0.0.1:3000 precisam ser abertas de dentro do container como http://host.docker.internal:3000:

# ~/.hermes/config.yaml
browser:
camofox:
rewrite_loopback_urls: true
loopback_host_alias: host.docker.internal # padrão; use um IP da rede se precisar

Variáveis equivalentes:

CAMOFOX_REWRITE_LOOPBACK_URLS=true
CAMOFOX_LOOPBACK_HOST_ALIAS=host.docker.internal

A reescrita vale só para URLs de navegação com host de loopback (localhost, 127.0.0.1, ::1). Ela não muda o CAMOFOX_URL. Deixe desligada em instalações do Camofox fora do Docker, em que o navegador já roda na máquina e as URLs de loopback estão certas.

Ou configure por hermes tools → Browser Automation → Camofox.

O Camofox é escolhido como qualquer outro backend: selecione Camofox em hermes tools → Browser Automation, o que grava browser.cloud_provider: camofox no config.yaml. O CAMOFOX_URL é só o endereço do servidor — defini-lo não escolhe mais o backend sozinho, depois que existe uma escolha gravada (instalações nunca configuradas ainda detectam).

Sessões persistentes​

Por padrão, cada sessão do Camofox ganha uma identidade aleatória — cookies e logins não sobrevivem a reinícios. Para persistir, acrescente ao ~/.hermes/config.yaml:

browser:
camofox:
managed_persistence: true

Depois reinicie o Hermes por completo, para a configuração nova valer.

O caminho aninhado importa

O Hermes lê browser.camofox.managed_persistence, e não um managed_persistence no topo. Um erro comum é escrever:

# ❌ Errado — o Hermes ignora
managed_persistence: true

Com a chave no caminho errado, o Hermes cai em silêncio num userId aleatório e efêmero, e o seu estado de login se perde a cada sessão.

O que o Hermes faz​
  • Manda ao Camofox um userId determinístico, com escopo de perfil, para o servidor reaproveitar o mesmo perfil do Firefox entre sessões.
  • Pula a destruição de contexto do lado do servidor na limpeza, então cookies e logins sobrevivem entre tarefas.
  • Dá escopo ao userId pelo perfil ativo do Hermes, então perfis diferentes ganham navegadores diferentes.
O que o Hermes não faz​
  • Ele não força a persistência no servidor Camofox. O Hermes só manda um userId estável; o servidor precisa honrar isso, mapeando aquele identificador para um diretório de perfil persistente.
  • Se a sua compilação do Camofox trata toda requisição como efêmera (chamando sempre browser.newContext() sem carregar um perfil), o Hermes não consegue fazer as sessões persistirem. Use uma compilação que implemente persistência por userId.
Conferir se está funcionando​
  1. Suba o Hermes e o servidor Camofox.
  2. Abra o Google (ou outro site com login) numa tarefa de navegador e entre na sua conta, na mão.
  3. Encerre a tarefa normalmente.
  4. Comece outra tarefa de navegador.
  5. Abra o mesmo site — você deve continuar logado.

Se o passo 5 mostrar você deslogado, o servidor não está honrando o userId. Confira o caminho da configuração, confirme que reiniciou o Hermes depois de editar o config.yaml, e verifique se a sua versão do Camofox suporta perfis persistentes por usuário.

Onde o estado fica​

O Hermes deriva o userId estável do diretório com escopo de perfil ~/.hermes/browser_auth/camofox/ (ou o equivalente sob o $HERMES_HOME, em perfis não padrão). Os dados do navegador em si ficam no servidor Camofox, indexados por aquele identificador. Para zerar um perfil persistente, limpe do lado do servidor e apague o diretório de estado do perfil no Hermes.

Sessões do Camofox gerenciadas por fora​

Quando outro aplicativo dirige o navegador Camofox visível (um assistente de desktop, uma integração própria, outro agente), configure o Hermes para operar dentro daquela mesma identidade, em vez de abrir um perfil isolado.

Três chaves controlam isso:

ConfiguraçãoVariávelEfeito
browser.camofox.user_idCAMOFOX_USER_IDO userId que o Hermes usa ao criar abas. Definir isso coloca a sessão em modo "gerenciado por fora".
browser.camofox.session_keyCAMOFOX_SESSION_KEYO sessionKey (também chamado listItemId), enviado na criação da aba. Serve para casar com uma aba existente na adoção. Sem valor, usa um por tarefa.
browser.camofox.adopt_existing_tabCAMOFOX_ADOPT_EXISTING_TABCom true, o Hermes chama GET /tabs?userId=<user_id> no primeiro uso e reaproveita uma aba existente antes de criar uma nova.

As variáveis de ambiente têm precedência sobre o config.yaml. As duas formas funcionam:

browser:
camofox:
user_id: shared-camofox
session_key: visible-tab
adopt_existing_tab: true
CAMOFOX_USER_ID=shared-camofox
CAMOFOX_SESSION_KEY=visible-tab
CAMOFOX_ADOPT_EXISTING_TAB=true

O que muda com o user_id definido:

  • O Hermes pula a limpeza destrutiva no fim da tarefa (igual ao managed_persistence: true). A aba, os cookies e o perfil do outro aplicativo sobrevivem.
  • O Hermes não chama DELETE /sessions/<user_id> — esse endpoint apaga todos os dados do usuário, e destruiria a sessão do aplicativo externo.

Como a adoção de aba funciona (com adopt_existing_tab: true):

  1. Na primeira chamada de ferramenta depois de o processo subir, o Hermes faz GET /tabs?userId=<user_id> (com 5 segundos de tempo limite).
  2. Se alguma aba na resposta tem listItemId == session_key, o Hermes adota a mais recente daquele grupo.
  3. Senão, adota a aba criada mais recentemente para aquele usuário, com qualquer listItemId.
  4. Se não houver aba, ou se a requisição falhar, o Hermes cria uma aba nova na operação seguinte.

A adoção só acontece até o tab_id estar preenchido. Se o aplicativo externo fechar a aba adotada no meio, a chamada seguinte devolve um erro do Camofox — o Hermes não fica consultando por uma aba nova a cada chamada.

Escolher o session_key: se você quer que o Hermes se anexe a uma aba específica de forma confiável, coloque no session_key o listItemId que o aplicativo externo usou ao criá-la. Se você deixar o session_key vazio e definir só o user_id, o Hermes gera um por tarefa (task_<id>) — ele compartilha cookies e perfil com o aplicativo externo, mas abre a própria aba ao lado, em vez de reaproveitar uma.

Sobre concorrência: o aplicativo externo e o Hermes podem dirigir o mesmo userId simultaneamente, mas o Camofox não coordena o foco de aba entre clientes. Coordene a posse na camada da aplicação (o aplicativo externo pausa enquanto o Hermes trabalha, por exemplo).

Acompanhar por VNC​

Quando o Camofox roda com janela visível, ele expõe uma porta de VNC na resposta de saúde. O Hermes descobre isso sozinho e inclui a URL do VNC nas respostas de navegação, então o agente consegue compartilhar um link para você assistir ao navegador ao vivo.

Motor Lightpanda​

O Lightpanda é um navegador sem interface, de código aberto, escrito do zero. Ele abre na hora, roda 9 vezes mais rápido e usa 16 vezes menos memória que o Chrome — o que importa em agentes que vivem em máquinas virtuais pequenas por longos períodos.

O Lightpanda é um motor local, escolhido dentro do caminho do agent-browser (não é um provedor de nuvem). Instale o binário, coloque no seu PATH (veja o guia de instalação) e defina:

# em ~/.hermes/config.yaml
browser:
engine: lightpanda

Ou por variável de ambiente:

AGENT_BROWSER_ENGINE=lightpanda

O Hermes dirige o Lightpanda pelo agent-browser, por CDP, do mesmo jeito que dirige o Chrome local.

Recuo automático para o Chrome. O Lightpanda ainda não cobre tudo que o Chrome faz, então a integração não atrapalha: o Lightpanda cuida do que suporta, e o Hermes tenta de novo no Chrome o resto, de forma transparente. O conjunto suportado cobre o fluxo principal do agente — navegar, tirar retrato, clicar, digitar, rolar, voltar, apertar tecla e avaliar. Capturas de tela também caem no Chrome, porque o Lightpanda não tem renderizador gráfico; o browser_vision já vai direto para o Chrome, pelo mesmo motivo.

Chromium local por CDP (/browser connect)​

Em vez de um provedor de nuvem, dá para anexar as ferramentas ao seu Chrome, Brave, Chromium ou Edge em execução, pelo Chrome DevTools Protocol (CDP). Serve para ver o que o agente está fazendo em tempo real, acessar páginas que dependem dos seus cookies e sessões, ou evitar o custo do navegador na nuvem.

observação

O /browser connect é um comando de barra da CLI interativa — o gateway não o executa. Se você tentar rodar numa interface web, no Telegram, no Discord ou em outra conversa de gateway, a mensagem vai para o agente como texto comum e o comando não roda. Abra o Hermes pelo terminal (hermes ou hermes chat) e use o /browser connect ali.

Na CLI:

/browser connect # abre ou conecta a um navegador local em http://127.0.0.1:9222
/browser connect ws://host:porta # conecta a um endpoint CDP específico
/browser status # mostra a conexão atual
/browser disconnect # desanexa e volta ao modo de nuvem ou local

Se não houver navegador rodando com depuração remota, o Hermes tenta abrir um da família Chromium com --remote-debugging-port=9222. A detecção inclui Brave, Google Chrome, Chromium e Microsoft Edge, com caminhos comuns do Linux, como /opt/brave-bin/brave e /snap/bin/brave.

dica

Para abrir um navegador da família Chromium na mão, com CDP ligado, use um diretório de dados dedicado — assim a porta de depuração sobe mesmo se o navegador já estiver rodando com o seu perfil normal:

# Linux — Brave
brave-browser \
--remote-debugging-port=9222 \
--user-data-dir=$HOME/.hermes/chrome-debug \
--no-first-run \
--no-default-browser-check &

# Linux — Google Chrome
google-chrome \
--remote-debugging-port=9222 \
--user-data-dir=$HOME/.hermes/chrome-debug \
--no-first-run \
--no-default-browser-check &

# macOS — Brave
"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser" \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/.hermes/chrome-debug" \
--no-first-run \
--no-default-browser-check &

# macOS — Google Chrome
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/.hermes/chrome-debug" \
--no-first-run \
--no-default-browser-check &

Depois abra a CLI do Hermes e rode /browser connect.

Por que o --user-data-dir? Sem ele, abrir um navegador da família Chromium com uma instância normal já rodando costuma só abrir uma janela nova no processo existente — e aquele processo não foi aberto com --remote-debugging-port, então a porta 9222 nunca sobe. Um diretório de dados dedicado força um processo novo, em que a porta de depuração realmente escuta. O --no-first-run --no-default-browser-check pula o assistente de primeira abertura do perfil novo.

No Chrome 136+, o perfil dedicado virou obrigatório. Como endurecimento de segurança, o Chrome 136 e posteriores se recusam, em silêncio, a abrir a porta de depuração remota quando o --remote-debugging-port é combinado com o diretório de dados padrão — mesmo partindo do zero, sem nenhum Chrome rodando. O navegador abre normalmente, mas nada escuta na 9222, e o /browser connect (e qualquer curl http://127.0.0.1:9222/json/version manual) falha com conexão recusada. Não há mensagem de erro. A solução é exatamente o comando acima: sempre passe um --user-data-dir apontando para outro lugar que não o seu perfil padrão (por exemplo, $HOME/.hermes/chrome-debug). Vale para Chrome, Chromium, Edge e Brave que já incorporaram a mudança.

Conectado por CDP, todas as ferramentas (browser_navigate, browser_click e as outras) operam no seu navegador ao vivo, em vez de subir uma sessão na nuvem.

WSL2 com Chrome no Windows: prefira MCP ao /browser connect​

Se o Hermes roda dentro do WSL2 mas a janela do Chrome que você quer controlar roda no Windows, o /browser connect costuma não ser o melhor caminho.

Por quê:

  • o /browser connect espera que o próprio Hermes alcance um endpoint CDP utilizável
  • as sessões modernas de depuração ao vivo do Chrome costumam expor um endpoint restrito à máquina, que não é diretamente alcançável do WSL como uma porta 9222 clássica
  • mesmo quando o Chrome do Windows é depurável, a integração mais limpa costuma ser deixar um servidor MCP de navegador, do lado do Windows, se anexar ao Chrome, e o Hermes falar com esse servidor MCP

Para isso, prefira o chrome-devtools-mcp pelo suporte a MCP do Hermes. Veja Usar MCP com o Hermes.

Navegador local​

Se você não define credencial de nuvem nenhuma e não usa o /browser connect, o Hermes ainda usa as ferramentas de navegador por uma instalação local do Chromium, dirigida pelo agent-browser.

Variáveis de ambiente opcionais​

# Proxies residenciais, para resolver CAPTCHA melhor (padrão: "true")
BROWSERBASE_PROXIES=true

# Furtividade avançada, com Chromium próprio — exige o plano Scale (padrão: "false")
BROWSERBASE_ADVANCED_STEALTH=false

# Reconexão de sessão depois de queda — exige plano pago (padrão: "true")
BROWSERBASE_KEEP_ALIVE=true

# Tempo limite da sessão, em segundos (máximo 21600 = 6 horas)
BROWSERBASE_SESSION_TIMEOUT=1800

# Tempo de inatividade antes da limpeza automática, em segundos (padrão: 120)
BROWSER_INACTIVITY_TIMEOUT=120

# Motor local. Vale para as ferramentas embutidas (caminho do agent-browser).
# Equivale ao browser.engine no config.yaml.
# auto — o padrão do agent-browser (hoje, o Chrome)
# lightpanda — Lightpanda
# chrome — força o Chrome
AGENT_BROWSER_ENGINE=auto

# Opções extras de abertura do Chromium (separadas por vírgula ou quebra de linha).
# O Hermes injeta `--no-sandbox,--disable-dev-shm-usage` sozinho quando detecta root
# ou espaços de nome de usuário restritos pelo AppArmor (Ubuntu 23.10+, DGX Spark,
# muitas imagens de container), então a maioria não precisa definir. Defina só se
# precisar de algo que o Hermes não acrescenta; defini-la desliga a injeção automática.
AGENT_BROWSER_ARGS=--no-sandbox

Instalar a CLI agent-browser​

Não é preciso instalar nada — o agent-browser é resolvido sozinho, por npx agent-browser, no primeiro uso. Para evitar essa busca única, dá para instalar antes (opcional):

npm install -g agent-browser
informação

O conjunto browser precisa estar na lista toolsets da sua configuração, ou ser habilitado com hermes config set toolsets '["hermes-cli", "browser"]'.

Ferramentas disponíveis​

browser_navigate​

Navega até uma URL. Precisa ser chamada antes de qualquer outra ferramenta de navegador.

Navegue até https://github.com/NousResearch
dica

Para buscar informação simples, prefira o web_search ou o web_extract — são mais rápidos e mais baratos. Use as ferramentas de navegador quando precisar interagir com a página (clicar em botões, preencher formulários, lidar com conteúdo dinâmico).

browser_snapshot​

Devolve um retrato em texto da árvore de acessibilidade da página atual, com os elementos interativos e seus identificadores (@e1, @e2), para usar com browser_click e browser_type.

  • full=false (padrão): visão compacta, só com os elementos interativos
  • full=true: o conteúdo completo da página

Retratos maiores que o browser.snapshot_threshold (padrão de 15 mil caracteres — o mesmo orçamento por página do web_extract) são cortados nos limites de linha; não há resumo por modelo. Quando isso acontece, o retrato completo é salvo em ~/.hermes/cache/web/, e a saída da ferramenta traz o caminho do arquivo mais uma chamada de read_file pronta, para o agente percorrer a árvore inteira — inclusive os elementos além do corte — sem tirar outro retrato.

Aumente o limite em páginas longas, quando mais conteúdo precisa chegar ao agente de uma vez:

# ~/.hermes/config.yaml
browser:
snapshot_threshold: 30000

Também dá para rodar hermes config set browser.snapshot_threshold 30000. Vale tanto para chamadas explícitas de browser_snapshot quanto para o retrato automático depois da navegação, inclusive no backend Camofox (mínimo de 1000). Reinicie a sessão depois de mudar, para o cache de configuração do navegador recarregar.

browser_click​

Clica num elemento, pelo identificador que veio no retrato.

Clique em @e5, o botão "Sign In"

browser_type​

Digita texto num campo. Limpa o campo antes.

Digite "hermes agent" no campo de busca @e3

browser_scroll​

Rola a página para cima ou para baixo, revelando mais conteúdo.

Role para baixo para ver mais resultados

browser_press​

Aperta uma tecla. Útil para enviar formulários ou navegar.

Aperte Enter para enviar o formulário

Teclas suportadas: Enter, Tab, Escape, ArrowDown, ArrowUp e outras.

browser_back​

Volta para a página anterior no histórico.

browser_get_images​

Lista todas as imagens da página atual, com URL e texto alternativo. Útil para achar imagens a analisar.

browser_vision​

Tira uma captura de tela e analisa com IA de visão. Use quando o retrato em texto não captura informação visual importante — especialmente em CAPTCHAs, layouts complexos ou verificações visuais.

A captura é salva de forma permanente, e o caminho do arquivo volta junto com a análise. Nas plataformas de mensagem (Telegram, Discord, Slack, WhatsApp), dá para pedir ao agente que compartilhe a captura — ela é enviada como foto nativa, pelo mecanismo MEDIA:.

O que o gráfico desta página mostra?

As capturas ficam em ~/.hermes/cache/screenshots/ e são apagadas depois de 24 horas.

browser_console​

Devolve a saída do console do navegador (log, aviso, erro) e as exceções não capturadas de JavaScript da página atual. Essencial para detectar erros silenciosos, que não aparecem na árvore de acessibilidade.

Veja se há erros de JavaScript no console

Use clear=True para limpar o console depois de ler, e as chamadas seguintes mostrarem só o que é novo.

O browser_console também avalia JavaScript, quando chamado com o argumento expression — no mesmo formato do console do DevTools. O resultado volta interpretado (objetos serializados em JSON viram dicionários; valores primitivos continuam primitivos).

browser_console(expression="document.querySelector('h1').textContent")
browser_console(expression="JSON.stringify(performance.timing)")

Quando há um supervisor CDP ativo na sessão (o normal em qualquer sessão que rodou browser_navigate contra um backend com CDP), a avaliação passa pelo WebSocket persistente do supervisor — sem custo de abrir subprocesso. Sem isso, ela cai no caminho normal da CLI. O comportamento é idêntico; só a espera muda.

A avaliação é irrestrita por padrão — o agente pode usar fetch, ler armazenamento, consultar valores de formulário e extrair o que quiser do DOM. Requisições para endereços privados ou internos continuam bloqueadas em backends que não são locais (a proteção contra SSRF é independente disso). Se você navega em páginas hostis com um perfil logado e quer uma lista de bloqueio rígida sobre primitivas sensíveis (cookies, armazenamento, área de transferência, chamadas de rede, valores de formulário), ligue o browser.restrict_evaluate: true. Atenção: a lista casa com os nomes das primitivas, então ela também bloqueia expressões legítimas que apenas contenham palavras como fetch ou cookie.

browser_cdp​

Repasse cru do Chrome DevTools Protocol — a saída de emergência para o que as outras ferramentas não cobrem. Serve para diálogos nativos, avaliação dentro de iframe, controle de cookie e de rede, ou qualquer verbo CDP de que o agente precise.

Só está disponível quando há um endpoint CDP alcançável no início da sessão — ou seja, quando o /browser connect se anexou a um Chrome, Brave, Chromium ou Edge em execução, ou quando o browser.cdp_url está definido no config.yaml. O modo local padrão, o Camofox e os provedores de nuvem (Browserbase, Browser Use, Firecrawl) não expõem CDP a esta ferramenta hoje — os provedores de nuvem têm URLs de CDP por sessão, mas o roteamento de sessão viva ainda está por vir.

Referência dos métodos: https://chromedevtools.github.io/devtools-protocol/ — o agente pode usar web_extract na página de um método para consultar parâmetros e formato de retorno.

Padrões comuns:

# Lista as abas (nível de navegador, sem target_id)
browser_cdp(method="Target.getTargets")

# Responde a um diálogo nativo numa aba
browser_cdp(method="Page.handleJavaScriptDialog",
params={"accept": true, "promptText": ""},
target_id="<tabId>")

# Avalia JavaScript numa aba específica
browser_cdp(method="Runtime.evaluate",
params={"expression": "document.title", "returnByValue": true},
target_id="<tabId>")

# Pega todos os cookies
browser_cdp(method="Network.getAllCookies")

Métodos de nível de navegador (Target.*, Browser.*, Storage.*) dispensam o target_id. Métodos de nível de página (Page.*, Runtime.*, DOM.*, Emulation.*) exigem um target_id, vindo do Target.getTargets. Cada chamada é independente — não há sessão entre elas.

Iframes de outra origem: passe o frame_id (do browser_snapshot.frame_tree.children[], onde is_oopif=true) para rotear a chamada pela sessão viva do supervisor daquele iframe. É assim que o Runtime.evaluate dentro de um iframe de outra origem funciona no Browserbase, onde conexões CDP sem estado esbarrariam na expiração da URL assinada:

browser_cdp(
method="Runtime.evaluate",
params={"expression": "document.title", "returnByValue": True},
frame_id="<frame_id vindo do browser_snapshot>",
)

Iframes da mesma origem não precisam de frame_id — use document.querySelector('iframe').contentDocument num Runtime.evaluate de nível superior.

browser_dialog​

Responde a um diálogo nativo (alert, confirm, prompt, beforeunload). Antes desta ferramenta, diálogos travavam a thread de JavaScript da página em silêncio, e as chamadas seguintes de browser_* travavam ou davam erro; agora o agente vê os diálogos pendentes na saída do browser_snapshot e responde explicitamente.

Fluxo:

  1. Chame o browser_snapshot. Se um diálogo está travando a página, ele aparece como pending_dialogs: [{"id": "d-1", "type": "alert", "message": "..."}].
  2. Chame browser_dialog(action="accept") ou browser_dialog(action="dismiss"). Em diálogos de prompt(), passe prompt_text="..." com a resposta.
  3. Tire outro retrato — pending_dialogs está vazio, e a thread de JavaScript da página voltou.

A detecção é automática, por um supervisor CDP persistente — um WebSocket por tarefa, assinando os eventos de Page, Runtime e Target. O supervisor também preenche o campo frame_tree do retrato, para o agente enxergar a estrutura de iframes da página atual, inclusive os de outra origem.

Matriz de disponibilidade:

BackendDetecção por pending_dialogsResposta (browser_dialog)
Chrome local por /browser connect ou browser.cdp_urlSimSim, fluxo completo
BrowserbaseSimSim, fluxo completo (por ponte de XHR injetada)
Camofox e agent-browser local padrãoNãoNão (sem endpoint CDP)

Como funciona no Browserbase. O proxy de CDP do Browserbase descarta diálogos nativos de verdade do lado do servidor, em cerca de 10 ms, então não dá para usar o Page.handleJavaScriptDialog. O supervisor injeta um script pequeno, por Page.addScriptToEvaluateOnNewDocument, que substitui window.alert, confirm e prompt por um XHR síncrono. Esses XHRs são interceptados por Fetch.enable — a thread de JavaScript da página fica travada no XHR até o Hermes chamar Fetch.fulfillRequest com a resposta do agente. Os valores de retorno do prompt() voltam intactos.

A política de diálogo fica no config.yaml, em browser.dialog_policy:

PolíticaComportamento
must_respond (padrão)Captura, mostra no retrato e espera uma chamada explícita de browser_dialog(). Descarte de segurança depois de browser.dialog_timeout_s (padrão de 300s), para um agente com defeito não travar para sempre.
auto_dismissCaptura e descarta na hora. O agente ainda vê o diálogo no histórico de browser_state, mas não precisa agir.
auto_acceptCaptura e aceita na hora. Útil ao navegar em páginas com beforeunload agressivo.

A árvore de quadros, em browser_snapshot.frame_tree, é limitada a 30 quadros e a 2 níveis de profundidade de iframe de outra origem, para o conteúdo não explodir em páginas cheias de anúncio. Um campo truncated: true aparece quando os limites foram atingidos; agentes que precisam da árvore inteira usam o browser_cdp com Page.getFrameTree.

Exemplos práticos​

Preencher um formulário​

Pessoa: Crie uma conta no example.com com meu e-mail joao@exemplo.com

Fluxo do agente:
1. browser_navigate("https://example.com/signup")
2. browser_snapshot() → vê os campos, com os identificadores
3. browser_type(ref="@e3", text="joao@exemplo.com")
4. browser_type(ref="@e5", text="SenhaSegura123")
5. browser_click(ref="@e8") → clica em "Create Account"
6. browser_snapshot() → confirma o sucesso

Pesquisar conteúdo dinâmico​

Pessoa: Quais são os repositórios em alta no GitHub agora?

Fluxo do agente:
1. browser_navigate("https://github.com/trending")
2. browser_snapshot(full=true) → lê a lista
3. Devolve o resultado formatado

Gravação de sessão​

Grave as sessões de navegador em vídeo WebM automaticamente:

browser:
record_sessions: true # padrão: false

Ligado, a gravação começa no primeiro browser_navigate e é salva em ~/.hermes/browser_recordings/ quando a sessão fecha. Funciona nos modos local e de nuvem (Browserbase). Gravações com mais de 72 horas são apagadas sozinhas.

Modo com janela visível​

Por padrão, o navegador local roda sem interface. Ligue o modo com janela para ter um Chromium visível, que você acompanha e usa:

browser:
headed: true # padrão: false

Ou pela variável AGENT_BROWSER_HEADED=1.

O modo com janela faz duas coisas:

  1. Abre o Chromium com janela visível (passando --headed ao agent-browser, no modo local).
  2. Mantém a janela aberta entre turnos. Normalmente a sessão é limpa depois de cada resposta; no modo com janela a limpeza por turno é pulada, então você acompanha o agente trabalhando, intervém na mão (desafios de login, CAPTCHAs) e mantém o estado de sessão quente durante a conversa.

Sessões paradas continuam sendo encerradas depois do browser.inactivity_timeout (padrão de 120 segundos sem atividade), e todas fecham no desligamento. O modo com janela afeta só o navegador local — sessões de nuvem não mudam.

Recursos de furtividade​

O Browserbase traz furtividade automática:

RecursoPadrãoObservações
Furtividade básicaSempre ligadaImpressões digitais aleatórias, viewport variável, resolução de CAPTCHA
Proxies residenciaisLigadosRoteia por IPs residenciais, para melhor acesso
Furtividade avançadaDesligadaChromium próprio, exige o plano Scale
Manter vivoLigadoReconexão depois de soluços de rede
observação

Se os recursos pagos não estão no seu plano, o Hermes recua sozinho — primeiro desligando o keepAlive, depois os proxies — para a navegação continuar funcionando em planos gratuitos.

Gestão de sessões​

  • Cada tarefa ganha uma sessão isolada
  • As sessões são limpas depois de um tempo sem uso (padrão: 2 minutos)
  • Uma thread de fundo confere a cada 30 segundos se há sessões paradas
  • Uma limpeza de emergência roda na saída do processo, para não deixar sessões órfãs
  • As sessões são liberadas pela API do provedor (estado REQUEST_RELEASE)

Limitações​

  • Interação por texto — depende da árvore de acessibilidade, não de coordenadas de pixel
  • Tamanho do retrato — páginas grandes são cortadas no browser.snapshot_threshold (padrão de 15 mil caracteres, igual ao web_extract; sem resumo por modelo); o retrato completo é salvo em ~/.hermes/cache/web/, e a saída aponta para ele, para leitura com read_file
  • Tempo limite de sessão — sessões de nuvem expiram conforme o plano do provedor
  • Custo — sessões de nuvem consomem créditos; elas são limpas quando a conversa termina ou depois do tempo sem uso. Use o /browser connect para navegar localmente, de graça.
  • Sem download de arquivo — não dá para baixar arquivos pelo navegador