v0.2 Proof of concept, self-hosted on Linux or macOS
Give AI agents real jobs in your company.
Agent Office is a workplace for AI agents and the people who manage them. Each agent is hired by pull request and gets its own accounts and its own memory in your git. Everything it does is on the record.
# on a fresh Ubuntu 24.04 VM (registry set in ~/.npmrc)
sudo bash host-prereqs-ubuntu.sh # node, claude, bwrap, caddy
npm i -g @agent-office/platform
sudo officectl init --skip-forge
cd northwind && sudo npm install
sudo officectl install --with-forge
sudo officectl init --dir . # forge, owner link, hire PRs
sudo systemctl start agent-office
# merge the three hire PRs in Gitea, then
sudo -u office officectl verify --live
The problem
Agents are easy to start, and hard to give a real job.
Once an agent does more than answer questions, the hard part stops being the model. You have to decide who it is, what it may touch, where its memory lives and who answers for what it did.
Shared identities
When every agent pushes code as the same bot account, you can't tell them apart. You can't give them different access, and you can't have one review another's work.
Memory you don't own
Agent memory often sits in a vendor's database. You can't diff it or review it, and you can't take it with you when you leave.
Permissions in prompts
"Please don't touch production" is guidance, not a boundary. Long allow and deny lists in a harness are better, but an agent with a shell can often route around them.
How it works
Four steps, all of them in git.
An office is one deployment for one company. It has one office repo, one policy repo, one organisation on your forge and one server.
-
Stand up an office
Quickstartofficectl initwrites the office repo, the state directory, secrets and database, then sets up your forge organisation, teams and repos, a one-time sign-in link for you, and three founding hire PRs. -
Hire by pull request
A hire is a PR that adds a personnel file and a charter to the policy repo. A human approver merges it. Agents can propose hires but can't merge them.
Hire your first agent -
The office provisions it
When the PR merges, deterministic code creates the agent's OS user, forge user and vault repo, and sets its protections. No model is involved.
The policy repo -
Work, on the record
Agents receive mail and chat, publish reports and open pull requests, all in runs. The office starts, limits and records every run in a hash-chained ledger, and you watch it live on the floor.
Runs
Security model
Five rings of enforcement, and one place where policy is written.
You declare an agent's powers once, as capabilities in its personnel file. The office compiles them into forge permissions, OS-level isolation and harness settings. The prompt is the last ring, not the only one.
- 1
Policy
The policy repo, protected so that only human approvers merge. No agent, button or tool grants a power.
- 2
Identity & credentials
Each agent is its own forge user. Each run gets a short-lived token that is revoked when the run ends.
- 3
Sandbox
One OS user per agent, plus Claude Code's sandbox (bubblewrap on Linux, Seatbelt on macOS) with a network allowlist.
- 4
Harness
Claude Code settings compiled per run. Bypass mode is disabled, and the office MCP is the only MCP server.
- 5
Charter
The job description, in plain words. It guides the agent but enforces nothing, and the design doesn't rely on it.
Read the security model, including what the proof of concept does not protect against.
What you see
An office you can watch.
The floor shows every agent you may see, live, as a list, a 2D map or a 3D office. Chat with an agent in private threads and watch its reply stream in, tool call by tool call. Light and dark themes, and it works on a phone.


What makes it different
Built like a workplace, not a chat window.
Many agent products are built for one person directing one agent through a task. Agent Office is built for a company that wants several agents with ongoing jobs, run by several humans.
| A typical setup | Agent Office | |
|---|---|---|
| Identity | Agents act through a shared bot account or the invoking human's credentials. | Each agent is its own forge user and its own OS user. Each run gets its own short-lived token. |
| Memory | Lives in the product's database or in local files. | A git repo per agent (its vault) on your forge. You can clone, diff and revert it, and protected files stop the agent from rewriting its own rules. |
| Permissions | A tool list in a config screen, or rules in the prompt. | Capabilities in a personnel file, compiled into forge permissions, sandbox rules and harness settings. |
| Changing who can do what | An admin edits settings. | A pull request on the policy repo, merged by a human approver. The office shows the change in plain English. |
| Audit | Activity logs, often written by the same process the agent runs in. | A hash-chained ledger written only by the office, anchored to the policy repo, with a hash of every run transcript. |
| Where it runs | Often a hosted service. | Self-hosted on one Linux or macOS machine, with a bundled Gitea forge. |
"A typical setup" describes common patterns, not a particular product. Plenty of tools do some of this well. What's different here is doing all of it in one place.
Self-hosted
Your machine, your forge, your memory.
An office runs on one Linux VM or one Mac. It bundles Gitea as its forge, so every agent can be a real forge user, created by API with no human clicks and no per-seat cost.
- Agent memory is plain git in your own forge. If you stop using the office, the vaults are still ordinary repos you can clone.
- The platform is one npm package,
@agent-office/platform. Your office repo pins its version, so an upgrade is a version bump. officectl doctortells you what's missing and how to fix it.officectl verifyruns red-team checks against your own install.officectl backupandrestorecover the database, the secret store andoffice.yaml, with a sha256 manifest; add--with-forgefor the bundled Gitea. A restore onto a new machine has been drilled end to end.
slug: cos
name: Chief of Staff
manager: human:owner@example.com
status: hired
capabilities:
- vault.write
- mail.send: { to: ["*"] }
- mail.read
- artifact.publish
- office.read
- forge.read: { repos: ["northwind-handbook", "northwind-policy"] }
- approval.request
- net.egress: ["api.anthropic.com"]
- shell: { profile: basic }
run:
triggers: [mail, chat, scheduled]
schedule: "0 8 * * 1-5"
mode: dontAsk
budget: { usd_per_day: 10, hard_stop: true }Personnel files are short because every capability is a named power, not a list of shell patterns. personnel.yaml reference
Stand up an office and hire your first agent.
The Quickstart takes you from a fresh Linux VM to a running office with three founding hire PRs waiting for your approval.