Hermes Desktop com backend remoto no macOS
Como usar o app desktop oficial como cliente de um Hermes rodando em outra máquina — com o que já funciona, o que ainda dói e onde a documentação oficial hoje deixa nuances implícitas.
Dá para usar o Hermes Desktop como interface gráfica de um Hermes rodando num servidor, VPS, workstation ou máquina da sua rede privada. Mas existe uma nuance decisiva: hoje isso ainda não é um cliente “burro” puro. O app desktop oficial continua instalando um runtime local do Hermes no Mac; o modo remoto existe e funciona, mas ainda está em fase de amadurecimento operacional.
A resposta curta: dá ou não dá?
Dá para conectar o Hermes Desktop a um backend remoto. O próprio código do app e a UI de Settings → Gateway → Remote gateway mostram isso com clareza.
Mas não dá dizer que o Mac fica totalmente sem Hermes. Na documentação oficial do app, o README do desktop explica que o pacote distribuído leva só o shell Electron, porém na primeira execução ele instala o runtime do Hermes Agent dentro de HERMES_HOME, reaproveitando o mesmo layout que a instalação de CLI usa.
O que foi analisado para este guia
Este guia foi montado a partir de quatro camadas de evidência:
- instalação real desta máquina, incluindo versão e árvore local do projeto;
- documentação oficial local do repositório Hermes, incluindo docs do dashboard, API server e README do desktop;
- código do app desktop, especialmente a parte de configuração de remote gateway;
- issues e PRs oficiais no GitHub, para captar bugs reais, lacunas de onboarding e correções ainda não totalmente refletidas na experiência releaseada.
$ hermes --version
Hermes Agent v0.15.1 (2026.5.29)
Project: /home/hermes/.hermes/hermes-agent
Python: 3.11.15
OpenAI SDK: 2.24.0
Update available: 473 commits behind — run 'hermes update'
$ hermes dashboard --help
--host HOST Host (default 127.0.0.1)
--port PORT Port (default 9119)
--insecure Allow binding to non-localhost
--tui Expose the in-browser Chat tab
$ hermes desktop --help
Launch the Hermes Electron desktop app...
--skip-build
--source
--build-only
--ignore-existing
A arquitetura correta de pensar
O erro mais comum é imaginar que o desktop remoto fala com o API server OpenAI-compatible do Hermes da mesma forma que Open WebUI, Jan, LibreChat ou ChatBox falariam. Não é isso.
O modo remoto do Hermes Desktop se conecta ao dashboard backend do Hermes e espera dois componentes:
- HTTP para endpoints como
/api/status; - WebSocket em
/api/wscom token de sessão.
/v1 do API server. Hermes Desktop remoto usa o backend do dashboard, com /api/status e /api/ws. Misturar esses dois modelos é a principal fonte de configuração errada.
O que o código oficial do desktop mostra
A análise do código local do app desktop confirma vários pontos operacionais que a documentação ainda trata de forma parcial.
- A UI de configurações já tem um modo explícito Local gateway / Remote gateway.
- O app aceita Remote URL e Session token.
- As variáveis de ambiente
HERMES_DESKTOP_REMOTE_URLeHERMES_DESKTOP_REMOTE_TOKENpodem forçar o modo remoto. - A URL remota aceita prefixo de path — por exemplo
https://gateway.exemplo.com/hermes. - O app constrói o WebSocket como
<base>/api/ws?token=....
function normalizeRemoteBaseUrl(rawUrl) {
...
parsed.pathname = parsed.pathname.replace(/\/+$/, '')
return parsed.toString().replace(/\/+$/, '')
}
function buildGatewayWsUrl(baseUrl, token) {
const parsed = new URL(baseUrl)
const wsScheme = parsed.protocol === 'https:' ? 'wss' : 'ws'
const prefix = parsed.pathname.replace(/\/+$/, '')
return `${wsScheme}://${parsed.host}${prefix}/api/ws?token=${encodeURIComponent(token)}`
}
Isso importa porque mostra duas coisas: o app não pressupõe só raiz de domínio, e ele não fala com /v1 nesse modo. Ele quer o backend do dashboard/TUI.
A limitação principal: “não instalar Hermes no Mac” ainda não é 100% verdade
O README oficial do desktop é explícito: o aplicativo empacotado leva o shell Electron e, no primeiro boot, instala o runtime do Hermes Agent dentro de HERMES_HOME. Em outras palavras, mesmo usando backend remoto, o app atual ainda nasce de uma filosofia local-first.
Isso não quer dizer que você precise configurar provider, models e gateway localmente para uso diário. Há trabalho oficial para pular essa parte. Mas quer dizer que, hoje, o produto ainda não é um cliente fino puro estilo “sem runtime local algum”.
Estado oficial atual da funcionalidade
Hoje o estado mais honesto da funcionalidade, olhando docs + código + issues/PRs, é este:
- o modo remoto existe e está visível na UI;
- há documentação oficial parcial e PRs de documentação/correção recentes;
- o onboarding ainda está em evolução;
- há bugs conhecidos de estabilidade e UX, especialmente em versões 0.15.1 / início de junho de 2026.
Dois itens do roadmap/comunidade deixam isso muito claro:
- #36970: pedido de onboarding nativo para “usar instância Hermes já existente” sem bootstrap local confuso;
- #39237 / #36674: proposta de desktop-only install mode, que reduz o atrito do setup quando a intenção é usar backend remoto.
Quando essa arquitetura vale a pena
Ela faz muito sentido quando você quer centralizar o “Hermes de verdade” numa máquina mais estável do que o laptop:
- um servidor doméstico com uptime alto;
- uma VPS sempre ligada;
- um Mac mini, Linux box ou workstation da rede privada;
- um host com seus repositórios, seus MCPs, suas credenciais e sua automação.
Nessa arquitetura, o Mac vira a sua janela de controle. O backend remoto concentra:
- sessões e histórico;
- skills e memórias;
- toolsets e integrações;
- acesso aos repositórios e arquivos reais;
- cron jobs, gateway e automações de longa duração.
Setup recomendado hoje
Se eu fosse desenhar o caminho mais estável hoje, seria este:
- rodar o Hermes principal numa máquina remota confiável;
- expor o dashboard, não apenas o API server;
- usar rede privada ou túnel confiável;
- fixar um token estável de dashboard para o desktop remoto;
- subir o dashboard com
--tui; - usar o Mac só como shell nativo do app desktop.
Passo 1 — preparar o backend remoto
Na máquina remota, você quer um Hermes completo, com dashboard e TUI embutida. O comando central é o hermes dashboard, não o hermes gateway sozinho e nem apenas o API server do /v1.
Garanta primeiro que a instalação tem o stack web e o suporte de PTY exigidos para o chat embutido no dashboard:
pip install 'hermes-agent[web,pty]'
Depois, fixe um token de sessão estável para o dashboard. Isso é crucial porque, por padrão, o dashboard gera um token efêmero a cada boot. Para um cliente remoto, você quer algo reaproveitável.
HERMES_DASHBOARD_SESSION_TOKEN=gere-um-token-forte-e-longo
Um jeito simples de gerar esse token:
python3 -c 'import secrets; print(secrets.token_urlsafe(32))'
Passo 2 — subir o dashboard da forma certa
A forma recomendada, quando ele vai aceitar conexão remota do desktop, é incluir --tui. Esse detalhe virou bug recorrente e motivou o PR oficial #38260, justamente porque /api/status podia responder bem enquanto o Desktop ficava preso depois do “backend ready”.
hermes dashboard \
--tui \
--no-open \
--insecure \
--host 0.0.0.0 \
--port 9119
Se você estiver numa overlay privada e quiser reduzir a superfície de exposição, pode preferir bindar no IP privado específico em vez de 0.0.0.0, desde que o cliente consiga alcançá-lo.
--insecure
A documentação oficial do dashboard é clara: --insecure é perigoso em rede aberta. Use isso só atrás de controles de rede confiáveis: Tailscale, ZeroTier, LAN fechada, túnel SSH ou proxy autenticado sob seu controle.
Passo 3 — validar o backend antes de abrir o desktop
Antes de tocar no Mac, valide do lado remoto ou a partir de outra máquina da mesma rede se o backend responde.
curl -H "X-Hermes-Session-Token: gere-um-token-forte-e-longo" \
http://SEU-HOST:9119/api/status
O ideal é receber 200 com JSON de status. Mas atenção: essa validação sozinha não basta. Um dos bugs conhecidos foi exatamente o “Test remote” falso-positivo, porque a checagem passava por REST e não confirmava corretamente a prontidão do WebSocket. Isso está sendo endereçado no PR #39522.
Em termos práticos, a regra de ouro é: se o backend não foi iniciado com --tui, não considere a validação completa, mesmo que /api/status responda.
Passo 4 — no Mac, instalar o Desktop e apontar para o remoto
No Mac, você pode usar o instalador oficial do Desktop ou o fluxo baseado no comando hermes desktop. Se a sua intenção é só usar a interface gráfica e se conectar ao backend remoto, o ponto mais importante é entender que o app ainda vai preparar runtime local no primeiro boot.
Depois da primeira abertura do app:
- entre em Settings;
- abra Gateway Connection;
- troque de Local gateway para Remote gateway;
- preencha a Remote URL com a base do dashboard remoto;
- cole o Session token fixado no servidor;
- use Test remote;
- depois Save and reconnect.
http://100.x.y.z:9119
https://hermes.seu-dominio.com
https://proxy.exemplo.com/hermes
Repare no terceiro exemplo: o app suporta prefixo de path. Isso está refletido no código que normaliza a URL e monta o WebSocket em <prefixo>/api/ws.
Quando usar variáveis de ambiente no desktop
O próprio código oficial do desktop prevê dois env vars relevantes:
HERMES_DESKTOP_REMOTE_URLHERMES_DESKTOP_REMOTE_TOKEN
Eles servem como override da configuração salva na UI. Isso é útil em três cenários:
- você quer forçar sempre um backend remoto específico;
- o salvamento local do token falhou por problema de keychain/secure storage;
- você está depurando a UI e quer eliminar dúvidas sobre estado persistido.
export HERMES_DESKTOP_REMOTE_URL='https://seu-host-ou-proxy/hermes'
export HERMES_DESKTOP_REMOTE_TOKEN='seu-token-fixo'
open -a Hermes
Quando esse override estiver ativo, a UI sinaliza isso explicitamente. O código do app também exige que, se a URL remota estiver definida por variável de ambiente, o token correspondente também esteja presente.
Segurança: o desenho certo de exposição
A forma mais segura de operar isso não é publicar o dashboard cru na internet pública. O desenho mais limpo costuma ser um destes:
- Tailscale / ZeroTier entre Mac e servidor;
- SSH tunnel quando você quer só um link ad hoc;
- reverse proxy privado com ACL forte;
- bind em IP privado específico e firewall restrito.
Em geral, se você já consegue abrir um endpoint interno como http://10.x.x.x:9119/api/status só dentro da sua malha privada, está no caminho certo.
Não confunda Desktop remoto com API server
Esta é a separação mais importante do guia inteiro.
| Caso | Endpoint-base | Token | Cliente típico |
|---|---|---|---|
| Hermes Desktop remoto | /api/status + /api/ws |
HERMES_DASHBOARD_SESSION_TOKEN |
app desktop oficial |
| Open WebUI / Jan / LibreChat / SDK | /v1 |
API_SERVER_KEY |
clientes OpenAI-compatible |
Essa distinção aparece também nas issues abertas. Há casos em que usuários apontaram o Desktop para um backend com semântica mais próxima de API server e acabaram em estados híbridos ou enganadores, especialmente quando a checagem de readiness era superficial.
Problemas conhecidos hoje
A funcionalidade existe, mas está claramente em fase de endurecimento. Os problemas mais importantes que apareceram nas issues/PRs oficiais são estes.
1. “Test remote” pode dar verde e ainda assim a sessão real falhar
Esse é um dos bugs mais importantes. As issues verificadas #38115 ("Test remote" falso-positivo + loop de reconexão) e #38266 (reconnect loop após sucesso aparente) mostram o padrão: a checagem REST parecia passar, mas depois o Desktop entrava em loop ou erro de boot. O PR #39522 existe justamente para endurecer a validação com um probe real de WebSocket, e não só de /api/status.
2. Sem --tui, o backend remoto pode parecer saudável e ainda assim não funcionar para o Desktop
Esse detalhe é tão importante que gerou PR de documentação próprio: #38260. O Desktop remoto espera a camada TUI/WS do dashboard. Se você subir só um dashboard “sem chat embutido”, a saúde aparente do endpoint pode enganar.
3. Há cenários em que o REST passa, mas o WebSocket /api/ws é rejeitado
A issue #38412 descreve exatamente isso: o Desktop empacotado consegue falar com a camada REST, mas a perna de WebSocket é rejeitada com 4403. Isso reforça o ponto central do guia: Desktop remoto não é só “um healthcheck HTTP”; ele depende de autenticação e prontidão reais na camada de WS.
4. Algumas builds entram em loop e voltam para backend local — ou morrem logo após o “backend ready”
Esse comportamento aparece em várias issues recentes. Em #38266 o app entra em reconnect loop após sucesso aparente. Em #38468 o Desktop no macOS chega ao backend remoto, mas falha com Object has been destroyed in getWindowState() logo depois do backend ready.
5. O file browser/workspace ainda não é um “workspace remoto verdadeiro”
A issue #38671 é muito relevante aqui. Ela mostra que, no modo remoto, a experiência de sessão pode estar remota enquanto o file browser do Electron continua apoiado no filesystem local do cliente. Isso cria um modelo meio híbrido: chat remoto, browsing local.
6. Colar imagens em modo remoto teve bug de path local
A issue #38078 e os PRs #39264 / #39437 mostram outro nuance importante: imagens coladas no cliente podiam virar paths locais do Mac/Windows/Linux, inviáveis no backend remoto. A correção caminha para embutir isso como base64/data URL, mas é uma área que vale testar no seu fluxo real antes de depender dela.
7. Troca de profile remoto ainda não é first-class na UI
A issue #37713 mostra bem essa lacuna. Em uso remoto, o profile efetivo continua sendo o profile com que o backend foi iniciado. A UI pode listar perfis, mas isso não significa, hoje, que você está de fato retargetando execução, memória e sessões para outro profile remoto em tempo real.
Melhores práticas para operar isso com menos atrito
- Suba o backend remoto com
--tui. Trate isso como obrigatório. - Fixe um token estável via
HERMES_DASHBOARD_SESSION_TOKEN. - Prefira rede privada a exposição pública.
- Teste o endpoint antes de abrir o Desktop.
- Se a UI começar a agir de forma estranha, use env override para eliminar estado persistido ruim.
- Não trate o file browser como garantia de semântica remota plena até validar seu caso específico.
- Se quiser isolamento por profile, considere um backend remoto separado por profile, cada um com URL/porta próprios.
Estratégia boa para múltiplos profiles
Como a troca dinâmica de profile remoto ainda não está madura na UI, uma estratégia operacional limpa é rodar um dashboard remoto por profile. Por exemplo:
default -> https://hermes.exemplo.com/default
crypto -> https://hermes.exemplo.com/crypto
research -> https://hermes.exemplo.com/research
Ou, em portas distintas dentro da sua overlay:
default -> http://100.x.y.z:9119
crypto -> http://100.x.y.z:9120
research -> http://100.x.y.z:9121
Não é o UX ideal, mas hoje tende a ser mais previsível do que esperar uma troca de contexto remota total dentro do mesmo processo/URL.
Se você realmente quiser zero Hermes local no Mac
Aqui vale ser brutalmente preciso. Se “zero local” significa nenhum runtime Hermes bootstrapado no Mac, então o desktop oficial ainda não entrega isso completamente. O que existe hoje é:
- modo remoto funcional, porém em cima de um app que ainda prepara runtime local;
- PRs para desktop-only install mode, que reduzem o atrito de setup local;
- issue de onboarding nativo para “conectar a um Hermes existente”.
Se o seu requisito for literal, as alternativas mais honestas hoje são:
- usar o web dashboard remotamente;
- usar Open WebUI ou outro frontend OpenAI-compatible contra o API server;
- esperar amadurecer o fluxo desktop-only / existing instance onboarding.
Isso não significa desistir do Desktop. Só significa alinhar a expectativa ao estado real do produto em junho de 2026.
Roteiro mínimo que eu seguiria hoje
- instalar Hermes completo no servidor remoto;
- instalar extras de web e pty;
- gerar e fixar
HERMES_DASHBOARD_SESSION_TOKEN; - subir
hermes dashboard --tui --no-open --insecure --host ... --port 9119; - validar
/api/statuscom headerX-Hermes-Session-Token; - instalar/abrir Hermes Desktop no Mac;
- configurar Remote gateway com a URL do dashboard, não a do
/v1; - usar env override se a UI estiver persistindo estado ruim;
- tratar explorer/attachments remotos como área que ainda exige teste cuidadoso;
- acompanhar os PRs/issues citados abaixo antes de consolidar esse fluxo como “produção sem dor”.
Veredito
A funcionalidade é real e já suficientemente concreta para uso por operadores técnicos. O app desktop oficial já tem UI de Remote gateway, código para URL remota + token, suporte a prefixo de path e uma direção clara de produto.
Mas, hoje, ela ainda deve ser tratada como funcionalidade promissora em consolidação, não como experiência totalmente acabada. O principal motivo é simples: a ideia de “Mac como cliente puro” ainda não está plenamente resolvida no produto, e a estabilidade do fluxo remoto ainda depende de detalhes como --tui, token estável, forma de exposição e versão exata do app.
Fontes oficiais e trilhas para acompanhar
- Hermes Desktop README oficial
- Documentação oficial do Web Dashboard
- Referência oficial de comandos CLI
- Variáveis de ambiente oficiais
- Open WebUI integration — útil para comparar com o caso do API server
- PR #38144 — docs do session token para Hermes Desktop remoto
- PR #38260 — documentação do
--tuino backend remoto - PR #39522 — validar readiness real de WebSocket
- PR #39264 — imagens inline para backends remotos
- PR #39237 — Add desktop-only install mode (salvage #36674)
- Issue #36970 — Desktop: add first-class remote-client onboarding for existing Hermes instances
- Issue #38115 — false-pass, loop de reconexão e instabilidade no macOS remoto
- Issue #38266 — Hermes Desktop 0.15.1 remote gateway enters reconnect loop after successful connection
- Issue #38412 — /api/ws rejeitado (4403) para cliente Desktop empacotado
- Issue #38468 — crash no macOS após backend ready:
Object has been destroyed - Issue #39365 — erro enganoso de OpenRouter quando a falha real é 401 de gateway/API_SERVER_KEY
- Issue #38575 — token fixado do dashboard pode envenenar o modo local