A search index for your team's notes and documents that you run yourself.

CompanyBrain copies text from the places your team already writes (folders of Markdown, Slack, Notion, GitHub and others) into a Postgres database on your machine. Ask it a question and it returns the passages that match, each with a link to where it came from. It is free and MIT licensed, and there is no hosted version to sign up for.

npx companybrain

Needs Docker, Node 18 or newer, and git. The first run builds two images, which takes a few minutes.

What it does

It reads a source, cuts the text into passages, and indexes every passage twice: once by its words, using Postgres full-text search, and once as a vector, using pgvector. A question is run against both. The two result lists are merged into one, and you get the passages back with their scores and their source.

Connect a language model and it will also write a short answer from those passages. Without one, it shows you the passages and stops there.

Other software can use the same index. There is a REST API, and an MCP server so that Claude, Cursor or your own agent can search it and add to it.

  1. A document comes in

    From a connector, an upload, or a call to the API.

  2. It is cut into passages

    About 512 tokens each. Neighbours share 64, so a sentence is not lost at a cut.

  3. Each passage is indexed twice

    By its words (top) and as a vector of 1,536 numbers (bottom).

  4. Two rankings become one

    Reciprocal rank fusion. By default the vector ranking counts double.

Twelve questions and what came back

The repository includes a small sample: twelve short company notes (a release process, an expense policy, where the espresso machine is) and twelve questions that each have one right note. The table shows where the right note landed in the results, in four setups. It was recorded on 13 October 2026 from a fresh install of commit e1945a0.

Question Choose one to see its results Words full-text only Vectors built in, no key Both the default Both with a model
Right note came 1st Right note came 1st Right note came 1st Right note came 1st
Right note came 1st Right note came 2nd Right note came 1st Right note came 1st
Right note came 1st Right note came 5th Right note came 2nd Right note came 1st
Right note came 1st Right note came 2nd Right note came 2nd Right note came 1st
Right note came 1st Right note came 1st Right note came 1st Right note came 1st
Right note came 1st Right note came 2nd Right note came 1st Right note came 1st
Right note came 1st Right note came 1st Right note came 1st Right note came 1st
Right note came 1st Right note came 1st Right note came 1st Right note came 1st
Right note came 1st Right note came 1st Right note came 1st Right note came 1st
Right note came 1st Right note came 1st Right note came 1st Right note came 1st
Right note came 1st Right note came 1st Right note came 1st Right note came 1st
Right note was none Right note came 1st Right note came 2nd Right note came 6th

What came back, default setup

how do we ship a release?

  1. Release processthe right note1.00
    vectors 0.142, words 0.068

    We cut releases every Thursday. Tag main, run the release workflow, then announce in the #engineering channel. Hotfixes can ship any day with a lead's approval.

  2. Deploy rollback0.98
    vectors 0.046, words 0.030

    To roll back a bad deploy, re-run the release workflow with the previous git tag. Page the on-call engineer if customer traffic is affected.

  3. Incident retro0.65
    vectors 0.045, no word match

    After any incident we run a blameless retro within three business days. The output is a written timeline, root cause, and action items with owners and due dates.

Words shared with the question are marked. The score is relative to the best result for that question, so the first result always reads 1.00.

Each cell is the top five results. The filled square is where the right note was. “Both, with a model” uses nomic-embed-text running locally through Ollama, which is free and needs no key.

With nothing configured, the right note came first for 9 of the 12 questions and first or second for all 12. With the embedding model it came first for 11, and sixth for the other.

The last question shows what goes wrong. It asks about an “outage”. The right note says “incident”. The note that came first is about support response times and happens to contain the word “outages”. The built-in vectors are a hash of the words in the text, so they cannot tell that two different words mean the same thing, and here the small embedding model did no better.

Twelve notes is a smoke test. It shows that the install works and the kind of mistake each setup makes. It says very little about how well this will search your documents.

$ node bench/run.mjs --verbose

Run that in a checkout while CompanyBrain is up and it prints the ranks in the “Both, the default” column. Add --mode keyword or --mode semantic for the first two.

Asking instead of searching

Asking sends the best passages to a language model along with your question. These are two real replies to “how do we ship a release?”, from the same twelve notes.

No model connected, the default

Here is the most relevant knowledge I found:

[1] We cut releases every Thursday. Tag main, run the release workflow, then announce in the #engineering channel. Hotfixes can ship any day with a lead's approval.

[2] To roll back a bad deploy, re-run the release workflow with the previous git tag. Page the on-call engineer if customer traffic is affected.

[3] After any incident we run a blameless retro within three business days. The output is a written timeline, root cause, and action items with owners and due dates.

Sources:
[1] Release process
[2] Deploy rollback
[3] Incident retro

With no model there is nothing to write a sentence, so you get the top three passages.

A small local model, llama3.2 through Ollama

Tag main, run the release workflow, then announce in the #engineering channel.

Sources:
[1] Release process
[2] Deploy rollback
[3] Incident retro
[4] Expense policy
[5] Onboarding checklist
[6] Billing system
[7] Data retention
[8] Support SLA

The sources are every passage the model was shown, in rank order, not only the ones it used. The model is asked to mark each claim with a number like [1]. This one did not, so check the passage before you rely on the sentence.

Run it

  1. Run npx companybrain. It clones the repository into ~/.companybrain/app and asks one thing: which model provider to use. Choose “Local only” to start without a key.
  2. It builds two Docker images and starts three containers: Postgres with pgvector, the API on port 3333, and the dashboard on port 3000. Those two ports and 5432 need to be free.
  3. Open http://localhost:3000. There is no sign-in. Paste some text, drop in Markdown files, or set up a source under Connections.
  4. Stop it with npx companybrain down. Your data stays in a Docker volume until you run npx companybrain uninstall.

Installer 0.6.2, the current release, has a bug: once everything is running it prints error: webPort is not defined and exits. The stack is up regardless, so open the dashboard. The fix is merged and goes out with 0.6.3.

The CompanyBrain dashboard showing search results for “how do we ship a release”. The first result is the note titled Release process, with the matching words highlighted and its vector and keyword scores listed.
The dashboard's search page, with the twelve sample notes loaded.

Without Docker

npx companybrain dev runs the API and the dashboard directly against a Postgres you already have: version 14 or newer, with the pgvector extension. It also needs pnpm.

Before it leaves your machine

The default has no login and the API listens on every network interface. That is fine on your own computer. On a server, set ACCESS_TOKEN or AUTH_MODE=multi in .env first, and go through the self-hosting checklist.

Adding a model later

Settings, then Providers, in the dashboard. OpenAI, Anthropic and Ollama can write answers. OpenAI, Google and Ollama can make embeddings. Changing the embedding model means re-indexing, because vectors from two models cannot be compared.

Where it reads from

There are 44 connectors in the repository. Every one is tested against recorded responses, not live accounts, so expect some rough edges with real data.

The web

Web page, Sitemap, RSS / Atom, YouTube, Hacker News, Reddit, Raindrop.io

Notes, wikis and help desks

Obsidian, Notion, Google Docs, Confluence, Zendesk, Intercom, Readwise, GitBook, Coda, Raycast

Files and drives

Local files, Google Drive, OneDrive, Dropbox, Box

Code and tickets

GitHub, Linear, Jira, GitLab, Bitbucket, Sentry

Chat, mail and meetings

Slack, Gmail, Discord, Telegram, Front, Freshdesk, Granola, Fathom

Tasks and sales

Trello, Airtable, Asana, ClickUp, Todoist, HubSpot, Pipedrive, Wispr Flow

26 of them take an API token. 5 (Gmail, Google Drive, OneDrive, Dropbox and Box) take an OAuth access token that you obtain yourself and that expires, so treat those as one-off imports. 6 (Local files, Obsidian, Wispr Flow, Granola, Fathom and Raycast) read a folder. The other 7 need nothing, though a Google Doc has to be shared by link.

The folder sources read a path on the machine the API runs on. In the Docker install that is inside a container, so mount the folder in docker-compose.yml first, or use npx companybrain dev.

Text you paste, files you upload, and anything you send to the API go into the same index. PDFs are read as text. Images need a model that can see, and audio needs OpenAI's Whisper. Video also needs ffmpeg, which the Docker image does not include.

How you reach it

Several of these exist in the repository but have not been published to a package registry yet. This list says which.

Dashboard
Runs with the install

Search, ask, browse what is stored, and manage sources and providers, at port 3000.

REST API
Runs with the install

At port 3333, with an interactive reference at /docs and an OpenAPI 3.1 document at /v1/openapi.json.

MCP server
In the repository only

Four tools: search_memory, ask_memory, add_memory and list_spaces. It is not on npm yet, so the npx -y @companybrain/mcp config that the installer prints does not work. Clone the repository, run pnpm install, and point your client at the checkout:

{
  "mcpServers": {
    "companybrain": {
      "command": "pnpm",
      "args": [
        "--dir", "/path/to/companybrain",
        "--filter", "@companybrain/mcp",
        "exec", "tsx", "src/index.ts"
      ],
      "env": { "COMPANYBRAIN_API_URL": "http://localhost:3333" }
    }
  }
}
n8n node
On npm

Published as n8n-nodes-companybrain: search, ask and add.

Command line and SDKs
In the repository only

A cb command, a TypeScript SDK and a Python SDK. None is on npm or PyPI yet, so use them from a checkout.

Framework adapters
In the repository only

A LangChain retriever, Vercel AI SDK tools, and OpenAI function-calling tools.

Chrome extension
In the repository only

Saves a page or a selection. Load apps/extension as an unpacked extension.

Slack
Runs with the install

A /brain slash command is built into the API. You create the Slack app yourself; the Slack guide has the steps.

A larger test

These are from two public BEIR datasets, measured in July 2026 and scored with pytrec_eval. The metric is nDCG@10, where 1.0 would be a perfect ranking. The grey bar is BM25, the standard keyword baseline, as reported in the BEIR paper.

NFCorpus 3,633 documents, 323 questions

  1. BM25, from the BEIR paper
    0.325
  2. text-embedding-3-small
    0.385
  3. text-embedding-3-large
    0.414
  4. and a reranker
    0.430
  5. and query expansion
    0.439

SciFact 5,183 documents, 300 questions

  1. BM25, from the BEIR paper
    0.665
  2. text-embedding-3-small
    0.730
  3. text-embedding-3-large
    0.773
  4. and a reranker
    0.810
  5. reranking one passage at a time
    0.816

Every amber bar uses an OpenAI embedding model, and the reranker and query expansion call a language model on each search. So these numbers cost money to reach and to reproduce, and most of the gain over BM25 comes from the embedding model.

The run files are not in the repository. bench/BEIR.md has the commands. The only comparison here is with BM25. Nothing on this page says it beats another product.

What it does not do

  • It does not understand meaning without a model. Out of the box, search matches words. That works when your question uses the words in the document, and fails when it does not.
  • It does not know when it is wrong. A wrong passage comes back looking exactly like a right one, with a score of 1.00, as the last question in the table shows.
  • It does not run itself. There is no hosted version. You install it, back up the database, and upgrade it.
  • It does not sign in to your accounts for you. Sources take a token that you create and paste in. There is no OAuth sign-in flow.
  • It is not finished. The installer is at version 0.6 and one person builds this. Things break. If something does, open an issue.