Introduction
brain is a local MCP server that gives Claude, ChatGPT, Cursor and any other AI agent the same memory about you. It runs on your Mac; nothing goes to anyone's cloud.
What brain is
Every AI app keeps its own little memory, and none of them talk to each other. brain is one knowledge base that all of them read and write through MCP, the standard protocol agents use to call tools:
- A vault of Markdown notes — your profile, what agents learned about you, projects, reusable skills and saved web pages.
- Search — hybrid: semantic (by meaning, with embeddings computed locally by Ollama) plus exact keyword (names, IDs, dates).
- A version history — every write is recorded, so anything an agent changes can be undone.
- A dashboard — a local web app to turn services on and off, edit your profile, import memory from other chatbots, connect agents, explore the graph and chat with a local model.
How the pieces fit
Each agent launches its own server.py process and talks to it over stdio. All processes share the same vault, the same history database and one Chroma server, and a file lock keeps concurrent writes safe.
| Piece | What it does | Where |
|---|---|---|
| MCP server | Exposes the tools to your agents | server.py |
| Vault | Markdown with YAML frontmatter | ~/.brain/vault/ |
| History | Previous and new content of every write | data/history.sqlite3 |
| Keyword index | SQLite FTS5 (BM25) over saved text | data/search.sqlite3 |
| Chroma | Vector database, shared HTTP server | 127.0.0.1:8055 |
| Ollama | Embeddings (nomic-embed-text) and the optional chat model | localhost:11434 |
| Dashboard | Local web UI | 127.0.0.1:8765 |
Who it's for
People who use more than one AI tool and are tired of explaining themselves again in each one. You don't need to write code: the installer and the dashboard cover everything. Developers get a plain Markdown vault and MCP tools they can build on.
Introducción
brain es un server MCP local que les da a Claude, ChatGPT, Cursor y cualquier otro agente de IA la misma memoria sobre vos. Corre en tu Mac; nada va a la nube de nadie.
Qué es brain
Cada app de IA guarda su propia memoria, y ninguna habla con las otras. brain es una sola base de conocimiento que todas leen y escriben por MCP, el protocolo estándar con el que los agentes llaman tools:
- Un vault de notas en Markdown: tu perfil, lo que los agentes aprendieron de vos, proyectos, skills reutilizables y páginas web guardadas.
- Búsqueda híbrida: semántica (por significado, con embeddings calculados en tu máquina por Ollama) más por palabra exacta (nombres, IDs, fechas).
- Historial de versiones: cada escritura queda registrada, así que cualquier cambio de un agente se puede deshacer.
- Un dashboard: una web local para prender y apagar servicios, editar tu perfil, importar la memoria de otros chatbots, conectar agentes, explorar el grafo y chatear con un modelo local.
Cómo encajan las piezas
Cada agente lanza su propio proceso de server.py y le habla por stdio. Todos comparten el mismo vault, la misma base de historial y un único server de Chroma, y un lock de archivo hace seguras las escrituras simultáneas.
| Pieza | Qué hace | Dónde |
|---|---|---|
| Server MCP | Expone las tools a tus agentes | server.py |
| Vault | Markdown con frontmatter YAML | ~/.brain/vault/ |
| Historial | Contenido anterior y nuevo de cada escritura | data/history.sqlite3 |
| Índice por palabra | SQLite FTS5 (BM25) sobre el texto guardado | data/search.sqlite3 |
| Chroma | Base vectorial, server HTTP compartido | 127.0.0.1:8055 |
| Ollama | Embeddings (nomic-embed-text) y el modelo de chat opcional | localhost:11434 |
| Dashboard | Interfaz web local | 127.0.0.1:8765 |
Para quién es
Para quien usa más de una herramienta de IA y está cansado de explicarse de nuevo en cada una. No hace falta programar: el instalador y el dashboard cubren todo. Si programás, tenés un vault de Markdown común y tools MCP para construir encima.
Installation
One command on macOS (Apple Silicon or Intel). You need git (xcode-select --install); the installer handles the rest.
curl -fsSL https://raw.githubusercontent.com/Lautaro005/brain/main/install.sh | bash
What the installer does
- Installs uv if it's missing. uv manages Python and the dependencies without touching the system Python.
- Clones brain into
~/.brain(or runsgit pullif it's already there). - Runs
uv syncand installs the headless Chromium used to scrape JavaScript sites. - Installs Ollama with Homebrew if needed and pulls
nomic-embed-text(~270 MB). Without Homebrew it tells you where to download Ollama. - Creates the
braincommand in~/.local/binand adds it to yourPATH.
It's idempotent: running it again updates the install. It never asks for input, because it runs through curl | bash.
Optional: a chat model
The Chat tab, source summaries (abstract) and entity extraction for the graph use a chat model in Ollama. nomic-embed-text only computes embeddings and can't write text. The installer doesn't pull a chat model (it's ~2 GB); get one when you want those features:
ollama pull llama3.2
Or click Download llama3.2 in the Chat tab. Without it, those three features are skipped and everything else works the same.
Installer options
| Variable | Default | What it changes |
|---|---|---|
BRAIN_HOME | ~/.brain | Install folder |
BRAIN_BIN | ~/.local/bin | Where the brain command goes |
BRAIN_REPO | GitHub repo | Where to clone from (useful for testing a local clone) |
BRAIN_BRANCH | main | Branch to install |
curl -fsSL https://raw.githubusercontent.com/Lautaro005/brain/main/install.sh | BRAIN_HOME=~/tools/brain bash
Manual installation
git clone https://github.com/Lautaro005/brain ~/.brain && cd ~/.brain uv sync uv run playwright install chromium ollama pull nomic-embed-text ./brain.sh
Instalación
Un comando en macOS (Apple Silicon o Intel). Hace falta git (xcode-select --install); el instalador se ocupa del resto.
curl -fsSL https://raw.githubusercontent.com/Lautaro005/brain/main/install.sh | bash
Qué hace el instalador
- Instala uv si falta. uv maneja Python y las dependencias sin tocar el Python del sistema.
- Clona brain en
~/.brain(o hacegit pullsi ya estaba). - Corre
uv synce instala el Chromium headless que se usa para scrapear sitios con JavaScript. - Instala Ollama con Homebrew si hace falta y baja
nomic-embed-text(~270 MB). Sin Homebrew, te dice de dónde bajar Ollama. - Crea el comando
brainen~/.local/biny lo agrega a tuPATH.
Es idempotente: correrlo de nuevo actualiza la instalación. Nunca pide nada, porque se ejecuta con curl | bash.
Opcional: un modelo de chat
La pestaña Chat, los resúmenes de fuentes (abstract) y la extracción de entidades para el grafo usan un modelo de chat en Ollama. nomic-embed-text solo calcula embeddings y no puede escribir texto. El instalador no baja un modelo de chat (pesa ~2 GB); bajalo cuando quieras esas funciones:
ollama pull llama3.2
O tocá Descargar llama3.2 en la pestaña Chat. Sin él, esas tres funciones se saltean y todo lo demás anda igual.
Opciones del instalador
| Variable | Por defecto | Qué cambia |
|---|---|---|
BRAIN_HOME | ~/.brain | Carpeta de instalación |
BRAIN_BIN | ~/.local/bin | Dónde va el comando brain |
BRAIN_REPO | el repo de GitHub | De dónde clonar (sirve para probar un clon local) |
BRAIN_BRANCH | main | Rama a instalar |
curl -fsSL https://raw.githubusercontent.com/Lautaro005/brain/main/install.sh | BRAIN_HOME=~/tools/brain bash
Instalación manual
git clone https://github.com/Lautaro005/brain ~/.brain && cd ~/.brain uv sync uv run playwright install chromium ollama pull nomic-embed-text ./brain.sh
Quickstart
From install to an agent that knows you, in four steps.
1. Open the dashboard
brain
It opens http://127.0.0.1:8765 and starts Ollama and Chroma if they aren't running. Keep it open while you use your agents; Ctrl+C closes it and stops only what it started.
2. Connect your agents
Connect agent tab → Connect on Claude Desktop, ChatGPT, Claude Code, Cursor or whichever you use. brain adds its entry to that app's config (with a backup). Restart the app. Details in Connecting agents.
3. Tell it who you are
Profile tab → fill in About you. Then Import memory: pick the chatbot you use today, copy the prompt, paste it in that chatbot, and paste its answer back. You get a preview before anything is saved.
4. Try it
In any connected agent:
What do you know about me according to brain?
Save this URL to brain: https://example.com/some-article
I moved from Palermo to Núñez — update my memory.
The last one uses add_memory with supersede: the old fact isn't deleted, it moves to the history of that memory file with the date. See Memory.
Inicio rápido
De la instalación a un agente que te conoce, en cuatro pasos.
1. Abrí el dashboard
brain
Abre http://127.0.0.1:8765 y prende Ollama y Chroma si no están corriendo. Dejalo abierto mientras usás tus agentes; Ctrl+C lo cierra y apaga solo lo que prendió él.
2. Conectá tus agentes
Pestaña Conectar agente → Conectar en Claude Desktop, ChatGPT, Claude Code, Cursor o el que uses. brain agrega su entrada a la config de esa app (con backup). Reiniciá la app. Detalles en Conectar agentes.
3. Contale quién sos
Pestaña Perfil → completá Sobre vos. Después Importar memoria: elegí el chatbot que usás hoy, copiá el prompt, pegalo en ese chatbot y pegá la respuesta de vuelta. Ves una previsualización antes de guardar nada.
4. Probalo
En cualquier agente conectado:
¿Qué sabés de mí según brain?
Guardá esta URL en brain: https://example.com/un-articulo
Me mudé de Palermo a Núñez: actualizá mi memoria.
La última usa add_memory con supersede: el hecho viejo no se borra, pasa al historial de ese archivo de memoria con la fecha. Ver Memoria.
The vault
Plain Markdown files with YAML frontmatter in ~/.brain/vault/. It's created from a template the first time brain starts.
Layout
| Path | What goes there |
|---|---|
BRAIN.md | A short index agents read first. Not content: just where each thing is. |
profile.md | Your profile (name, headline, about you). |
memory/ | One file per category ("Work", "Preferences"…), one fact per bullet. |
projects/ | Notes about your projects. |
skills/ | Reusable instructions agents can load with get_skill. |
knowledge/sources/ | The full text of every saved URL. |
knowledge/connections/, knowledge/composio/ | Results captured from your connections. |
Frontmatter
Every note starts with a YAML block. name and description are expected; the description is what list_vault and the graph show.
--- name: online-store description: Next.js store, launch at the end of the month tags: [work, nextjs] related: [pricing-that-converts] --- # Online store Uses the ideas from [[pricing-that-converts]].
Fields brain writes on its own: chroma_ids (chunk ids of a source), abstract (summary of long sources), entities (names mentioned, for the graph), url, scraped_at, and in memory files category, sources and related.
Linking notes
[[name]]in the text links to another note.tags: [a, b]groups notes under shared tag nodes.related: [name]relates notes without a link in the text.
Frontmatter validation
Every write checks the YAML. If an agent writes something that breaks it (usually an unquoted : in a description), brain quotes the value automatically. If it can't be repaired, the write is rejected with a clear error. Use set_frontmatter to change metadata without rewriting the note.
Path safety
Tools reject empty and absolute paths, .., hidden files and symlinks that point outside the vault. Agents can't read or write anything else on your disk through brain.
El vault
Archivos Markdown comunes con frontmatter YAML en ~/.brain/vault/. Se crea desde una plantilla la primera vez que arranca brain.
Estructura
| Path | Qué va ahí |
|---|---|
BRAIN.md | Un índice corto que los agentes leen primero. No es contenido: solo dónde está cada cosa. |
profile.md | Tu perfil (nombre, en una línea, sobre vos). |
memory/ | Un archivo por categoría ("Trabajo", "Preferencias"…), un hecho por viñeta. |
projects/ | Notas sobre tus proyectos. |
skills/ | Instrucciones reutilizables que los agentes cargan con get_skill. |
knowledge/sources/ | El texto completo de cada URL guardada. |
knowledge/connections/, knowledge/composio/ | Resultados capturados de tus conexiones. |
Frontmatter
Cada nota empieza con un bloque YAML. Se esperan name y description; la description es lo que muestran list_vault y el grafo.
--- name: tienda-online description: Tienda en Next.js, lanzamiento a fin de mes tags: [trabajo, nextjs] related: [precios-que-convierten] --- # Tienda online Usa las ideas de [[precios-que-convierten]].
Campos que escribe brain solo: chroma_ids (ids de los chunks de una fuente), abstract (resumen de fuentes largas), entities (nombres mencionados, para el grafo), url, scraped_at, y en los archivos de memoria category, sources y related.
Relacionar notas
[[nombre]]en el texto enlaza otra nota.tags: [a, b]agrupa notas bajo nodos de tag compartidos.related: [nombre]relaciona notas sin un link en el texto.
Validación del frontmatter
Cada escritura revisa el YAML. Si un agente escribe algo que lo rompe (típicamente un : sin comillas en una description), brain pone el valor entre comillas solo. Si no se puede reparar, la escritura se rechaza con un error claro. Usá set_frontmatter para cambiar metadatos sin reescribir la nota.
Seguridad de paths
Las tools rechazan paths vacíos o absolutos, .., archivos ocultos y symlinks que salgan del vault. Los agentes no pueden leer ni escribir nada más de tu disco a través de brain.
Memory
What your agents know about you: a profile you write, plus facts imported from other chatbots or saved by agents as they learn them. Facts are dated, and when one changes the old version is kept.
Profile
profile.md holds your name, a one-line headline and a free "about me". Edit it in the Profile tab. Agents are told to read it first.
Memory files
Each category is one file in memory/ with one fact per bullet. Every active fact carries the date it was saved, as an HTML comment at the end of the line (invisible when reading the note):
--- name: about-me description: Memoria · About me (2) category: About me sources: [chatgpt, claude] related: [online-store] entities: [Palermo, Next.js] --- # About me - Lives in Núñez <!-- since:2026-09-28 --> - Building an online store in Next.js <!-- since:2026-09-20 --> ## Historial - Lives in Palermo (since 2026-03-02, superado el 2026-09-28, ver: "Lives in Núñez")
If a fact names one of your projects, skills or sources, the category is related to it automatically (related) and shows up connected in the graph.
Saving facts: add_memory
Agents call add_memory(fact, category?) whenever they learn something durable about you. Duplicates are ignored (comparison ignores case, accents and punctuation).
When a fact changes: supersede
If the new fact replaces an old one (you moved, changed jobs, switched tools), the agent passes the old text in supersede:
add_memory("Lives in Núñez", "About me", supersede="Lives in Palermo")
- The old fact isn't deleted: it moves to a
## Historialsection at the end of its file, with the date it stopped being true and what replaced it. - The match is the same as the duplicate check; if there's no exact match, a fact that contains the text (or is contained in it) is used when there's exactly one. It looks in the same category first, then in the others.
- If nothing matches, the new fact is saved anyway and the answer includes a warning.
- Agents only see active facts when they read your memory; the history stays in the file (
read_file) and inmemory_history(category).
Importing from other chatbots
Profile tab → Import memory. Pick Claude, ChatGPT, Gemini or other, copy the prompt (it asks the chatbot for everything it remembers, grouped as ## Category / - fact) and paste the answer. The parser also accepts plain lists, bold labels, numbered lists and JSON, strips date prefixes and drops the chatbot's intro line. You can remove items in the preview before importing.
Memoria
Lo que tus agentes saben de vos: un perfil que escribís vos, más hechos importados de otros chatbots o guardados por los agentes a medida que los aprenden. Los hechos llevan fecha, y cuando uno cambia se conserva la versión vieja.
Perfil
profile.md guarda tu nombre, una línea que te describe y un "sobre mí" libre. Se edita en la pestaña Perfil. Los agentes tienen la instrucción de leerlo primero.
Archivos de memoria
Cada categoría es un archivo en memory/ con un hecho por viñeta. Cada hecho activo lleva la fecha en que se guardó, como comentario HTML al final de la línea (no se ve al leer la nota):
--- name: sobre-mi description: Memoria · Sobre mí (2) category: Sobre mí sources: [chatgpt, claude] related: [tienda-online] entities: [Palermo, Next.js] --- # Sobre mí - Vive en Núñez <!-- since:2026-09-28 --> - Está armando una tienda online en Next.js <!-- since:2026-09-20 --> ## Historial - Vive en Palermo (desde 2026-03-02, superado el 2026-09-28, ver: "Vive en Núñez")
Si un hecho nombra uno de tus proyectos, skills o fuentes, la categoría queda relacionada sola (related) y aparece conectada en el grafo.
Guardar hechos: add_memory
Los agentes llaman a add_memory(fact, category?) cuando aprenden algo duradero sobre vos. Los duplicados se ignoran (la comparación no distingue mayúsculas, acentos ni puntuación).
Cuando un hecho cambia: supersede
Si el hecho nuevo reemplaza a uno viejo (te mudaste, cambiaste de trabajo o de herramienta), el agente pasa el texto viejo en supersede:
add_memory("Vive en Núñez", "Sobre mí", supersede="Vive en Palermo")
- El hecho viejo no se borra: pasa a una sección
## Historialal final de su archivo, con la fecha en que dejó de valer y qué lo reemplazó. - La coincidencia es la misma que la de los duplicados; si no hay una exacta, se usa el único hecho que contiene el texto (o está contenido en él). Busca primero en la misma categoría y después en las demás.
- Si no coincide nada, el hecho nuevo se guarda igual y la respuesta trae un aviso.
- Al leer tu memoria, los agentes ven solo los hechos activos; el historial queda en el archivo (
read_file) y enmemory_history(category).
Importar de otros chatbots
Pestaña Perfil → Importar memoria. Elegí Claude, ChatGPT, Gemini u otro, copiá el prompt (le pide al chatbot todo lo que recuerda, agrupado como ## Categoría / - dato) y pegá la respuesta. El parser también acepta listas planas, etiquetas en negrita, listas numeradas y JSON, saca prefijos de fecha y descarta la línea de introducción del chatbot. En la previsualización podés sacar ítems antes de importar.
Saving and search
Save any web page, then find it by meaning or by exact words. Search is hybrid: semantic and keyword results are merged into one list.
Saving a URL
save_url(url, render_js?), or the Knowledge tab:
- trafilatura downloads the page and extracts clean text.
- If it gets fewer than 30 words (typical of JavaScript-built sites) or the download fails, the page is rendered in headless Chromium with Playwright and extracted again.
render_js=Truegoes straight to Chromium. - The text is split into ~500-word chunks with a 50-word overlap.
- Each chunk is embedded with Ollama (
nomic-embed-text) and stored in Chroma, and also written to the keyword index. - If a chat model is installed: pages over 800 words get a short
abstract, and the names they mention go toentities. knowledge/sources/<slug>.mdis written with the full text. Saving the same URL again updates it instead of duplicating it.
How search works
search_knowledge(query, top_k?) runs two searches and fuses them:
| Search | Good at | Engine |
|---|---|---|
| Semantic | Topics and paraphrases: "how to price a product" finds "pricing that converts" | Chroma + Ollama embeddings |
| Keyword | Proper names, IDs, numbers, dates, error codes | SQLite FTS5 with BM25 (data/search.sqlite3) |
Each side returns 3× top_k candidates, and they're merged with reciprocal rank fusion: every chunk scores Σ 1 / (60 + rank) over the lists it appears in. Chunks found by both rise to the top.
Each result has text, url, source_md_path, score (semantic similarity 0–1, or null if only the keyword search found it) and match (both, semantic or keyword). The keyword index ignores case and accents: "nunez" finds "Núñez".
When something is down
If Chroma or Ollama isn't running, keyword search keeps working and the answer includes a note saying semantic search wasn't available. It only fails if both are unavailable.
Rebuilding the keyword index
Sources saved before v0.02.5 aren't in the keyword index. Run reindex_keyword_search() (or Rebuild keyword index in the Knowledge tab): it rebuilds the index from the .md files in knowledge/ without scraping or embedding anything again.
Summaries
list_sources() returns each source's abstract, so an agent can decide whether a long page is worth reading in full. Summaries are best-effort: if Ollama doesn't answer, the source is saved without one.
Guardar y buscar
Guardá cualquier página web y después encontrala por significado o por palabras exactas. La búsqueda es híbrida: los resultados semánticos y por palabra se juntan en una sola lista.
Guardar una URL
save_url(url, render_js?), o la pestaña Conocimiento:
- trafilatura baja la página y extrae el texto limpio.
- Si saca menos de 30 palabras (típico de sitios hechos con JavaScript) o falla la descarga, la página se renderiza en Chromium headless con Playwright y se extrae de nuevo.
render_js=Trueva directo a Chromium. - El texto se parte en chunks de ~500 palabras con 50 de solapamiento.
- Cada chunk se embebe con Ollama (
nomic-embed-text) y se guarda en Chroma, y también en el índice por palabra. - Si hay un modelo de chat instalado: las páginas de más de 800 palabras llevan un
abstractcorto, y los nombres que mencionan van aentities. - Se escribe
knowledge/sources/<slug>.mdcon el texto completo. Guardar la misma URL de nuevo la actualiza en vez de duplicarla.
Cómo funciona la búsqueda
search_knowledge(query, top_k?) corre dos búsquedas y las fusiona:
| Búsqueda | Sirve para | Motor |
|---|---|---|
| Semántica | Temas y paráfrasis: "cómo ponerle precio a un producto" encuentra "precios que convierten" | Chroma + embeddings de Ollama |
| Por palabra | Nombres propios, IDs, números, fechas, códigos de error | SQLite FTS5 con BM25 (data/search.sqlite3) |
Cada lado devuelve 3× top_k candidatos, y se fusionan con reciprocal rank fusion: cada chunk suma Σ 1 / (60 + posición) en las listas donde aparece. Los que encuentran las dos suben arriba.
Cada resultado trae text, url, source_md_path, score (similitud semántica 0–1, o null si solo lo encontró la búsqueda por palabra) y match (both, semantic o keyword). El índice por palabra ignora mayúsculas y acentos: "nunez" encuentra "Núñez".
Cuando algo está caído
Si Chroma u Ollama no están corriendo, la búsqueda por palabra sigue funcionando y la respuesta trae una nota que avisa que la semántica no estaba disponible. Solo falla si no está ninguna de las dos.
Reconstruir el índice por palabra
Las fuentes guardadas antes de v0.02.5 no están en el índice por palabra. Corré reindex_keyword_search() (o Reindexar búsqueda por palabra en Conocimiento): reconstruye el índice desde los .md de knowledge/ sin volver a scrapear ni embeber nada.
Resúmenes
list_sources() devuelve el abstract de cada fuente, así un agente decide si vale la pena leer entera una página larga. Los resúmenes son best-effort: si Ollama no responde, la fuente se guarda sin él.
The graph
An interactive map of the vault: how your profile, memories, projects, skills, sources, tags and entities connect.
Node types
The graph is black and white by default; types differ by fill, outline and stroke. Settings (gear icon in the sidebar) lets you give each type its own color.
| Type | What it is |
|---|---|
| Brain | BRAIN.md, the hub |
| Profile | profile.md, thick ring, labeled with your name |
| Memory | A memory category (hollow) |
| Projects, Skills, Notes | Files in those folders |
| Sources | Saved pages and captures (dashed outline) |
| Folders, Tags | Folder hierarchy and tags: |
| Entities | A person, place, organization or project named in entities (small, dotted ring) |
How links are found
In order of strength (only the strongest is drawn per pair of nodes): [[wikilinks]] and Markdown links → memory under the profile → related: → shared entities → paths mentioned in backticks → tags → folders.
Entities
When a source, a capture or a memory file is saved, the local chat model lists the names it mentions and they go to entities in the frontmatter. Each entity becomes a node, so two notes that mention the same person or project end up connected through it, even if nobody linked them. It's best-effort: without a chat model in Ollama, notes are saved without entities, and Reflect lists the ones missing them.
Controls
- Click a node to see its content and connections in the side panel;
[[links]]are clickable. - Filter by type with the chips, search by name.
- Zoom in/out and re-center with the buttons at the bottom right, the
+/-/0keys, or double-click the background.
El grafo
Un mapa interactivo del vault: cómo se conectan tu perfil, memorias, proyectos, skills, fuentes, tags y entidades.
Tipos de nodo
Por defecto el grafo es blanco y negro; los tipos se distinguen por relleno, contorno y trazo. En Ajustes (engranaje del sidebar) podés darle un color a cada tipo.
| Tipo | Qué es |
|---|---|
| Brain | BRAIN.md, el centro |
| Perfil | profile.md, anillo grueso, con tu nombre |
| Memoria | Una categoría de memoria (hueca) |
| Proyectos, Skills, Notas | Archivos de esas carpetas |
| Fuentes | Páginas guardadas y capturas (contorno punteado) |
| Carpetas, Tags | Jerarquía de carpetas y tags: |
| Entidades | Una persona, lugar, organización o proyecto nombrado en entities (chico, anillo de puntos) |
Cómo se encuentran las relaciones
De más fuerte a más débil (se dibuja solo la más fuerte por par de nodos): [[wikilinks]] y links Markdown → memoria bajo el perfil → related: → entidades compartidas → paths mencionados entre backticks → tags → carpetas.
Entidades
Al guardar una fuente, una captura o un archivo de memoria, el modelo de chat local lista los nombres que menciona y van a entities en el frontmatter. Cada entidad es un nodo, así dos notas que nombran a la misma persona o proyecto quedan conectadas por él aunque nadie las haya enlazado. Es best-effort: sin un modelo de chat en Ollama, las notas se guardan sin entidades, y Reflect lista las que les faltan.
Controles
- Click en un nodo para ver su contenido y conexiones en el panel lateral; los
[[links]]se pueden clickear. - Filtrá por tipo con los chips y buscá por nombre.
- Acercá, alejá y volvé al centro con los botones de abajo a la derecha, las teclas
+/-/0, o doble click en el fondo.
Version history
Every write and every delete stores the file's previous and new content. Any file can go back to any earlier version, including files that were deleted.
How it works
The history lives in data/history.sqlite3 (table changes: id, timestamp, operation, path, before, after). It doesn't use git, so the app's repo never carries your data or a nested repository.
Several processes write at the same time (one server.py per agent, plus the dashboard). Every write takes a file lock on data/.vault.lock that covers read, write and history, and SQLite runs in WAL mode.
Restoring
file_history("projects/online-store.md")
# → [{"id": 42, "ts": "2026-09-28T14:03:11Z", "op": "edit", …}, …]
restore_file("projects/online-store.md", 41)
The restore is itself recorded, so it can be undone too. Operations: create, update, edit, append, delete, restore.
Historial de versiones
Cada escritura y cada borrado guardan el contenido anterior y el nuevo del archivo. Cualquier archivo puede volver a cualquier versión anterior, incluso si se borró.
Cómo funciona
El historial vive en data/history.sqlite3 (tabla changes: id, fecha, operación, path, antes, después). No usa git, así que el repo de la app nunca arrastra tus datos ni un repositorio anidado.
Varios procesos escriben a la vez (un server.py por agente, más el dashboard). Cada escritura toma un lock de archivo sobre data/.vault.lock que cubre leer, escribir y registrar, y SQLite corre en modo WAL.
Restaurar
file_history("projects/tienda-online.md")
# → [{"id": 42, "ts": "2026-09-28T14:03:11Z", "op": "edit", …}, …]
restore_file("projects/tienda-online.md", 41)
La restauración también queda registrada, así que se puede deshacer. Operaciones: create, update, edit, append, delete, restore.
Dashboard
The local web app at http://127.0.0.1:8765, opened with brain. English or Spanish, light, dark or system theme.
Tabs
| Tab | What it's for |
|---|---|
| Dashboard | Switches for Chroma, Ollama and the MCP Inspector; vault metrics, 30-day activity, sources by domain, system health, recent changes. |
| Chat | A local Ollama model with your memory as context and the same tools as your agents. See Chat. |
| Profile | Your profile, your memory (filterable, delete per item), the memory importer and Reflect. |
| Connect agent | One-click connect/disconnect for each supported agent, manual config for anything else, and My connections. |
| Connections | Other MCP servers brain uses for you. See Connections. |
| Graph | The graph. |
| Knowledge | Save a URL, hybrid search, rebuild the keyword index, list of sources. |
| Logs | Live output of every service the dashboard manages. |
Services
Each service has a state: Running, Starting, External, Off or Error. When the dashboard starts it turns on Ollama and Chroma if they're off. If one was already running outside the dashboard (for example the Ollama menu-bar app) it shows as External, its switch is locked and the dashboard never stops it. Ctrl+C stops only what the dashboard started.
Sidebar
The button next to the logo collapses the sidebar into a narrow rail of icons. At the bottom: theme, language and Settings (the gear). Preferences are stored in the browser (localStorage).
Settings
A full view (#ajustes) with four sections:
- Version: the installed version and a Check for updates button. brain asks GitHub for the latest release only when you click it. If there's a newer one, Settings shows it with a link to the release notes, and the gear turns green until you update with
brain update. - Sidebar: reorder the views with the arrows and hide the ones you don't use. A hidden view is still reachable by its URL (
#logs,#grafo…). - Chat: the default model, selected when the chat opens and on every new chat. "The last one I used" keeps the previous behavior.
- Graph colors: a color per node type, or back to black and white.
Dashboard
La web local en http://127.0.0.1:8765, que se abre con brain. En español o inglés, con tema claro, oscuro o el del sistema.
Pestañas
| Pestaña | Para qué sirve |
|---|---|
| Panel | Switches de Chroma, Ollama y el Inspector MCP; métricas del vault, actividad de 30 días, fuentes por dominio, salud del sistema, últimos cambios. |
| Chat | Un modelo local de Ollama con tu memoria como contexto y las mismas tools que tus agentes. Ver Chat. |
| Perfil | Tu perfil, tu memoria (filtrable, se borra por ítem), el importador y Reflect. |
| Conectar agente | Conectar y desconectar cada agente soportado en un click, config manual para cualquier otro, y Mis conexiones. |
| Conexiones | Otros servers MCP que brain usa por vos. Ver Conexiones. |
| Grafo | El grafo. |
| Conocimiento | Guardar una URL, búsqueda híbrida, reindexar la búsqueda por palabra, lista de fuentes. |
| Logs | Salida en vivo de cada servicio que maneja el dashboard. |
Servicios
Cada servicio tiene un estado: Corriendo, Iniciando, Externo, Apagado o Error. Al arrancar, el dashboard prende Ollama y Chroma si están apagados. Si uno ya corría por fuera (por ejemplo la app de Ollama) aparece como Externo, con el switch bloqueado, y el dashboard nunca lo apaga. Ctrl+C apaga solo lo que prendió él.
Sidebar
El botón al lado del logo pliega el sidebar en un riel angosto de íconos. Abajo: tema, idioma y Ajustes (el engranaje). Las preferencias se guardan en el navegador (localStorage).
Ajustes
Una vista completa (#ajustes) con cuatro secciones:
- Versión: la versión instalada y un botón Buscar actualizaciones. brain le pregunta a GitHub por el último release solo cuando lo tocás. Si hay uno más nuevo, Ajustes lo muestra con un link a las novedades y el engranaje se pone en verde hasta que actualices con
brain update. - Sidebar: reordená las vistas con las flechas y ocultá las que no uses. Una vista oculta sigue accesible por su URL (
#logs,#grafo…). - Chat: el modelo por defecto, que se elige al abrir el chat y en cada chat nuevo. "El último que usé" mantiene el comportamiento de antes.
- Colores del grafo: un color por tipo de nodo, o volver a blanco y negro.
Chat
Talk to a local Ollama model that already knows your profile and memory, and can look things up and edit your vault with the same tools your agents have.
Context
The system prompt includes profile.md, all your active memories (up to ~12k characters), BRAIN.md and the fragments of past chats most similar to your question.
Tools
The chat gets exactly the tools your agents get, including your connections'. Every call is listed under the answer; expand it to see the arguments and the result. Up to 6 rounds of tool calls per answer.
Models that can't take native tools (common with GGUF models pulled from Hugging Face, which fail with "Unable to generate parser for this template") switch to text mode: the tools are described in the prompt and the model asks for them with <tool_call>{…}</tool_call>. The mode is remembered per model while the dashboard runs.
History and floating window
Chats are stored in Chroma (collection chats) with embeddings, so past conversations feed the context of new ones. Without Chroma the chat works but isn't saved. Float opens the chat in an always-on-top window (Document Picture-in-Picture in Chrome, Edge and Arc; a regular pop-up elsewhere).
Choosing a model
The selector lists your installed chat models. Without any, click Download llama3.2. Small models sometimes don't follow the tool format; larger ones (llama3.2, qwen2.5, mistral) do better.
Chat
Hablá con un modelo local de Ollama que ya conoce tu perfil y tu memoria, y que puede consultar y editar tu vault con las mismas tools que tus agentes.
Contexto
El system prompt incluye profile.md, todas tus memorias activas (hasta ~12k caracteres), BRAIN.md y los fragmentos de chats anteriores más parecidos a tu pregunta.
Tools
El chat recibe exactamente las tools de tus agentes, incluidas las de tus conexiones. Cada llamada aparece debajo de la respuesta; desplegala para ver los argumentos y el resultado. Hasta 6 vueltas de tools por respuesta.
Los modelos que no aceptan tools nativas (típico de GGUF bajados de Hugging Face, que fallan con "Unable to generate parser for this template") pasan al modo texto: las tools van descritas en el prompt y el modelo las pide con <tool_call>{…}</tool_call>. El modo se recuerda por modelo mientras corre el dashboard.
Historial y ventana flotante
Los chats se guardan en Chroma (colección chats) con embeddings, así las conversaciones anteriores alimentan el contexto de las nuevas. Sin Chroma el chat funciona pero no se guarda. Ventana flotante abre el chat en una ventana siempre visible (Document Picture-in-Picture en Chrome, Edge y Arc; una ventana emergente común en el resto).
Elegir un modelo
El selector lista tus modelos de chat instalados. Si no hay ninguno, tocá Descargar llama3.2. Los modelos chicos a veces no siguen el formato de tools; los más grandes (llama3.2, qwen2.5, mistral) andan mejor.
Connecting agents
Each agent keeps its list of MCP servers in its own file. Connect adds brain's entry without touching anything else, after saving a backup (<file>.bak-brain).
Supported agents
| Agent | Config | Notes |
|---|---|---|
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json | Claude rewrites this file when it quits, so it's edited with the app closed; the dashboard offers to quit, connect and reopen it. |
| ChatGPT (desktop) | ~/.codex/config.toml | Works in Codex and ChatGPT Work modes; regular chat doesn't use local servers. Then Settings → MCP servers → Restart. |
| Claude Code | claude mcp add -s user | Available in all your projects. |
| Codex CLI | ~/.codex/config.toml | Same file as ChatGPT. |
| Cursor | ~/.cursor/mcp.json | |
| VS Code (Copilot) | ~/Library/Application Support/Code/User/mcp.json | If the file has comments (JSONC) it isn't rewritten; you get the snippet to paste. |
| Windsurf | ~/.codeium/windsurf/mcp_config.json | |
| Gemini CLI | ~/.gemini/settings.json |
All of them launch the same command with absolute paths, so they work from any folder:
/Users/you/.local/bin/uv run --directory /Users/you/.brain python server.py
Apps with an "Add MCP server" form
Choose Run a command, not "Connect to a URL": brain is a local (stdio) server and doesn't expose an MCP URL. Pointing an app at the dashboard's address returns 403.
| Field | Value |
|---|---|
| Name | brain |
| Command | absolute path to uv (which uv) |
| Arguments (one per line) | run, --directory, /Users/you/.brain, python, server.py |
The Connect agent tab shows these values filled in for your machine, with copy buttons.
My connections
Lists the agents brain configured, plus every app that has used brain: brain records the client name each app sends in the MCP handshake (data/clients.json), so apps you set up with a form appear the first time they use it. You can also note an app by hand.
Conectar agentes
Cada agente guarda su lista de servers MCP en su propio archivo. Conectar agrega la entrada de brain sin tocar nada más, después de guardar un backup (<archivo>.bak-brain).
Agentes soportados
| Agente | Config | Notas |
|---|---|---|
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json | Claude reescribe este archivo al cerrarse, así que se edita con la app cerrada; el dashboard ofrece cerrarla, conectar y volver a abrirla. |
| ChatGPT (escritorio) | ~/.codex/config.toml | Funciona en los modos Codex y ChatGPT Work; el chat común no usa servers locales. Después: Settings → MCP servers → Restart. |
| Claude Code | claude mcp add -s user | Disponible en todos tus proyectos. |
| Codex CLI | ~/.codex/config.toml | El mismo archivo que ChatGPT. |
| Cursor | ~/.cursor/mcp.json | |
| VS Code (Copilot) | ~/Library/Application Support/Code/User/mcp.json | Si el archivo tiene comentarios (JSONC) no se reescribe; te da el fragmento para pegar. |
| Windsurf | ~/.codeium/windsurf/mcp_config.json | |
| Gemini CLI | ~/.gemini/settings.json |
Todos lanzan el mismo comando con paths absolutos, así funcionan desde cualquier carpeta:
/Users/vos/.local/bin/uv run --directory /Users/vos/.brain python server.py
Apps con formulario "Add MCP server"
Elegí Run a command, no "Connect to a URL": brain es un server local (stdio) y no expone una URL MCP. Apuntar una app a la dirección del dashboard devuelve 403.
| Campo | Valor |
|---|---|
| Nombre | brain |
| Comando | path absoluto de uv (which uv) |
| Argumentos (uno por línea) | run, --directory, /Users/vos/.brain, python, server.py |
La pestaña Conectar agente muestra estos valores completos para tu máquina, con botones de copiar.
Mis conexiones
Lista los agentes que configuró brain, más cada app que usó brain: brain anota el nombre de cliente que manda cada app en el handshake MCP (data/clients.json), así las apps que agregaste con un formulario aparecen la primera vez que lo usan. También podés anotar una app a mano.
Connections
brain is also an MCP client. Add other MCP servers (GitHub, Notion, Gmail…) and their tools show up in every agent you connected, with their results saved to your memory.
Types
- Local command (recommended): an MCP server that runs on your Mac, e.g.
npx -y @modelcontextprotocol/server-githubwithGITHUB_TOKEN=…. The token stays on your machine. - URL: a remote MCP server, with optional headers (
Authorization: Bearer …). - Composio (optional): hundreds of apps through one connection. Composio keeps your accounts' OAuth tokens in its own cloud. A consumer key (
ck_…) connects directly; a project key (ak_…) lets you pick auth configs and creates an MCP server through Composio's developer API.
Proxied tools
Tools are re-exposed with the connection's prefix: github__create_issue, composio__GMAIL_FETCH_EMAILS. Turning a connection off removes its tools from your agents right away, without restarting anything. Each call opens a session with the origin server, runs, and closes it.
Save to memory
With the switch on, every result is written to knowledge/connections/<connection>/…md (or knowledge/composio/<app>/…) with the tool, arguments and time in its frontmatter, and indexed for semantic and keyword search. Long results get an abstract, and all get entities when a chat model is available. Capturing never breaks the call: without Chroma or Ollama the .md is saved anyway.
Secrets
Env values, headers and API keys go to ~/.brain/.env (permissions 600, gitignored); the config only stores references ($env:KEY). The dashboard never returns them.
Conexiones
brain también es cliente MCP. Agregá otros servers MCP (GitHub, Notion, Gmail…) y sus tools aparecen en todos los agentes que conectaste, con sus resultados guardados en tu memoria.
Tipos
- Comando local (recomendado): un server MCP que corre en tu Mac, por ejemplo
npx -y @modelcontextprotocol/server-githubconGITHUB_TOKEN=…. El token queda en tu máquina. - URL: un server MCP remoto, con headers opcionales (
Authorization: Bearer …). - Composio (opcional): cientos de apps con una sola conexión. Composio guarda los tokens OAuth de tus cuentas en su nube. Una consumer key (
ck_…) conecta directo; una key de proyecto (ak_…) te deja elegir auth configs y crea un server MCP con la API de desarrollador de Composio.
Tools proxeadas
Las tools se re-exponen con el prefijo de la conexión: github__create_issue, composio__GMAIL_FETCH_EMAILS. Apagar una conexión saca sus tools de tus agentes en el momento, sin reiniciar nada. Cada llamada abre una sesión con el server de origen, ejecuta y la cierra.
Guardar en memoria
Con el switch prendido, cada resultado se escribe en knowledge/connections/<conexión>/…md (o knowledge/composio/<app>/…) con la tool, los argumentos y la hora en el frontmatter, y se indexa para la búsqueda semántica y por palabra. Los resultados largos llevan un abstract, y todos llevan entities si hay un modelo de chat. Capturar nunca rompe la llamada: sin Chroma u Ollama el .md se guarda igual.
Secretos
Los valores de env, headers y API keys van a ~/.brain/.env (permisos 600, en el gitignore); la config solo guarda referencias ($env:CLAVE). El dashboard nunca los devuelve.
Reflect and skills
Two ways to make stored memory more useful: Reflect reviews it and suggests fixes, and distill_skill turns everything on a topic into a reusable skill.
Reflect
Profile tab → Review my memory. It looks for:
| Suggestion | When | Suggested action |
|---|---|---|
| Possible duplicate | The same fact (or nearly) in two places of memory/ | Remove one (Profile → Your memory, or str_replace_file) |
| Possible contradiction | Two facts that start the same but say something different ("Lives in Palermo" / "Lives in Núñez") | add_memory(new, category, supersede=old) |
| No entities | Recently changed notes in knowledge/ or memory/ without entities | set_frontmatter(path, {"entities": […]}) with the names the local model found |
Reflect never writes anything. Each suggestion shows the tool call that would apply it; apply it yourself or ask the chat to. Without a chat model, the entity check is skipped; it processes up to 20 files per run.
distill_skill
Ask an agent "make a skill about X". It calls distill_skill("X"), which returns:
{
"topic": "pricing",
"skill_path": "skills/pricing.md",
"existing_skill": null,
"chunks": [ …hybrid search hits… ],
"memory": [ {"category": "Work", "fact": "…"} ],
"sources": [ "knowledge/sources/…md" ],
"instructions": "Synthesize this material into a reusable skill…"
}
The agent writes the skill and saves it with write_file. brain only gathers the material: the skill is written by the same model that will use it later, not by a hidden call with another prompt. If a skill with that name exists, the agent is told to update it instead of overwriting it.
Reflect y skills
Dos formas de hacer más útil la memoria guardada: Reflect la revisa y sugiere arreglos, y distill_skill convierte todo lo que hay sobre un tema en un skill reutilizable.
Reflect
Pestaña Perfil → Revisar mi memoria. Busca:
| Sugerencia | Cuándo | Acción sugerida |
|---|---|---|
| Posible duplicado | El mismo hecho (o casi) en dos lugares de memory/ | Sacar uno (Perfil → Tu memoria, o str_replace_file) |
| Posible contradicción | Dos hechos que empiezan igual pero dicen otra cosa ("Vive en Palermo" / "Vive en Núñez") | add_memory(nuevo, categoría, supersede=viejo) |
| Sin entidades | Notas de knowledge/ o memory/ tocadas hace poco sin entities | set_frontmatter(path, {"entities": […]}) con los nombres que encontró el modelo local |
Reflect nunca escribe nada. Cada sugerencia muestra la tool que la aplicaría; aplicala vos o pedíselo al chat. Sin un modelo de chat, se saltea la revisión de entidades; procesa hasta 20 archivos por corrida.
distill_skill
Pedile a un agente "armá un skill sobre X". Llama a distill_skill("X"), que devuelve:
{
"topic": "precios",
"skill_path": "skills/precios.md",
"existing_skill": null,
"chunks": [ …resultados de la búsqueda híbrida… ],
"memory": [ {"category": "Trabajo", "fact": "…"} ],
"sources": [ "knowledge/sources/…md" ],
"instructions": "Sintetizá este material en un skill reutilizable…"
}
El agente redacta el skill y lo guarda con write_file. brain solo junta el material: el skill lo escribe el mismo modelo que después lo va a usar, no una llamada oculta con otro prompt. Si ya existe un skill con ese nombre, el agente tiene la instrucción de actualizarlo en vez de pisarlo.
MCP tools
Every tool brain exposes to your agents. Errors come back as text starting with Error:, never as exceptions.
Vault
| Tool | What it does |
|---|---|
list_vault(prefix?) | Lists .md files with their description. prefix filters by folder, e.g. projects. |
read_file(path) | Full content of a file. |
write_file(path, content) | Creates or replaces a whole file. |
append_file(path, content) | Appends to the end (creates the file if missing). |
str_replace_file(path, old, new) | Targeted replace; old must appear exactly once. |
set_frontmatter(path, fields) | Changes metadata without touching the content; null removes a field. |
delete_file(path) | Deletes a file (recoverable). |
file_history(path) | A file's versions, newest first. |
restore_file(path, version_id) | Restores a version (also brings back deleted files). |
Memory
| Tool | What it does |
|---|---|
add_memory(fact, category?, supersede?) | Saves a dated fact in memory/<category>.md without duplicates. With supersede, the old fact moves to ## Historial. |
memory_history(category?) | Superseded facts of a category. |
Knowledge
| Tool | What it does |
|---|---|
save_url(url, render_js?) | Scrapes, indexes and saves a URL. |
search_knowledge(query, top_k?) | Hybrid search (semantic + keyword). top_k 1–50, default 5. |
list_sources() | Saved URLs with title, date, path and abstract. |
reindex_keyword_search() | Rebuilds the keyword index from knowledge/. |
Skills
| Tool | What it does |
|---|---|
list_skills() | Skills in skills/ with their description. |
get_skill(name) | A skill's content. |
distill_skill(topic) | Gathers the material on a topic so the agent writes a skill. |
Connections
| Tool | What it does |
|---|---|
list_connections() | Your connections, whether they're active, and their tools. |
refresh_connectors() | Re-discovers the tools of every active connection. |
<connection>__<tool> | Any tool from an active connection, proxied. |
Tools MCP
Todas las tools que brain expone a tus agentes. Los errores vuelven como texto que empieza con Error:, nunca como excepciones.
Vault
| Tool | Qué hace |
|---|---|
list_vault(prefix?) | Lista los .md con su description. prefix filtra por carpeta, ej. projects. |
read_file(path) | Contenido completo de un archivo. |
write_file(path, content) | Crea o reemplaza un archivo entero. |
append_file(path, content) | Agrega al final (crea el archivo si no existe). |
str_replace_file(path, old, new) | Reemplazo puntual; old tiene que aparecer exactamente una vez. |
set_frontmatter(path, fields) | Cambia metadatos sin tocar el contenido; null borra un campo. |
delete_file(path) | Borra un archivo (recuperable). |
file_history(path) | Versiones de un archivo, la más nueva primero. |
restore_file(path, version_id) | Restaura una versión (también recupera archivos borrados). |
Memoria
| Tool | Qué hace |
|---|---|
add_memory(fact, category?, supersede?) | Guarda un hecho con fecha en memory/<categoría>.md sin duplicar. Con supersede, el hecho viejo pasa a ## Historial. |
memory_history(category?) | Hechos superados de una categoría. |
Conocimiento
| Tool | Qué hace |
|---|---|
save_url(url, render_js?) | Scrapea, indexa y guarda una URL. |
search_knowledge(query, top_k?) | Búsqueda híbrida (semántica + por palabra). top_k de 1 a 50, por defecto 5. |
list_sources() | URLs guardadas con título, fecha, path y abstract. |
reindex_keyword_search() | Reconstruye el índice por palabra desde knowledge/. |
Skills
| Tool | Qué hace |
|---|---|
list_skills() | Skills de skills/ con su description. |
get_skill(name) | El contenido de un skill. |
distill_skill(topic) | Junta el material sobre un tema para que el agente redacte un skill. |
Conexiones
| Tool | Qué hace |
|---|---|
list_connections() | Tus conexiones, si están activas y sus tools. |
refresh_connectors() | Vuelve a descubrir las tools de cada conexión activa. |
<conexión>__<tool> | Cualquier tool de una conexión activa, proxeada. |
The brain command
Installed in ~/.local/bin/brain. From a clone, ./brain.sh does the same.
brain opens the dashboard and starts Ollama and Chroma brain --port 8766 dashboard on another port brain --no-autostart don't start Ollama/Chroma automatically brain --no-browser don't open the browser brain update updates to the latest version (git pull + uv sync) brain path shows where it's installed brain uninstall removes the command (keeps your data) brain help help
Standalone scripts
For when you need a piece without the dashboard:
./chroma_server.sh # Chroma alone on 127.0.0.1:8055 ./start.sh # MCP server over stdio (normally launched by the client) npx @modelcontextprotocol/inspector uv run python server.py # MCP Inspector
El comando brain
Se instala en ~/.local/bin/brain. Desde un clon, ./brain.sh hace lo mismo.
brain abre el dashboard y prende Ollama y Chroma brain --port 8766 dashboard en otro puerto brain --no-autostart no prender Ollama/Chroma solo brain --no-browser no abrir el navegador brain update actualiza a la última versión (git pull + uv sync) brain path muestra dónde está instalado brain uninstall saca el comando (tus datos quedan) brain help ayuda
Scripts sueltos
Para cuando necesitás una pieza sin el dashboard:
./chroma_server.sh # solo Chroma en 127.0.0.1:8055 ./start.sh # server MCP por stdio (normalmente lo lanza el cliente) npx @modelcontextprotocol/inspector uv run python server.py # Inspector MCP
Configuration
brain works without configuration. These are the knobs and the files it uses.
Environment variables
| Variable | Default | What it does |
|---|---|---|
BRAIN_CHROMA_PORT | 8055 | Port of the Chroma server (read by the scripts and the server). |
BRAIN_SUMMARY_MODEL | llama3.2 if installed, otherwise the first chat model | Ollama chat model used for abstract and entities. off disables both. |
BRAIN_LLM_TIMEOUT | 45 | Seconds to wait for a summary or entity list before giving up (the note is saved anyway). |
Ports
| Port | Service |
|---|---|
8765 | Dashboard (--port to change) |
8055 | Chroma |
11434 | Ollama |
6274 / 6275 | MCP Inspector |
Files
Path (inside ~/.brain) | Contents |
|---|---|
vault/ | Your notes, profile and memory |
data/history.sqlite3 | Version history |
data/search.sqlite3 | Keyword index (can be rebuilt) |
data/chroma/ | Vector index |
data/connections.json, connections_tools.json | Connections and their cached tools |
data/clients.json | Apps detected through the MCP handshake |
.env | Secrets (permissions 600) |
vault/, data/ and .env are in .gitignore. To start from scratch, close the dashboard and your agents, delete vault/ and data/, and open brain again.
Configuración
brain funciona sin configurar nada. Estas son las perillas y los archivos que usa.
Variables de entorno
| Variable | Por defecto | Qué hace |
|---|---|---|
BRAIN_CHROMA_PORT | 8055 | Puerto del server de Chroma (lo leen los scripts y el server). |
BRAIN_SUMMARY_MODEL | llama3.2 si está instalado, si no el primer modelo de chat | Modelo de chat de Ollama para abstract y entities. off apaga los dos. |
BRAIN_LLM_TIMEOUT | 45 | Segundos de espera para un resumen o una lista de entidades antes de abandonar (la nota se guarda igual). |
Puertos
| Puerto | Servicio |
|---|---|
8765 | Dashboard (--port para cambiarlo) |
8055 | Chroma |
11434 | Ollama |
6274 / 6275 | Inspector MCP |
Archivos
Path (dentro de ~/.brain) | Contenido |
|---|---|
vault/ | Tus notas, perfil y memoria |
data/history.sqlite3 | Historial de versiones |
data/search.sqlite3 | Índice por palabra (se puede reconstruir) |
data/chroma/ | Índice vectorial |
data/connections.json, connections_tools.json | Conexiones y el caché de sus tools |
data/clients.json | Apps detectadas por el handshake MCP |
.env | Secretos (permisos 600) |
vault/, data/ y .env están en el .gitignore. Para arrancar de cero, cerrá el dashboard y tus agentes, borrá vault/ y data/, y abrí brain de nuevo.
Privacy and security
Your data stays on your Mac. brain only goes online when you save a URL or use a connection that talks to a remote service.
What stays local
- The vault, the history, both search indexes and your secrets live in
~/.brain. - Embeddings, summaries and entities are computed by Ollama on your machine.
- Composio, if you use it, keeps your app tokens in its cloud; everything it fetches is saved locally.
The dashboard
- Listens only on
127.0.0.1. - Rejects any request whose
Hostisn't127.0.0.1:<port>orlocalhost:<port>(DNS-rebinding protection). - Every POST requires the
X-Brain: 1header, which forces a CORS preflight the server never approves: no website you have open can start processes or write to your vault.
Agents
- Tools can't leave the vault (
.., absolute paths, hidden files and outbound symlinks are rejected). - Every write is versioned and can be undone.
- Agent configs are never rewritten without a backup, and other entries are never removed.
Reporting a vulnerability
Please don't open a public issue. Use GitHub's private reporting: Security → Report a vulnerability. Scope and response times are in SECURITY.md.
Privacidad y seguridad
Tus datos se quedan en tu Mac. brain solo sale a internet cuando guardás una URL o usás una conexión que habla con un servicio remoto.
Qué queda local
- El vault, el historial, los dos índices de búsqueda y tus secretos viven en
~/.brain. - Los embeddings, resúmenes y entidades los calcula Ollama en tu máquina.
- Composio, si lo usás, guarda los tokens de tus apps en su nube; todo lo que trae se guarda local.
El dashboard
- Escucha solo en
127.0.0.1. - Rechaza cualquier pedido cuyo
Hostno sea127.0.0.1:<puerto>olocalhost:<puerto>(protección contra DNS rebinding). - Cada POST exige el header
X-Brain: 1, que fuerza un preflight CORS que el server nunca aprueba: ninguna web que tengas abierta puede prender procesos ni escribir en tu vault.
Agentes
- Las tools no pueden salir del vault (se rechazan
.., paths absolutos, archivos ocultos y symlinks hacia afuera). - Cada escritura queda versionada y se puede deshacer.
- Las configs de los agentes nunca se reescriben sin backup, y nunca se borran entradas ajenas.
Reportar una vulnerabilidad
Por favor no abras un issue público. Usá el reporte privado de GitHub: Security → Report a vulnerability. El alcance y los tiempos de respuesta están en SECURITY.md.
Troubleshooting
The usual problems and their fixes.
Services
| Problem | Fix |
|---|---|
| "Ollama isn't running" | Turn on the Ollama switch in the Dashboard tab, or open the Ollama app. |
| "The Chroma server isn't running" | Open the dashboard (brain); it starts Chroma. Keyword search keeps working without it. |
| Port 8765 is taken | brain --port 8766 |
brain: command not found | Open a new terminal, or add export PATH="$HOME/.local/bin:$PATH" to ~/.zshrc. |
Search and memory
| Problem | Fix |
|---|---|
| A name you know is saved isn't found | Sources from before v0.02.5 aren't in the keyword index: Rebuild keyword index in Knowledge, or reindex_keyword_search. |
No abstract or entities | Install a chat model: ollama pull llama3.2. Then run Reflect to find notes missing entities. |
| "Couldn't extract text from that URL" | The site may be paywalled or need a login. Try Force JS rendering. |
Agents
| Problem | Fix |
|---|---|
| brain doesn't show up in Claude Desktop | Connect it from Connect agent and restart Claude. |
| brain doesn't show up in ChatGPT | Use Codex or ChatGPT Work mode, then Settings → MCP servers → Restart. |
An app returns 403 | You used "Connect to a URL". Use Run a command. |
Composio returns 401 | A consumer key (ck_…) only works with Save and connect; Choose apps is for project keys (ak_…). |
Chat
| Problem | Fix |
|---|---|
| No chat model | Download llama3.2 in the Chat tab, or ollama pull llama3.2. |
| It answers but can't save anything | Open the actions under the answer to see what failed; try a larger model. |
Solución de problemas
Los problemas típicos y cómo resolverlos.
Servicios
| Problema | Solución |
|---|---|
| "Ollama no está corriendo" | Prendé el switch de Ollama en el Panel, o abrí la app de Ollama. |
| "El server de Chroma no está corriendo" | Abrí el dashboard (brain); prende Chroma. La búsqueda por palabra sigue andando sin él. |
| El puerto 8765 está ocupado | brain --port 8766 |
brain: command not found | Abrí una terminal nueva, o agregá export PATH="$HOME/.local/bin:$PATH" a ~/.zshrc. |
Búsqueda y memoria
| Problema | Solución |
|---|---|
| No encuentra un nombre que sabés que está guardado | Las fuentes de antes de v0.02.5 no están en el índice por palabra: Reindexar búsqueda por palabra en Conocimiento, o reindex_keyword_search. |
Sin abstract ni entidades | Instalá un modelo de chat: ollama pull llama3.2. Después corré Reflect para ver qué notas no tienen entidades. |
| "No se pudo extraer texto de esa URL" | El sitio puede tener paywall o pedir login. Probá Forzar render con JS. |
Agentes
| Problema | Solución |
|---|---|
| brain no aparece en Claude Desktop | Conectalo desde Conectar agente y reiniciá Claude. |
| brain no aparece en ChatGPT | Usá el modo Codex o ChatGPT Work, y después Settings → MCP servers → Restart. |
Una app devuelve 403 | Usaste "Connect to a URL". Usá Run a command. |
Composio devuelve 401 | Una consumer key (ck_…) solo anda con Guardar y conectar; Elegir apps es para keys de proyecto (ak_…). |
Chat
| Problema | Solución |
|---|---|
| No hay modelo de chat | Descargar llama3.2 en la pestaña Chat, o ollama pull llama3.2. |
| Responde pero no puede guardar nada | Abrí las acciones debajo de la respuesta para ver qué falló; probá un modelo más grande. |
License
MIT with the Commons Clause. Source available: use it, study it, change it and share it for free, including at work. Don't sell it.
What you can do
- Use brain personally or at work, for free.
- Read, modify and fork the code.
- Share it, keeping the copyright notice and both license files.
What you can't do
Sell it: charge third parties for a product or service (hosting, support or consulting included) whose value comes entirely or substantially from brain.
Files
LICENSE has the MIT text and COMMONS-CLAUSE.md the condition. They're separate so GitHub can detect the base license; together they're brain's license. Because of the Commons Clause, brain isn't "open source" under the OSI definition. Versions before v0.02.0 remain under plain MIT.
Licencia
MIT con Commons Clause. Código a la vista: usalo, estudialo, cambialo y compartilo gratis, también en el trabajo. No lo vendas.
Qué podés hacer
- Usar brain para vos o en el trabajo, gratis.
- Leer, modificar y hacer fork del código.
- Compartirlo, manteniendo el aviso de copyright y los dos archivos de licencia.
Qué no podés hacer
Venderlo: cobrarle a terceros por un producto o servicio (incluidos hosting, soporte o consultoría) cuyo valor venga entera o sustancialmente de brain.
Archivos
LICENSE tiene el texto MIT y COMMONS-CLAUSE.md la condición. Están separados para que GitHub detecte la licencia base; juntos son la licencia de brain. Por la Commons Clause, brain no es "open source" según la definición de la OSI. Las versiones anteriores a v0.02.0 siguen bajo MIT puro.
Edit this page on GitHubEditar esta página en GitHub · v0.02.5