O OpenHands Agent Canvas é um painel self-hosted, distribuído como o pacote npm @openhands/agent-canvas e como imagem Docker, que centraliza conversas com agentes de código e automações agendadas ou disparadas por webhook. Ele roda o agente open source OpenHands por padrão, mas também conduz Claude Code, Codex, Gemini CLI, Pi, OpenCode ou qualquer agente compatível com ACP. Serve para quem quer tirar o agente do terminal do laptop e rodá-lo num container, numa VM ou num cluster, alternando entre esses ambientes por uma única interface.
Este texto se baseia na leitura do código e da documentação do repositório OpenHands/OpenHands. Não executei a ferramenta. Na data deste post, o repositório tem 90744 estrelas e licença MIT. O próprio README marca o projeto como beta.
O que é o OpenHands Agent Canvas?
O nome do repositório é OpenHands, mas o produto descrito no README é o Agent Canvas, definido como "o centro de controle self-hosted para agentes de código e automações". Na prática, é um frontend em React e TypeScript que conversa com um ou mais Agent Servers, além de um launcher que sobe o stack local completo.
O repositório deixa claro o que fica de fora dele:
| Repositório | Responsabilidade |
|---|---|
OpenHands/OpenHands |
Interface do Agent Canvas, seleção de backend e orquestração do stack local |
OpenHands/software-agent-sdk |
SDK Python, Agent Server, agentes, ferramentas e API canônica |
OpenHands/typescript-client |
Cliente TypeScript da API do Agent Server |
OpenHands/automation |
Definição de automações, agendamento, webhooks e histórico de execuções |
O agente não executa nada dentro do Canvas. Quem executa é o Agent Server. O Canvas registra o que você quer, mostra eventos, terminal, arquivos e diffs, e manda as ações para o backend escolhido.
Como o Agent Canvas funciona por dentro?
O comando agent-canvas sobe quatro processos atrás de um ingress proxy, um proxy reverso que expõe uma única porta e roteia por caminho. A documentação de self-hosting descreve o layout padrão:
| Serviço | Porta | Rotas |
|---|---|---|
| Ingress proxy | 127.0.0.1:8000 |
ponto de entrada único |
| Static server (frontend) | 3001 |
/* |
| Agent Server | 18000 |
/api/*, /sockets |
| Automation backend | 18001 |
/api/automation/* |
O Dockerfile em docker/Dockerfile faz o mesmo numa imagem só. Parte da imagem oficial do Agent Server, instala openhands-automation via uv pip, copia o build estático do frontend e usa docker/entrypoint.sh como entrypoint, com tini na frente.
Algumas peças que valem conhecer:
- Versões pinadas em
config/defaults.json. O Agent Server e o automation rodam viauvxcom a versão deversions.agentServereversions.automation. O campocompatibility.minimumAgentServerdefine o Agent Server mais antigo que o frontend aceita, verificado em runtime porassertAgentServerVersionIsSupported(). Dá para trocar o backend comOH_AGENT_SERVER_VERSION,OH_AGENT_SERVER_GIT_REFouOH_AGENT_SERVER_LOCAL_PATH. - Cliente tipado obrigatório. O frontend só fala com o Agent Server pelo
@openhands/typescript-client. Existe um teste (src/api/no-direct-agent-server-calls.test.ts) que barrafetchouaxiosdireto para esses endpoints. - ACP como ponte para agentes de terceiros. O ACP (Agent Client Protocol) é um padrão de comunicação com agentes de código via JSON-RPC sobre stdio. Quando você escolhe Claude Code, o Agent Server sobe a CLI do agente como subprocesso (por padrão
npx -y @agentclientprotocol/claude-agent-acp) e repassa cada turno. O LLM, as ferramentas e a execução ficam com o agente externo. - Segredos viram variáveis de ambiente. Cada credencial cadastrada é salva como "global secret" com o nome exato da variável que o Agent Server exporta para o subprocesso ACP, por exemplo
ANTHROPIC_API_KEY. - Contexto de runtime injetado. O launcher expõe
/server_info.runtime_services, e o frontend repassa esse bloco para novas conversas, para o agente usar as URLs corretas em vez de chutar portas.
Como instalar o Agent Canvas?
O README traz quatro caminhos. Os pré-requisitos comuns são Node.js 24 ou superior e uv. Para os modos com container, também Docker.
Opção 1, sem sandbox (o agente tem acesso total ao seu filesystem):
npm install -g @openhands/agent-canvas
agent-canvas
Dá para separar as partes com agent-canvas --frontend-only ou agent-canvas --backend-only.
Opção 2, com sandbox Docker. O agente só enxerga o que estiver em PROJECTS_PATH:
export PROJECTS_PATH="$HOME/projects" mkdir -p "$PROJECTS_PATH" "$HOME/.openhands" docker run -it --rm \ -p 127.0.0.1:8000:8000 \ -e AGENT_CANVAS_ALLOW_LAN_SESSION_KEY=true \ -v "$HOME/.openhands:/home/openhands/.openhands" \ -v "${PROJECTS_PATH}:/projects" \ ghcr.io/openhands/agent-canvas:1.27.1
Nesse modo a interface fica em http://localhost:8000/canvas.
Opção 3, um container por conversa. Útil para rodar vários agentes em paralelo:
npm install -g @openhands/agent-canvas
OH_CONVERSATION_RUNTIME=docker agent-canvas
Cada conversa ganha seu próprio Agent Server num container. O Canvas e o serviço de automação continuam no host. No Windows, esse modo só funciona dentro do WSL 2.
Opção 4, a partir do código-fonte: git clone, npm install e npm run dev.
Também existe um chart Helm em helm/agent-canvas, que a própria documentação chama de experimental, e um app desktop em Electron.
Como usar o Claude Code dentro do Agent Canvas?
Este é o fluxo que mais interessa a quem já usa Claude Code no terminal. Se você já configurou o Claude Code no projeto, com o que descrevi em como configurar o Claude Code em projetos Laravel com CLAUDE.md, hooks e comandos, o Canvas reaproveita a CLI em vez de substituí-la.
O onboarding tem quatro passos:
- Choose agent: escolha Claude Code em vez de OpenHands.
- Check backend: confirma que o Agent Server responde.
- Set up credentials: em backend local, é opcional. Se você já fez login no Claude Code na mesma máquina (Keychain no macOS,
~/.claude/.credentials.jsonno Linux), o login de assinatura é detectado e tem prioridade sobre a API key. Em backend Docker ou cloud, o passo é obrigatório, porque o container não tem login do host. Nesse caso você informaCLAUDE_CODE_OAUTH_TOKENouANTHROPIC_API_KEY. - Say hello: cria a primeira conversa.
Depois, em Settings → Agent, dá para trocar entre OpenHands e ACP, escolher outro preset ou usar Custom com o comando de qualquer servidor ACP via stdio. Uma conversa em andamento mantém o agente com que começou. A mudança só vale para as próximas.
A documentação traz um alerta específico: não defina ANTHROPIC_BASE_URL junto com o token OAuth do Claude. Uma base URL herdada de um LiteLLM, por exemplo, quebra a autenticação bearer sem erro claro.
Para deixar os agentes rodando com o laptop fechado, o guia docs/SELF_HOSTING.md propõe uma VM:
export LOCAL_BACKEND_API_KEY=$(openssl rand -base64 32) npx @openhands/agent-canvas --public
Com --public, a chave não é injetada no HTML. Quem abrir a interface precisa colar o valor de LOCAL_BACKEND_API_KEY, e toda chamada /api/* exige o header X-Session-API-Key. O guia inclui uma unit systemd, a configuração do nginx com suporte a WebSocket e o passo a passo do Let's Encrypt. Depois, no Canvas local, você adiciona a VM em Manage backends → Add a backend e alterna entre os dois pelo seletor.
Quando vale a pena usar o Agent Canvas e quando não?
Vale a pena quando:
- Você mantém vários projetos e quer agentes trabalhando fora do horário, por exemplo gerando relatórios ou quebrando issues do GitHub em tarefas. Para quem toca vários produtos sozinho, como discuti em como manter vários SaaS em produção sendo dev solo, automatizar esse tipo de rotina libera tempo de verdade.
- Você quer compartilhar um Agent Server com o time para code review e atualização de dependências, e manter agentes pessoais no laptop. O README cita esse cenário explicitamente.
- Você usa mais de um agente (Claude Code para uma coisa, Codex para outra) e quer uma interface só, com histórico, terminal, diff e segredos no mesmo lugar.
- Você precisa de isolamento por conversa sem montar a infraestrutura na mão (Opção 3).
Não vale a pena quando:
- Você usa um agente só, num repositório só, pelo terminal. O stack (Agent Server, automation, ingress, frontend) é peso extra para pouco ganho.
- Você precisa de multiusuário com autenticação e isolamento entre times. O chart Helm diz que o Agent Canvas é "não autenticado e single-tenant" e aponta o produto Enterprise para esse caso.
- O ambiente é Windows nativo e você quer containers por conversa.
- Você não tolera mudanças frequentes. O projeto está em beta e depende de quatro repositórios versionados de forma independente.
Quais cuidados tomar antes de rodar o Agent Canvas?
Tudo aqui roda com as permissões de quem instala. A documentação é bem honesta sobre isso, e vale levar a sério:
- Filesystem e shell. Nas opções 1 e 4, o Agent Server roda direto no host e o agente lê e escreve qualquer arquivo do seu usuário, executa comandos e acessa a rede. A skill
verify-openhands, do próprio repositório, registra que, com prompts vagos, um modelo leu o diretório de execução, o checkout, arquivos de outras sessões em/tmpe a saída deenv. Tudo o que o agente lê vai para o provedor do LLM. Num ambiente de fintech, isso basta para nunca rodar o modo sem sandbox numa máquina que tenha.envde produção ou credenciais de gateway. - Variáveis de ambiente e segredos. As credenciais viram variáveis de ambiente do subprocesso do agente. Um agente que roda
envvê todas elas. Os riscos de prompt injection levando a vazamento são os mesmos que descrevi em prompt injection e LGPD em agentes de IA. - Chave de sessão no navegador. O
SELF_HOSTING.mdavisa que o editor OpenVSCode embutido compartilha a origem do Canvas. Um script nessa origem pode ler olocalStorage, onde ficam as chaves de sessão de todos os backends cadastrados naquele navegador. O problema está rastreado na issue #16492. - Bind de rede. O launcher npm escuta só em
127.0.0.1. Se você passar--host 0.0.0.0ou publicar o Docker numa interface de LAN, removaAGENT_CANVAS_ALLOW_LAN_SESSION_KEYe defina umaLOCAL_BACKEND_API_KEYforte. Para exposição na internet, siga o roteiro de firewall do guia antes de subir o serviço. - Download de código em runtime. Os agentes ACP Pi e OpenCode não vêm na imagem: a primeira conversa baixa a CLI via
npx. O Agent Server e o automation também são baixados viauvxno primeiro start. Fixe versões se isso importar para a sua cadeia de suprimentos. - Telemetria. O frontend inclui
posthog-js, a imagem Docker recebeVITE_POSTHOG_API_KEYno build e há um banner de consentimento de telemetria. Revise essa configuração se o ambiente for sensível. - Workspace compartilhado. Mesmo com um container por conversa, conversas que apontam para o mesmo diretório do host compartilham arquivos. A documentação recomenda diretórios ou worktrees separados.
- Kubernetes. No chart Helm,
rbac.clusterAdmin=truedácluster-adminao agente. Prefira restringir porrbac.namespacese coloque um ingress autenticado na frente.
Por onde começar com o Agent Canvas
Se eu fosse avaliar o Agent Canvas num contexto de back-end com dados financeiros, começaria pela Opção 2. O PROJECTS_PATH apontaria para uma pasta só com clones de trabalho, sem .env real, e as credenciais de LLM ficariam numa conta com limite de gasto. Com isso estável, o passo seguinte é uma VM com --public, firewall fechado e acesso via túnel SSH, cadastrada como segundo backend no Canvas local. Só depois disso eu criaria automações que tocam GitHub ou Slack, sempre lembrando que quem fala com o Agent Server tem, na prática, um shell na máquina.