Headless Help Documentation
Headless mode lets Hawa Code run without launching the terminal interactive interface, making it suitable for UI-less environments, remote services, and automation scenarios. Note that Headless is NOT enabled via a --headless parameter. Hawa Code provides two UI-less ways of running:
hcode server: Headless resident service. The process stays running without rendering a terminal UI, with a built-in WebServer (HTTP + WebSocket) for remote control via browser. This is the official Headless run mode.hcode -p "...": Single-turn non-interactive mode. Executes one task, prints the result to standard output, and exits. Suitable for pipes and script invocation, but not a resident service.
Note: The
headlessBrowsersetting (headless browser) is used for web page fetching and rendering, and is unrelated to the Headless run mode. Do not confuse the two.
1. Differences Between the Two Modes
| Comparison | hcode server |
hcode -p "..." |
|---|---|---|
| Run mode | Process stays resident, does not exit | Exits after a single run |
| Interactivity | Real-time interaction in browser, tool-call approval | No interaction, one-shot output |
| Use cases | Remote resident services, UI-less environments | CI/CD, scripts, pipe invocation |
- Use
hcode serverwhen you need to “run long-term on a remote machine and use the full Agent capability via browser”. - Use
hcode -pwhen you need to “run a single command in a pipeline and judge the result by exit code”.
2. Starting the Headless Service with hcode server
2.1 Command Format
hcode server [options] |
2.2 Parameters
| Parameter | Description |
|---|---|
--port <n> |
Web service port. Reads settings.webServer.port by default, falling back to 3210; automatically increments by 1 on port conflict |
--host <addr> |
Bind address, defaults to 127.0.0.1. Binding to a non-loopback address (e.g., 0.0.0.0) requires --token, otherwise startup fails |
--token <token> |
Access token. Passed via WebSocket subprotocol or ?token= query param for WS handshake; via Authorization: Bearer <token> for REST |
--resume <id> |
Resume a historical session (matching the full log path or file name suffix <id>.jsonl); exits with code 1 if not found |
--cwd <path> |
Working directory, defaults to the process’s current directory |
--verbose |
Verbose output |
--dangerously-skip-permissions |
Skip all permission confirmations; carries security risks, see Notes |
Command-line parameters take precedence over the webServer configuration in settings.json; in Headless mode, webServer.enabled is forcibly treated as enabled.
2.3 Examples
hcode server # Local 127.0.0.1:3210, open in browser |
3. Prerequisites
- Complete terminal-mode initialization first: Headless mode skips terminal-interaction-dependent steps such as Onboarding, the trust dialog, and MCP approval. Please run
hcodeonce in terminal mode first to complete initialization configuration such as model/API. - Model and API configuration: Make sure the model and API have been configured via terminal mode and are valid; startup or queries will report errors if the configuration is invalid.
- Permissions and token: Binding to a loopback address (e.g.,
127.0.0.1) requires no token; binding to a non-loopback address requires--token, otherwise the service fails to start. - Working directory: The process automatically grants read permission to the
--cwddirectory, without terminal trust confirmation.
4. How to Tell If Startup Succeeded
Signs of a successful startup:
Hawa Code headless server starting...andTools, commands and MCP clients loaded, starting Web server...appear on standard output in sequence.- Followed by
Hawa Code headless server startedand the access URL (e.g.,URL: http://127.0.0.1:3210); if a token is configured, access instructions are also printed. The actual port is subject to theURL:line in the startup output (already incremented by 1 on port conflict). - The process stays resident and does not exit; open the URL in a browser to use it.
After a session starts, session content is no longer printed to terminal standard output; session messages are persisted as JSONL and pushed to the browser in real time via WebSocket.
5. Logs and Troubleshooting
Logs are located under UCODE_ROOT_DIR/projects/<project directory>/:
| Path | Content |
|---|---|
messages/*.jsonl |
Session message records |
log/*.log |
Runtime logs |
log/error-<date>.log |
Error logs |
errors/*.txt |
Error records |
mcp-logs-<server>/ |
Logs of each MCP Server |
Common failure signals and exit codes:
| Symptom | Description |
|---|---|
Failed to start WebServer: ... and exits with code 1 |
WebServer failed to start, commonly due to non-loopback binding without token, port occupied, etc. |
Session log not found: <id> and exits with code 1 |
The session log specified by --resume does not exist |
| Process killed or exits after successful startup | Abnormal; check the error logs |
Suggested troubleshooting order: check the hints in standard output → inspect log/error-*.log → check whether the browser connection is rejected due to token → check MCP logs if necessary.
6. CI/CD and Script Scenarios
Prefer
hcode -p: Executes one query, prints the result to standard output, and exits with code 0, suitable as a CI step judged by exit code.hcode -p "Fix the lint errors"
echo "instruction" | hcode -p # Standard input is also supportedThe process exits with code 1 when standard input has no content.
Use
hcode serverfor resident remote services / UI-less environments: runs resident on servers, Docker, systemd, with the browser as the frontend.Batch and automation tasks: Tasks can be submitted programmatically via the WebServer REST / WebSocket API (REST requires a Bearer token).
7. Notes
- Permission confirmations require someone to approve in the browser: In Headless mode, the Web client is the only approval channel; tool confirmations time out after about 5 minutes if no client responds.
- Security risks of
--dangerously-skip-permissions: This parameter skips all permission confirmations, and the Headless path does not perform the isolated-environment check from terminal mode. Use it only in trusted, isolated environments. - Mind standard input when running in the background: Running in the background via systemd,
docker run -d, etc. is unaffected; but pipe/heredoc scenarios (e.g.,somecmd | hcode server) block startup while waiting for stdin EOF. When running in the background, make sure standard input is/dev/nullor setCI=true. - Port conflicts are handled automatically: On port occupation, the port is incremented by 1 automatically; the actual port is subject to the
URL:line in the startup output. - Token security: The token appears in process arguments and the URL query param; on multi-user machines, beware of leaks via process listings and browser history.
- Other limitations: No built-in task timeout or failure retry; the integrity of cross-session recovery via
--resumehas not been fully validated; the Headless path does not execute SessionStart hooks — users relying on that hook to inject context should take note.