Documentation · v0.2

Build a brain, and keep it true.

Everything from an empty folder to a knowledge graph Claude can query — the commands, the flags, what each one actually writes to disk, and what to do when a step fails quietly.

New here? Read what brainiphy is, then work through the quickstart. Looking for a specific flag? Jump to the command reference. Something not working? Troubleshooting covers the failures that are quiet rather than loud.

What brainiphy is

Everything a business knows is spread across systems that do not talk to each other: proposals in a Drive folder, contacts and deals in a CRM, last year's numbers in a spreadsheet, meeting notes in somebody's Documents. Ask Claude about any of it and it has no idea. The information exists — it just is not anywhere Claude can reach.

brainiphy builds that reachable place, once per client. You point it at your folders and systems; it pulls everything in, indexes it into a knowledge graph, and wires that graph into Claude. It then keeps itself current in the background.

Four stages, left to right

Sources feed connector scripts, which write normalized Markdown into raw/; graphify indexes that into graph.json; Claude Code and Claude Desktop read the graph.
Your sources stay where they are. A script per source normalizes them. graphify turns that into a graph. Claude reads the graph.
StageWhat happensWho does it
Your sourcesNothing is moved and nothing is uploaded. You tell brainiphy where to look — a folder on this Mac, an API base URL, a CRM sub-account.You, once
A connector per sourceOne script per system, pulling records out and writing them all as plain Markdown into raw/. For a folder or a preset it is written for you.brain new-connector
The graphgraphify indexes the normalized files into graphify-out/graph.json — the people, companies, deals and documents, and how they connect.brain sync
Claude reads itClaude Code works out of the box. Claude Desktop is one extra flag.brain connect-claude

The difference the third stage makes is the difference between a folder full of files and something that can answer which clients did we quote in March and never hear back from.

What you will need

  • A Mac. Scheduling uses macOS's own launchd, and credentials live in the macOS Keychain. These are the two reasons there is no Linux or Windows build.
  • Python 3.9 or newer — already present on almost every Mac.
  • Nothing else. The installer brings in graphify and the two Python libraries it needs.

A model is needed to index documents, but not necessarily an API key — see indexing, models and cost.

Install

One command. It sets everything up in its own isolated folder, so it cannot disturb anything else on your Mac, and reports at the end whether it found what it needs.

$ curl -fsSL https://raw.githubusercontent.com/rvst312/brainiphy/main/install.sh | bash

Then:

$ brain

Look before you leap

Reasonable, for anything piped into bash. Download it and have it tell you what it would do:

$ curl -fsSL https://raw.githubusercontent.com/rvst312/brainiphy/main/install.sh -o install.sh
$ bash install.sh --dry-run

Outside its own folder the installer touches exactly three things: two shortcuts in ~/.local/bin, a marked block in your shell profile (backed up first), and a link that registers it with Claude Code.

Installer options

FlagEffect
--prefix DIRWhere to put the files. Default ~/.claude/skills/brainiphy.
--python BINWhich Python to build with. Default: the newest python3 ≥ 3.9.
--no-graphifySkip the graphify engine.
--no-pathDon't touch the shell profile.
--no-skillDon't register it with Claude Code.
--uninstallRemove everything it installed.
--dry-runPrint what would happen and change nothing.

Installing from a clone, for working on brainiphy itself or on a fork:

$ git clone https://github.com/rvst312/brainiphy.git
$ bash brainiphy/install.sh --prefix "$PWD/brainiphy"

Uninstalling

$ bash install.sh --uninstall

Removes the virtualenv, the two shortcuts, the marked block in your shell profile and the skill link. Your brains are your own folders and are left alone.

Quickstart

A complete brain for one client, from an empty folder to a graph Claude can query. This walks the seven steps by hand so you can see what each one does; in practice brain on its own runs the same sequence and tells you which step you are on.

1. Create the brain

brain init prepares an ordinary folder to receive connectors. It is safe to re-run: it never overwrites an existing registry.

$ mkdir -p ~/clients/acme
$ brain init ~/clients/acme

That writes connectors/registry.yaml and connectors/state/, adds the generated output directories to .gitignore, and adds connectors/ to .graphifyignore so your connector scripts are never indexed as content.

2. Add a source you already have

The cheapest source is a folder on this Mac — including a synced Drive or Dropbox folder. It is generated complete and works on the next sync.

$ brain new-connector ~/clients/acme docs --mirror ~/Dropbox/acme

3. Add a source that needs a credential

For a system with a preset, you supply an account id and a token — no code. Run brain presets to see what ships today and what each one needs.

$ brain new-connector ~/clients/acme crm --preset gohighlevel --var LOCATION_ID=abc123
$ brain secret set graphify-acme-crm

The secret prompt is hidden as you type. The credential goes into the macOS Keychain and nowhere else — never into registry.yaml, never into a command argument.

4. Check where you are

brain guide reads the project and works out which steps are done, what is missing from the pending ones, and the exact next command. It only reads, so it is safe to run anywhere.

brain guide ~/clients/acme
sample output
4/7 done   ✓ done  ▸ next  ○ pending  – n/a

 ✓ 1  Install graphify
 ✓ 2  Scaffold the project
 ✓ 3  Add data sources
 ▸ 4  Finish the custom connectors
       not runnable yet: hubspot (needs code)
       write the fetching for anything generated from a stub, and fill in the
       account details a preset needs
       $EDITOR ~/clients/acme/connectors/hubspot/sync.py
 ✓ 5  Run the first sync
 ○ 6  Connect it to Claude
       not connected yet
       brain connect-claude ~/clients/acme --desktop --trust-desktop
 ○ 7  Keep it in sync
       not scheduled — sync is manual for now
       brain schedule ~/clients/acme --interval-minutes 15 --load

↳ next step:
    $EDITOR ~/clients/acme/connectors/hubspot/sync.py

Steps can be done out of order, which is why 5 is ticked while 4 is not. A brain you set up six months ago usually only needs “add one more source”, and walking it through all seven to get there would be silly.

5. First sync

This pulls every source in and indexes it. The first build is always a full one, and it is the slow one — later syncs only run what is due.

$ brain sync ~/clients/acme

It prints ran=[...] skipped=[...] errors=[...] graph_rebuilt=<bool> and exits non-zero if any connector failed, so it drops straight into a script or a CI job.

6. Wire it into Claude

$ brain connect-claude ~/clients/acme

That connects Claude Code. Add --desktop to also register the graph with Claude Desktop, and restart Desktop afterwards to pick it up.

7. Stop thinking about it

$ brain schedule ~/clients/acme --interval-minutes 15 --load

macOS now re-runs the sync on its own, whether or not a terminal is open. Logs land in connectors/logs/.

Vocabulary

Seven words do most of the work in this documentation, and in the CLI's own output. They are used consistently and mean exactly this.

brain
One business or client's knowledge base. An ordinary folder you can back up, copy to another Mac or delete. There is no account and no server behind it.
source
A system that feeds a brain — a folder on this Mac, a CRM sub-account, a REST API, a public page.
connector
The script that pulls one source in and writes it out as normalized Markdown. One per source, living at connectors/<name>/sync.py in your own project.
preset
A connector brainiphy already ships finished for a known system. You supply an account id and a credential; there is no code to write.
graph
What graphify builds from the normalized files: the people, companies, deals and documents, and the edges between them. It lives at graphify-out/graph.json.
sync
One run of the connectors whose interval has elapsed, plus a graph rebuild if any of them actually ran.
step
One of the seven items on a brain's setup checklist.
skill
The Claude Code skill brainiphy installs, which lets Claude run the same seven-step playbook on your behalf.

The seven steps

A checklist, not a wizard. brain re-reads the folder every time it draws, so it always knows which steps are already done and puts you on the one you are actually on. You can jump around.

The brains list in a terminal: each brain with its setup progress, source count, graph size and last sync time.
Every brain on this machine, how far along each one is, how much is in it, and when it last updated. Nothing on that screen is cached — each line is read off the brain as it is drawn, so it can't tell you a brain is current when it isn't.
The seven-step checklist in a terminal, with completed steps ticked and the cursor on the next one.
Press to run the step you’re on. You can also jump: a new brain wants the sequence, but a brain you set up six months ago just needs “add one more source”, and walking it through all seven to get there would be silly.
  1. 1

    Install graphify

    The engine that turns the collected files into a graph. The installer does this for you.

  2. 2

    Scaffold the project

    Creates registry.yaml, .gitignore and .graphifyignore, so the connector scripts are never indexed as content.

  3. 3

    Add data sources

    One connector per system that feeds the brain: a folder, a URL, a CRM, an API.

  4. 4

    Finish the custom connectors

    Write the fetching for anything generated from a stub, and fill in the account details a preset needs.

  5. 5

    Run the first sync

    Pull every source in and index it into a graph.

  6. 6

    Connect it to Claude

    So Claude Code, and optionally Claude Desktop, can query the graph.

  7. 7

    Keep it in sync

    A LaunchAgent that re-runs brain sync on its own, whether or not a terminal is open.

brain guide prints the same seven steps as text, works out which are done, and gives the exact command for the next one — see step 4 of the quickstart.

A brain on disk

A brain is an ordinary folder. This is everything brain puts in it — nothing is hidden anywhere else on the system except the credentials, which are in the Keychain.

~/clients/acme
connectors/
├── registry.yaml         # which connectors exist + their type and interval
├── <name>/sync.py        # one script per data source
├── state/<name>.json     # last-run timestamps, drives interval checks
└── logs/                 # LaunchAgent stdout/stderr
raw/<name>/               # connector output — normalized Markdown
graphify-out/graph.json   # the built graph
.graphifyignore           # excludes connectors/ from indexing
.gitignore

registry.yaml is meant to be readable and is safe to edit by hand — a malformed entry is skipped rather than taking down the whole sync. Everything under state/, logs/, raw/ and graphify-out/ is generated and gitignored.

Adding data sources

Five kinds of source, and each one tells you upfront whether it leaves you with homework — before you pick. Add as many as you like, each with its own polling interval.

SourceWhen your data isWhat is left for youFlag
local folderA folder on this Mac, including a synced Drive or Dropbox folder.ready to run--mirror <folder>
presetA system brainiphy already ships a finished connector for.ready to run--preset <name>
http apiAny REST API with no preset.needs code--api <base-url>
urlA public web page. Fetched once by graphify, not a live source.one-offgraphify add <url>
customA database, a local export, anything else.needs code(no flag)

A local folder

Generated complete with rsync -a --delete, so a file removed at the source disappears from the brain instead of lingering as a stale node.

$ brain new-connector ~/clients/acme docs --mirror ~/Dropbox/acme

It copies rather than symlinks, because graphify does not follow symlinks and a linked folder would simply never be indexed. It also converts the file types graphify cannot read — CSV, JSON — into one Markdown record per row, and names anything still unreadable in its summary rather than leaving it silently out of the graph.

A preset

The preset that ships today is GoHighLevel / LeadConnector — contacts, opportunities, pipelines, conversations, calendars, users and forms from one sub-account. Adding another preset is dropping a file into the package and registering it, which is the point: presets are the fast path, not the boundary.

$ brain presets
$ brain new-connector ~/clients/acme crm --preset gohighlevel --var LOCATION_ID=abc123

A REST API

Reach for --api before the bare template for anything REST. A connector that hand-rolls urllib re-introduces the four bugs the shipped HTTP client exists to prevent: a banned default user-agent, a second unguarded fetch for the next page, no retry on transient faults, and a missing scope reported as an auth failure.

$ brain new-connector ~/clients/acme billing --api https://api.example.com

What is left is one collect_* function per kind of object. Before you write any of them, probe the generated connector against the live API: it reports which objects your credential can actually read and writes nothing. That is the fastest way to find out whether a token has the scopes you assumed.

A public URL

A one-off, not a live source — graphify fetches it once. No connector is involved.

$ graphify add https://example.com/handbook
$ brain sync ~/clients/acme --full

Writing a connector

brain new-connector generates a script that already satisfies the contract. In most cases you only fill in fetch_records().

connectors/hubspot/sync.py
SOURCE_SYSTEM = "hubspot"

def fetch_records() -> list[dict]:
    token = get_secret("graphify-acme-hubspot")
    req = urllib.request.Request(
        "https://api.example.com/v3/records",
        headers={"Authorization": f"Bearer {token}"},
    )
    with urllib.request.urlopen(req, timeout=30) as resp:
        data = json.load(resp)
    return [
        {"id": r["id"], "title": r["name"], "body": r["notes"]}
        for r in data["results"]
    ]

Each record needs id, title and body; any other keys are written into the Markdown frontmatter. The template's main() handles --out, normalization and stable file naming.

The contract

If you ever write one from scratch, this is all it has to do:

  • Accept --out <dir> and write normalized Markdown there via frontmatter.write_record().
  • Name files by a stable slug of the remote record ID, so re-runs overwrite in place instead of piling up a second copy of everything as new graph nodes.
  • Exit 0 on success and non-zero on failure, with a human-readable summary on stdout.
  • Read credentials only through keychain.get_secret() — never as a CLI argument and never hardcoded, since shell history, process listings and launchd logs would all leak them.

Nothing in the orchestrator branches on what kind of connector a script is. At run time every connector is just an executable that satisfies the contract above, which is why supporting a new kind of source means writing a script and never extending brainiphy.

Choosing an approach, cheapest first

If the source isDo thisCode you write
A local folder already on disk--mirror <folder>none
Content reachable by public URLgraphify add <url>none
A system Claude already has an MCP connector forCall that from the generated sync.py rather than building fresh auth.a little
A REST API--api <base-url>one collect_* per object
Anything else — a database, a local exportThe bare template.one fetch_records()

Syncing and scheduling

Each source says how often it should be checked. brain sync runs the ones that are due — tracked in connectors/state/<name>.json — and rebuilds the graph only if one of them actually ran. So running it often is cheap.

$ brain sync ~/clients/acme             # just what's due
$ brain sync ~/clients/acme --dry-run   # what would run, touching nothing
$ brain sync ~/clients/acme --full      # re-read and re-index everything

Two rebuild passes, and picking the wrong one silently does nothing

brain sync picks for you. This table matters when you script around it instead.

PassIndexesNeeds a modelWhen brain uses it
graphify extractdocuments and codeyes, for documentsfirst build, and every --full
graphify updatecode only (local AST)noevery later manual run

Letting macOS do it

$ brain schedule ~/clients/acme --interval-minutes 15 --load

Writes a LaunchAgent at ~/Library/LaunchAgents/com.graphify.sync.<slug>.plist. Without --load it only writes the plist and prints the launchctl bootstrap command. It refuses to run if the project has no registered connectors — scheduling a sync loop with nothing to sync is a silent no-op that is confusing to debug later.

Indexing, models and cost

Indexing code is a local AST pass with no model involved. Indexing documents — the proposals, the notes, the CRM records — needs one. That does not mean it needs a new bill.

brain sync chooses a backend in this order:

  1. 1--backend <name>, if you pass one.
  2. 2Whichever API key is in the environment — ANTHROPIC_API_KEY, GEMINI_API_KEY, OPENAI_API_KEY, and so on.
  3. 3Your Claude Code subscription, when neither is set and the claude CLI is installed. graphify shells out to claude -p, so indexing is billed to your Pro or Max plan instead of pay-as-you-go API credit.
$ brain sync ~/clients/acme --full --backend claude-cli   # force the subscription
$ export GRAPHIFY_CLAUDE_CLI_MODEL=haiku                  # faster and lighter than the Opus default

The subscription backend runs one chunk at a time, so a large first sync is slower than an API key would be. A local model works too: --backend ollama.

Connecting Claude

$ brain connect-claude ~/clients/acme                    # Claude Code
$ brain connect-claude ~/clients/acme --desktop         # ...and Claude Desktop
FlagEffect
(none)Connects Claude Code via CLAUDE.md and hooks. The low-risk default.
--desktopAlso registers a graphify-mcp MCP server in claude_desktop_config.json, pointed at this project's graph.json.
--trust-desktopAppends the project to localAgentModeTrustedFolders. Additive — existing entries are never replaced.

claude_desktop_config.json is backed up to .bak-<timestamp> before any edit. Restart Claude Desktop to pick up the change.

Credentials

Connector credentials live in the macOS Keychain — the same place Safari keeps your logins — and only there. Connectors read them at run time.

$ brain secret set graphify-acme-hubspot   # prompts, hidden as you type
$ brain secret get graphify-acme-hubspot   # debugging only; prints bare, for piping

A secret never reaches registry.yaml, a CLI argument, or shell history. Process arguments are readable by anything running as the same user for as long as the command runs, and they land in ps output and launchd logs — so the value is written to security's stdin instead of passed as an option.

What else is worth knowing before you review this

  • Your data never leaves the machine. Sources are read locally or pulled from their own APIs, written into a folder you chose, and indexed there. There is no server and no account. The one exception is what you send when a model indexes your documents — the same trust boundary you already accepted by using Claude.
  • Connector scripts are executed. brain sync runs every connectors/<name>/sync.py in the target project. A brain built from an untrusted project directory runs whatever those scripts contain.
  • Content pulled off the web is untrusted text, not instructions. The usual prompt-injection caution applies to anything a connector brings in. Record titles are escaped on the way into YAML and printed without markup interpretation.
  • Removing a brain from the list deletes nothing. brain forget removes the entry and touches nothing inside the folder. Deleting a client's knowledge base for real is rm, deliberately, by a human.
  • The source is the product. Every connector brainiphy generates is a readable Python file in your own project, which you can open, diff and change. Nothing is compiled and nothing is hidden. MIT licensed.

Security issues go to a private advisory, not a public issue.

Command reference

brain on its own covers everything below. These exist for scripts, for automation, and for when you know exactly what you want. Every one of them takes --help. Output is coloured and tabulated at a terminal and plain when piped, so logs stay clean.

brain status output: a table of sources with type, readiness, schedule and record count, then the graph size and setup progress.
brain status answers “is this thing actually working”: every source, whether it can really run, when it next will, how much it has brought in, and how big the graph is. When a source can’t run, the table says which kind of not-ready it is instead of making you open files to find out.

brain

The guided flow, and the front door. Opens on the list of brains this machine knows about; opening one drops you into its checklist. Needs a terminal, because it asks questions — in a script, use the individual commands.

brain new [project]

Start a new brain, skipping the list.

brain list

Every brain on this machine, as text: setup progress, source count, graph size, last sync and location. A folder that has moved or been deleted is reported as missing rather than quietly dropped.

brain add [folder]

Register a brain that already exists — one made before the list did, or one that arrived with a cloned repo. At a terminal, run it with no argument to browse for the folder.

brain forget <folder>

Remove a brain from the list and touch nothing inside it. The connectors, the graph and the mirrored documents all stay. brain add puts the entry back.

brain init [project]

Prepare a folder to receive connectors: creates connectors/registry.yaml and connectors/state/, appends generated output to .gitignore, and appends connectors/ to .graphifyignore. Never overwrites an existing registry, so it is safe to re-run.

brain guide [project]

Print the seven steps, work out from the project on disk which are done, and give the exact next command. Read-only, so it is safe to run anywhere — including from an agent that needs to know where a brain stands.

--verbose
Also show the details of the steps already completed.

brain status [project]

Registered sources — type, whether each can actually run, when it next will, how many records it has pulled in — then the graph size in nodes and edges, and where the setup stands.

brain presets

List the systems brainiphy ships a finished connector for, and the account details each one needs.

brain new-connector <project> <name>

Write connectors/<name>/sync.py and register it in registry.yaml with its type and interval. Existing scripts are never overwritten.

(none)
The generic template. Implement fetch_records(), then register any credential with brain secret set.
--mirror FOLDER
A complete connector that mirrors a local folder with rsync -a --delete. Nothing to implement.
--preset NAME
A finished connector for a system brainiphy already knows. See brain presets.
--api URL
A REST API with no preset. Pagination, retries, backoff and scope handling are already written; you add one collect_* function per object.
--var K=V
Fill a constant in the generated script. Applied last, so it can override a computed default such as SECRET_ITEM.
--interval-minutes N
How often this source is due. Default 60.

brain sync [project]

Run every connector whose interval has elapsed, then rebuild the graph — but only if at least one connector actually ran. Prints ran / skipped / errors / graph_rebuilt and exits non-zero if any connector failed.

--dry-run
Report which connectors are due and whether their scripts exist. Runs nothing.
--full
Force a full re-index and rebuild even if nothing was due. Implied on the first build.
--backend NAME
Force a specific model backend for the indexing pass.

brain view [project]

Open graphify's interactive graph in your browser. If the picture is older than the graph it is redrawn first, which costs no tokens.

brain connect-claude [project]

Wire the graph into Claude.

(none)
Connect Claude Code via CLAUDE.md and hooks. The low-risk default.
--desktop
Also register a graphify-mcp MCP server in claude_desktop_config.json, pointed at this project's graph.json.
--trust-desktop
Append the project to localAgentModeTrustedFolders. Additive — existing entries are never replaced.

brain schedule [project] --interval-minutes N

Generate a LaunchAgent that runs brain sync <project> --full on an interval. Logs land in connectors/logs/. Refuses to run if the project has no registered connectors.

--load
Activate it immediately. Without this it only writes the plist and prints the launchctl command.

brain secret set <item>

Store a connector credential in the macOS Keychain, prompting with hidden input. The write is confirmed by reading it back.

brain secret get <item>

Print a stored credential, bare, for piping. Debugging only.

For the parts that change least often — the exact on-disk layout and the connector contract — see a brain on disk and writing a connector above.

Troubleshooting

These are the failures that are quiet rather than loud — the ones where something reports success and the result is still wrong. Loud errors usually say what they are.

The first sync reports an empty project, or a graph with almost nothing in it.

Why

graphify honours .gitignore, and brain init puts raw/ there so mirrored client material is never committed. Without --no-gitignore, graphify skips the whole corpus.

Fix

Use brain sync, which passes the flag for you. If you are calling graphify extract by hand, add --no-gitignore.

A scheduled brain keeps reporting success, but the graph stops answering new questions.

Why

The incremental graphify update pass indexes code only. A brain made of documents needs the full extract pass.

Fix

The LaunchAgent brain schedule writes already passes --full. If you wrote your own cron entry, add it.

brain view shows a picture that does not match the graph.

Why

graphify extract writes graph.json without redrawing graph.html, so after a full rebuild the picture is the previous one.

Fix

brain view redraws it when it is stale. Run brain view rather than opening graph.html directly.

A source is listed but will not run, and the script is clearly there.

Why

A stub with no fetching written, and a preset missing its account id, are both present on disk and neither can run.

Fix

brain status names which kind of not-ready it is. brain guide gives the exact command to fix it.

A connector authenticates but returns nothing for some objects.

Why

The credential has no scope for those objects. A missing scope can look like an auth failure.

Fix

Probe the generated connector before syncing: it reports which objects the credential can actually read and writes nothing.

A credential reports as saved, then fails on the next unattended run.

Why

macOS security can exit 0 on a write that stored nothing, or that stored a different value.

Fix

brain secret set already reads the value back to confirm it. If you wrote the item another way, re-set it with brain secret set.

brain schedule refuses to run.

Why

The project has no registered connectors.

Fix

Add at least one source first. Scheduling a sync loop with nothing to sync is a silent no-op that is confusing to debug later.

Connector scripts are showing up in the graph as source code.

Why

connectors/ is missing from .graphifyignore — usually because brain init was skipped on a project that already had a registry.yaml.

Fix

Run brain init on the project. It never overwrites an existing registry, so it is safe.

FAQ

What is graphify, and why is it separate?

graphify is the engine that turns a folder of normalized files into a knowledge graph. brainiphy is the layer around it: discovering sources, writing the connectors, keeping them synced, and wiring the result into Claude. Keeping them apart means graphify stays a general graph tool and brainiphy stays replaceable around it. The installer brings graphify in for you.

Why macOS only?

Two hard dependencies: credentials go in the macOS Keychain, and scheduling is a launchd LaunchAgent. Everything else is ordinary Python. Ports are welcome — it is MIT.

My CRM isn't the one preset you ship. Now what?

Then it is a REST API, and --api <base-url> generates a connector with the networking already done. You write one function per kind of record — or ask Claude to, since the skill exists for exactly that. If it is not an API at all, the bare template takes one function that returns records.

Does anything get uploaded?

No. Sources are read locally or from their own APIs and indexed on your machine. The only thing that leaves is what you send when a model indexes your documents — the same trust boundary you already accepted by using Claude.

Will re-syncing duplicate everything?

No. Files are named by a stable slug of each record's remote ID, so a re-sync overwrites in place. Mirrored folders use rsync --delete, so a file removed at the source stops being a node.

Can I hand a brain to a colleague?

Yes — it is a folder. Copy it, and brain add puts it on their list. What does not travel is the credentials, which are in their own Keychain, not in the folder.

Does removing a brain delete my client's data?

No, and this is deliberate. brain forget and the app's d key only remove the entry from the list. The connectors, the mirrored documents and the graph all stay exactly where they are. Deleting them for real is rm.

How do I get rid of brainiphy itself?

bash install.sh --uninstall. It removes the virtualenv, the two shortcuts in ~/.local/bin, the marked block in your shell profile, and the skill link. Your brains are your own folders and are left alone.

Build one for your next client this afternoon.

One brain per business. A folder on your Mac, a handful of scripts you can read, and a graph Claude can query.

$ curl -fsSL https://raw.githubusercontent.com/rvst312/brainiphy/main/install.sh | bash
$ brain