CLI
Every command and flag, the environment variables, and the exit codes.
You mostly do not need this page. Run brainlyy with no arguments and it
opens the dashboard, where setup, connecting sources and writing claims all
live. The commands below exist for scripting and for people who prefer them.
Every command reads its instance from $BRAINLYY_HOME, defaulting to
~/.brainlyy. Set that variable to run more than one instance on a machine.
brainlyy init
Set up an instance: write config, generate secrets, render templates, register with your MCP client, and verify.
brainlyy init
| Flag | Does |
|---|---|
--force |
Overwrite an existing config and rotate tokens. Rotating breaks every registered client. |
--no-register |
Skip registering with the MCP client. Use in CI. |
Asks three questions, all defaulted; a non-interactive shell takes every default. Finishes by running the property suite and refuses to report success if it fails.
Safe to re-run. Existing tokens are never regenerated and existing SOULs are never overwritten, because they get hand-edited and those edits matter.
brainlyy doctor
What works, what is missing, and what the next tier would add.
brainlyy doctor
Probes every dependency rather than reading config, so the result reflects the machine rather than your intent. Never raises: a failed probe means absent.
brainlyy connect
Pair this machine with the web app, then answer for it.
brainlyy connect A7K2QM94 # pair, then stay connected
brainlyy connect # reconnect a machine already paired
| Flag | Does |
|---|---|
--url URL |
Control plane to pair with. Defaults to the hosted one. |
--pair-only |
Pair and exit, instead of staying connected. |
Where the code comes from. Open the web app, create an account or sign in
with Google or GitHub, then press Add a machine. The code it shows is
single-use and expires in fifteen minutes, and the page prints the exact
connect line to paste here.
You do not need an account to use Brainlyy. This one exists only so a machine can be reached from a phone or a web assistant; everything else works without it.
The connection is dialled out from here. Nothing on this machine is exposed, no port is opened, and the control plane cannot reach in. It can only answer on a connection this machine chose to make. That is why it works behind NAT, on hotel wifi, and on a laptop that moves.
Only /api/ paths are relayed, and only read methods, unless
ui.remote_writes is set. See Security.
brainlyy logs
What this instance has been asked to do.
brainlyy logs # the last 40 lines from the last 7 days
brainlyy logs --failures # only what was refused
brainlyy logs --days 0 # everything kept
brainlyy logs --path # just the directory, for piping
| Flag | Does |
|---|---|
--days N |
How many days back to read. 0 reads everything. |
--limit N |
How many lines to show. |
--failures |
Only calls that were refused or failed. |
--path |
Print the log directory and exit. |
Every call the servers answer is written down: if it is not logged, it did
not happen. That included the refusals: a rejected token, a path that escaped
the vault, a cmd check the API declined to create.
The directory is paths.root/logs, one file per day, kept for 30 days.
Older files are removed the first time a log line is written on a new day.
Thirty days is long enough to answer "what happened last week", and short
enough to stay a log rather than an archive. Files that are not Brainlyy's are
never touched.
brainlyy uninstall
Undo what Brainlyy did to this machine.
brainlyy uninstall # stop autostart, unregister, keep everything
brainlyy uninstall --purge # and delete the instance directory too
| Flag | Does |
|---|---|
--purge |
Also delete the instance directory: config, tokens, evidence log. |
It never touches your vault. Those are your notes, in a folder you chose, which may be a git repository or an Obsidian vault or simply where you keep your writing. Knowing where it is does not make it ours. That includes notes Brainlyy wrote: a claim is a markdown file you now own.
Without --purge the instance directory is kept, because it holds the
evidence log, the record of what was true and when, which is the one thing
here that cannot be rebuilt.
Autostart is removed only if it serves this instance. A machine can run
several (that is what BRAINLYY_HOME is for) and there is one autostart entry
naming one of them; removing another instance's is how a dashboard silently
stops coming back after a reboot.
It cannot uninstall the program while running from it, so it prints the line for that instead of pretending:
uv tool uninstall brainlyy
brainlyy service
Keep Brainlyy running across reboots.
brainlyy service # install (the default)
brainlyy service status
brainlyy service uninstall
Without this the dashboard dies when the machine restarts and nothing brings it back, so you have to remember a command. By week two you have stopped remembering, and your claims have stopped being re-checked. A freshness promise that depends on somebody remembering is the exact defect this project exists to catch.
Two things are registered, and they fail independently: the dashboard, and
(only once this machine is paired) the link to the control plane. Run it
again after brainlyy connect <code> to pick up the second.
| System | What it uses | Where |
|---|---|---|
| Linux | systemd --user |
~/.config/systemd/user/brainlyy*.service |
| macOS | launchd | ~/Library/LaunchAgents/xyz.brainlyy.*.plist |
| Windows | a .cmd in your Startup folder |
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup |
All three are user services. Brainlyy reads a vault in your home directory and answers on loopback; it has no business running as root or before you log in.
Windows deliberately does not use Task Scheduler: schtasks /Create is
refused for an ordinary user on a default Windows 11 install, so an autostart
built on it would work only for someone willing to run an installer as
administrator. The Startup folder needs no elevation, and it leaves a file you
can find and delete without this tool.
On Linux, a user service stops when your last session ends unless lingering is
enabled, so it survives a logout but not a reboot. The command tells you if
that applies, and it is the one step that needs sudo:
sudo loginctl enable-linger $USER
If BRAINLYY_HOME is set, it is carried into the service, so a machine
running more than one instance keeps serving the right vault.
brainlyy verify
Re-check every claim in your vault and record what was observed.
brainlyy verify
brainlyy verify --strict # in CI
| Flag | Does |
|---|---|
--strict |
Exit 1 if any claim is unverified. For CI. |
--json |
Machine-readable output. |
--dry-run |
Classify without running any check. |
Prints only what needs attention, since verified claims are the boring case, then a count, and how long the longest-lived false claim read VERIFIED before a run caught it.
The status is computed here and nowhere else. A note declares a claim and the evidence it rests on; it never says how it is doing. See Claims.
brainlyy ui
Open the dashboard in a browser.
brainlyy ui
| Flag | Does |
|---|---|
--no-open |
Start the server without launching a browser. |
--print-url |
Print the one-time authenticated URL and exit. |
Binds loopback unless ui.bind: mesh is set. Write controls render only when
the request arrived on 127.0.0.1; see Security.
--watch: the scheduler
brainlyy verify --watch
Re-runs every claim's checks on a timer and keeps going. This is what makes "it tells you when something stops being true" true: without it a claim is only ever re-checked when somebody remembers to ask, which is what every wiki already does.
The interval is verify.interval_minutes in config (default 60; 0 turns it
off). brainlyy service install registers it, so on a machine with autostart
set up there is nothing to remember.
It also tells you. When a claim goes from VERIFIED to UNVERIFIED, the loop
raises a desktop notification, prints a line, and records it where the
dashboard shows it as a banner. Only that transition. See
Claims for why. notify.desktop: false
keeps the record without the toast.
Failures never stop the loop. A disconnected network drive, a check whose host is down, a file being written as it is read: each is a reason to try again in an hour, not a reason to stop checking forever.
brainlyy passphrase
Set the passphrase that signs in to the dashboard at /login.
brainlyy passphrase
| Flag | Does |
|---|---|
--stdin |
Read the passphrase from stdin instead of prompting. For scripts; nothing is echoed either way. |
Prompts twice without echo and refuses anything under 10 characters. Stores
an scrypt hash in passphrase.json, never the passphrase itself. Session
and lockout details live in Security.
brainlyy serve
Run a server in the foreground.
brainlyy serve # read server, binds hosts.brain_mesh_ip
brainlyy serve --write # write server, binds 127.0.0.1 only
The write server exits at startup if its bind address is not loopback. That is an exit code, not a preference.
brainlyy search
Query your notes without a browser.
brainlyy search on-ramp fee
brainlyy search --limit 12 settlement
| Flag | Does |
|---|---|
--limit N |
Maximum excerpts to return. Default 6. |
Works at tier 0 over plain markdown, with no vector store running.
brainlyy docs
Build the documentation site.
brainlyy docs # where the markdown lives
brainlyy docs --build --open # render it and open it
brainlyy docs --build --output ~/brainlyy.html # somewhere specific
| Flag | Does |
|---|---|
--build |
Render docs/*.md into one page. Without it, docs only reports where the sources are. |
--open |
Open the result in a browser. |
--output PATH |
Where to write it. Default ./brainlyy-docs.html. Never into docs/, which stays pure markdown, and never into the install, which is not a build target. |
Output is self-contained: the stylesheet and both fonts are inlined, so it reads identically offline. The markdown ships inside the wheel, so this works on a machine that has never seen the repository.
Environment variables
| Variable | Effect |
|---|---|
BRAINLYY_HOME |
Where config, secrets and instance data live. Default ~/.brainlyy. |
BRAINLYY_CONFIG |
Path to a specific config file, bypassing discovery. |
BRAINLYY_READ_HOST / BRAINLYY_READ_PORT |
Override the read server's bind. |
BRAINLYY_READ_TOKEN |
Override the read token. |
BRAINLYY_WRITE_HOST / BRAINLYY_WRITE_PORT |
Override the write server's bind. Non-loopback hosts are refused. |
BRAINLYY_WRITE_TOKEN |
Override the write token. |
Exit codes
0 success · 1 a check failed and the reason was printed · a SystemExit
message on startup means a boundary refused, not a crash.