Skip to content

omrajguru/shelf

shelf

Shelf — self-hostable personal knowledge web app and MCP server banner

An open-source, self-hostable web app and MCP server for your personal knowledge. Dump raw text into the web UI. Your AI client (Claude.ai, Claude Desktop, any MCP-compatible tool) connects via MCP and pulls from your shelf when answering you.

Shelf has zero LLM calls. No API keys to run. It is purely storage, search, and an MCP server.

Deploy with Vercel


Pick your setup path

Path When to use it Time
Cloud (Supabase + Vercel) You want a Shelf you can hit from any device, and you want Claude.ai (web) to connect to it. No terminal commands needed. ~10 min
Local (SQLite + Claude Desktop) You want everything on your laptop and you're comfortable in a terminal. ~3 min

You can also do both at the same time — point your local Claude Desktop at your cloud Supabase and everything stays in sync.


Cloud setup (no code, no terminal)

You need three accounts: GitHub, Supabase (free), Vercel (free, sign in with GitHub). Then:

1. Fork this repo

On this page, click Fork (top right). Accept defaults. You now have your own shelf at github.com/<you>/shelf.

2. Create a Supabase project

  1. Go to supabase.comNew project.
  2. Name it shelf. Pick a database password. Pick a region close to you. Click Create.
  3. Wait ~30 seconds for it to spin up.

3. Apply the database migration

  1. In your Supabase project, click SQL Editor (left sidebar) → New query.
  2. Open supabase/migrations/0001_init.sql in your fork. Copy the whole file.
  3. Paste into the SQL editor. Click Run. You should see "Success. No rows returned."

4. Grab your Supabase keys

In Supabase: Settings (gear icon, bottom left) → API. Copy two things:

  • Project URL (looks like https://abcd1234.supabase.co)
  • anon / public key (a long eyJ... string — NOT the service role key)

Keep these safe but they're not maximally sensitive — the anon key is read/write but only against your own database, and row-level security is on by default.

5. Deploy to Vercel

Click the Deploy with Vercel button at the top of this README (or go to vercel.com/new and import your fork).

When Vercel asks for environment variables, paste in:

Name Value
SHELF_STORAGE_ADAPTER supabase
SUPABASE_URL the Project URL from step 4
SUPABASE_ANON_KEY the anon key from step 4

Click Deploy. First build takes 1–2 minutes.

6. Visit your shelf

Vercel gives you a URL like https://shelf-<random>.vercel.app. Open it. Dump your first entry. It should appear in the list immediately.

Health-check: visit <your-vercel-url>/api/health — you should see {"adapter":"supabase","ok":true,...}.

7. Connect Claude.ai

In Claude.ai: SettingsConnectorsAdd custom connector. Fill in:

Field Value
Name shelf
Remote MCP server URL <your-vercel-url>/api/mcp
OAuth Client ID leave empty
OAuth Client Secret leave empty

Save. Open a new conversation and try one of these prompts — Claude will call the relevant tool automatically:

What's in my shelf?
Save this to my shelf: I prefer Postgres over MySQL because of better JSON support and stricter types.
Search my shelf for anything I've written about API design.

You're done. Dump from any device — your laptop, your phone, your tablet — and Claude pulls from it grounded in what you wrote.


Local setup (terminal-friendly)

git clone https://github.com/omrajguru/shelf
cd shelf
npm install
cp .env.example .env.local        # no API keys to add
npm run db:init                   # creates ./shelf.db (SQLite)
npm run dev                       # web app at http://localhost:3000

In a second terminal:

npm run mcp                       # MCP server over stdio

…or skip the second terminal and wire Shelf into Claude Desktop so it spawns the MCP server itself. See docs/connect-claude.md for the exact config.

Requires Node 22.5 or newer (Shelf uses the built-in node:sqlite, no native compilation needed).


The five MCP tools

Tool What it does
shelf_search(query, limit?) Full-text search across all entries
shelf_dump(content, source?) Save a new entry
shelf_rules() Returns all entries you've marked as rules — standing instructions for the AI
shelf_pinned() Returns all pinned entries — your most important reference material
shelf_list(limit?, offset?) List entries in reverse-chronological order (pinned first) — useful for "what's in my shelf?"

The MCP server (whether stdio or /api/mcp) and the web app share the same storage adapter and database. Anything you dump in one is immediately visible to the other.

What it is not

  • A note-taking app with folders and tags
  • A RAG pipeline or AI-powered search engine
  • An app that calls any LLM or AI API internally
  • A tool that processes or summarizes content on ingest
  • A team knowledge base (v1 is personal only)

Tech stack

  • Framework: Next.js 14 (App Router for the web app, Pages Router for /api/mcp)
  • MCP: @modelcontextprotocol/sdk — stdio for Claude Desktop, Streamable HTTP for Claude.ai
  • Language: TypeScript · Styling: TailwindCSS · State: Zustand
  • Default storage: SQLite via Node's built-in node:sqlite (no native compilation, no install)
  • Cloud storage: Supabase (full implementation) · AWS (stub)

Storage adapters

Switch via SHELF_STORAGE_ADAPTER:

Adapter Status Setup
local (default) Working Zero config. Used for local dev.
supabase Working docs/adapters/supabase.md. Used for cloud / Vercel deploys.
aws Stub Open issue or PR if you want to contribute one.

Every adapter implements StorageAdapter — adding a new one is a well-scoped contribution.

Project structure

src/
├── adapters/                  # StorageAdapter implementations + factory
│   ├── types.ts
│   ├── local.ts               # node:sqlite (lazy-loaded so Vercel builds don't choke)
│   ├── supabase.ts            # @supabase/supabase-js + Postgres FTS
│   ├── aws.ts                 # stub
│   └── index.ts
├── app/                       # App Router — web UI + non-MCP API routes
│   ├── api/
│   │   ├── entries/route.ts
│   │   ├── entries/[id]/route.ts
│   │   ├── search/route.ts
│   │   └── health/route.ts
│   ├── layout.tsx
│   ├── page.tsx               # single-screen: dump + list
│   └── globals.css
├── pages/                     # Pages Router — required for raw Node req/res
│   └── api/mcp.ts             # Streamable HTTP MCP transport
├── components/
│   ├── layout/Navbar.tsx
│   ├── shelf/                 # DumpBox, EntryList, EntryDetail
│   └── ui/                    # Container, Button
├── lib/utils.ts
├── mcp/
│   ├── server.ts              # stdio transport entry (npm run mcp)
│   ├── build-server.ts        # shared tool registration (used by both transports)
│   ├── format.ts
│   └── tools/                 # search, dump, rules, pinned, list
└── store/shelf.ts             # Zustand
supabase/
└── migrations/0001_init.sql   # paste-into-SQL-editor migration
docs/
├── adapters/supabase.md
├── deploy-vercel.md
└── connect-claude.md

Scripts

Script Purpose
npm run dev Web app at http://localhost:3000 (and /api/mcp for remote MCP)
npm run mcp MCP server over stdio (for Claude Desktop)
npm run build Production build
npm run start Run the production build
npm run db:init Initialize the local SQLite DB
npm run lint ESLint

Customizing your fork

  • Brandingsrc/components/layout/Navbar.tsx uses the generic lucide Library icon. Swap it for your own logo.
  • Home copysrc/app/page.tsx has the headline and subheading. Edit them however you like.
  • Source-label suggestionssrc/components/shelf/DumpBox.tsx has the SOURCE_SUGGESTIONS array.

Open source principles

  • Default local adapter works with zero external accounts
  • No API keys, no LLM keys, no telemetry, no analytics, no phoning home
  • .env.local is in .gitignore, never committed
  • All adapters implement the full StorageAdapter interface
  • MIT licensed

Contributing

See Contributing for project conventions, adapter requirements, and pull request guidelines.

License

This project is licensed under the MIT License.

About

An open-source, self-hostable web app and MCP server for your personal knowledge. Dump raw text into the web UI. Your AI client (Claude.ai, Claude Desktop, any MCP-compatible tool) connects via MCP and pulls from your shelf when answering you.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors