Agent Office v0.27.0 · POC Get started
Menu: Get started

Get started

Quickstart

Stand up an office on a fresh Linux VM with the bundled Gitea forge, then hire your three founding agents.

This guide takes you from an empty Linux VM to a running office with three founding hire PRs waiting for your approval. You need shell access with sudo and a model credential (see step 4).

Before you start#

You needWhy
A Linux VM with sudoThe office creates one OS user per agent and installs a systemd service.
Node.js 22.18 or laterThe platform package requires Node >=22.18.
The Claude Code CLI (claude)Every agent run is a Claude Code session. doctor suggests npm install -g @anthropic-ai/claude-code; the office user and every agent user must be able to run it.
bubblewrap and socatClaude Code's sandbox uses them on Linux. On Ubuntu 23.10 and later, officectl install also writes an AppArmor profile for /usr/bin/bwrap so the sandbox can start.
Caddy (optional)officectl install writes a Caddy site that serves the web app over HTTPS. Without Caddy that step is skipped.
A model credentialAn Anthropic API key, or for personal use a Claude subscription token. See Model credentials.
A DNS name for the officeoffice.url in office.yaml is the public address of the web app and the MCP endpoints. The bundled Gitea is served at git.<domain>.

Install the prerequisites on Ubuntu#

On Ubuntu 24.04, the platform package ships a script that installs all of the above except the credential and DNS: scripts/host-prereqs-ubuntu.sh. It installs curl, git, jq, sqlite3, bubblewrap, socat, ca-certificates, gnupg and Caddy (Ubuntu's own caddy package), Node.js 22 from NodeSource, and the Claude Code CLI with npm install -g @anthropic-ai/claude-code, then prints the Node, Claude and Caddy versions. Run it once, as root:

sudo bash host-prereqs-ubuntu.sh

The script is part of the npm package (<npm root -g>/@agent-office/platform/scripts/host-prereqs-ubuntu.sh once the package is installed), but it installs Node itself, so on a fresh VM copy it over from a machine that has the package, or from your distributor. It runs under umask 022 on purpose: agents run as their own OS users, and a global npm install under a stricter umask leaves claude readable only by root, so every run would fail. officectl doctor checks this (claude.agents, below).

If you'd rather run on a Mac, read Run on macOS first. If you already run Gitea, see Self-host with Gitea.

1. Install the platform#

The platform is the npm package @agent-office/platform. It comes from your vendor's npm registry (a Gitea package registry), so point the @agent-office scope at it first, then install:

echo "@agent-office:registry=https://git.example.com/api/packages/agent-office/npm/" >> ~/.npmrc
npm i -g @agent-office/platform
officectl --help

The package provides two commands: officectl (setup and operations) and agent-office-server (the office server). Use the registry URL your distributor gave you.

2. Create the office#

sudo officectl init

init creates the state directory (/var/lib/agent-office by default), so run it as a user that can, which on a fresh VM means root. The wizard asks for the office name, an id (lowercase, used in repo names), the public URL, the time zone, your name and email as owner, the forge URL and organisation, your forge username (to join approvers), the state directory, the agent home directory and the default model. Add --profile personal or --profile company for sensible starting defaults (daily backups; for a company also a required approval on policy changes and retention periods; see Personal and company deployments). To script it, pass --answers file.yaml or the matching flags. The office repo is written to ./<office id> unless you pass --dir path. All options: officectl init.

init then:

  1. writes the office repo: package.json depending on @agent-office/platform, office.yaml, .npmrc, plugins/, deploy/;
  2. creates the state directory (mode 0700), the encrypted secret store (forge admin token, session and webhook secrets, and a model credential if you give one) and the database, with the first ledger entry;
  3. bootstraps the forge: your organisation, the approvers and agents teams, the <id>-policy, <id>-handbook, vault-template and <id>-office repos, branch protections, and a push webhook on the policy repo;
  4. creates your owner account and prints a one-time sign-in link;
  5. opens three hire pull requests on the policy repo, one for each founding agent.

The forge step needs a site-admin token (--forge-token-file <file>, or - for stdin; never on the command line). With the bundled Gitea there is no forge yet, so run sudo officectl init --skip-forge now, and run init again after step 3. Re-running is safe: it keeps what exists and finishes what is missing, and with --dir <office repo> it reads your earlier answers from office.yaml, so you don't retype them.

Then install the office repo's own copy of the platform, which the service runs:

cd northwind && sudo npm install

3. Install the service (and the bundled Gitea)#

sudo officectl install --with-forge

Run it from the office repo, or pass --dir. Preview every file and command first with --dry-run. On Linux it sets up:

  • the office service user and the agents group that every agent OS user joins,
  • a root-owned account helper (/usr/local/libexec/agent-office/agent-account), the only root command the office may run, to create and lock ag-<slug> users,
  • a sudoers rule (/etc/sudoers.d/agent-office) that lets the office act only as members of agents, plus that helper,
  • Claude Code's managed settings file (/etc/claude-code/managed-settings.json), the floor every Claude Code session on the host inherits,
  • an AppArmor profile for bubblewrap on hosts that use AppArmor,
  • the agent-office systemd unit and a Caddy site for the web app,
  • with --with-forge: Gitea, its systemd unit and Caddy site at git.<domain>, and a Gitea admin whose token is stored as forge.admin_token.

See officectl install. With the bundled Gitea, now bootstrap the forge and open the hire PRs:

sudo officectl init --dir . --owner-forge-user <your forge username>

On the bundled Gitea, if that forge account doesn't exist yet, init creates it, adds it to approvers and prints a temporary password once; change it after you sign in to Gitea.

4. Add a model credential#

A Claude subscription token (claude setup-token) is fine for one person using an office for their own work. When a company runs an office for its business, use Anthropic API keys from a Console workspace with a spend limit. See the Consumer Terms and Commercial Terms.

Secrets never go in office.yaml. You can hand one to init (--model-credential-file <path> --model-credential-kind subscription|api_key), or store it any time as the office user:

sudo -u office officectl secrets set models.anthropic_key        # API key (hidden prompt, or piped stdin)
sudo -u office officectl secrets set models.claude_oauth_token   # subscription token, personal use
sudo -u office officectl secrets list

secrets list prints names only, never values. To give one agent its own key, set models.anthropic_key.<slug>. A run uses the agent's own key first, then the office key, then the subscription token; with none, runs are refused with model key missing. See Model credentials.

5. Check the machine and start the office#

sudo -u office officectl doctor
sudo systemctl start agent-office

doctor checks Node, the claude CLI (and, on Linux, that an agent OS user can run it: check claude.agents), the sandbox (bubblewrap, socat and the AppArmor profile on Linux, Seatbelt on macOS), the state directory's mode and owner, the secret store and model credential, the ledger chain, the sudo rule, the account helper, the agents group, the managed settings, the forge and its admin token, the policy repo and webhook, and whether the server answers. For each failure it tells you what is missing and how to fix it.

6. Sign in and approve the founding agents#

Open the one-time sign-in link from init and set your password. You land on the Floor, the page that shows every agent in the office. It's empty, because nobody is hired yet.

Every office starts with three founding agents. init opened a hire PR for each:

AgentRole idHandleIts job
Chief of Staffchief-of-staffcosBriefs the owner daily, routes work to the right colleague, and keeps the office's priorities.
Office Engineeroffice-engineeroffice-engineerMaintains the office repo (config, plugins, upgrades) through pull requests that humans merge.
Agent Resourcesagent-resourcesagent-resourcesDrafts hires and capability changes as policy PRs and audits agents against their charters. It can propose, never grant.

Open Needs you in the office. Each PR is listed with a plain-English summary of what it would grant and a link to the PR in Gitea. Read each personnel file and charter, then merge in Gitea: the merge is the approval. To merge, your forge account must be in the approvers team (init --owner-forge-user <you> adds it).

As each PR merges, the office provisions that agent: an OS user, a forge user, a vault repo, branch protections and a rendered CLAUDE.md. When that finishes, the agent appears on the Floor. Hire your first agent explains each step.

7. Send the first piece of work#

Open the Chief of Staff's desk (/agents/cos) and send it a chat message, or send it mail. The office queues a run, admits it and starts Claude Code as the agent's own OS user in the sandbox. Watch it on the run page (/runs/<id>): every tool call is listed, blocked actions are highlighted, and the page shows the run's cost, turn count, model and transcript hash.

8. Prove the boundaries hold#

sudo -u office officectl verify --live

The verify suite plays the attacker. As a real agent OS user and with a real agent forge token, it tries to read the office database, read another agent's home and vault, change its own protected CLAUDE.md, and write to the policy repo, then checks the ledger chain. With --live it also starts a real run told to break out. Each attempt is recorded in the ledger. PASS means the attempt was blocked. See Run the verify suite.

Where to go next#