
How to Keep AxiOwl Running Across Multiple Machines
AxiOwl is built around a practical idea: agents and provider sessions live where they actually run. A Windows workstation, a Linux desktop, and a remote Linux node should not pretend to be one magic process. Each machine needs its own AxiOwl state, its own provider discovery, and a clear way to prove that another node is reachable before it becomes part of routing.
That distinction matters when you are operating AxiOwl across more than one computer. The current codebase has real node registry and remote discovery commands, but the provider support matrix still marks remote as unsupported for local-provider remediation builds. In plain terms: do not use remote routing as a silent fallback when a local provider is broken. Treat every remote machine as an explicit node that must be installed, verified, discovered, and watched.
Start With One AxiOwl Per Machine
The AxiOwl repository separates product targets by platform. The root README identifies the Windows desktop app, Linux desktop app, and a reserved Linux remote package area. The architecture docs describe AxiOwl as a coordinator with a CLI, an MCP server, a durable registry, discovery, provider-specific delivery edges, and evidence logging.
On disk, AxiOwl keeps machine-local state. In the Linux implementation, state_root() resolves to $XDG_STATE_HOME/axiowl when available, or ~/.axiowl by default. Inside that state root, AxiOwl stores:
registry/agents.tsv
registry/nodes.tsv
logs/events.jsonl
On Windows, the same path helper uses %LOCALAPPDATA%\AxiOwl. That is the right shape for multi-machine operation: each node owns its local provider facts, while the operator machine keeps a node registry that says how to reach other AxiOwl installations.
Keep The Registry Boring
The AxiOwl discovery plan says the registry should stay simple:
agent name -> provider -> provider session id -> node
The implemented registry follows that model. Agent rows include display_name, aliases, provider, provider_session_id, node_id, enabled, sendable, source, timestamps, and last_error. Node rows include node_id, display_name, aliases, host, ssh_user, ssh_key_path, enabled, verification timestamps, and last_error.
This is the main operating rule for multiple machines: do not copy whole registries around and hope they remain correct. Let each machine discover its own provider sessions, then let the coordinating machine import only the facts it needs through explicit discovery.
Add Remote Nodes Explicitly
The Linux CLI exposes node commands for registering and checking remote machines:
axiowl node add --id <node-id> --host <host> --ssh-user <ssh-user> --key <ssh-key-path> --name <display-name>
axiowl node list
axiowl node verify --id <node-id>
node verify is deliberately concrete. The implementation opens SSH in batch mode and runs:
hostname; whoami; pwd; hostname -I
That output gives an operator the basics that matter before a node is trusted: which host answered, which user owns the process, where the command landed, and which network addresses the machine reports. If SSH fails, AxiOwl stores a last_error on the node record instead of pretending the node is healthy.
Discover Remote Provider Sessions Through The Remote Install
Remote discovery is not a blind file sync. The implementation asks the remote node to run AxiOwl locally:
axiowl discover remote --node <node-id> --target <agent>
Under the hood, the local command uses SSH to run a remote command shaped like:
axiowl discover codex --json --target <agent>
The coordinating AxiOwl then parses the remote discovered_agent JSON lines and imports matching rows as provider remote, with the configured node id attached. That means the remote node remains responsible for knowing its own local Codex facts. The local node decides what to enroll.
This is a useful boundary. A remote Linux machine may have different home directories, provider state, CLI authentication, and available provider surfaces. Asking that machine's AxiOwl to report its own facts is safer than scanning remote files from the outside.
Do Not Let Remote Hide Local Failure
The provider support matrix is explicit: remote is currently unsupported for local-provider remediation builds. The remote provider page says remote delivery is out of scope for current local provider builds and should not be used as a fallback to hide local provider failures.
That is an important operational habit. If local Codex, VS Code, Cursor, or Antigravity delivery is failing, fix that provider edge directly. Do not make a remote node catch the message silently. AxiOwl's reliability depends on visible routing decisions, clear provider identity, and evidence that the intended target received the message.
Keep Linux Installs Alive With The Guard Service
The Linux installer does more than copy a binary. It creates the state directories, installs helper scripts, writes the Antigravity CDP port file when that integration is selected, registers MCP config when requested, can run local discovery, and verifies the installed binary against the body-builder contract.
When installed as root on a systemd machine, the installer can also enable:
axiowl-body-guard.service
The service runs:
/usr/bin/axiowl guard watch --interval 60 --binary /usr/bin/axiowl --contract /usr/share/axiowl/body_builder_contract.txt
It is not the general AxiOwl message daemon. The current status command still reports that the local service is not implemented yet and that the CLI is running the direct local pipeline skeleton. The guard service has a narrower job: keep checking that the installed AxiOwl binary and body-builder contract still match the expected installation.
That distinction keeps expectations honest. For now, keeping AxiOwl running across machines means keeping the binary installed, the provider integrations registered, the node records verified, and the provider sessions discoverable. It does not mean there is a fully implemented always-on cluster service.
Use Localhost Boundaries For Services
The local service plan reserves:
127.0.0.1:37661
The plan also says the service must bind localhost only, not a public interface. That matches the broader AxiOwl design: provider control should happen through local process boundaries, MCP, CLI, SSH, or explicit relay sessions, not by exposing provider-control ports to the network.
The relay implementation follows the same conservative pattern. axiowl relay-session --stdio speaks a simple JSON-line protocol over standard input and output. It can receive a deliver frame, run the normal message pipeline on that node, emit upstream messages from a temporary outbox, and return a delivery result. The transport is explicit; it is not an open public listener.
A Practical Multi-Machine Checklist
Use a checklist like this when adding another AxiOwl machine:
- Install AxiOwl on the remote machine.
- Run
axiowl --versionandaxiowl statuson that machine. - Confirm its state root, registry path, node registry path, and evidence log path.
- Register MCP and provider integrations that are actually needed on that machine.
- Run provider discovery locally on that machine.
- From the coordinating machine, run
axiowl node add. - Run
axiowl node verify --id <node-id>. - Run targeted remote discovery with
axiowl discover remote --node <node-id> --target <agent>. - Check
axiowl list agentsfor sendable enrolled targets. - Treat any
last_erroras a real routing problem, not as noise.
For Linux machines installed system-wide, also check the body guard:
systemctl status axiowl-body-guard.service
If the install was user-scoped rather than root-scoped, the installer logs that the systemd guard was skipped and tells you to run with sudo to enable the always-on guard.
Closing
The safest way to keep AxiOwl running across multiple machines is to make every boundary visible. Each machine owns its local AxiOwl state. Each remote node is registered with a node id, SSH host, user, and optional key path. Each remote target is discovered by asking the remote AxiOwl installation what it can actually see. And remote routing stays explicit, because AxiOwl is designed to prefer inspectable routing facts over quiet fallback behavior.
That is less glamorous than pretending every provider session is part of one automatic mesh, but it is much better for real operations. When a message moves between machines, the registry, node verification, discovery output, and evidence log should all tell the same story.