cortex
A brain your whole household can talk to.
Capture a thought in one keystroke, ask about it later and get a cited answer, and see what is on today — all on a model you run yourself. Shared and personal vaults, peer chat, Obsidian-style editing. Home brain, company brain, club brain: one folder each.
- alpha
- 138 tests passing
- LangGraph + LangChain
- Python 3.11+ · React 18
- MIT
bash docs/promo/build.sh.Install
A wizard, then a URL
pip install cortxai
cortex setup # brain dir → endpoint → models → admin account
cortex serve --host 0.0.0.0 # dashboard on :8642
The wizard pings your endpoint's /models, warns plainly if it is
unreachable or public, and creates the first admin account. Docker instead:
docker compose up after the one-time setup documented in
docker-compose.yml;
or the curl-able install.sh.
What it does not do. cortex hosts no model — bring Ollama, vLLM, LM Studio, a LiteLLM proxy, OpenRouter, or an Anthropic key. Vector search is exact cosine in-process: built for personal- and team-sized brains, not millions of chunks. Vault edits are conflict-detected (409 + a banner), not git-merged.
Dashboard
Open it for Today, stay for the rest
Today
The default view: what is on, a few open tasks you tick straight from the list, what changed, and what you wrote on this date in earlier years. Computed without the model, so it answers instantly — and works on a brain with no model configured at all.
Capture
Press c anywhere, or run cortex note "…". One line into
today's daily note. No folder to choose, no title to invent — search does not care
which note a line is in.
Search
Full-text and vector search fused, over everything you are allowed to read, from
/ anywhere. It keeps working when the model box is off.
Chat
Private agent threads. Tool calls stream as they run; answers cite files by path, and a citation click opens the file in the vault view. Conversation state lives in a LangGraph checkpoint per thread.
Channels
Peer chat over WebSocket for everyone on the brain. Mention @cortex
and the agent replies in-channel — scoped to the shared vault only, streamed token
by token as it thinks.
Vault
Shared vault for the group, a private vault per user. CodeMirror editing with Obsidian rendering: wikilinks, embeds, callouts, frontmatter, write-through task checkboxes, tags. Ctrl-S saves; concurrent edits get a conflict banner.
Import
Bring an existing Obsidian vault: zip upload, git URL, or server path.
.obsidian/, .git/ and non-vault file types are skipped,
and the index catches up in the background.
Admin
Accounts with two roles. Passwords are scrypt-hashed, sessions are HttpOnly signed cookies, and every search or tool call is scoped to what that user may read — filtered inside the query, never trimmed after it.
MCP export
claude mcp add brain -- cortex mcp --brain ~/brain gives Claude
Code, Cursor, or Hermes the same tool registry the dashboard agent uses.
Stack
LangGraph agent, pluggable models, hybrid retrieval
The agent is LangGraph's ReAct graph over LangChain chat models with an
AsyncSqliteSaver checkpointer. Provider profiles map one OpenAI-compatible
wire onto Ollama, vLLM, LM Studio, OpenRouter, and a
LiteLLM proxy (its routing policy stays in the proxy — cortex carries no
LiteLLM SDK), plus direct Anthropic. Chat and embeddings can come from different
endpoints, and roles switch in cortex.yaml, not in code.
providers:
local: {kind: openai, base_url: "http://localhost:11434/v1",
chat_model: qwen3, embed_model: nomic-embed-text}
router: {kind: openrouter, api_key_env: OPENROUTER_API_KEY,
chat_model: anthropic/claude-sonnet-5}
roles:
chat: router
embed: local
Retrieval fuses FTS5 and vector cosine with reciprocal rank fusion plus recency — no single scorer is trusted on its own, following Cerebras' knowledge-base write-up. Changing the chunk schema or embedding model re-indexes from scratch; a missing embedding endpoint degrades to full-text and says so. Endpoints are classified by network facts — private, loopback, CGNAT and Tailscale are trusted, public ones get a plain warning that notes will leave the network.
Extend
Four plugin surfaces, one rule: broken plugins are isolated
| Surface | Contract | When it runs |
|---|---|---|
| Tool plugin | plugins/*.py exposing register(registry), or a
package with a cortex.tools entry point |
agent time |
| MCP server | mcp_servers: block — stdio or streamable HTTP, attached via
langchain-mcp-adapters; exclude wins over include |
agent time |
| Skill | skills/<name>/SKILL.md
(agentskills.io), instructions
load lazily via use_skill |
on demand |
| Connector | connectors/*.py exposing sync(out_dir, settings);
distill, don't dump |
connectors run |
The agent can write, narrowly: add a line to today's note, tick a task by exact path and line, save a web page as markdown. There is no general write-any-file tool — on a vault with no version control, that narrowness is the safety property.
Registration is not authorization: a tool that touches something sensitive keeps its own checks inside the callable. Remembered facts are brain-wide by design — a household brain wants "we water the rosemary on Fridays" visible to everyone, and the agent is told never to remember one person's private secrets.
Managed from the dashboard
The admin-only Extend panel lists every plugin, skill,
connector and MCP server with what it provides and its load error if it has one. Write a
plugin in the browser and it is loaded before it is saved — code that will not import is
refused with the loader's own message rather than breaking the next turn — then the agent
is rebuilt so the new tool is live without a restart. Toggling one off never edits your
source file, and anything declared in cortex.yaml stays read-only there.
Saving a plugin or connector runs that code on the server as the cortex user — the
same trust level as configuring a stdio MCP server. That is why the panel is admin-only.
cortex ext list|enable|disable|delete does the same from a terminal.
Restraint
What it will not do to keep you coming back
No streaks, no daily-open counter, no "you have not opened cortex in three days". The daily view is bounded: it shows a handful of tasks and then says that is everything for today. It never shows a growing count of what you have not done — that is a debt counter, and the products that shipped one document the same outcome, which is that people stop opening them.
The digest is a fact, not an opinion: it is computed from your files without asking a model, so it cannot invent a reason to ping you, takes no time to produce, and works when the model box is off. Every large "AI decides what you need each morning" product shipped since 2024 has since been retired or reworked. On a tool you host yourself, your absence is not a problem to be solved.
Lineage
What cortex borrows, and from where
The retrieval design (hybrid fusion, distill-don't-dump connectors) follows Cerebras' knowledge base. The extensibility model — built-in tools, then MCP, then skills — follows Hermes Agent. The SQLite-first storage floor exists because a home brain should not need Postgres, Qdrant, and a vector database cluster to answer a question about rosemary. Usage telemetry keeps preflight's field names, and absent token counts stay absent — unmeasured is not zero.