Search DevTools

Jump to any tool or page

Cellarion Wine Registry

Unexplored

Public wine registry and guides: search wines, grapes, regions, appellations. No account.

jagduvi119 stars5 forksDesign & UX
View source

Install

mcp_config.json

{
  "mcpServers": {
    "app-cellarion-wine-registry": {
      "url": "https://cellarion.app/api/mcp/public",
      "type": "streamable-http"
    }
  }
}

Documentation

Cellarion

Cellarion is a hosted wine cellar app โ€” a ready-to-use online service at cellarion.app. Create a free account and start tracking your bottles, organizing them into cellars and racks, searching a shared wine registry, getting sommelier-curated drink-window recommendations, and chatting with an AI sommelier about your collection. No installation, no server, no setup โ€” just sign up and go. Every feature is free, forever.

Just want to use Cellarion? Go to cellarion.app and sign up. You do not need to clone this repository, run Docker, or host anything yourself. There's also a public demo account (Try the demo on the landing page) and an Android app on Google Play.

Cellarion is also open-source (AGPL-3.0), so if you'd prefer to run your own private instance, you can self-host it. The rest of this README covers self-hosting โ€” see Quick Start. Most people should just use the hosted service at cellarion.app.

Hosted Service (recommended)

Cellarion is live and publicly available at:

๐Ÿ‘‰ https://cellarion.app

This is the primary way to use Cellarion. Create an account and start using the full service today โ€” every feature is free, forever. No credit card, no trial clock, no paywalled features, nothing to install or maintain. If you want to chip in, optional Supporter, Patron and Benefactor tiers (monthly or yearly) and GitHub Sponsors fund development โ€” they unlock nothing extra, just our thanks.

Features

Your cellar

  • Bottle tracking โ€” Log every bottle with vintage, producer, region, price, rating, and tasting notes; add more of a bottle you already own in one click
  • Cellar & rack management โ€” Multiple cellars with customizable rack grids (up to 20ร—20) and a 3D cellar room view for physical placement
  • Open-bottle tracking โ€” Open a bottle, pour glasses over days, close or finish it โ€” with preservation-aware drink-soon nudges
  • Reserved bottles โ€” Mark bottles as "spoken for" (a birthday, a dinner) so suggestions and consume flows respect them
  • Drink-window alerts โ€” Sommelier-curated maturity windows per wine and vintage; alerts when bottles approach peak, are in window, or slipping past it
  • Rich statistics โ€” Charts, world choropleth map, breakdowns by country, grape, value, and drink status
  • Import & export โ€” Bring collections from Vivino (incl. drinking history), CellarTracker, generic CSV, or Cellarion's own JSON; export everything as JSON or a ZIP with your images

The shared registry

  • Smart search โ€” Meilisearch-powered fuzzy search with aggressive deduplication and canonical-key matching
  • Label scanning โ€” Snap a photo of a wine label and let AI fill in the details
  • Regional grape names โ€” One canonical variety per grape, displayed the way the label writes it (a Douro Port shows Tinta Roriz, an Alentejo red Aragonez โ€” both stored as Tempranillo)
  • Registry quality tooling โ€” Duplicate/fragmentation queues, cross-field domain checks, name checks, and a sommelier correction-proposal workflow keep the shared data clean

AI

  • AI cellar chat โ€” Ask questions about your collection โ€” food pairings, occasion picks, cellar health (Claude + Voyage embeddings + Qdrant; only ever answers from wines you actually own)
  • Connect your own AI โ€” A built-in MCP server lets Claude, and any MCP-capable client, read and manage your cellar conversationally
  • Bring your own models โ€” Self-hosters can point every AI feature at any OpenAI-compatible endpoint (Ollama, vLLM, LM Studio) instead of Anthropic/Voyage

Community & sharing

  • Cellar sharing โ€” Invite others to browse or co-manage a cellar with role-based access
  • Wine lists, reviews & discussions โ€” Build shareable lists, review wines, discuss them, follow other users, and get restock alerts
  • Tasting journal & wishlist โ€” Keep private notes and a want-to-try list

Platform

  • Climate monitoring โ€” Connect cellar temperature/humidity sensors (Home Assistant-friendly ingest API) with per-cellar dashboards
  • Sign in with Google โ€” Optional Google SSO alongside email/password
  • Installable app โ€” PWA with push notifications, plus an Android app on Google Play
  • Internationalization โ€” Community-translated via Weblate (help translate)
  • Privacy & GDPR โ€” Full data export, account deletion with cooling-off, one-click email opt-out, optional self-hosted cookie-free analytics (Umami)
  • Everything free โ€” Optional Supporter/Patron/Benefactor tiers (Stripe, monthly or yearly) and GitHub Sponsors fund development; they unlock nothing extra
  • Sommelier & admin tools โ€” Maturity/pricing curation surfaces, wine requests, quality reports, registry health watchdog, audit log, super-admin dashboard

Stack

  • MongoDB 7 โ€” Database (Mongoose 8)
  • Express 4 โ€” Backend API
  • React 19 โ€” Frontend (React Router 6, built with Vite 7)
  • Node.js 24 โ€” Runtime
  • Meilisearch โ€” Fuzzy search engine
  • Qdrant โ€” Vector database for AI cellar chat
  • Voyage AI โ€” Wine embedding generation (swappable for any OpenAI-compatible endpoint)
  • Anthropic Claude โ€” Label scanning + AI chat (swappable, same mechanism)
  • MCP โ€” Model Context Protocol server (/api/mcp) with OAuth, for AI assistants
  • Stripe โ€” Optional supporter payments (hosted Checkout + Portal)
  • nginx โ€” Serves the React SPA and proxies /api/ to the backend (internal)
  • Traefik โ€” External reverse proxy (bring your own; not included in this Compose file)
  • Docker Compose โ€” Containerization
  • rembg โ€” Python/Flask background removal microservice
  • Umami โ€” Optional self-hosted, cookie-free analytics (compose --profile analytics)

Self-Hosting (Quick Start)

This section is only for people who want to run their own private instance. If you just want to use Cellarion, head to cellarion.app instead โ€” no setup required.

Prerequisites

  • Docker + Docker Compose

Run the app

The app is routed through Traefik, so create the external web Docker network before the first up (compose declares it external โ€” the first command fails otherwise):

git clone https://github.com/jagduvi1/Cellarion.git
cd Cellarion
cp .env.example .env
# Edit .env and set JWT_SECRET and MEILI_MASTER_KEY to strong random strings
docker network create web        # once; skip if it already exists
docker-compose up --build
URLDescription
http://localhostFrontend (React SPA) โ€” served via Traefik
http://localhost/api/healthBackend health check

Seed demo data

After the containers are running:

docker exec cellarion-backend node src/seed-demo.js

This creates demo accounts plus a starter taxonomy, wine registry entries, and a demo cellar with sample bottles:

AccountEmailPasswordRole
Adminadmin@cellarion.appAdmin1234!demoadmin
Demo useruser@cellarion.appUser1234!demouser

These are local development credentials. Change them before deploying anywhere public.

Stop

docker-compose down          # keep data
docker-compose down -v       # also remove all volumes (wipes database)

Architecture

The tree below shows the shape of the codebase โ€” the highlights, not every file. The backend has 57 Mongoose schemas and ~65 route modules (44 top-level + admin/ + somm/), plus the MCP server.

Cellarion/
โ”œโ”€โ”€ backend/
โ”‚   โ”œโ”€โ”€ server.js                   # Entry point
โ”‚   โ””โ”€โ”€ src/
โ”‚       โ”œโ”€โ”€ app.js                  # Express app setup, mounting, rate limiters
โ”‚       โ”œโ”€โ”€ config/                 # db, plans, upload, aiConfig (models, prompts, limits)
โ”‚       โ”œโ”€โ”€ middleware/
โ”‚       โ”‚   โ”œโ”€โ”€ auth.js             # JWT + role middleware (requireAuth, requireAdmin, requireSomm)
โ”‚       โ”‚   โ””โ”€โ”€ bottleAccess.js     # requireBottleAccess(minRole) factory
โ”‚       โ”œโ”€โ”€ models/                 # 57 Mongoose schemas โ€” core: User, WineDefinition,
โ”‚       โ”‚                           #   Bottle, Cellar, Rack, WineVintageProfile/Price,
โ”‚       โ”‚                           #   WineRequest, WineCorrectionProposal, BottleImage,
โ”‚       โ”‚                           #   AuditLog, Country/Region/Appellation/Grape;
โ”‚       โ”‚                           #   community: Discussion*, Review, JournalEntry,
โ”‚       โ”‚                           #   WishlistItem, WineList, Follow, RestockAlert;
โ”‚       โ”‚                           #   infra: Notification, PushSubscription, SupportTicket,
โ”‚       โ”‚                           #   ImportSession, StripeWebhookEvent, WineEmbedding,
โ”‚       โ”‚                           #   ClimateDevice/Reading, OAuth*, McpActionLog, โ€ฆ
โ”‚       โ”œโ”€โ”€ routes/                 # ~44 top-level route modules: auth (incl. Google SSO),
โ”‚       โ”‚                           #   cellars, bottles, wines (public read), racks, chat,
โ”‚       โ”‚                           #   stats, import, export, wineRequests, wineReports,
โ”‚       โ”‚                           #   discussions, reviews, journal, wishlist, wineLists,
โ”‚       โ”‚                           #   follows, recommendations, restockAlerts, climate,
โ”‚       โ”‚                           #   notifications, support, stripe, blog, og, sitemap,
โ”‚       โ”‚                           #   users, settings, images, health, superadmin, โ€ฆ
โ”‚       โ”‚   โ”œโ”€โ”€ admin/              # /api/admin/* โ€” registry curation, taxonomy, users,
โ”‚       โ”‚   โ”‚                       #   tickets, proposals, fragmentation/cross-field queues
โ”‚       โ”‚   โ””โ”€โ”€ somm/               # /api/somm/* โ€” maturity windows, prices, wine profiles
โ”‚       โ”œโ”€โ”€ mcp/                    # MCP server: registry, tools (read/write/somm/admin),
โ”‚       โ”‚                           #   OAuth, action ledger with undo
โ”‚       โ”œโ”€โ”€ services/               # search (Meili), embedding (Voyage/OpenAI-compatible),
โ”‚       โ”‚                           #   aiChat (RAG), labelScan, enrichmentJob, audit,
โ”‚       โ”‚                           #   findOrCreateWine, imageProcessor, taxonomyMerge,
โ”‚       โ”‚                           #   registryHealthJob, crossFieldScan, statsService, โ€ฆ
โ”‚       โ”œโ”€โ”€ utils/                  # normalize (dedup), cellarAccess, drinkWindow,
โ”‚       โ”‚                           #   grapeDisplay (regional names), nameChecks,
โ”‚       โ”‚                           #   crossFieldChecks, ratingUtils, maturityUtils, โ€ฆ
โ”‚       โ”œโ”€โ”€ data/                   # Taxonomy reference JSON
โ”‚       โ””โ”€โ”€ seed-demo.js
โ”œโ”€โ”€ frontend/
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ api/                    # Typed API client modules (one per resource)
โ”‚   โ”‚   โ”œโ”€โ”€ components/             # Reusable UI (Layout, Modal, BottleCard, rack grids, โ€ฆ)
โ”‚   โ”‚   โ”œโ”€โ”€ pages/                  # App screens (cellars, bottles, stats, chat, admin, โ€ฆ)
โ”‚   โ”‚   โ”œโ”€โ”€ contexts/               # Auth, Theme, Notifications
โ”‚   โ”‚   โ”œโ”€โ”€ locales/                # i18n (Weblate-managed except en)
โ”‚   โ”‚   โ””โ”€โ”€ utils/
โ”‚   โ”œโ”€โ”€ nginx.conf                  # nginx config (SPA + /api/ proxy)
โ”‚   โ””โ”€โ”€ Dockerfile                  # Multi-stage: Node build โ†’ nginx-unprivileged
โ”œโ”€โ”€ rembg/                          # Python background-removal service
โ””โ”€โ”€ docker-compose.yml

Services

All external traffic enters through Traefik (runs on the shared web Docker network, external to this Compose file). All services inside this Compose file are internal only.

ServiceHost portDescription
Traefik80External reverse proxy (external)
nginxinternalServes React SPA + proxies /api/
BackendinternalExpress REST API (port 5000)
MongoDBinternalDatabase (port 27017)
MeilisearchinternalFuzzy search engine (port 7700)
QdrantinternalVector database (port 6333)
rembginternalBackground removal (port 5000)
Umami (+db)internalOptional analytics โ€” --profile analytics

Running behind Traefik

Cellarion is designed to sit behind a Traefik reverse proxy on a shared Docker network called web. Traefik handles incoming HTTP on port 80 (SSL termination is handled upstream by Cloudflare or similar).

Requirements:

  • A running Traefik instance connected to an external Docker network named web
  • The web network must exist before starting Cellarion: docker network create web

The frontend service declares the following Traefik labels in docker-compose.yml:

traefik.enable: "true"
traefik.docker.network: "web"
traefik.http.routers.cellarion.rule: "Host(`cellarion.app`)"
traefik.http.routers.cellarion.entrypoints: "web"
traefik.http.services.cellarion.loadbalancer.server.port: "8080"

The upstream port is 8080 (not 80): the frontend image is built on nginxinc/nginx-unprivileged, whose non-root nginx cannot bind ports below 1024.

Update the Host(...) rule to match your own domain.


Connect your AI (MCP)

Cellarion ships a built-in Model Context Protocol server, so AI assistants can read and manage your cellar conversationally โ€” "what should I open tonight?", "add these six bottles", "set the drink window for this vintage".

  • Personal server โ€” https://cellarion.app/api/mcp (OAuth; your own cellar, read/write/consume scopes, sommelier and admin tools for those roles, with an action ledger and undo_last)
  • Public registry server โ€” https://cellarion.app/api/mcp/public (no signup; read-only shared wine registry)
  • Setup guide โ€” cellarion.app/connect-ai has copy-paste config for Claude (web/Desktop/Code) and other MCP clients
  • Also published as cellarion-mcp on npm and in the official MCP registry (app.cellarion/cellarion, app.cellarion/wine-registry)

Self-hosted instances serve the same endpoints from their own origin โ€” the /connect-ai page renders instance-specific snippets automatically.


Core Concepts

EntityDescription
WineDefinitionVintage-neutral wine entry in the shared registry. Admin-managed; grows via user wine requests, imports, and sommelier correction proposals with one-click admin review.
BottleA user's bottle: references a WineDefinition and adds vintage, price, rating, notes, rack location, open/reserved state.
CellarNamed container of Bottles, owned by a user. Can be shared with other users via role-based access.
RackCustomizable grid (up to 20ร—20, default 8ร—4) within a Cellar for physical bottle placement, with a 3D room view.
WineVintageProfileSommelier-curated drink-window (maturity) data per wine + vintage โ€” the source of drink alerts.
WineRequestUser-submitted wine suggestion. Admins review and fulfil by creating a WineDefinition.
TaxonomyAdmin-managed Countries, Regions, Appellations, and Grapes (with regional display names) to prevent free-text proliferation.
NotificationIn-app + push notification for events like wine requests resolved, images approved, cellars shared, restocks.
SupportTicketUser support tickets with admin response tracking.
WineReportUser-submitted wine quality reports (wrong info, duplicates, inappropriate content).

User Roles

RoleDescription
userStandard user โ€” manages own cellars, bottles, and requests
sommelierCurates maturity windows, pricing data, tasting profiles, and correction proposals for the shared registry
adminFull access โ€” wine library, taxonomy, user management, image review, registry quality queues, audit log
super adminPlatform-level access โ€” system monitor, service health, rate limits, AI config, embedding management

API Summary

The backend exposes ~65 route modules; this is the core surface, not an exhaustive reference. Wine registry reads (/api/wines, public wine pages, OG images, sitemap) are public; everything personal requires a JWT (Authorization: Bearer <token>).

Auth โ€” /api/auth

MethodPathDescription
POST/registerCreate account (sends verification email if Mailgun is configured)
POST/loginLogin, returns JWT (blocked until email is verified when Mailgun is configured)
GET/google โ†’ /google/callbackGoogle SSO (when GOOGLE_CLIENT_ID/SECRET are set)
GET/verify-email?token=Verify email address, returns JWT on success
POST/resend-verificationResend verification email
POST/forgot-passwordRequest password reset email
POST/reset-passwordReset password with token

Cellars โ€” /api/cellars (auth required)

MethodPathDescription
GET/List user's cellars
POST/Create cellar
GET/:idGet cellar + bottles
PUT/:idUpdate cellar
DELETE/:idDelete cellar
GET/:id/statisticsAggregated stats

Bottles โ€” /api/bottles (auth required)

MethodPathDescription
POST/Add bottle to cellar
PUT/:idUpdate bottle
DELETE/:idRemove bottle
POST/:id/consume ยท /:id/open ยท pour/closeDrink-tracking lifecycle
POST/import/validateValidate import data and match wines (registry-read-only)
POST/import/confirmCreate bottles from validated import

Wine Registry โ€” /api/wines

Public read. Regular-user searches are capped; admin/sommelier get full browse.

MethodPathDescription
GET/Search/filter wines. Params: search, type, country, region, grapes, sort, limit, offset
GET/:idGet a single wine definition (grapes carry displayName regional labels)

Chat โ€” /api/chat (auth required)

MethodPathDescription
POST/Send a question to the AI cellar chat (RAG pipeline)

MCP โ€” /api/mcp and /api/mcp/public

See Connect your AI. OAuth 2.0 with dynamic client registration on the personal server; the public server needs no auth.

Community (auth required)

/api/discussions, /api/reviews, /api/journal, /api/wishlist, /api/wine-lists, /api/follows, /api/recommendations, /api/restock-alerts โ€” lists, reviews, discussions, journal, wishlist, follows, and restock alerts.

Climate โ€” /api/climate (auth required)

Register cellar sensors, ingest readings (Home Assistant-friendly token auth), per-cellar dashboards.

Notifications / Stats / Support / Wine Reports / Wine Requests (auth required)

As before: /api/notifications, /api/stats/overview, /api/support, /api/wine-reports, /api/wine-requests.

Sommelier โ€” /api/somm/* (somm or admin role)

MethodPathDescription
GET/PUT/maturityCurate drink-window phases per wine + vintage
GET/POST/pricesCurate pricing data
PUT/profile/:wineIdCorrect a wine's tasting profile, type, and grapes

Admin โ€” /api/admin/* (admin role required)

Wine definitions + merges, wine requests, correction proposals, taxonomy (incl. grape regional names), registry quality queues (dupl

Sourced from the repository README.

More in Design & UX