Shelf

|7 min read
Share

Every developer I know has the same problem. The knowledge that matters, the opinions formed after three failed approaches, the architectural decisions made at 11pm, the preferences refined over years of building, lives in a graveyard of note-taking apps. Notion pages. Apple Notes. Obsidian vaults. Bear drafts. The ideas are there. The context is there. But when you open a conversation with Claude and need that context to make a real decision, you are starting from zero every single time. I got tired of that. So I built Shelf.

Repo

Shelf is a self-hostable web app and MCP server for personal knowledge. Self-hostable means you run it on your own infrastructure, either on your laptop or on a cloud service you control. You own the data, the server, and the database. Shelf has no accounts to log into, no subscription, and zero LLM calls inside the system itself. It is purely storage and retrieval, with an MCP server on top that gives Claude direct access to everything you have saved.

MCP stands for Model Context Protocol. It is an open standard that defines how AI clients like Claude communicate with external tools and data sources during a conversation. Think of it as a structured bridge. On one side is Claude. On the other side is your data. MCP defines the exact language they speak so Claude can call your tools, receive structured responses, and weave that information into its answers. Shelf implements this protocol so your stored knowledge becomes part of every conversation you have.

Shelf exposes five tools over MCP. The first is shelf_search, which runs a full-text search across all your entries. Full-text search means the system scans the actual words in your content and returns entries that match your query. The second tool is shelf_dump, which saves a new entry and optionally tags it with a source label so you know where it came from. The third is shelf_rules, which returns every entry you have marked as a rule. Rules are standing instructions for Claude, the things you want it to always factor in when talking to you. The fourth is shelf_pinned, which returns your highest-priority reference entries. The fifth is shelf_list, which shows your entries in reverse chronological order with pinned items at the top. These five tools cover every meaningful way an AI interacts with a personal knowledge store.

The storage layer is built to be swappable. By default, Shelf uses SQLite through Node's built-in node:sqlite module. SQLite is a file-based database that lives entirely on your machine as a single file. There is no database server to run, no network connection involved, and no external account to create. You run npm run db:init once and a file called shelf.db appears in your project directory. That file is your entire database. For cloud deployments, Shelf ships with a full Supabase adapter. Supabase is a hosted Postgres database service with a generous free tier. Postgres is a production-grade relational database used by large-scale applications worldwide. You switch one environment variable, SHELF_STORAGE_ADAPTER=supabase, and Shelf routes all storage operations through Supabase instead of your local file.

There are two setup paths and I designed them to serve genuinely different people. The local path is for developers comfortable in a terminal. You clone the repository, run four commands, and Shelf is live at localhost:3000 with an MCP server ready for Claude Desktop. The whole process takes about three minutes. The cloud path is for anyone who wants Shelf reachable from every device, including the browser version of Claude.ai. You fork the repository on GitHub, create a free Supabase project, paste one SQL migration file into Supabase's query editor, and deploy to Vercel. Vercel is a hosting platform that builds and serves your Next.js application for free on their infrastructure. That path takes about ten minutes with zero terminal commands.

The cloud setup works because Vercel hosts both the web app and the MCP server under the same URL. Your web interface lives at https://your-shelf.vercel.app and the MCP endpoint lives at https://your-shelf.vercel.app/api/mcp. When you add that endpoint as a custom connector in Claude.ai's settings under Connectors, Claude gains access to your Shelf tools from any browser on any device. You save an entry from your phone on the way to a meeting. You reference it from your laptop that afternoon. Supabase keeps both in sync because both point to the same database.

The technical foundation is Next.js 14, a React framework built and maintained by Vercel. React is a JavaScript library for building user interfaces. Shelf uses Next.js in a deliberate way: the web UI and standard API routes live in the App Router, which is Next.js's newer file-based routing system, and the MCP server lives in the Pages Router, which is the older routing system. The MCP server requires the Pages Router because it needs direct access to Node's raw HTTP request and response objects. The App Router abstracts those away in a way that breaks the MCP transport layer. Both routing systems coexist in the same project without conflict. The MCP SDK handles two transport modes from the same tool registration code: stdio for Claude Desktop, where the process communicates through standard input and output streams, and Streamable HTTP for Claude.ai, where communication happens over a standard web request.

Every storage adapter in Shelf implements a shared TypeScript interface called StorageAdapter. TypeScript is a version of JavaScript that adds type annotations, meaning you declare the exact shape your data takes and the TypeScript compiler verifies that your code respects those shapes. The StorageAdapter interface declares the methods every adapter must implement: saving entries, retrieving them, searching them, updating them, and deleting them. The web app and MCP server write code against this interface and have zero knowledge of which database sits underneath. The adapter handles every database-specific detail in isolation. Adding a new adapter for any database means implementing this one interface and registering it in the factory file. The architecture makes contribution a well-scoped task.

I made one architectural decision that I consider the most important one in the entire project. Shelf has zero LLM calls internally. There is no summarization on ingest, no embeddings generation, and no AI-powered relevance ranking. An embedding is a numerical representation of text used to measure semantic similarity between documents, the approach many AI-powered knowledge tools use to find conceptually related content. Shelf skips all of that. The search is full-text, meaning it matches the exact words you type against the exact words in your entries. This makes Shelf fast, free to run, and completely predictable. What you write is exactly what Claude receives. Your knowledge stays in your words, in your phrasing, with your original meaning intact.

One setup detail worth calling out is the Supabase migration. A database migration is a SQL script that creates the tables and indexes your application needs. SQL is the language used to define and query relational databases. Shelf ships the migration as a single file at supabase/migrations/0001_init.sql. You open Supabase's SQL editor in the browser, paste the file contents, and run it. The editor confirms success with "No rows returned." That one step creates everything the Supabase adapter needs. There is no migration CLI to install, no local Postgres to run, and no version tracking to set up for a first deployment.

The project is fully open source under the MIT license. MIT means you can use Shelf, modify it, host it, fork it, and build on top of it for any purpose, personal or commercial, as long as you include the original license text. The codebase is organized so that the entry points for contributors are obvious. The adapter directory holds all storage implementations alongside the shared interface they implement. The MCP tools directory holds each tool as a separate file. The web components directory separates layout, shelf-specific UI, and generic UI elements. Every layer is a standalone concern. You can read one directory and understand it fully without needing to hold the entire codebase in your head.

Shelf is for the kind of person whose thinking happens in fragments across many places. The entries you store do not need to be polished. They can be half-formed opinions, preferences you have refined over time, decisions you made and the reasoning behind them, rules you want Claude to always apply when talking with you. The more you put in, the richer every Claude conversation becomes. A shelf with fifty entries is a meaningfully better thinking partner than one with five. The tool is straightforward to run. The habit of dumping your knowledge into it, the same way you would leave yourself a quick note, is what compounds into something genuinely useful over time.