Skip to main content

Remote Agent Guide

The remote agent is a Python daemon that runs on remote machines to provide AI coding tool access via the Open ACE platform.

Architecture

┌──────────┐ HTTP Polling ┌──────────────┐
│ Agent │ ◄──────────────► │ Flask API │
│ (daemon) │ 1s interval │ │
└────┬─────┘ └──────────────┘

├── subprocess ──► CLI Tool (claude/qwen/codex/openclaw)

└── WebSocket ──► Terminal Server (PTY / piped subprocess)

Browser (xterm.js)

Installation

Linux / macOS

curl -fsSL https://<server>/api/remote/agent/install.sh | bash -s -- \
--server https://your-server.com \
--token <agent-token> \
--name my-machine

Options:

  • --server — Open ACE server URL (required)
  • --token — Agent registration token (required)
  • --name — Machine display name
  • --install-cli — Default CLI tool (default: qwen-code-cli)
  • --dir — Installation directory (default: ~/.open-ace-agent)
  • --ca-bundle PATH — PEM CA bundle for a private or self-signed server
  • --insecure-skip-tls-verify — Explicitly disable TLS verification (dangerous)

When the installer endpoint itself uses a private CA, bootstrap curl with the same bundle and pass it through to the installer:

curl --cacert /path/to/ca.pem -fsSL https://<server>/api/remote/agent/install.sh | \
bash -s -- --server https://<server> --token <agent-token> --ca-bundle /path/to/ca.pem

Windows

.\install.ps1 -ServerUrl https://your-server.com -RegistrationToken <agent-token>

For a private CA, add -CaBundlePath C:\path\to\ca.pem. The emergency -InsecureSkipTlsVerify switch is intentionally explicit and should only be used for short-lived testing.

Requirements

  • Python 3.8+
  • websocket-client, requests, websockets (auto-installed)

Starting and Managing the Agent

After installation, you can use the start scripts to manage the agent process:

Linux / macOS

# Start the agent (skips if already running)
bash ~/.open-ace-agent/start-agent.sh

# Check agent status
bash ~/.open-ace-agent/start-agent.sh --status

# Stop the agent
bash ~/.open-ace-agent/start-agent.sh --stop

# Configure auto-start on boot (requires sudo to create systemd service)
bash ~/.open-ace-agent/start-agent.sh --auto-start

Auto-start details:

  • Systems with systemd (Ubuntu 16.04+, CentOS 7+, RHEL 7+): Creates a systemd service that starts on boot and restarts on crash
  • Environments without systemd (e.g., WSL2): Uses crontab @reboot for auto-start

Windows

# Start the agent (skips if already running)
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.open-ace-agent\start-agent.ps1"

# Check agent status
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.open-ace-agent\start-agent.ps1" -Status

# Stop the agent
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.open-ace-agent\start-agent.ps1" -Stop

# Configure auto-start on login (Windows Task Scheduler)
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.open-ace-agent\start-agent.ps1" -InstallAutoStart

Auto-start details:

  • Uses Windows Task Scheduler to start automatically on login
  • Task name: OpenACEAgent
  • Can be managed in Task Scheduler

Shortcut (Windows)

Windows users can also use the batch wrapper:

%USERPROFILE%\.open-ace-agent\start-agent.cmd

Configuration

Config file: ~/.open-ace-agent/config.json

SettingDefaultDescription
server_urlhttp://localhost:19888Open ACE server
heartbeat_interval60sHeartbeat frequency
reconnect_base_delay1sInitial reconnect delay
reconnect_max_delay60sMax reconnect delay (exponential backoff)
output_buffer_size4096Terminal output buffer
max_sessions5Concurrent sessions
log_levelINFOLogging level
skip_ssl_verifyfalseSkip TLS verification; non-local HTTPS also requires an explicit CLI acknowledgement
allow_insecure_tlsfalseAdministrator policy gate for the explicit insecure switch
ca_bundle_pathnullPEM CA bundle for private/self-signed certificates

Environment variable overrides: OPENACE_SERVER_URL, OPENACE_AGENT_TOKEN, OPENACE_MACHINE_ID, OPENACE_HEARTBEAT_INTERVAL, OPENACE_MAX_SESSIONS, OPENACE_LOG_LEVEL, OPENACE_SKIP_SSL_VERIFY, OPENACE_ALLOW_INSECURE_TLS, OPENACE_CA_BUNDLE_PATH

TLS policy and migration

New installations verify server certificates by default. For an internal CA, install with --ca-bundle /path/to/ca.pem (or -CaBundlePath on Windows), or set ca_bundle_path in config.json. The same CA is used by agent HTTP calls, terminal relay WebSockets, openace login/menu/shell, installer downloads, and registration.

For a non-local HTTPS server, a legacy configuration containing "skip_ssl_verify": true no longer starts silently. Prefer replacing it with a CA bundle. If verification must be disabled temporarily, start the daemon with python agent.py --insecure-skip-tls-verify; the installer equivalents persist both skip_ssl_verify=true and the administrator approval allow_insecure_tls=true, then add the explicit service argument. Manual use requires the same two-step approval: policy plus CLI flag. Administrators can disable the escape hatch by leaving allow_insecure_tls=false. This mode prints a prominent warning and exposes credentials and commands to man-in-the-middle attacks.

Use python agent.py --ca-bundle /path/to/ca.pem for a one-run CA override, and openace login|menu|shell --ca-bundle /path/to/ca.pem for a CLI override. Run openace config-check to inspect the persisted TLS configuration.

Supported CLI Tools

ToolExecutableNPM PackageConfig Location
Claude Codeclaude@anthropic-ai/claude-code~/.claude/
Qwen Codeqwen@qwen-code/qwen-code~/.qwen/
Codexcodex@openai/codex~/.codex/config.toml
OpenClawopenclawN/A
ZCodezcodeN/A (bundled with the ZCode desktop app)~/.zcode/

Each tool has a dedicated adapter in cli_adapters/ that handles start arguments, environment variables, permission modes, and session resume.

openace CLI

The openace command-line tool is installed alongside the agent:

CommandDescription
openace login [--token TOKEN] [--ca-bundle PATH]Authenticate to server
openace logoutRemove stored credentials
openace statusShow server URL, machine ID, login state
openace menu [--ca-bundle PATH]Start interactive AI tool selector
openace shell [--ca-bundle PATH]Start shell with proxy credentials
openace config-checkValidate the persisted TLS configuration

Terminal Server

The terminal server provides WebSocket-based terminal access:

  • Terminal process model — Uses a persistent PTY on Linux/macOS and a persistent piped subprocess on Windows
  • Authentication — HMAC token via query parameters
  • Reconnection — Terminal process persists across WebSocket disconnects; 64KB output history for screen restore
  • Resize — JSON control messages {"type":"resize","cols":N,"rows":N}
  • Environment — Auto-injects ANTHROPIC_API_KEY/OPENAI_API_KEY from proxy tokens

On Windows, openace menu uses a numbered text menu instead of the Unix arrow-key raw-terminal UI so the same workflow remains available in PowerShell/cmd and browser terminals.

Known limitations of the Windows pipe mode

On Linux/macOS the terminal server spawns the shell on a real PTY. On Windows it uses a piped subprocess instead (stdin/stdout are anonymous pipes, not a pseudo-terminal). Because there is no tty attached to stdin, the Windows pipe mode has these limitations — this is expected behavior, not a regression:

  • No interactive tty semantics on stdin — there is no echo, no line editing, no Tab completion, and no prompt redraw. Input is forwarded to the shell as raw bytes once the client submits it (typically on Enter).
  • Raw-byte CJK / wide-char input — multi-byte input is sent as raw bytes into a non-tty stdin, so IME composition and wide-char readline handling are not available the way they are on a Unix PTY.
  • Resize does not take effect — there is no tty to apply a window-size change to, so {"type":"resize",...} only records the requested size and the shell keeps wrapping output at the original width. The server logs a one-time notice on the first resize. Writing an ANSI size sequence is deliberately avoided: stdin is a pipe, so those bytes would be consumed as shell input and pollute the session. Real resize support requires ConPTY (pywinpty/winpty or the Win32 API) and is tracked as future work.
  • Persistence and history still work — the piped shell still persists across WebSocket reconnects, and the 64KB output history is replayed for screen restore on reconnection.

Process-tree cleanup (Windows)

To make shutdown reliable, the Windows terminal server binds the shell process tree to a Win32 Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. When the server exits (normal shutdown, hard-kill, or crash), the kernel reaps the whole tree — including grandchildren holding the stdout write-end — which is what lets the output relay stop cleanly. The soft-kill path (kill_pty) closes the Job handle first, falling back to taskkill /T /F only when no Job is bound.

Narrow residual (accepted): if Job creation and taskkill /T both fail, the shell tree may be orphaned (it then needs manual cleanup; the agent's proc.kill() targets the terminal server, not the orphaned shell), and the output relay may stay pinned until the process is force-killed. An agent-initiated stop_terminal is reaped by the agent's proc.kill() watchdog; agent shutdown intentionally leaves terminal servers running, so a natural-exit under this dual-failure may wedge a terminal server until that terminal is restarted.

Session Sync

The agent scans session history directories every 30s and syncs to the server:

ToolDirectory
Claude Code~/.claude/projects/ (JSONL)
Qwen Code~/.qwen/projects/ (JSONL)
Codex~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl

Sync state is tracked in ~/.open-ace-agent/session_sync_state.json.

Codex CLI Specifics

  • Config format: TOML (~/.codex/config.toml), not JSON
  • Permission modes: plan--ask-for-approval untrusted, auto--dangerously-bypass-approvals-and-sandbox
  • Non-interactive mode: codex exec --json --sandbox read-only
  • Session files: JSONL with event types session_meta, turn_context, response_item
  • Content blocks: input_text, output_text, reasoning, function_call

Daemon Commands

The agent handles these commands from the server:

CommandDescription
start_sessionStart a new CLI session
send_messageSend user message to active session
stop_sessionTerminate CLI session
pause_sessionSIGSTOP the CLI process
resume_sessionSIGCONT the CLI process
permission_responseForward user's permission decision
update_permission_modeChange session permission mode
update_modelSwitch AI model
start_terminalLaunch WebSocket terminal server
stop_terminalShutdown terminal server

Troubleshooting

Agent won't connect:

  • Check OPENACE_SERVER_URL is reachable
  • Verify agent token is valid
  • Check ~/.open-ace-agent/agent.log

CLI tool not found:

  • Ensure the tool is installed globally (which claude / which qwen / which codex)
  • Check PATH includes npm global bin directory

Terminal not connecting:

  • Verify WebSocket port is not blocked by firewall
  • Check terminal server process is running (ps aux | grep terminal_server)
  • Review HMAC token in ~/.open-ace-agent/.terminal_sessions/

Session sync not working:

  • Check ~/.open-ace-agent/session_sync_state.json is writable
  • Verify session directories exist and contain JSONL files