🚀
It's live on Product Hunt today.If this resonates, an upvote genuinely helps:[Vellum on Product Hunt]
Every time I gave my AI assistant "memory," I ended up in the same place: the memory lived in someone else's database, as embeddings I couldn't read, in a cloud I didn't control. Cancel the subscription and the memory goes with it. That felt backwards.
So I built the opposite. It's called Vellum, it's open source (MIT), and the whole idea fits in one sentence:
Point your agent at a folder of markdown. It reads and writes notes over MCP. The folder stays flat files
youown.
Vellum is a small, self-hosted MCP server over a plain directory of .md
files. Any MCP client (Claude, Cursor, ChatGPT desktop, the MCP Inspector) connects to it and can list, read, write, patch, search, tag, and backlink your notes. Every note is also exposed as a first-class MCP resource (vellum://note/{path}
), so your agent can attach a note as context straight from its resource picker, no tool call, no copy-paste.
And because the "database" is just a folder, you keep editing the same vault in Obsidian, vim, or git
. Nothing is trapped.
docker run --rm -p 8080:8080 -v "$PWD/vault:/vault" ghcr.io/freema/vellum
claude mcp add --transport http vellum https://your-host/mcp
The whole project is an exercise in picking the smallest thing that just works.
No database. Ever (v1). Tags, backlinks, and task states live in an in-RAM index rebuilt in ~50 ms at startup. There's nothing to migrate, corrupt, or back up separately. Your data is the files.
No embeddings. Search is a ranked in-memory scan: the metadata index narrows by tag/dir, content is matched from a cache, results are ranked (title > tag > path > body). It's case-, diacritics-, and typo-insensitive ("preklapy" finds "překlepy") and runs in ~0.4 ms warm over a 2,000-note vault. No vector store, no warm-up, no index to rebuild. The Searcher
interface exists so I can slot in bleve if it ever hurts. It hasn't.
It never calls an LLM itself. Vellum prepares context; your agent decides. The optional "curator" tools (folder suggestions by tag overlap, orphan/untagged/stale-inbox lists) are all deterministic, no API keys, no calls out.
It's its own OAuth 2.1 issuer. One client secret, PKCE, opaque in-memory tokens that die with the process. No external identity provider, nothing phones home. Writes are conflict-safe: every read returns a content hash, and write tools reject a stale hash instead of clobbering.
Small on purpose. One static Go binary with an embedded React UI, a 24 MB distroless image, ~5 MB idle RAM, a read-only container that only ever writes into the mounted vault. docker compose up -d
and you're done, or one-click on Railway / Render / Fly.
ls
and grep
.It also ships an embedded three-pane workspace (tree / list / editor) in the same binary. It stays in sync with the vault on its own: MCP writes appear without a reload, a split view puts raw markdown beside the rendered note, and tasks (type: task
- status) filter by state. It's the "human" window into the same folder your agent is working in.
v1 is intentionally boring and solid. I'd love feedback on two things especially: the MCP tool surface (15 tools today: what's missing, what's noise?) and the no-embeddings bet (where does a pure scan stop being enough for you?).
If "your agent's memory should be files you own" resonates, the repo is here:
👉 ** github.com/freema/vellum** (MIT)
Where does a pure scan stop being enough for you: at what vault size would you reach for embeddings? That's the bet I'm least sure about.