Skip to main content
The machine that should run five agents, five dev servers, and a test suite is often not the laptop in front of you. Because archcar owns all the state and every surface is a client of it, moving execution to a server is a deployment choice rather than a different product. Nothing here requires a display on the server. It has no GUI dependency at all.

What ends up where

Agent CLI authentication and gh auth login have to happen on the server. Authenticating on your laptop does nothing for a server-hosted session.

Set up the server

Install the CLI and daemon by whichever channel you prefer — the tarball, CLI AppImage, AUR package, Nix, Homebrew, or the APT/DNF archductor package all ship both archductor and archcar. Then:
That installs the background service (a systemd user unit on Linux, a launchd agent on macOS, a Task Scheduler logon task on Windows), starts it, provisions an access token, and reports whether the daemon can reach the tools it needs. Add --listen 0.0.0.0:7420 only if clients will use the TCP transport. For SSH, which is what you should use, omit it — SSH needs no open port. service setup exits non-zero if the daemon did not start, so a provisioning script can trust its status, and it refuses to print connection instructions for a listener that is not actually up. Two things it handles that are easy to get wrong by hand: Surviving logout. systemd stops a user manager when the user’s last login session ends, so a unit you install over SSH dies the moment you disconnect. Install runs loginctl enable-linger and tells you if it could not. archductor service status reports boot_persistent. The daemon’s PATH. launchd gives a job /usr/bin:/bin:/usr/sbin:/sbin, and a systemd user unit is barely richer. Neither can see Homebrew, a version manager, or ~/.local/bin, so the daemon fails to find codex even though your shell finds it instantly. Install probes your login shell and bakes the resulting PATH into the unit.
service doctor is the check that distinguishes “the service is running” from “the service is usable”. Run it after any change to how tools are installed.

Platform caveats

  • macOS: a launchd agent starts at login, not at boot. On a headless Mac, log in once after a reboot, or install a root-owned LaunchDaemon yourself.
  • Windows: logon tasks have the same scope. Running while logged off means storing the account password in Task Scheduler, which Archductor will not do on your behalf.
  • AppImage: install refuses to write a unit pointing into an AppImage’s temporary mount (/tmp/.mount_*), because that unit works right up until the next reboot. Extract or install properly on a server.

Connect from a client machine

connect verifies the daemon responds before saving, so a typo fails fast instead of half-configuring the machine. One profile moves the whole machine: the CLI, the desktop app (Settings → Remote daemon), and archductor mcp serve all follow it. The desktop app will not spawn a local sidecar while a remote is configured. Resolution order, highest first:
  1. ARCHDUCTOR_ARCHCAR_REMOTE / ARCHDUCTOR_ARCHCAR_TOKEN in the environment
  2. The saved profile ($XDG_STATE_HOME/archductor/remote.json, owner-only)
  3. The local daemon

Why SSH rather than the token

ssh:// runs archductor archcar stdio-proxy on the far side and pipes the protocol through the SSH connection. The destination is handed to ssh verbatim, so ~/.ssh/config applies — host aliases, jump hosts, and per-host keys all work. If archductor is not on the non-interactive PATH over SSH, give the path explicitly:
On the TCP transport. It is a shared bearer token in cleartext: no TLS, no per-client identity, and rotating the token revokes every client at once. A bare port (--listen 7420) binds loopback only; anything else must sit behind a VPN, an SSH tunnel, or a TLS reverse proxy. Use ssh:// and none of this applies.

Several daemons

Save more than one and switch between them — a work server, a home box, and your laptop.
The label is what appears in the app’s switcher.

Working against a remote

Most commands behave the same; paths are the exception, because they resolve on the daemon’s filesystem, not yours. archductor repo add is refused while a remote profile is active — it takes a local path that means nothing on the server. Use the daemon-side command instead:
Two commands answer “is the server healthy”, as opposed to this machine:
archductor service status and archductor service doctor, without archcar, always answer for the machine you typed them on. That distinction matters when you are debugging a session that will not start.

Pulling a workspace back to your machine

You reviewed something on the server and now want it locally — same branch, same conversation. remote import reads from the remote and writes to your local daemon, matching repositories by clone URL rather than by path. Both daemons are contacted; neither talks to the other.
Omit --thread-id to import the workspace without a chat. --name and --branch rename it locally. Without --clone-into the import stops and asks rather than picking a directory on your disk. With it, the whole first-time flow is one command — which matters precisely here, since repo add is refused while a remote profile is active. In the app this is “Copy to this machine” on a workspace’s right-click menu, shown only while a remote client is selected.

MCP against a remote

Because MCP tools are archcar requests, an MCP client pointed at a machine with a saved remote profile drives the server’s daemon:
Your local Claude Code can now read and drive the server-hosted workspaces. Prefer the default session profile over --full unless you specifically want an agent that can create and archive workspaces.

Protocol details

docs/api.md documents the transports, the envelope format, the workflow objects, and the stability policy. Read it if you are writing a client rather than operating one.