A portable brain for all us mere mortals trying to create a second brain.
smolbren turns a folder of markdown files — an Obsidian vault, a notes directory,
anything with frontmatter — into a local, queryable knowledge graph with full-text
search on top. It doesn't impose a schema; it discovers one from the frontmatter
you already write, then lets you (or your agent) query it with Cypher and BM25.
- Ontology-first. Tools like
qmdapproach vault search embeddings-first. smolbren instead starts from the structure your notes already encode: the frontmattertypekey becomes a node type, and every frontmatter key holding[[wikilinks]]becomes a typed edge in a graph. Embeddings come on top —smolbren embedruns a local model (EmbeddingGemma-300M via ONNX, nothing leaves your machine) for semanticsimilarsearch and BM25+vectorsearch --hybrid. - Built for agents. Commands print single-line JSON to stdout, errors are
JSON on stderr with stable exit codes, and nothing is interactive. Humans pipe to
jq; agents parse directly — andsmolbren docs --agentemits the canonical ready-made skill from the running binary. - Fully local and fast. Storage is Lance on
disk under
~/.smolbren/. Indexing is incremental (blake3 content hashes, mtime+size fast path) and parses files in parallel across all cores.
Everything starts from a note like this:
---
type: book
status: reading
started: 2026-06-01
author: "[[people/ursula-k-le-guin]]"
themes: ["[[topics/anarchism]]", "[[topics/utopia]]"]
related: ["[[books/the-left-hand-of-darkness]]"]
---
# The Dispossessed
An ambiguous utopia: two worlds, one wall, and the physicist who tries to
unbuild it.From each file, smolbren index derives an id (the vault-relative path without
.md — books/the-dispossessed, the same shape wikilink targets use), a type
(book, which becomes a Cypher node label alongside the catch-all Note), a
title (the first # heading), and edges — every frontmatter key whose values
contain wikilinks becomes a relationship type (here author, themes, and
related), while scalar keys like status and started become queryable node
properties.
The discovered types and edge types are the vault's ontology: a graph schema you
never have to configure, queryable with Cypher and searchable with BM25.
Install the pre-built binary with Homebrew:
brew install junaidrahim/tap/smolbrenRelease archives for macOS and Linux on Intel/AMD and ARM64 are also available on
the GitHub Releases page.
Neither installation method requires Rust or protoc on your machine.
smolbren vault add personal ~/notes # register a vault
smolbren index # incremental index (rerun any time)
smolbren types # the discovered ontology
smolbren search "ambiguous utopia" # BM25 full-text search
smolbren query "MATCH (b:book)-[:themes]->(t:Note) RETURN b.id, t.id"
smolbren embed # embed chunks with a local model (~300MB, one-time download)
smolbren similar "two worlds divided by ideology" # semantic similarity search
smolbren search "utopia" --hybrid # BM25 + vector, fused with RRF
smolbren unresolved # enumerate dangling wikilinks
smolbren query 'MATCH (b:book) WHERE b.status = "reading" RETURN b.id, b.started'Long-running index, repair, and embed commands log their current stage and
periodic progress, throughput, and ETA to stderr. Their final machine-readable
JSON result remains on stdout.
Full documentation lives at smolbren.com: the quickstart, core concepts (vaults, ontology, indexing, search), guides for Obsidian setup, querying the graph, and scripting & agents, plus the complete CLI reference with every flag, output shape, and exit code.
This CLI is designed to be driven by agents, and skills/smolbren/SKILL.md
is a ready-made Agent Skill that teaches an agent the output
contract, the explore-the-ontology-first workflow, Cypher rules, and the common
gotchas. Install it with the skills CLI,
which detects your coding agents (Claude Code, Cursor, …) and installs it into each:
npx skills add junaidrahim/smolbrenOr generate the exact skill bundled with your installed binary:
smolbren docs --agent > ~/.claude/skills/smolbren/SKILL.md- Wikilink targets are resolved when the source note is indexed; deleting a target
leaves stale
resolvedflags on unchanged notes untilindex --full. Usesmolbren unresolvedto inspect the current queue. embedis a separate step fromindex— new or edited notes are invisible tosimilar/search --hybriduntil you run it again.vault listexposes exact lag counts and anembeddings_staleflag so this is never silent.
Full rebuilds are transactional: index --full and repair build and validate a
sibling index, atomically swap it into place, and preserve the last good index on
failure.
Requires Rust (edition 2024) and protoc on PATH (brew install protobuf).
cargo build
cargo test # includes an end-to-end CLI test over tests/fixture_vaultVersion lock: lance-graph 0.5.4 pins
lance ^1.0/arrow 56.2/datafusion 50.3. Do not bumplancepast 1.x until lance-graph tracks a newer release. Verify withcargo tree -d.
Releases are automated: every push to main runs
release-plz, which computes the next semver from
Conventional Commits, updates the changelog,
publishes to crates.io, tags a GitHub release, builds native macOS/Linux archives,
and updates the Homebrew tap. Use conventional commit messages (feat:, fix:, …)
so your change lands in the right version bump. Docs live in docs/ as a
Mintlify site and deploy on push to main.