This page is for the person, not the agent. It covers an always-on machine you control, a VPS, a home server, a Raspberry-class box, that runs three things: an Any server on your account, anyrt serve as the always-on bao, and, if you want ChatGPT or Claude on your phone to reach your spaces, an MCP endpoint in front of it. The visiting-agent page is Connect Any to your agents.
Three questions this page answers, in order of how much they need:
You want | What it takes |
|---|---|
bao keeps working when the laptop is closed: scheduled jobs, chat replies, the memory maintenance |
|
your spaces on your phone | nothing on the server: the Any mobile apps run their own |
ChatGPT or Claude on your phone working inside your spaces | the server above plus an MCP endpoint with HTTPS and OAuth, which Any does not ship yet |
Any is local-first: every device holds the whole space and syncs with the others, so there is no server in the design. What a server adds is presence. bao runs wherever the active device is, and a laptop in a bag is not active; a scheduled digest that is pinned to it waits until the lid opens. A machine that never sleeps gives bao a permanent seat: the chat responder, the standing jobs and every trigger pinned to it run at 03:00 whether or not you are awake.
The second reason is the phone. The Any apps for iOS and Android already carry your spaces, because each embeds the same server and syncs on your account. The chat apps you also use, ChatGPT and Claude, cannot: they run nothing on your device and reach the world only through connectors. A connector is a remote MCP server at an HTTPS address, and the only honest place to put one is a machine you run.
any binary (Install): the release tarball with the local embedder, or go install.anyrt, built from the anybao repository (runtime quickstart: make kernel, make runtime).Treat the server like your laptop. It will hold the account's keys and an unencrypted copy of every space it syncs: use full-disk encryption, keep SSH on keys, and keep the box patched.
Two choices, and they are not interchangeable.
Your own account (the usual choice). Restore it from the recovery phrase. The server becomes one more device of yours: it sees every space you are in, and bao on it is the same bao, with the same memory, because the agent's memory lives in the account's derived bao space. This is what "always-on bao" means.
A separate account for the server, invited into the spaces it should see. The server then sees only those spaces, which is the right shape for a shared machine or a team box. But its bao is a different bao with an empty brain: it answers in the spaces it was invited to and knows nothing of yours. Pick this only when least privilege matters more than continuity.
The rest of this page assumes your own account.
anyCreate the data root, restore the account with the phrase on stdin so it never lands in shell history, and encrypt the wallet with a passkey:
export ANY_DATA_DIR="$HOME/.any"
export ANY_INDEX_EMBEDDER=local # keep indexed text on the box; see Configuration for the online option
export ANY_WALLET_PASSKEY='<a long passphrase>'
any init --mnemonic-stdin < phrase.txt && shred -u phrase.txt
any run --addr 127.0.0.1:7001any init with an existing phrase mints a fresh device key for this machine and keeps the account id; the phrase itself is never stored. With nothing else configured the server joins the production network, the same one your app is on, and the spaces start syncing in the background. GET /v1/health reports bootstrapping: true until the first pass is done.
any run is a foreground process with no daemon mode of its own; run it under a supervisor. A user unit is enough:
# ~/.config/systemd/user/any.service
[Unit]
Description=Any server
After=network-online.target
[Service]
Environment=ANY_DATA_DIR=%h/.any
Environment=ANY_INDEX_EMBEDDER=local
Environment=ANY_WALLET_PASSKEY=<the passphrase>
ExecStart=%h/.local/bin/any run --addr 127.0.0.1:7001
Restart=on-failure
KillSignal=SIGTERM
TimeoutStopSec=20
[Install]
WantedBy=default.targetsystemctl --user enable --now any
loginctl enable-linger "$USER" # keep the user session alive without a login
curl -s http://127.0.0.1:7001/v1/healthThe listener refuses any non-loopback address, by design: the API has no authentication, and the loopback socket is the trust boundary (Security model). The account is single-instance: a second any run on the same account fails with 409 auth.account_in_use, so the server never races itself after a restart.
anyrt serve reads anybao.toml from its working directory and the model key from .connectors.env next to it:
# ~/bao/anybao.toml
addr = "http://127.0.0.1:7001"
[agent]
space = "bao"
name = "bao"
control_port = 7010
[overlays]
agent = { space = "<agentRepoSpaceId>", invite = "<inviteToken>" }
[paths]
traces = "traces"# ~/bao/.connectors.env
llm.key.anthropic=sk-ant-…The overlay is the repo space that ships bao's own programs and skills; its id and invite are the ones your desktop app was configured with. The key is written through to the agent's secret store on every start and syncs, end-to-end encrypted, to your other devices, so a key you enter on the phone reaches the server too. Then:
cd ~/bao && anyrt serve
# anyrt serving space=bafyreig… chat=bafyreic… control=127.0.0.1:7010Put it under the same supervisor as any (After=any.service, WorkingDirectory=%h/bao, ExecStart=%h/.local/bin/anyrt serve).
Make it the active device. Several devices of one account elect one active agent; the others stand by and still fire the triggers pinned to them. By default the election follows the device that claimed last, which is usually your laptop. Move the role to the server once, from any of your servers or from the desktop app (Settings → Agent → Devices):
SERVER=$(curl -s http://127.0.0.1:7001/v1/devices | jq -r .self)
curl -s -X POST http://127.0.0.1:7001/v1/devices/activate \
-H 'content-type: application/json' -d "{\"app\":\"bao\",\"peerId\":\"$SERVER\"}"
curl -s http://127.0.0.1:7010/election
# {"app":"bao","enabled":true,"active":true,"peerId":"12D3…","winner":"12D3…"}From now on the server answers the chat and runs the standing jobs; your laptop's bao stands down when it sees the verdict, within one ten-second poll, and still runs anything pinned to its own peer id. Re-run the activate call if you ever move the role back by hand. One rule to keep: one agent per Any server. Do not also run anyrt serve against the laptop's app on the same machine.
Pin the jobs that should live here. A trigger's owner is a device pin. Triggers the server created are already pinned to it; a job created on the laptop stays on the laptop until you repin it, by writing its owner to the server's peer id (Device pins).
Nothing to do on the server. Install the Any app for iOS or Android, restore the same account, and the spaces arrive by sync. bao answers in the chat from wherever it is active, which is now the server, so a question typed on the phone at 23:00 gets a reply without the laptop. Push notifications ride the production push node by default.
This is the part Any does not ship. Both chat apps reach outside tools through remote MCP connectors: an HTTPS endpoint that speaks MCP over streamable HTTP and authenticates the user with OAuth 2.1. You add the connector once in the app's settings (Claude: Settings → Connectors → add a custom connector by URL; ChatGPT: Settings → Connectors / developer mode, by URL) and it is then available on every device signed into that account, phone included. The exact menus move; check each product's current connector documentation before you start.
What you run is a small gateway on the same box, the only thing on it that listens publicly:
phone (ChatGPT / Claude) ──HTTPS──▶ reverse proxy (TLS) ──▶ MCP gateway ──loopback──▶ any 127.0.0.1:7001
└──▶ bao 127.0.0.1:7010Requirements, from the connector side:
The tool list is the real design decision. The gateway is your phone's door, so it should expose verbs, not the API:
Tool | Does | Behind it |
|---|---|---|
| list the spaces and roles |
|
| search one space, return excerpts with |
|
| a page as Markdown, or an object's properties | the editor Markdown route, |
| add to a page, or change quoted text |
|
| tell bao to remember something | a chat message in the connector's own harness space |
| ask bao for a brief, wait for | the same exchange the agents page describes |
| file a task for an agent | a page in the inbox collection, if you set one up |
Rules that make this safe to leave on the internet:
ChatGPT, Claude), never in your main chat, exactly as an external agent would, so what the phone asked is readable later and your conversation with bao stays yours.The Multimem kit already ships a local MCP server (mcp_server.py, stdio) with the memory half of that list, multimem_context, multimem_search, multimem_decision and the rest. A gateway for phones is that server behind streamable HTTP and OAuth, plus the page and bao tools above. Until it exists as a package, this section is the specification for building it; the agents page and the docs' HTTP reference hold every route it needs.
curl -s http://127.0.0.1:7001/v1/health for the server, curl -s http://127.0.0.1:7010/election for bao. A supervisor probe needs nothing more.any run --log-level info to stderr; journalctl --user -u any -f. bao's runs are traces in the server's local store: anyrt trace ls --addr http://127.0.0.1:7001, anyrt trace show <runId>.any stop sends SIGTERM and waits for the lock; streams end with closed{reason: "server_shutdown"}, in-flight requests drain for ten seconds.409 sdk.crdt_version_newer until it is upgraded. Upgrade the server first or at the same time; never let it lag a release behind.The server holds a full plaintext copy of the spaces it syncs, the account's keys, bao's traces and the model key. It is your device, with your device's trust. The network sees what it always sees: which peer ids sync which space ids, and ciphertext. The model provider sees what bao sends it, the same as from the laptop. The chat apps on your phone see what the gateway's tools return, and nothing the gateway does not expose.
any under systemd, anyrt serve and the active-device election, the Any apps on the phone, the MCP gateway specification for ChatGPT and Claude, operations and limits.