OpenHands CLI QuickStart: installazione, flag, modalità headless
Installazione da CLI, flag, modalità headless, modelli locali
OpenHands è un agente di coding open source che modifica file ed esegue comandi in un ambiente sandbox. Questo quickstart CLI è stato verificato il 26/10/2026 contro il pacchetto 1.16.0.
Il pacchetto su PyPI è openhands 1.16.0, caricato l'8 maggio 2026, con dipendenza fissa su openhands-sdk==1.21.0. Il tag README richiede Python 3.12 e uv 0.11.6 o versioni successive. Il README del ramo principale di OpenHands-CLI indica che quel repository non è più mantenuto attivamente e reindirizza le nuove installazioni ad Agent Canvas. La modalità headless e openhands acp fanno ancora parte del set di comandi della versione 1.16.0.

La guida agli strumenti per sviluppatori AI segue gli altri agenti terminali presenti su questo sito. Questa pagina si concentra sul CLI di OpenHands: installazione, file di configurazione, URL dei modelli locali e i flag effettivamente passati da uno script.
Cos’è il CLI
Un assistente di coding AI genera o modifica tipicamente il codice a partire da un prompt. OpenHands estende questo concetto in un loop di agente: pianificare, compiere un’azione come scrivere un file o eseguire un test, osservare il risultato e continuare. Il progetto si chiamava precedentemente OpenDevin. Il paper di OpenHands descrive un runtime Docker-sandboxed con shell e navigazione, che è il modello di esecuzione che il CLI ancora avvolge.
La release 1.16.0 documenta cinque modi per eseguire quel loop.
| Modalità | Comando | Utilizzo |
|---|---|---|
| Interfaccia terminale | openhands |
Sessione interattiva. Chiede prima di ogni azione a meno che non si passi un flag di approvazione. |
| Headless | openhands --headless -t "task" |
CI e script. Richiede --task o --file. Approva sempre le azioni. |
| ACP | openhands acp |
Server Agent Client Protocol per Zed, JetBrains, Toad e l’estensione ACP di VS Code. |
| TUI nel browser | openhands web |
Lo stesso CLI in un browser. Bind predefinito su 0.0.0.0:12000. |
| GUI legacy | openhands serve |
GUI Docker dal launcher del CLI. URL predefinito http://localhost:3000. |
Agent Canvas, l’installazione che il progetto documenta attualmente
Il 3 giugno 2026 la FAQ di OpenHands ha messo l’interfaccia terminale in manutenzione fino al 1 ottobre 2026, dichiarando che la modalità headless e l’ACP sarebbero rimasti pienamente supportati. La GUI locale (openhands serve) doveva restare in manutenzione finché Agent Canvas non avrebbe potuto eseguire sandbox isolati ed effimeri. Quella FAQ definisce la manutenzione come aggiornamenti delle dipendenze, correzioni di bug critici e nuovi LLM. Il repository principale di OpenHands ha rilasciato Agent Canvas 1.33.0 il 23 ottobre 2026.
agent-canvas avvia l’interfaccia utente attuale e il relativo backend. openhands serve avvia la GUI legacy e non avvia Agent Canvas.
Agent Canvas richiede Node.js 24 o versioni successive e uv. Una prima esecuzione senza installazione globale:
npx @openhands/agent-canvas
Il processo ascolta su http://localhost:8000. Chiudere quel terminale ferma il backend locale. Un’installazione globale è npm install -g @openhands/agent-canvas, poi agent-canvas. Il percorso npm esegue il server agente come l’utente corrente, quindi l’agente può operare sui file locali con i permessi del tuo account.
Il percorso Docker pubblica la porta solo su localhost e monta una directory progetti:
mkdir -p ~/projects
docker run -it --rm \
-p 127.0.0.1:8000:8000 \
-v openhands-data:/home/openhands/.openhands \
-v ~/projects:/projects \
ghcr.io/openhands/agent-canvas:latest
Il contenitore serve l’interfaccia su http://localhost:8000/canvas. Il volume denominato openhands-data mantiene le impostazioni dopo --rm. Su Linux, il bind-mount di ~/.openhands in questa immagine fallisce con l’errore unable to open database file: l’utente del contenitore ha UID 10001, e una directory host è di solito posseduta dal proprio UID. La pagina di installazione usa il volume denominato per questo motivo. Le impostazioni già presenti in ~/.openhands non vengono copiate in un nuovo volume.
Installazione del CLI OpenHands
Usa il CLI se si desidera ancora openhands --headless o openhands acp. La wheel pubblicata si installa solo su Python 3.12 (==3.12.* su PyPI). uv deve essere 0.11.6 o versioni successive. Su Windows, la pagina di installazione dice di eseguire i comandi in WSL (Ubuntu).
Installazione con uv
uv tool install openhands --python 3.12
openhands
Aggiorna con la stessa pinning dell’interprete:
uv tool upgrade openhands --python 3.12
La pagina local-setup dice che uv è ciò che isola il CLI dal virtualenv del progetto, e che i server MCP predefiniti lo richiedono.
Installazione del binario standalone
curl -fsSL https://install.openhands.dev/install.sh | sh
openhands
Su macOS, un dialogo Gatekeeper può bloccare il binario (“Impossibile aprire openhands perché Apple non può verificarlo per software malevolo”). Il percorso della pagina di installazione è Impostazioni di Sistema, Privacy e Sicurezza, poi Consenti comunque sotto Sicurezza, poi eseguire di nuovo openhands.
Esecuzione del CLI tramite Docker
Il contenitore della pagina di installazione imposta AGENT_SERVER_IMAGE_TAG sull’immagine agent-server. Il uv tool install openhands all’interno del contenitore è il CLI di PyPI. Il tag in quell’esempio, verificato per questa pagina, è 1.26.0-python. Le copie più vecchie di questo comando usavano 1.12.0-python.
export SANDBOX_VOLUMES="$PWD:/workspace"
docker run -it \
--pull=always \
-e AGENT_SERVER_IMAGE_REPOSITORY=ghcr.io/openhands/agent-server \
-e AGENT_SERVER_IMAGE_TAG=1.26.0-python \
-e SANDBOX_USER_ID=$(id -u) \
-e SANDBOX_VOLUMES=$SANDBOX_VOLUMES \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/root/.openhands \
--add-host host.docker.internal:host-gateway \
--name openhands-cli-$(date +%Y%m%d%H%M%S) \
python:3.12-slim \
bash -c "pip install uv && uv tool install openhands --python 3.12 && openhands"
SANDBOX_USER_ID=$(id -u) fa corrispondere l’utente sandbox all’utente host, in modo che l’agente non lasci file di proprietà root nello workspace montato. SANDBOX_VOLUMES è la directory a cui l’agente può accedere.
OPENHANDS_VERSION seleziona la versione dell’immagine Docker per openhands serve. Non cambia la versione del CLI di PyPI.
File di configurazione
Al primo avvio, il CLI chiede le impostazioni del modello e le scrive sotto ~/.openhands/. Il README della 1.16.0 e il riferimento ai comandi nominano questi file:
| File | Contenuto |
|---|---|
~/.openhands/agent_settings.json |
Specifica agente persistita, inclusa la sezione LLM e la configurazione del condenser |
~/.openhands/cli_config.json |
Preferenze del CLI, incluso se il critic è abilitato |
~/.openhands/mcp.json |
Definizioni dei server MCP |
~/.openhands/conversations/ |
Storico delle conversazioni |
La pagina di installazione dice ancora agli utenti Docker di preparare ~/.openhands/settings.json. Il README del CLI e AgentStore nell’albero 1.16.0 persistono la specifica agente in agent_settings.json. Un’installazione CLI che ha saltato il nome file della pagina di installazione e ha scritto agent_settings.json è in linea con quella fonte.
create_and_save_from_settings costruisce due oggetti LLM dallo stesso modello, chiave API e base URL: uno per l’agente e uno per il condenser che riassume. Questo è perché un file salvato ripete i campi llm. Modifica il file agente con un editor a piacere:
nano ~/.openhands/agent_settings.json
LLM_API_KEY, LLM_MODEL e LLM_BASE_URL sono ignorati a meno che non si opti per l’override. L’override non viene salvato:
export LLM_MODEL="gpt-4o"
export LLM_API_KEY="la-tua-chiave-api"
openhands --override-with-envs
OPENHANDS_CLOUD_URL imposta il server cloud predefinito. I comandi cloud e login usano https://app.all-hands.dev come predefinito quando quella variabile non è impostata.
Gli aggiornamenti da una CLI precedente alla 1.0.0 richiedono di reinserire le impostazioni. La pagina di installazione dice che il formato della configurazione è cambiato nella 1.0.0.
Modelli locali
La guida sui LLM locali datata 21 maggio 2026 raccomanda Qwen3.6-35B-A3B come primo modello locale da provare. Richiede una GPU con almeno 24GB di VRAM per una build quantizzata, o un Mac con Apple Silicon con almeno 64GB di memoria unificata. La stessa pagina dice di impostare la lunghezza del contesto ad almeno 22000 token, e che il predefinito di Ollama di 4096 è troppo piccolo per il system prompt.
Quando l’agente non chiama mai tool, la guida tratta ciò come un limite del modello e cita rapporti della comunità per qwen2.5-coder-14b-instruct e qwopus3.5-27b-v3. Il confronto sull’hosting locale è la tabella server per server quando Ollama, vLLM, LM Studio o LocalAI è ancora una scelta aperta.
Ollama
L’avvio di Ollama nella guida imposta la lunghezza del contesto prima di ollama serve. La scheda rapida del CLI Ollama copre serve, run e ps accanto a quella variabile.
OLLAMA_CONTEXT_LENGTH=32768 OLLAMA_HOST=0.0.0.0:11434 OLLAMA_KEEP_ALIVE=-1 ollama serve
ollama pull qwen3.6:35b-a3b
Per OpenHands eseguito in Docker, le impostazioni della guida sono modello personalizzato openai/qwen3.6:35b-a3b, base URL http://host.docker.internal:11434/v1 e qualsiasi chiave API segnaposto. Un CLI eseguito sulla stessa host di Ollama usa http://127.0.0.1:11434/v1 al posto di host.docker.internal. I server solo loopback come Linux LM Studio e altri sono irraggiungibili da un contenitore su 127.0.0.1; il check della guida è abilitare il serving sulla rete locale e curlare host.docker.internal da dentro il contenitore.
La pagina terminale apre quella schermata con Ctrl+P, poi Impostazioni. Un profilo CLI salvato usava un id modello ollama/ e una base URL senza /v1:
- Modello personalizzato:
ollama/devstral-small-2:24b - Base URL:
http://localhost:11434

Quella sessione di Devstral-Small-2 è quella che continuava a fermarsi. I campi scritti per essa, sia nell’LLM dell’agente sia nell’LLM del condenser, erano:
"llm": {
"model": "ollama/devstral-small-2:24b",
"api_key": "aaa",
"base_url": "http://localhost:11434"
}
llama.cpp e vLLM
llama.cpp usava il prefisso compatibile con OpenAI e una base URL /v1, ancora una volta in entrambi gli oggetti LLM:
"model": "openai/Qwen3.5-35B-A3B-UD-IQ3_S.gguf""base_url": "http://localhost:8080/v1"
Il comando del server, con flag coperti nel quickstart di llama.cpp, era:
./llama.cpp/llama-server \
-m /mnt/ggufs/Qwen3.5-35B-A3B-UD-IQ3_S.gguf \
--ctx-size 70000 \
-ngl 40 \
--temp 0.6 \
--top-p 0.95 \
--top-k 20 \
--min-p 0.00
Contro quel server, il CLI ha completato un client Go IndexNow: sorgente, un eseguibile e un README. Il testo del task era create for me a cli tool in Go, that would call bing and other search engines' indexnow endpoints to notify about changes on my website.
L’esempio di vLLM nella guida sui LLM locali per il modello Qwen3.6 più recente è un serve a doppia GPU. Il quickstart di vLLM passa in rassegna i flag di vllm serve e i controlli out-of-memory. La stringa modello corrispondente di OpenHands nella guida è openai/Qwen3.6-35B-A3B, con base URL http://host.docker.internal:8000/v1 e lo stesso --api-key con cui è stato avviato il server (mykey nel loro esempio).
vllm serve Qwen/Qwen3.6-35B-A3B \
--host 0.0.0.0 --port 8000 \
--api-key mykey \
--tensor-parallel-size 2 \
--served-model-name Qwen3.6-35B-A3B \
--enable-prefix-caching
Controlli interattivi
openhands senza sotto-comando apre l’interfaccia terminale. La pagina terminale elenca questi controlli:
| Controllo | Azione |
|---|---|
Ctrl+P |
Palette comandi. Impostazioni, stato MCP, cronologia, piano, tema, uscita. |
Esc |
Mette in pausa l’agente in esecuzione. |
Ctrl+Q o /exit |
Esce dal CLI. |
Comandi slash dal riferimento ai comandi: /help, /new, /history, /confirm, /condense, /skills, /feedback, /exit. I cambi di modello dall’entry Impostazioni della palette si applicano senza riavvio. --exit-without-confirmation salta il dialogo di uscita. --exp seleziona l’interfaccia utente testuale ed è documentato come un flag di compatibilità perché quell’interfaccia è già quella predefinita.
Flag e sotto-comandi
openhands [OPTIONS] [COMMAND]
Opzioni globali nel riferimento ai comandi, verificate contro argparsers/util.py sul tag 1.16.0 per i flag di approvazione e ambiente:
| Opzione | Effetto |
|---|---|
-v, --version |
Stampa la versione ed esce. |
-t, --task TEXT |
Seme la conversazione con questo task. |
-f, --file PATH |
Seme la conversazione da un file. |
--resume [ID] |
Riprende quella conversazione. Senza ID, elenca quelle recenti. |
--last |
Con --resume, riprende la conversazione più recente. |
--headless |
Nessuna interfaccia. Richiede --task o --file. Approva sempre. |
--json |
Stream di eventi JSONL. Richiede --headless. |
--always-approve, --yolo |
Approva ogni azione. Mutualmente esclusivo con --llm-approve. |
--llm-approve |
Conferma solo le azioni che l’analizzatore di sicurezza LLM marca come rischio elevato. |
--override-with-envs |
Applica LLM_API_KEY, LLM_MODEL e LLM_BASE_URL per questo processo. |
--exit-without-confirmation |
Esce senza il dialogo di conferma. |
--always-approve e --llm-approve non possono essere combinati. La modalità interattiva predefinita chiede prima delle azioni.
Sotto-comandi che emergono quando la TUI non basta:
openhands serveavvia la GUI legacy in Docker.--mount-cwdmonta la directory corrente in/workspace.--gpuattiva nvidia-docker.openhands webserve il CLI in un browser.--hostpredefinito su0.0.0.0,--portsu12000,--debugdisattivato.openhands acpparla Agent Client Protocol su stdio. Flag:--resume,--last,--always-approve,--llm-approve,--streaming.openhands cloud -t "task"apre una conversazione cloud.--server-urloverride suhttps://app.all-hands.dev.openhands logineopenhands logoutgestiscono quell’account cloud.logoutsenza--server-urlfa disconnessione da ogni server salvato.openhands mcpgestisce i server:add,list,get,remove,enable,disable.addrichiede--transportdihttp,sseostdio.
Un server MCP dal README 1.16.0:
openhands mcp list
openhands mcp add tavily --transport stdio \
npx -- -y mcp-remote "https://mcp.tavily.com/mcp/?tavilyApiKey=<la-tua-chiave-api>"
openhands mcp enable tavily
openhands mcp disable tavily
Esempi
Task interattivo
openhands -t "Fix the bug in auth.py and add a regression test"
File di task
cat > task.txt << 'EOF'
Refactor the database connection module.
Add unit tests and ensure the test suite passes.
EOF
openhands -f task.txt
Headless, incluso JSONL
La modalità headless richiede --task o --file. Esegue sempre come always-approve, e --llm-approve è respinto lì. Tratta la directory di lavoro come una che l’agente può modificare liberamente.
openhands --headless -t "Add unit tests for auth.py and run them"
openhands --headless --json -t "Create a simple Flask app with healthcheck endpoint" > openhands-output.jsonl
La pagina headless descrive --json come un oggetto JSON per evento, trasmesso come JSONL.
Ripresa
openhands --resume
openhands --resume --last
openhands --resume abc123def456
TUI nel browser vincolato a localhost
openhands web predefinito su 0.0.0.0:12000, che è raggiungibile dalla rete. I documenti del CLI dicono che quell’interfaccia ha la piena capacità del CLI, quindi un bind solo locale è il predefinito più sicuro:
openhands web --host 127.0.0.1 --port 12000
ACP per un editor
I client ACP nella pagina IDE sono Zed e JetBrains (nativi), Toad (nativo), e VS Code (estensione community). L’editor avvia openhands acp e parla JSON-RPC 2.0 su stdio, usando le impostazioni LLM salvate del CLI.
openhands acp
openhands acp --llm-approve
openhands acp --resume --last
Approvazione, codici di uscita e risultati modelli locali
Le sessioni interattive chiedono prima delle azioni. /confirm cambia quella politica nella sessione. --always-approve (alias --yolo) approva tutto. --llm-approve chiede solo per le azioni che l’analizzatore di sicurezza classifica come rischio elevato. La modalità headless è always-approve per tutta l’esecuzione.
openhands serve --mount-cwd monta la directory corrente in /workspace dentro il contenitore della GUI legacy. Il flusso Docker CLI usa SANDBOX_VOLUMES per lo stesso confine.
Codici di uscita nel riferimento ai comandi:
| Codice | Significato |
|---|---|
| 0 | Successo |
| 1 | Errore, o il task è fallito |
| 2 | Argomenti non validi |
Devstral-Small-2 24B su Ollama si è fermato ripetutamente in questo CLI.

La sessione llama.cpp sopra, Qwen3.5-35B-A3B su un contesto di 70000 token, ha completato il task IndexNow. Per un agente terminale che ha continuato a lavorare sulla stessa macchina, il quickstart di OpenCode è l’installazione e la configurazione dei provider.