databasedmcp

← Articles

Alternative to Vivino: a wine cellar and tasting log with ChatGPT

Know which bottles you own, which slot in the rack each one is in and what you thought of the last one you opened, by telling ChatGPT.

7 min read

databasedmcp gives your AI assistant databases it keeps between conversations, so everything in this article works from the day you connect it. Free to start, no card.

Get started free

Why build it yourself

Vivino does two jobs for many people: a record of wines they've tried and liked, and a list of what's in the rack at home. The second is the one a notebook never keeps up with, because a bottle moves or gets opened and nobody writes it down.

Both are three tables: wines, bottles and tastings. Tell ChatGPT you put 3 bottles in slots B1 to B3, and later that you opened the one in B2. It updates the rack and logs the tasting in the same conversation, and it can tell you which bottles are near the end of their drinking window.

Connect ChatGPT to databasedmcp

databasedmcp is a remote MCP server that gives AI assistants private SQLite databases, with nothing to install.

ChatGPT connects to remote MCP servers as custom connectors in developer mode. That's on paid plans, on the web. Turn on developer mode in ChatGPT's settings, then create a connector: give it a name, enter https://databasedmcp.com/mcp as the URL and choose OAuth. When ChatGPT opens a databasedmcp page, sign in and select Allow. In a new chat, turn the connector on from the tools menu.

ChatGPT moves these menus between releases. If yours look different, search its settings for developer mode and custom connectors.

Any other MCP client works the same way; the docs have the details.

Copy this prompt to build it

Paste this into ChatGPT to set up the database, its tables and its guide in one go. The rest of this article walks through what it makes and how you use it.

prompt
Set up a wine cellar and tasting log for me in databasedmcp, in one go.

1. Create a database called cellar, described as "Wine cellar: the bottles I own, where they are in the rack, and my tastings".
2. Create three tables:
   - wines: id, producer (required), name (the cuvée, optional), grape, region, vintage (a year).
   - bottles: id, wine_id (references wines), slot (where it is in the rack, like B3), bought_on (date), drink_from and drink_by (years), opened_on (NULL until I open it). One row per bottle.
   - tastings: id, wine_id (references wines), bottle_id (references bottles, empty if it wasn't one of mine), tasted_on (date, defaults to today), rating (1 to 5, optional), notes (in my words), occasion.
3. Write the database a guide that says what each table is for, to look wines up by producer and vintage before adding them so there are no duplicates, that a bottle stays in the rack until opened_on is set, and the queries for "what's in the rack and where", "what should I drink soon" and "which grapes do I rate highest".

From then on: when I buy bottles, add the wine if it's new and one bottles row per bottle with its slot. When I open one, set opened_on and log a tasting with my rating and notes. When I taste something elsewhere, log a tasting with no bottle. Show me the tables when you're finished.

Ask for the database

You don't write the schema. Describe what you want:

Set up a wine cellar in databasedmcp: the wines I own, one row per bottle with its slot in the rack and drinking window, and a tasting log with ratings. When I buy, open or taste a wine, log it.

ChatGPT creates a database called cellar and its tables:

schema
CREATE TABLE wines (
  id INTEGER PRIMARY KEY,
  producer TEXT NOT NULL,
  name TEXT,
  grape TEXT,
  region TEXT,
  vintage INTEGER
);

CREATE TABLE bottles (
  id INTEGER PRIMARY KEY,
  wine_id INTEGER NOT NULL REFERENCES wines(id),
  slot TEXT,
  bought_on TEXT,
  drink_from INTEGER,
  drink_by INTEGER,
  opened_on TEXT
);

CREATE TABLE tastings (
  id INTEGER PRIMARY KEY,
  wine_id INTEGER NOT NULL REFERENCES wines(id),
  bottle_id INTEGER REFERENCES bottles(id),
  tasted_on TEXT NOT NULL DEFAULT (date('now')),
  rating REAL CHECK (rating BETWEEN 1 AND 5),
  notes TEXT,
  occasion TEXT
);

It also writes the database a guide on how the tables are meant to be used. The guide comes back with the schema whenever an assistant looks the database up. ChatGPT files things the same way next week as today, and so does any other assistant you connect.

guide
# cellar: wine rack and tasting log

- **wines**: one row per wine and vintage. Look it up by producer and vintage before adding.
- **bottles**: one row per physical bottle. `slot` is its place in the rack. A bottle is in the rack while `opened_on` is NULL.
- **tastings**: what I thought, rated 1 to 5. `bottle_id` is set when it was one of mine.

In the rack: `SELECT b.slot, w.producer, w.name, w.vintage, b.drink_by FROM bottles b JOIN wines w ON w.id = b.wine_id WHERE b.opened_on IS NULL ORDER BY b.slot`

Drink soon (window ends by next year): `SELECT b.slot, w.producer, w.vintage, b.drink_by FROM bottles b JOIN wines w ON w.id = b.wine_id WHERE b.opened_on IS NULL AND b.drink_by <= CAST(strftime('%Y', 'now') AS INTEGER) + 1 ORDER BY b.drink_by`

Best grapes: `SELECT w.grape, count(*) AS tastings, round(avg(t.rating), 1) AS avg_rating FROM tastings t JOIN wines w ON w.id = t.wine_id GROUP BY w.grape ORDER BY avg_rating DESC`

Use it

From here on you talk, and ChatGPT writes the rows. Each request below is one statement:

I bought 3 bottles of Clos Verlaine Les Pierres 2019, a Pinot Noir from Burgundy.
execute
INSERT INTO wines (producer, name, grape, region, vintage) VALUES (?, ?, ?, ?, ?) RETURNING id
-- params: ["Clos Verlaine","Les Pierres","Pinot Noir","Burgundy",2019]
They're in slots B1 to B3. The shop said drink them between 2026 and 2030.
execute
INSERT INTO bottles (wine_id, slot, bought_on, drink_from, drink_by) VALUES (?, ?, date('now'), ?, ?), (?, ?, date('now'), ?, ?), (?, ?, date('now'), ?, ?)
-- params: [1,"B1",2026,2030,1,"B2",2026,2030,1,"B3",2026,2030]

One row per bottle, so each one keeps its own slot and can be opened on its own.

Opened the one in B2 for Sam's birthday dinner.
execute
UPDATE bottles SET opened_on = date('now') WHERE slot = ? AND opened_on IS NULL
-- params: ["B2"]
It was lovely. Cherries and a bit of earth, still young. 4 stars.
execute
INSERT INTO tastings (wine_id, bottle_id, rating, notes, occasion) VALUES (?, ?, ?, ?, ?)
-- params: [1,2,4,"Cherries and a bit of earth. Still young; the other two can wait.","Sam's birthday dinner"]

Ask it questions

Once there's data, each report you'd pay for is a single query:

What's in the rack, and where?
query
SELECT b.slot, w.producer, w.name, w.vintage, b.drink_by FROM bottles b JOIN wines w ON w.id = b.wine_id WHERE b.opened_on IS NULL ORDER BY b.slot
Anything I should drink before it's past its best?
query
SELECT b.slot, w.producer, w.vintage, b.drink_by FROM bottles b JOIN wines w ON w.id = b.wine_id WHERE b.opened_on IS NULL AND b.drink_by <= CAST(strftime('%Y', 'now') AS INTEGER) + 1 ORDER BY b.drink_by
Which grapes do I rate highest?
query
SELECT w.grape, count(*) AS tastings, round(avg(t.rating), 1) AS avg_rating FROM tastings t JOIN wines w ON w.id = t.wine_id GROUP BY w.grape ORDER BY avg_rating DESC

You can also open the database on the website, page through its rows and run read-only SQL yourself.

What you give up

Vivino recognises a wine from a photo of its label and fills in the producer, vintage and region for you. Here, you say or type them, and databasedmcp stores no photos. ChatGPT can read a label you show it, but nothing is looked up for you.

Vivino also shows what many other drinkers thought of a wine and where to buy it. There's no community rating, marketplace or price data here. The only ratings are yours, and a bottle has whatever price you write down. If you choose wine in the shop by its crowd score, take Vivino to the shop and keep the rack at home here.

Try it

databasedmcp is free to start, with no card. Free has 100 tool calls a week, enough to set this up and try it for a week. Starter has 1,000 for everyday use.

Create an account

More articles · databasedmcp · Docs