We host the control plane, the cockpit, the inbox, and the job queue at app.yothere.ai. Your machine runs the agents. You pair a machine, it leases queued threads, and it runs each turn locally on the coding-agent subscription you already pay for: Claude Code or the Codex CLI. We never hold your model credentials and we never bill you for inference.
What you need to bring
| Requirement | Detail |
|---|---|
| A machine you can leave open | macOS or Linux. Windows takes the Linux path via WSL2. |
| Python 3.11 to 3.13 | 3.14 is not supported, and yothere doctor fails hard on it. |
pipx |
yothere installs isolated. |
| Your own agent login | Claude Code or the Codex CLI, on the Claude or ChatGPT subscription you already pay for. |
An install is “set up” when four things are true: a brain is connected, a safe work directory is chosen, unattended tool use is acknowledged, and the always-on service is installed. This page walks that path and shows the commands that check and apply each piece. For the full env-var reference, see Configuration.
Pair a machine
Signup is open at app.yothere.ai/signup. Your first 7 days are free, no credit card; after the free week, the Founding plan ($20/mo) keeps the workspace running. See Pricing.
1. Create your workspace at app.yothere.ai/signup and type a first task.
2. Install the CLI on the machine that should do the work (Python 3.11 to 3.13), and check it:
pipx install yothere
yothere doctor
doctor reports pass, warn, or fail per check, with the fix for each one.
3. Run yothere login on that machine. It prints a short pairing code (rendered
XXXX-XXXX) plus a link to app.yothere.ai/activate:
yothere login
4. Approve the machine in your browser, then start the service. Open that link in the browser where you are already logged in, confirm which machine is asking, and pick its permission tier (read-only, workspace, or full; the full tier ticks a bypass-consent checkbox). The CLI polls, saves the per-device credential, and prints success. No token is pasted, and your coding agent never handles a secret. Then start the service:
yothere service
login runs a browser device flow and saves a per-device credential at
~/.yothere/credentials.json (mode 0600). That credential carries no compute keys. If yothere login does not print a code and a link, the wheel predates the device flow: pipx upgrade yothere.
yothere login on the box and open the printed /activate link in a browser on any device, your laptop or your phone. Only unattended provisioning (or self-host break-glass) needs a token: an operator runs yothere admin pair-token <email> on the control plane, which mints a single-use token (it expires after 60 minutes and is stored hashed) and prints the exact command to run on the machine:yothere login --url https://app.yothere.ai --token <pairing-token>
yothere service long-polls the control plane, runs each leased thread’s turn locally
through your coding agent (Claude Code or the Codex CLI), and pushes the result back. It runs
up to five work turns at once by default, plus a separate pool for typed questions, so a reply
never queues behind a long turn. Once it connects, the “no machine connected” banner clears
and any queued tasks start advancing. Run yothere service install for the launchd or systemd
unit that survives a reboot. The first start requires the unattended-tool-use acknowledgement
described below.
Manage paired machines with yothere devices list and yothere devices revoke <id>.
Two ways to onboard
There are two entry points, and they do different jobs. Both are idempotent and safe to re-run.
yothere initis the fast scaffold. It creates the home layout, detects any brain already on the machine, and can run a live zero-key demo in about 30 seconds. Start here.- The onboarding step registry (
python -m yothere.onboarding) is the single source of truth for whether an install is actually set up. Every surface, the CLI wizard, the cockpit first-run card, andyothere doctor, renders the same ordered steps. Use it to bring a real install to done.
init scaffolds and demos; it does not, by itself, complete setup. The step registry below is what tracks whether the install is ready.yothere init
yothere init creates the YOTHERE_HOME layout (threads/ data/ state/ logs/), reports
any brain already configured (a remote brain URL, existing brains.yaml entries, or a
local coding-agent CLI on PATH: claude or codex), and seeds brains.yaml only when
none exists (a commented template plus a bundled zero-key demo brain). It is idempotent and
never overwrites an existing file.
yothere init
yothere init --demo runs a live zero-key loop end to end. It starts the bundled demo
brain on a local port, spawns one thread, and drives it through the real runner: spawn,
work, blocked, reply, done. Nothing leaves your machine and no API key is required.
yothere init --demo
The onboarding steps
The step registry is the single source of truth for setup state. State derives entirely from files and env, so there is no separate progress database and the registry can never disagree with reality.
| Step | What it sets | Confirm before apply |
|---|---|---|
brain |
writes a local default into brains.yaml (local-claude, or local-codex on a machine that only has the Codex CLI) |
no |
workdir |
the directory workers run jobs in (their file and tool scope) | no |
consent |
acknowledges unattended tool use | yes |
notifier |
how you get pinged when a thread needs you | no |
service |
installs the always-on runner and watchdog | yes |
mcp |
registers the yothere MCP server with a Claude client | yes |
voice |
optional, and only if you run the cockpit yourself: stores a GEMINI_API_KEY for a local voice server |
yes |
first_thread |
spawns your first thread | no |
voice step above exists for the self-hosted path only.Each step is a {check, describe, apply} triple. check reports ok / missing /
error from files and env, describe prints the exact change apply would make (file
paths, unit names) so you can read it before consenting, and apply performs it. Steps
that touch the system or store a credential or a consent record (consent, service,
mcp, voice) are marked confirm-before-apply, and every consumer must confirm those first.
Drive the steps from the module:
# every step with its live state (exits non-zero until setup is complete)
python -m yothere.onboarding status
# apply one step; safe steps take structured args
python -m yothere.onboarding apply workdir --args '{"path": "~/code/my-project"}'
# confirm-before-apply steps prompt unless you pass --yes
python -m yothere.onboarding apply consent --yes
status prints each step and exits non-zero until the required steps pass. apply <step>
runs one step, printing the plan and waiting for y on a confirm-before-apply step unless
you pass --yes.
yothere onboard subcommand. Onboarding is driven through the module (python -m yothere.onboarding); yothere init is the separate quick-start scaffold.workdir: pick a safe directory
The harness runs every job against your work directory, and that directory is the file
and tool scope for each headless worker turn. yothere refuses a work directory under
~/Documents or ~/Desktop. On macOS a launchd worker cannot read those paths under TCC,
so it crash-loops on first file access. Pick a normal project or repo directory instead.
Pick it the way you would pick a directory to hand someone: an agent turn can read anything that directory and your configured MCP servers reach.
consent: unattended tool use
The consent step records that you accept the agent running tools unattended. On a
machine paired at the FULL permission tier, a worker turn runs your coding agent at full
capability, scoped to your work directory (claude -p --permission-mode bypassPermissions,
or codex exec -s danger-full-access). Machines paired read-only or workspace (the pairing
ladder; editable in Settings → Machines) run under generated deny rules + a path gate
instead, and don’t need this ack when the local cap is exported as their pairing block
instructs.
Inside a turn the agent may read and write files and run commands without per-action
prompts, and it spends the coding-agent subscription you already pay for.
A send gate is injected into every worker turn and denies outward actions (mail and
messaging send CLIs, mutating gh, HTTP requests carrying a body) until you approve them.
Approving mints a single-use, thread-bound grant. Two things are worth saying plainly:
git pushandghcan never be granted to an agent. No approval unlocks them for a worker turn, ever. yothere pushes only when you press Ship it on a diff, and that rail runs as you, outside the turn.- The gate is a guardrail, not a sandbox. It inspects shell and tool calls, so reads and outbound GET requests are not contained. Pick the work directory accordingly.
Blocked threads still stop and wait for your reply. The acknowledgement is stored as
YOTHERE_BYPASS_PERMISSIONS_ACK=1 in the env file.
Register a repo (optional, for code threads)
If you want threads that build software, register the git repos yothere may work in. It only ever works in a repo you already have on this machine: it never clones, and it holds no git credential.
yothere workspace add site ~/code/my-site
yothere spawn --repo site "fix the layout shift on the pricing page"
A bound thread runs in its own git worktree (under ~/.yothere/worktrees/), on its own
branch, so it never touches your working tree. It commits, and it ends with the diff for
you to read. The agent cannot push, open a PR, or merge, and no approval can unlock that; press
Ship it and yothere does it as you, outside the turn. Details in
the CLI reference.
The home layout
Everything writable roots at YOTHERE_HOME (default ~/.yothere). Its contents:
| Path | What |
|---|---|
credentials.json |
the per-device credential written by yothere login (mode 0600; no compute keys) |
threads/ |
the dir-per-thread fleet store |
threads-archive/ |
archived threads (yothere kill --archive) |
data/ |
cost ledger, router and scope learning logs, presence, watchdog state |
state/ |
ping state, runner.lock, the rendered board, the VAPID key, push subscriptions, learned constraints |
logs/ |
runner and watchdog logs. A hosted call runs on our media worker, so nothing lands here; the control plane renders the live transcript during the call and deletes it at hang-up (Privacy) |
worktrees/ |
one git worktree per code thread, so a thread bound to a repo never runs in your own working tree |
bin/ |
generated service wrappers (written by service install) |
vault/ |
notes root (capture target, preset reads) |
brains.yaml |
the named-brain registry |
workspaces.json |
the git repos you registered with yothere workspace add (paths only: yothere never clones and holds no git credential) |
task-sources.yaml |
the brain-discovered task source (where your to-dos live) |
The env file the service wrappers source is $YOTHERE_HOME/yothere.env (mode 600).
Consent and safety
- yothere binds its network surface to loopback by default and refuses work directories that would crash-loop a launchd worker, so the safe default needs no extra hardening.
consent,service,mcp, andvoicenever apply without an explicit confirmation (or--yes), because each touches the system or stores a credential or consent.- The consent record is a single env line you can revoke by removing it; it does not weaken the per-thread block-and-wait behavior, so a thread that needs your judgment still pauses.
- Cost caps run per thread and per day, on by default ($10 each), and a capped thread comes back to the Inbox as an answerable card.
- Revoke a paired machine at any time with
yothere devices revoke <id>. The credential lives on that machine only.
The full boundary, including what the gate does not contain, is on the Trust page.