Last month a national magazine wrote about people using Claude as a sommelier. The writer had inherited a cupboard of old bottles from a great-aunt, photographed the labels, and asked Claude what she had. It told her the 1982 Meursault was oxidised and past saving, and that the 1972 Bordeaux came from one of the worst vintages of the decade. Both answers were correct. The piece was still, fairly, a bit sniffy about the whole exercise.
My app (https://cellarion.app) got a passing mention in it, in scare quotes, which is how I ended up thinking about why that experiment was doomed from the start.
Claude did nothing wrong there. It gave good general answers. The problem is that "is this specific bottle worth opening" is not a general question, and no amount of world knowledge gets you to it. That gap is the entire reason MCP exists, and wine turns out to be an unusually clear way to see it.
A language model knows an enormous amount about wine in general. It knows that white Burgundy from the early eighties is a lottery, that 1972 was a washout in Bordeaux, that Nebbiolo needs time. All of that is in the training data, freely available, and genuinely useful.
What it does not know is what is in your cellar.
So the questions you actually have are the ones it cannot answer. Which of my bottles is closest to falling off. What should I open tonight given I'm cooking lamb. Am I drinking faster than I'm buying. Every one of those depends entirely on private state, and the general knowledge is nearly worthless without it.
This is not a wine problem. It's the shape of most useful questions. Your codebase, your tickets, your customers, your homelab, your library. The model knows the domain and knows nothing about your instance of it.
MCP is the boring plumbing that closes that gap. That's it. It is not a way to make the model smarter. It's a way to let it see your stuff.
Cellarion is a wine cellar app. Free, open source, and I built it with friends after another service made it unreasonably hard to get my own data back out.
The MCP server exposes around 60 tools over a remote endpoint, covering the things you'd expect: search the cellar, get a bottle, place it in a rack, mark it consumed, look up a wine in the shared registry, record a tasting note. Reads mostly, writes where they make sense.
The interesting part is not the tool list. It's what happens when a model can chain them.
"What should I open tonight?"
Sounds trivial. It isn't. Answering it properly means knowing what's currently in the cellar, which of those bottles are inside their drinking window, whether anything is already open and needs finishing, and ideally what I've been drinking lately so it doesn't suggest the same Chianti for the fourth time. That's several tools and a judgement call. The model does the chaining itself; I just ask the question in the way I'd ask a person.
"What goes with lamb?"
The generic answer to this is free everywhere on the internet and completely useless, because it recommends wines I don't own. The useful version matches the dish against what's physically on my racks right now. Same question, entirely different answer, and the difference is access.
"Am I in trouble?"
Buying pace versus drinking pace, bottles clustered at the end of their window, wines I have too many of. This is the one that genuinely changed my behaviour, and it's the one that would be impossible without state. It's also, I suspect, the version of this that matters in every other domain. The model is good at noticing the pattern once it can see the data.
"Here's what we drank last night."
This is the one I didn't expect to work at all. After a party I photograph the empty bottles standing on the kitchen counter and hand the picture over. Claude reads the labels, matches them against what's actually in my cellar, and marks those bottles as consumed. It lists what it's about to do before it writes anything, which given the circumstances is the correct order of events.
Fifteen minutes of admin that I would simply never have done, turned into one message and a photograph taken while clearing up.
It's worth noticing that this is the same input as the magazine experiment. A photograph of some bottles. In that case the model could only offer general commentary, because there was nothing behind the picture. Here the photograph resolves against real inventory and turns into an action. Identical input, completely different value, and the only thing that changed is that it can see my data.
Some of this was surprising enough that it's the real reason I'm writing this up.
Your data quality becomes the model's problem.
I had a resolution function for matching a wine the user names against the shared registry. It worked acceptably for humans, who tolerate a bad first result and try again. It worked badly for a model, which takes the first plausible answer and proceeds confidently.
The specific failure: producers whose name had been typed into the wine name field as well as the producer field. A human skims past the duplication. The matcher scored those entries wrong and the model built on the bad match without hesitating. The bug had been sitting there for months, invisible, because every human user had been silently working around it.
Exposing a database to a model is a data quality audit you didn't ask for.
Writes are a different category from reads.
Reads are forgiving. If the model fetches the wrong bottle, you notice and correct it. Writes are not, especially when they touch data other people see.
Cellarion has drinking windows that are shared across every user. If a wine is marked as peaking between 2028 and 2034, everyone sees that. Letting a model write to shared reference data unsupervised is a bad idea no matter how good it is, so the workflow is that it proposes values and I confirm before anything is written. Never once regretted it.
If you build one of these, split your tools by blast radius rather than by feature area, and put the friction where the damage would be permanent. More tools is not straightforwardly better.
There's a point where adding tools starts costing you accuracy, because tool selection is itself a hard problem and the model has to pick correctly before it can do anything useful. Clear names help. Descriptions that say when not to use a tool help more than descriptions that say what it does. Annotations marking which tools are read-only and which are destructive help the client behave sensibly.
I don't have a clean number for where the ceiling is. I do know that "expose everything" is not a strategy.
It's a fresh look at your own API.
Every place my tools were confusingly named or badly scoped, the model found it by using them wrong. It can't ask a colleague what the field means. It reads the description and commits. That is a rather unforgiving reviewer and it improved the design.
It doesn't taste anything. It has no idea whether your specific bottle was stored badly, which is exactly why the magazine experiment went the way it did. Photographs of a dead cupboard are the hardest possible input, because there's nothing to check the answer against.
And I'd say this about the tool generally: it's a multiplier on what you bring. I get good code out of Claude because I've written code long enough to see the mistake immediately. I get good wine answers because I know enough to argue back. Ask it about something you can't evaluate and it sounds precisely as confident as it does when it's right. That's the part worth being careful about, and it doesn't go away when you add MCP. It just gets faster.
Pick the thing where your private state matters more than world knowledge does. That's the whole heuristic. If the general answer is already good enough, MCP adds nothing but latency. If the general answer is useless without knowing your specifics, that's where it earns its place.
For me that turned out to be two hundred bottles in my basement. It'll be something else for you. The code is open source if you want to see how the server is put together: github.com/jagduvi1/Cellarion