The final version
The finished product in full: what it is, every feature, every surface, the guarantees it makes, and how you know it is done.
This is not the canonical definition.
docs/product-contract.mdis, and where the two disagree the contract wins. This page is the readable orientation: what Brainlyy is, why it exists and what the finished product looks like. The contract is the version that acceptance statements are written against.
It is not a status report and not a plan. It is the fixed point every piece of work is measured against; anything that does not move something in here is a detour, and should be named as one.
Contents: About · Why it exists · What it is not · The shape · What an account gives you · Features · Capabilities · The three guarantees · Flow · User journey · Surfaces · The thirteen destinations · Components and tabs · Design · UI and UX · CSS · MCP · API · Platform and device · How to set up · Instruction · How you know it is finished
About
Brainlyy is the account that turns a pile of private infrastructure into one thing an assistant can use, from anywhere, with proof of where every answer came from, without the data ever leaving the machines it lives on.
Why it exists
Private infrastructure is easy to build and almost impossible to reach. A personal brain on one machine, a company brain on a server, call graphs over a dozen repositories, local models, a notes vault, agents on Discord and ClickUp
- each of them works, and none of them is reachable together. They live behind a tailnet or a firewall, they are registered one machine at a time, and the only public door anyone builds is a proxy in front of one host with a shared secret pasted into a dialog and an IP allowlist that silently stops matching.
So the knowledge exists and the assistant cannot use it. Every question is answered from whatever happens to be in front of the model, and the answer carries no trace of where it came from.
Brainlyy is the way in. It does not replace the brains, the graphs, the models or the servers. It gives them one account, one endpoint, one place that knows which machine holds what, and it can say, of every answer, exactly where that answer came from.
What it is not
- Not a hosted brain. Models, notes and graphs stay on the user's machines. The moment Brainlyy stores note text, the claim the whole product rests on becomes false, and there is a test whose job is to fail if it ever does.
- Not a note-taking app. Notes are the substrate, not the point.
- Not a replacement for Graphify, Ollama, Obsidian or a company server. It is the layer that makes them reachable together and answerable for.
The shape
Claude · Cursor · phone · browser
│ one connection, one account
▼
┌──────────────────────┐
│ Brainlyy control │ identity · routing · provenance
│ plane (hosted) │ holds NO note text, ever
└──────────┬───────────┘
│ relay: the machine dials out, nothing is exposed
┌─────────────┼─────────────┬──────────────┐
▼ ▼ ▼ ▼
workstation server laptop 3rd-party MCP
vault company repos (ClickUp, Sentry…)
models agents graphs
Every machine keeps its own data and answers for itself. The plane knows who you are and which machine, never what the answer said.
What an account gives you
The moment you sign up, before you touch a terminal:
- One MCP endpoint,
app.brainlyy.xyz/mcp, authenticated by your account, revocable, usable from Claude, Cursor, Claude Desktop or a phone. No shared token, no IP allowlist, no per-machine registration. - A dashboard reachable from any signed-in device, showing every machine, what each contributes, and whether it is answering right now.
- One install line. Run it on a machine and that machine attaches itself: the agent finds the vault, the models, the code graphs and any MCP servers already registered there, and lights them up as capabilities with nothing configured.
That is the plug-and-play principle: the account is the starting point, and the infrastructure comes to it, rather than assembling everything first and arriving with it.
Features
Identity and access
- An account created with Google or GitHub. No password exists anywhere in the product, so none can be lost, phished or reused.
- One MCP endpoint per account, revocable, usable from any device and any assistant.
- Sessions listable and revocable; sign out everywhere ends every one at once, including at the identity provider.
Machines
- A machine joins with a single-use code and dials out. No inbound port, no public address, no firewall change.
- It attaches itself: the agent finds the vault, the local models, the code graphs and any MCP servers already on that machine, and reports each as a capability.
- Its dashboard opens from any signed-in device, and it reports its own health from the relay rather than from a timestamp.
- Autostart on Windows, macOS and Linux; a reboot restores it unprompted.
Knowledge
- Search, ask and read across the vault, with an answer that names the note it came from, or abstains.
- Call and import graphs across every indexed repository, queryable by an assistant rather than grepped.
- Company documents and personal notes reachable through one account and kept structurally apart.
Verification
- A claim carries its evidence and the check that tests it; the evaluator decides its state, and note text can never assert its own verification.
- A claim that stops being true demotes itself and says so unprompted, a desktop notification, a line in the terminal, a banner on every screen.
- An append-only, hash-chained evidence log, with tampering visible in the interface and not only to the command line.
- Checks are editable and diagnosable from the dashboard; a wrong path never requires opening a config file.
The hub
- Third-party MCP servers connected from a catalogue: a button, OAuth in the browser, no JSON edited and no restart.
- Everything re-exposed through the single account endpoint, namespaced, so one assistant connection reaches native and third-party tools alike.
- Health per server, failure isolation, an audit line per call, and provenance on every answer.
Ownership
- Export everything the service holds about you, as one readable file.
- Delete the account and everything it owns, permanently.
- Installers served over the product's own host and verified by SHA256.
Capabilities
| Capability | Source | Tool |
|---|---|---|
| Notes search | the vault | search_notes |
| Fast answers | local model | ask_fast |
| Licensed answers | permissively licensed model | ask_licensed |
| Code graphs | indexed repositories | code_search |
| Company documents | the company host | company search |
| Agents | agent profiles | run_agent, agent_status |
| Messaging | chat integrations | post_message |
| Anything else | third-party MCP | namespaced through the hub |
The three guarantees
These are what make it Brainlyy rather than a proxy.
- Privacy is structural, not promised. Notes stay on their machine. The plane brokers in memory and persists nothing vault-shaped, and a test reads the raw database to prove it.
- Claims check themselves. A claim carries evidence and a check; the evaluator decides its state; a claim that stops being true demotes itself and says so, unprompted.
- Every answer carries provenance. Which machine, which source, which server. An answer with no evidence abstains rather than guesses.
Flow
account created
│
├─ gateway token minted ──► claude mcp add app.brainlyy.xyz/mcp
│
└─ one install line per machine
│
├─ agent pairs (single-use code, dials out)
├─ agent auto-detects: vault · models · graphs · MCP servers
└─ agent long-polls the relay
│
assistant calls a tool
│
plane authenticates the ACCOUNT, picks the machine, relays
│
agent forwards to 127.0.0.1 with its read token
│
answer returns, labelled with machine + source
Nothing inbound is ever opened on a machine. The plane holds identity and routing; the answer passes through memory and is never written down.
User journey
First hour. Discover on brainlyy.xyz → Sign in opens a side panel →
Google or GitHub → the account exists. The dashboard teaches three steps: add a
machine, run one line, open it. Run the line on the workstation; the vault, the
models and the code graphs light up by themselves. Add the gateway to Claude
with one command. Ask a question in Claude; the answer cites the note it came
from.
Day two. Pair the laptop. It attaches its own repositories. The same one connection in Claude now reaches both machines.
Day seven. A check fails. The claim demotes itself, a notification arrives, and the dashboard shows which evidence stopped being true, from the phone, without a terminal.
Week two. Connect a third-party MCP server from the catalogue. No JSON, no restart. Its tools appear namespaced beside the native ones, and its answers are labelled with its name.
Surfaces
| Surface | What it is |
|---|---|
brainlyy.xyz |
Marketing and documentation, one source with the repository; sign-in is a panel over the page, never a separate screen |
app.brainlyy.xyz |
Account, machines, capabilities, tokens, the gateway's own screens |
app.brainlyy.xyz/m/{id} |
A machine's dashboard over the relay, the thirteen destinations |
app.brainlyy.xyz/mcp |
The account-scoped MCP gateway |
get.brainlyy.xyz |
Installers, verified by SHA256 |
| CLI | brainlyy, init, connect, verify, service, logs, uninstall |
| Local dashboard | The same thirteen destinations, on the machine, no account required |
The thirteen destinations
| Group | Items |
|---|---|
| Knowledge | Overview · Notes · Graph · Ask · Search |
| Verification | Claims · Evidence · Checks |
| Connections | Machines · Integrations · MCP |
| (footer) | Settings · Help |
Thirteen, counting Settings and Help. Earlier drafts here said twelve by leaving the footer out of the count, which made every gap analysis written against it wrong by one.
Claims is the item the product exists for, and it has a heading of its own rather than fourth place in a strip that scrolls.
Components and tabs
The component set, in brainlyy/ui/static/app.css:
.side .side__ws .side__mark .side__nav .side__group .side__foot
.side__user .side__avatar .side__signout · .nav__item[aria-current] ·
.pagehead + __eyebrow / __title / __sub · .stats .stat .stat__n ·
.card .card--quiet .label .title .sub · .list .list__row
.list__name .list__act · .btn .btn--primary .btn--quiet · .pill ·
.metrics · .empty · .skeleton · .pal (command palette) · toasts ·
.auth split door + .auth__provider · .start .steps · .foot.
.prov is the provenance badge, VERIFIED / UNVERIFIED / ASSERTED. It is
reserved; nothing else may use that class name.
Design
The information architecture is a persistent rail, a workspace card, grouped navigation with a left-accent active state, a per-page head band, stat rows, and a status foot.
Three rules override any reference design:
- Semantic colour is reserved.
--ok,--warn,--err,--infomean claim state and system status only. Page chrome and section accents draw from the category ramp. A test asserts no section chrome resolves to a semantic token. - No navigation item opens onto nothing. Each is gated on a capability that exists, and the machine list is itself part of the navigation.
- Numbering means sequence.
01 / 02 / 03appears only where the steps genuinely must happen in that order.
UI and UX
- Phone first. Built at 390px; the rail becomes a drawer below 900px. Every screen is verified at 390 and 1280, in both themes.
- Every screen has four states: loading (a skeleton, not the word "Loading…"), empty (teaches the next action, never reports a zero), error (says what happened and offers a way out), populated.
- Expected states are not errors. A machine that is off gets MACHINE OFFLINE, not "This screen broke". A missing capability is absent, with the one step that turns it on.
- Nothing critical depends on JavaScript. Sign-in is a real link upgraded to a panel; tabs are query parameters. This is the one control whose failure costs somebody the ability to get in at all.
- Keyboard:
/focuses search,⌘Kopens the palette,?lists shortcuts, Esc closes any overlay, focus is trapped in a panel and returns to its trigger on close. - Motion honours
prefers-reduced-motion.
CSS
Vanilla, no build step, because the first claim is "runs on Python alone" and a
dashboard that needs npm makes that false. Two files, served by both the local
server and the plane: theme.css (tokens) and app.css (components).
Tokens are defined on :root, redefined under
@media (prefers-color-scheme: dark) :root:not([data-theme="light"]), and
again under :root[data-theme="dark"], so an explicit choice wins in both
directions.
| Group | Tokens |
|---|---|
| Ground | --bg --surface --surface-2 |
| Line | --border --border-strong |
| Text | --text --muted --faint |
| Action | --link --btn-primary-bg --btn-primary-text |
| Semantic | --ok --warn --err --info, claim state only |
| Category | --cat-1 --cat-4 --cat-7, decoration, graph communities |
| Shape | --radius-card --radius-ctl --radius-pill --shadow |
| Metric | --font --mono --header-h --page-max --tap |
Every colour comes from a token, never a literal. Both themes are defined for
every token, asserted by a test. A tinted wash is drawn on a pseudo-element
with opacity rather than color-mix(), so older browsers render it the same.
MCP
Native tools, read, loopback or relayed:
| Tool | Does |
|---|---|
search_notes(question, limit) |
Retrieval over the vault, returns excerpts |
ask_fast(prompt) |
The fast local model |
ask_licensed(prompt) |
The permissively licensed model, for commercial work |
code_search(repo, mode, target) |
Call and import graph queries |
Native tools, write, loopback only, never relayed unless
ui.remote_writes is on: post_message, run_agent, agent_status,
rate_answer.
The gateway exposes all of the above for every attached machine, plus every connected third-party server, through one endpoint:
claude mcp add --transport http --scope user brainlyy \
https://app.brainlyy.xyz/mcp --header "Authorization: Bearer <account token>"
It also accepts X-Auth-Token, because a hosted assistant's connector sends
its own bearer alongside custom headers and Authorization is not reliably
ours on that path.
Hub rules: tools are namespaced (clickup.create_task); a name may never
shadow a native tool; third-party output is untrusted input and can never be
treated as an instruction; no chain of tool calls may reach a write tool;
each server is classified read or write at connect time; one hung server cannot
stall the rest; every call gets an audit line; every answer carries its origin.
API
Machine (:8780, bearer token; the relay forwards these verbatim):
| Endpoint | Returns |
|---|---|
GET /api/status |
tier, capabilities, counts, bind, paired, writes_enabled |
GET /api/notes |
the vault index |
GET /api/notes/{path} |
one note, raw |
GET /api/search?q= |
search results |
GET /api/graph |
repositories, nodes, edges |
GET /api/agents |
agent profiles |
GET /api/evidence |
the hash-chained log, and whether it verifies |
GET /api/checks |
the check registry, with last result |
POST /api/ask |
an answer with its sources, or an abstention |
POST /api/verify |
re-run the checks now |
POST /api/claims, PUT/DELETE /api/claims/{path} |
write a claim |
POST /api/checks, DELETE /api/checks/{name} |
write a check |
GET/POST /api/setup |
the first-run wizard |
/mcp |
Streamable HTTP, bearer only, never cookie |
Control plane: /login /signup /auth/callback /logout · /
/account /machines · /api/pair · /relay/poll /relay/reply ·
/m/{id} and /m/{id}/api/… · /mcp · /healthz.
Platform and device
| Support | |
|---|---|
| Machines | Windows 11, macOS, Ubuntu, install, autostart, pair |
| Python | 3.10+, standard library only for the core claim |
| Browsers | Chrome, Firefox, Edge, Safari, iOS Safari |
| Widths | 390 phone · 900 the rail appears · 1280 desktop |
| Themes | system, light, dark, a three-way control, not a toggle |
| Assistants | Claude Code, Claude Desktop, the claude.ai connector, Cursor |
| Network | Machines dial out only; no inbound port, no public address |
How to set up
As a user:
1. brainlyy.xyz → Sign in → Google or GitHub
2. Add a machine → copy the code
3. On that machine, one line:
Windows $env:BRAINLYY_CODE="CODE"; irm https://get.brainlyy.xyz/install.ps1 | iex
macOS/Linux curl -fsSL https://get.brainlyy.xyz/install.sh | sh -s -- CODE
4. Connect the assistant, once, on any device:
claude mcp add --transport http --scope user brainlyy \
https://app.brainlyy.xyz/mcp --header "Authorization: Bearer <token>"
Nothing else is typed. The agent attaches what the machine has.
As the operator: deploy/deploy.sh <host> ships the plane and the UI;
environment at /etc/brainlyy-plane.env; nightly backup and liveness timers;
deploy/restore.sh for the drill. The identity provider's application is named
Brainlyy, and its allowed logout URL includes the application origin.
Instruction
Rules this project holds itself to, which are not negotiable per task:
- A bug gets a failing test first, then the fix. A test that asserts broken behaviour is worse than no test.
- Look at it. Verify at real viewports over the DevTools protocol;
--window-sizedoes not set the layout viewport on every platform. - Local green is not live green. Assert the property that was violated, not the symptom: that the client identifies itself, that the deploy carries every file the server opens.
- State what a test does not prove. A run against a stubbed identity provider says so in its output.
- No credential in configuration, ever. Secrets live in files; configuration is committable.
How you know it is finished
- One
claude mcp addon a machine that has never heard of a private network reaches every capability of every attached machine. - A stranger signs up, runs one line, and their vault, models and repository graphs appear as capabilities without editing a file.
- Revoking a token in the dashboard kills access immediately.
- A third-party MCP server is connected from the catalogue with no JSON edited and no restart, and its answers are labelled with its name.
- No third-party tool can reach a write tool, proven by a test.
- The plane's database, read as raw bytes after a full session, contains no note text.
- Every document in the repository agrees with this one.