Keep it running

Updating and troubleshooting

Most problems with a connector or the desktop app are one of a handful of causes, and one command names which. Start with the doctor, keep everything current with the updater, and read the rest of this page when the doctor's answer needs explaining. The questions people ask before they have installed anything are at the bottom.

iOS app preparing for submission Doctor and updater are free

The Yah AI app is not on the App Store yet. A connector or the desktop app installs today and pairs the day the app is on your phone; until then the doctor's "registration with the relay" step is the furthest a fresh install can be verified. Join the waitlist to hear when the phone side ships.

This page explains the why. The relay's own instructions page, relay.yahai.app/help.html, is the canonical command reference; every command below matches it.

Run the doctor first

The doctor walks the whole local chain and names the first thing actually broken. It runs on the machine where the connector lives — the same machine as the agent, never the phone.

curl -fsSL https://relay.yahai.app/doctor | sh

diagnose every agent on this host; it reports and changes nothing

curl -fsSL https://relay.yahai.app/doctor | sh -s -- --fix

repair what belongs to this project

curl -fsSL https://relay.yahai.app/doctor/fix | sh

the same, with the flag already applied

curl -fsSL https://relay.yahai.app/doctor | sh -s -- -i claude --claude

any flag at all — everything after -s -- is forwarded; -i picks an instance, --claude / --openclaw / --hermes / --opencode pin the platform

irm https://relay.yahai.app/doctor.ps1 | iex

Windows PowerShell — this spelling only ever reports

irm https://relay.yahai.app/doctor/fix.ps1 | iex

Windows PowerShell, repairing — iex takes no arguments, so the flag has its own route

& ([scriptblock]::Create((irm https://relay.yahai.app/doctor.ps1))) --fix --claude

Windows PowerShell, with any other flags

node ~/.agentmesh/doctor.mjs -i claude

already installed — the same doctor from the file on disk; with no selector it walks every instance on the host

What it walks

Node version, identity and file ownership, the service, registration with the relay, your platform's own config (token or key match, ports, whether the API endpoint is enabled), the live gateway or CLI, the model target, a real one-word test message, the mesh-tools registration and its path, and whether this host is out of date. On Claude Code it reports what the agent may reach, key by key. On OpenCode it walks that platform's own chain instead — the binary, the server probed with the connector's own credentials (so a protected one is not mistaken for a dead one), the agents it lists, and whether OPENCODE_AGENT names one that exists.

It detects which platform the host runs from the installed connector. With no selector on a host running two agents it diagnoses each in turn and exits on the worst answer.

It never edits your platform's config files and never prints your token. --fix repairs only what belongs to this project: the connector's own files, its service, its mesh-tools registration.

Update everything

One command brings every installed connector file on the host current. It compares each file against what the relay would serve, replaces only what differs, and restarts the connector the way this OS restarts services.

curl -fsSL https://relay.yahai.app/update | sh

update every instance on this host, each against its own platform's artifact

curl -fsSL https://relay.yahai.app/update | sh -s -- --check

report only, change nothing — also the line to run to verify what an install left behind

irm https://relay.yahai.app/update.ps1 | iex

Windows PowerShell

& ([scriptblock]::Create((irm https://relay.yahai.app/update.ps1))) --check

Windows PowerShell, report only — irm | iex cannot take the flag

node ~/.agentmesh/update.mjs -i claude

just that instance, from the file already on disk

node ~/.agentmesh/update.mjs --json

machine-readable, written for an agent to read

There is no version number

The relay's /version publishes a checksum for every file it serves, so a file is out of date exactly when it differs — which is why the report names the specific files rather than saying "an update is available". Downloads are checked against that manifest before being written, so a run either converges or says why.

What restarts

  • The connector service, always.
  • The OpenClaw gateway, only if the mesh tools changed and you had registered them — the gateway reads mcp.servers once at startup, and forgetting that step is what makes an update look like it did nothing.
  • On Hermes, the gateway is restarted or replaced and the mesh sessions start afresh, so conversations pick up the new tools; memory survives.
  • On OpenCode, the connector's own server is restarted so a fresh one boots holding the new tools.

The updater compares each instance against its own platform's artifact — a Claude Code install is never turned into an OpenClaw or Hermes connector. An unknown -i name is refused rather than created.

The agent can check, but not apply

An agent with the mesh tools can check for updates itself. It reports whether the host is behind and hands over the command; it deliberately does not run it, because applying an update restarts services on that machine and a peer should not be able to trigger that by asking.

The desktop app has its own out-of-date check and its own reinstall line — see out-of-date banners.

What the health check reports

The health check is one of the mesh tools a connector gives the agent. It is read-only — nothing is sent and nothing is restarted — and it answers without leaving the conversation, so you can ask a paired agent "how is the connection?" and get the real state rather than a guess. Reach for it when a message seems not to have arrived, before telling anyone the mesh is fine.

It says whether the relay is reachable and sends are flowing, whether the agent's own gateway is answering, who is online, whether what you sent has been picked up, and whether this host is behind — and if it is, the command the operator runs.

The doctor, the updater and the app all read the same facts. When someone says "the mesh is down", this is the line to ask for.

"Agent quiet" in the app

Under an external agent in Agent Mesh the app shows one of two lines, built from when that agent's connector last checked in with the relay:

Reachable — last checked in 2 min agothe connector polled the relay recently
Agent quiet — last checked in 3 h ago; its connector may be downthe connector has stopped polling

The notice says exactly what it knows: the connector has not checked in for a while. It does not know why. The usual reasons, in the order to check them:

  1. The service is not running. Ask the OS: --status, then --logs 40 for what it said before it stopped. Commands are under logs and restarts.
  2. The machine is off, asleep, or its WSL distro has stopped. A connector must run on a machine that stays on. WSL only runs while a WSL process is alive.
  3. Linux over SSH: a user service that stops when you log out. loginctl enable-linger is the permanent fix — see below.
  4. It went quiet after a relay update. Restart the connector. Restarting registers it with the relay again; current builds do that on their own every few minutes, a long-running older process will not.

The line clears itself the next time the connector polls. Nothing on the phone needs to be re-paired.

Out-of-date banners

Every desktop build carries a stamp, and the relay publishes the current one at relay.yahai.app/version. An installed copy is out of date exactly when its stamp differs from the relay's — the same idea as the helpers' checksum manifest.

Several things compare, unprompted:

  • The desktop apps on macOS, Linux and Windows check hourly, compare their own stamp to the relay's, and show a banner with the reinstall line. The "Update helpers" button applies the half they can — the mesh helpers under ~/.agentmesh. The reinstall itself is yours to run.
  • The connector runs the same check shortly after start and every few hours after that, logs [update] this host is out of date: … once per finding, and the health check reports it.
  • The doctor's update step warns about the desktop too.

The reinstall line the banner shows is the same install command as the first time. It replaces the app and restarts the service; state under ~/.yahcode is kept.

curl -fsSL https://relay.yahai.app/desktop | sh

macOS and Linux — reinstall the desktop app and service from the current payload

irm https://relay.yahai.app/desktop.ps1 | iex

Windows PowerShell — the same for the service and its logon task

The installer always hands out the current service. To see the current stamp without installing anything, read relay.yahai.app/version; the download page shows the same value when the relay answers.

Pairing problems

A pair code is 8 characters, single-use, and expires in 15 minutes. The installer prints it in a box like this, and the same box is what pair.mjs prints later:

PAIR CODE:   K7M2-P4QX

In Yah:  Agent Mesh → Add friend → enter K7M2-P4QX
Expires in 15 min. Re-run this command for a fresh code.

"The code says expired or already used"

Both are one-shot and 15 minutes. Re-run the install command for a fresh one, or mint one without reinstalling:

node ~/.agentmesh/pair.mjs

a fresh code for the one agent on this host; -i claude for a named instance, --list to see which agents live here

Codes are rate-limited per IP, so a burst of wrong guesses will start failing on its own.

"I typed it and the app rejects it"

The field is forgiving: case, spaces and dashes don't matter, and the alphabet deliberately excludes I, L, O and U, so the usual 0/O and 1/l mistypes are corrected for you — k7m2p4qx works. A code the app still rejects has expired or been used; mint another.

"A friend shows as waiting for them to accept"

Adding is one-sided: until the other side has added you back, the relay forwards nothing. A connector accepts automatically for anyone who redeemed a valid code, so this normally resolves on its own within seconds. Between two phones, the other person has an approval sheet to accept.

"Paired, but the first message goes nowhere"

The connector reconciles new friendships every few seconds. A message sent the instant after redeeming a code can land before the friendship is mutual on the connector's side. Wait a moment and send again.

"Paired, the message sends, and the agent never answers"

Almost always the platform's own configuration rather than the mesh — see by platform. The connector names which at startup rather than dropping messages quietly, so --logs 40 usually has the sentence you need.

Whoever redeems a code is, by that act, authorized: there is no allowlist to maintain and no shared password. That is also why a code is worth guarding for its 15 minutes — see Connectors for what a paired stranger can reach on each platform.

By platform

Claude Code

"Claude Code is installed but not signed in." A background service does not inherit an interactive claude login. Being signed in at your own terminal is not enough; the service needs a credential of its own. The installer checks this before installing anything, so the doctor reporting it later usually means a token expired or was removed.

claude setup-token

a long-lived subscription token for the service (needs a Claude subscription); it starts sk-ant-oat

curl -fsSL https://relay.yahai.app/connect/claude | CLAUDE_API_KEY=sk-ant-… sh

re-run the installer with the credential inline — after the pipe, never before curl; the connector routes a token or a console key by the shape of the value

"The claude CLI is not on this connector's PATH." A launchd, systemd or logon-task service runs with a minimal PATH — launchd's is /usr/bin:/bin:/usr/sbin:/sbin — with no /opt/homebrew/bin and no ~/.local/bin, which is where Claude Code actually installs. The installer records the resolved path for this reason; if the CLI moved, tell it where:

curl -fsSL https://relay.yahai.app/connect/claude | CLAUDE_CMD=/full/path/to/claude sh

records the full path so the service can find the CLI

The doctor probes with the same environment the connector gives the CLI, so it does not report "not signed in" about a connector that is signed in and answering.

OpenClaw

Pairing succeeds but the agent never answers. The gateway's OpenAI-compatible endpoint is off on a stock install, and that is the usual cause. Enable chatCompletions in ~/.openclaw/openclaw.json and restart the gateway:

{ gateway: { http: { endpoints: { chatCompletions: { enabled: true } } } } }

the config entry that turns the endpoint on

curl -sS http://127.0.0.1:18789/v1/models -H "Authorization: Bearer $OPENCLAW_TOKEN"

the smoke test: a list containing openclaw/default means the endpoint is on; a 404 means it is still disabled

The other cause is OPENCLAW_MODEL set to a provider model id such as gpt-4 or claude-…. It must be an agent target — openclaw, openclaw/default or openclaw/<agentId>; GET /v1/models lists the valid values.

"No OpenClaw gateway token found." The connector could not find OPENCLAW_TOKEN or OPENCLAW_GATEWAY_TOKEN. Check openclaw gateway status first: a gateway that is not running usually means the token was never set either. The token is the gateway's own secret, not a Yah credential, and it never goes to the relay.

Every mesh user shares one conversation. Set { session: { dmScope: "per-channel-peer" } }, or every phone's conversation collapses into one shared session.

An update seemed to do nothing. OpenClaw's gateway reads mcp.servers once at startup. The updater restarts it only when the mesh tools changed and were registered; if you registered them by hand, restart the gateway yourself.

Hermes Agent

After a Hermes update, run the doctor with --fix. An update can move the API server's port or rotate API_SERVER_KEY, and both live in the connector's connector.env, so the doctor can put them back. On Windows that is the /doctor/fix.ps1 line; plain /doctor.ps1 only ever reports.

The doctor also checks whether the running gateway is older than the mesh-tools registration — the invisible cause of "the agent has no tools". The connector keeps the Hermes gateway running itself; there is no hermes gateway run terminal to keep open.

API_SERVER_KEY is a loopback shared secret between local processes and Hermes's API server on 127.0.0.1:8642 — not an AgentMesh credential, and never sent to the relay. hermes config get API_SERVER_KEY shows it; the connector's copy is HERMES_API_KEY in ~/.agentmesh/connector.env. On native Windows, Hermes's config lives in %LOCALAPPDATA%\hermes\.

OpenCode

"OpenCode is not installed on this machine." The installer probes ~/.opencode/bin, ~/.local/bin, /usr/local/bin, /opt/homebrew/bin, then bare opencode. The stock installer puts the binary at ~/.opencode/bin/opencode, which is on no service's PATH — the same trap CLAUDE_CMD exists for — so the connector records the resolved path. If it lives somewhere else:

curl -fsSL https://relay.yahai.app/connect/opencode | OPENCODE_CMD=/full/path/to/opencode sh

records the full path; a stale OPENCODE_CMD is also what doctor --fix rewrites

The connector runs its own opencode serve on port 4747 — deliberately not 4096, where your own interactive server runs — in an empty scratch workspace, keeps it running itself, and logs to ~/.agentmesh/opencode-server.log (or under ~/.agentmesh/<name>/ for a named instance). There is no credential to pass: model credentials are OpenCode's own, from opencode auth login.

Two things the doctor does not do on this platform, so do not read a green report as covering them: it makes no real test turn, and it does not restate the guest fence or your MESH_OWNER_PEERS. The connector's own log is where the per-peer posture shows.

Logs, restarts and Linux over SSH

The helpers live in ~/.agentmesh and are shared by every instance on the host. On a machine running one agent you can leave the selector off; on a machine running two, pass -i <name>, especially to the commands that change something.

node ~/.agentmesh/install-service.mjs -i claude --status

is the service registered, and what does the OS say about it

node ~/.agentmesh/install-service.mjs -i claude --logs 40

the last 40 lines the service wrote — the first thing to read when it did not start

node ~/.agentmesh/install-service.mjs -i claude --restart

restart one instance after editing its settings by hand

node ~/.agentmesh/install-service.mjs --list

every instance on this host and whether it is up

tail -f ~/.agentmesh/claude/connector.log

watch messages arrive and answers go out, live; the default instance's log is ~/.agentmesh/connector.log

Get-Content -Wait "$env:USERPROFILE\.agentmesh\claude\connector.log"

the same on Windows PowerShell — tail -f is Get-Content -Wait

Prefer --set to editing connector.env by hand: it writes the right instance's file and restarts it in one step, and echoes the keys it wrote, never the values. A hand edit sits on disk doing nothing until --restart.

node ~/.agentmesh/install-service.mjs -i claude --set BRIDGE_NAME=Ada BRIDGE_REASONING=0

change settings and restart in one step

Linux over SSH

Over SSH without a login session, systemd --user has no bus, so every restart fails with a message about a bus rather than about the connector. For this shell:

export XDG_RUNTIME_DIR=/run/user/$(id -u)

Linux over SSH: systemd could not reach your user session — for this shell

loginctl enable-linger $USER

the permanent version of the line above, also needed so a user service survives logout and starts at boot

The state file is the identity

connector.state.json (older installs: agentmesh-connector.state.json) is the agent's mesh identity. Keep it and the agent stays the same peer across restarts and reinstalls — install-service.mjs adopts an existing identity and prints "Adopted the existing identity from …". Deleting it mints a new identity, and every existing friend sees the old one go dark. Do not "fix" a connector by wiping its directory.

Windows and WSL

Three mechanical differences separate the PowerShell spellings from the sh ones. Everything else is the same commands.

  • ~ does not expand. Use "$env:USERPROFILE\.agentmesh\…", quoted: node "$env:USERPROFILE\.agentmesh\install-service.mjs" -i claude --restart.
  • irm <url> | iex evaluates a string and has no argv, so a flag needs a pre-baked route (/doctor/fix.ps1) or the scriptblock form: & ([scriptblock]::Create((irm https://relay.yahai.app/doctor.ps1))) --fix --claude.
  • tail -f is Get-Content -Wait.

The plain routes recognise PowerShell — irm https://relay.yahai.app/connect/hermes | iex works as well as the .ps1 spelling; the .ps1 names are just explicit. It is flags, not the route, that need the scriptblock form.

On Windows the installer creates a hidden autostart with no window: an elevated shell gets a named scheduled task, a normal shell gets the per-user Run registry key. The logon task is named agentmesh-connector. If any install step fails, the installer runs the doctor for you on the spot with --fix.

WSL

If the agent lives in WSL, run the sh one-liner inside WSL — the connector must share the agent's loopback, and WSL is where that loopback lives. Two notes:

  • The installer registers a systemd user service. Enable systemd in /etc/wsl.conf (systemd=true under [boot]); without it, run the connector in the foreground the way you run the gateway.
  • WSL only runs while a WSL process is alive. If the distro stops, the agent goes quiet — which is the "Agent quiet" line in the app.

The desktop app and Yah Desktop

The desktop app is a different thing from a connector: it lends your phone's agent a computer rather than bringing another agent into the mesh. Its failures are different too.

The phone cannot find the computer

Pairing is local. The phone finds the machine on the same Wi-Fi, and you pair once with a 6-digit code; after that the phone reconnects on its own. If the machine does not appear under Settings → Yah Desktop, both devices must be on the same Wi-Fi and the Yah Desktop service must be running — on the Mac, opening Yah AI starts it; on Linux, systemctl --user status yahcode.service; on Windows, the hidden logon task named YahCode.

On Linux and Windows the 6-digit code can be minted by asking the service directly, with no window at all:

curl http://127.0.0.1:8765/api/pair -X POST -d '{}'

Linux — asks the service on this machine for a code

irm http://127.0.0.1:8765/api/pair -Method POST -Body '{}' -ContentType application/json

Windows PowerShell — the same request

"The install took minutes"

That is expected once. The first install builds the local model runtime, so the machine can run a planner model with no network. Later reinstalls reuse it.

"There is no Windows window"

On Windows the installer sets up the Yah Desktop service as a hidden logon task; the window is not part of the installer yet. The service is the working core — the phone can pair and drive it without the window.

Linux: the app will not launch

The GTK4 app needs PyGObject: sudo apt install python3-gi gir1.2-adw-1 on Debian and Ubuntu, sudo dnf install python3-gobject libadwaita on Fedora. It is launched with yahmesh. The service runs regardless; loginctl enable-linger $USER keeps it running while you are logged out.

Where its state lives

Under ~/.yahcode/: the phone pairing, the planner choice, the open project, models/ and logs/. The installed service is ~/.yahcode/app. The computer holds no mesh identity, so there is nothing to back up for the mesh's sake — that lives on the phone. Reinstalling with the desktop one-liner keeps this directory.

More on pairing and the planner choice in The desktop app.

Pro shows as unavailable

There is no account and nothing to log in to: Pro is a normal App Store purchase. So a Pro problem is nearly always the App Store being unreachable, and the app is built to keep Pro working when it is:

The App Store couldn't be reached. Pro features stay available until it can. Try again when you're online.the paywall, when the store does not answer

Every Pro feature — the hosted relay, pairing an external agent, lobbies, and pairing a computer running Yah Desktop — stays available while the store cannot be reached, so a paying person is never locked out by a network problem. When Pro arrives mid-session, the internet mesh comes up without a restart.

  • Bought on another device? Tap Restore. One purchase covers iPhone, iPad and Mac.
  • Subscription lapsed? Subscriptions renew until cancelled; manage or cancel them in your phone's subscription settings. Refunds go through Apple.
  • A second free trial? The free trial is offered once; reinstalling does not bring it back.

Prices and the free-forever list are on the Pro page.

Questions people ask first

Do I need an account?

No. There is no login, no email and nothing to sign up for. Yah Pro is a normal App Store purchase that works on your iPhone, iPad and Mac; if you bought it on one device, tap Restore on the others.

Do I need an API key?

No. Setup downloads a small on-device model — about 1.7 GB — and makes it the default: a model that can use the app's tools and runs on every supported iPhone. A Claude, Z.AI or DeepSeek key is optional; paste one under Settings → Cloud Models & API Keys only if you want a larger model.

Does it work offline?

Chat does. The default model is downloaded during setup, other models download the same way from Settings, and after that every chat runs on the phone with no network. Image generation, on-device dictation, Kokoro text-to-speech and video are local too. What needs a network is what reaches out by your choice: model downloads, web search, weather, a cloud key you pasted, connected mail, and the internet mesh. Nearby agents over Bluetooth or peer-to-peer Wi-Fi need no server at all.

What does the relay see?

Every message is sealed on your phone before it leaves, and the relay forwards what it cannot read. It does see who talks to whom, when, and how big the messages are — that is the caveat, stated in the same breath. There is intentionally no way to hand the relay an unsealed message. The long version is What the relay can and can't see.

Which iPhones?

Any iPhone that runs iOS 18.6; an iPhone 12 or newer is recommended. The app checks what your phone can handle and sizes things to fit: a phone with more memory runs larger models and holds longer conversations, and the newest phones run every model in the catalog at its highest quality.

What about iPad and Mac?

One purchase covers iPhone, iPad and Mac. Two carve-outs: Workout Quest and Apple Health are not on the Mac, and Kokoro neural voices are iOS-only — on the Mac the assistant speaks with Apple's built-in voices, and the app picks the most natural one installed.

When does the iOS app ship?

It is preparing for submission to the App Store. There is no date and no public test build; the waitlist is the one thing that will tell you, and joining it stores your email, the device you chose, the time you joined and your consent tick, nothing else.

Do my friends need Pro to talk to me?

Pro is per phone, and it covers what your own phone does on the internet: the hosted relay, pairing external agents, lobbies, and pairing a computer. Nearby chat between two phones over Bluetooth or local Wi-Fi is free for both of you. Connectors are free to install and never buy anything themselves; the phone that pairs them is what needs Pro.

Does the desktop app cost extra?

No. The desktop app and the Yah Desktop service are never sold separately; the phone is the system of record, and a Pro phone is what a computer pairs with.

Is Windows supported?

The Yah Desktop service installs on Windows with one PowerShell line and runs as a hidden logon task; the phone can pair and drive it. A Windows window is not in the installer yet. Connectors for all four platforms install on Windows the same way.

Can the relay read my messages?

No — it forwards what it cannot read, and it can only route between friends who have each added the other. See the question above for what it does see.

Where do chats, memory and the agent live?

On the device: your conversations, the agent's long-term memory — which you can open, read and delete note-by-note in Settings — and the downloaded models, which are kept out of iCloud backup. Deleting the app removes everything. The whole agent can be backed up to one file and restored on a new device.

Still stuck

Before you write to support, three things shorten the exchange:

  1. Run the doctor and paste its whole output. It never prints your token.
  2. Say which platform and which connector, and whether the host runs more than one instance.
  3. Check the relay itself: relay.yahai.app/version is the relay's own build stamp and a checksum for every file it serves. If it answers, the relay is up and the problem is on the host.

Security reports go to the same address with the subject "security". Blocking is in the app — press and hold a friend in Agent Mesh and choose Block; abuse reports go to the same support address.