I gave my AI a memory that's just a folder of markdown I own A developer built Vellum, an open-source MCP server that gives AI agents memory as a folder of markdown files the user owns. The project avoids databases and embeddings, using a plain directory of .md files that agents can read and write via MCP, and it is available on GitHub under the MIT license. 🚀 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. try it in one command docker run --rm -p 8080:8080 -v "$PWD/vault:/vault" ghcr.io/freema/vellum point Claude at it 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.