OpenHands CLI QuickStart: installazione, flag, modalità headless

Installazione da CLI, flag, modalità headless, modelli locali

Indice

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.

openhands text user interface

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

openhands settings ollama mistral

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 serve avvia la GUI legacy in Docker. --mount-cwd monta la directory corrente in /workspace. --gpu attiva nvidia-docker.
  • openhands web serve il CLI in un browser. --host predefinito su 0.0.0.0, --port su 12000, --debug disattivato.
  • openhands acp parla Agent Client Protocol su stdio. Flag: --resume, --last, --always-approve, --llm-approve, --streaming.
  • openhands cloud -t "task" apre una conversazione cloud. --server-url override su https://app.all-hands.dev.
  • openhands login e openhands logout gestiscono quell’account cloud. logout senza --server-url fa disconnessione da ogni server salvato.
  • openhands mcp gestisce i server: add, list, get, remove, enable, disable. add richiede --transport di http, sse o stdio.

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.

OpenHands with Ollama-hosted Devstral-Small-2

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.

Iscriviti

Ricevi nuovi articoli su sistemi, infrastruttura e ingegneria AI.