I Built an AI Dinner Planner to Finally Kill the 'What’s for Dinner?' Question
Every family has the same 5pm conversation, and it's a bad one. Someone asks what's for dinner, nobody has an answer, and forty minutes later you're eating cereal or paying for delivery. I got tired of the friction, so I built an AI Dinner Planner called Yossio Meals—a purpose-built app running on my own hardware that finally kills the question by connecting the recipes, the calendar, and the kitchen.
The Scattered Information Trap
The reason the dinner question is so exhausting isn't just a lack of inspiration; it’s a data fragmentation problem. To answer it well, you need to synthesize three distinct silos of information that never talk to each other. Your recipes live in one place—bookmarks, physical books, or apps. Your family calendar, with all its late meetings and soccer practices, lives in another. And the inventory of what is actually sitting in your fridge usually lives nowhere at all, existing only as a vague memory until you realize the chicken expired yesterday.
When these data points are scattered, the friction of planning becomes higher than the friction of just giving up. You end up staring at the pantry, checking your phone for the evening's schedule, and realizing you don't have the bandwidth to bridge the gap. Forty minutes later, you’re either eating cereal or paying for delivery because the mental overhead of 'figuring it out' was too high.
I’d been limping along for a while with a makeshift solution: an n8n workflow. It was a series of automated nodes that tried to stitch these pieces together, but it was a half-measure. It could move data, but it couldn't manage the nuance of a household. It lacked the interface to handle quick changes and the intelligence to understand why we were choosing certain meals over others. I realized that to actually kill the 5pm question, I didn't need a better automation script; I needed a purpose-built environment.
That realization led to Yossio Meals. I moved away from generic workflows and built a mobile-first meal-planning and shopping web app. It runs on my own hardware, tucked safely behind a Cloudflare tunnel. It isn't a generic cloud service; it’s a dedicated system designed to sit at the intersection of our recipes, our calendar, and our kitchen, turning scattered information into a concrete plan before the 5pm panic even has a chance to start.
The information needed to answer well is scattered — recipes live in one place, the family calendar in another, what's actually in the fridge nowhere at all.— Steve Yoss
The AI Dinner Planner Loop: AI Drafts, You Edit
The heart of Yossio Meals is a simple, iterative process: the AI dinner planner drafts, you edit, and the app executes. I didn’t want a chatbot that I had to haggle with; I wanted a system that could take a vague prompt about my week and turn it into a concrete schedule.
You start by telling the app what kind of week you want. You can specify how many days to plan, which meals to include, how ambitious you’re feeling, or how much time you have on a specific weeknight. You can mention cuisines that sound good or flag specific ingredients you need to use up or avoid. The app sends that context to a language model via OpenRouter—a choice that allows me to swap models from a dropdown menu whenever a better one comes along.
Crucially, what comes back isn't a wall of prose. I don't want a conversational essay about why tacos are a great Tuesday choice. The app demands strict, schema-validated data. If the model returns something malformed, the system triggers a repair retry to ensure the output is machine-readable. This ensures that every suggestion is something the app can actually process and display.
- Review the Draft
You see the full plan before anything is committed. If Tuesday looks uninspiring, you don't have to scrap the whole week.
- The Reroll
Hit the reroll button on just that specific meal to get a fresh idea without disturbing the rest of your schedule.
- Materialize the Plan
When you hit save, the schedule fills in, the shopping list is generated, and the app can optionally write events to Google Calendar and email out an itinerary.
Learning the Household Rules
A meal planner that suggests kale salads and salmon isn't helpful if your family won't touch them. To move from a generic AI chatbot to a functional household tool, the system had to understand our specific constraints. It took some hardening; early on, the model would cheerfully suggest salmon for a Tuesday night, ignoring the fact that we don't eat fish. Now, the app knows our hard rules—no fish except shrimp, no quinoa, no kale, and exactly how many people we’re feeding—and enforces them directly in the prompt.
Beyond those hard dietary boundaries, I built a feedback loop to capture the nuance of personal taste. Every time the AI makes a suggestion, it's logged. If you pick a meal, it’s marked as accepted; if you hit the reroll button to find something else, that meal is marked as rejected. Both data points are fed back into future prompts, allowing the system to gradually learn our preferences without me having to re-specify them every single week.
To keep the variety high and the friction low, I implemented a frequency penalty. If you pass on a specific suggestion, the system won't suggest it again for a few weeks, preventing the 'AI loop' where it gets stuck on a single idea. There is also a free-text dislikes list for more subjective vibes—like 'nothing too spicy' or 'no green salads'—which you can update instantly by hitting a 👎 on any suggestion during the planning phase.
The Guardrails of the Prompt
- Hard Constraints: Enforcing 'no fish except shrimp,' no quinoa, and no kale.
- Accepted/Rejected Logging: Tracking every suggestion to refine the taste profile over time.
- Frequency Penalties: Ensuring rejected ideas don't resurface for several weeks.
- The Dislike List: Real-time updates via a 👎 button for subjective preferences like spice levels.
- Household Scaling: Hard-coding the number of people to ensure portions and shopping lists remain accurate.
The Calendar is the App
The home screen is a rolling two-week grid—though there are month, week, and agenda views if I’m feeling traditional. The core philosophy here is that a meal plan shouldn’t exist in a vacuum. It overlays my actual Google Calendar on top of the meal plan, which is the entire point. If Thursday has soccer at 6:00 PM and a work dinner at 7:00 PM, you shouldn’t be planning a braise that takes three hours of active kitchen time.
Free/busy data is fed directly into the planner so it schedules around real life. I have granular control over this: I can toggle per-calendar which ones show up in the view and, more importantly, which ones the AI is actually allowed to see when it’s drafting the week. It’s the difference between the system suggesting a complex three-course meal on a night I'm working late versus suggesting something fast because it knows I'm busy.
The Day Editor and Meal Shortcuts
When you tap any day in the grid, you get a full day editor that handles the messy reality of how we actually eat. You aren't locked into the AI’s suggestions. You can type a meal in by hand, browse the existing recipe library, or paste a URL to scrape a new recipe on the fly. If you're feeling indecisive, you can let the AI generate three specific options for that slot and just pick one.
I also built in shortcuts for the 'meals' that aren't really meals, because life happens:
- 🦇 Leftovers: For when the fridge is full and nobody needs to cook.
- 🍴 Dining out: Includes a restaurant lookup via Google Places so the location is logged.
- ✈️ Away: Specifically for the 'I’m traveling and I have no idea where I’ll be' scenarios.
The interface stays out of the way—you can drag meals between days to swap Tuesday for Wednesday, and everything happens in place without annoying page reloads thanks to HTMX.
The Shopping List and My Favorite Defeat
Once the week is planned, the app rolls every recipe's ingredients into a single deduplicated, quantity-summed list. It sorts items into aisles in the order you actually walk a grocery store—produce, bakery, meat, dairy, pantry, and frozen. It handles staples you always need, multiple stores, and manual additions. But getting that list from my server into my hands at the store led to the most significant engineering failure of the project.
I really wanted the app to talk to my grocery store directly—search prices, build a cart, and clip coupons. I built the whole thing: a browser-automation stack, a remote login flow, the works. And I got comprehensively beaten by the store's bot detection. I spent a long time masking browser fingerprints, plugging WebRTC IP leaks, and defeating captchas. Every time I thought I'd won, a new check appeared. Eventually, I made the correct engineering decision, which was to delete all of it.
The replacement is almost stupid, and it works perfectly. Instead of trying to force a brittle connection, the app renders your shopping list as a big, clean, high-contrast image. It features bold aisle headers and well-spaced items laid out in columns so everything fits on one screen. I then use the grocery app's own 'import a photo of your list' feature. Their OCR does the work. No bot detection, no brittle scraping, and nothing to maintain. The lesson was that the best integration was the one where I stopped trying to be clever and used the door they'd already left open.
The Rest of the Machinery
Cook Mode and Recipe Management
When it’s time to actually make the food, the app shifts into Cook Mode. It presents ingredients and steps in a highly readable format designed for a kitchen environment, but the real value is the integrated chat. You can ask the recipe specific questions like, 'Can I substitute half-and-half?' or 'What do I do while the oven preheats?' It’s the single feature my family uses most because it bridges the gap between a static list of instructions and the messy reality of cooking.
Underneath, the system is wired into Mealie, a self-hosted recipe library. Yossio Meals acts as the planner and the brain, while Mealie serves as the pantry. Meals can be pulled from the library, saved back to it, or imported from any URL I find online.
Calendar Reconciliation
To keep the system honest, meal events written to Google Calendar are stamped with a hidden unique ID tying them to exactly one scheduled meal. This solved a frustrating bug where I’d find duplicate 'ghost' events from meals I had renamed or rescheduled months earlier—orphaned because nothing tracked which event belonged to which meal. Now, a cleanup script reconciles the calendar against the schedule and deletes anything that doesn't belong.
Nothing Motivates Like Destruction
The backup system exists because of a failure. Early on, a careless cleanup script performed a fuzzy search and deleted a real recipe I cared about with no way to recover it. Now, the app backs itself up daily, keeps two weeks of snapshots, and takes a safety snapshot before any restore. It even triggers Mealie to back itself up simultaneously. Nothing motivates a robust backup system like accidentally destroying your own data.
The Cleanup Logic
This is the logic that ensures the Google Calendar stays in sync with the internal database, preventing the 'ghost event' problem.
def reconcile_calendar(scheduled_meals, calendar_events):
# Extract hidden IDs from calendar event descriptions
calendar_map = {e.extended_props['meal_id']: e.id for e in calendar_events if 'meal_id' in e.extended_props}
for meal in scheduled_meals:
if meal.id not in calendar_map:
create_calendar_event(meal)
else:
update_calendar_event(meal, calendar_map[meal.id])
# Delete orphaned events that no longer exist in the app
orphans = set(calendar_map.keys()) - set(m.id for m in scheduled_meals)
for event_id in orphans:
delete_calendar_event(calendar_map[event_id])What It Actually Is
When you peel back the AI integrations and the grocery store workarounds, the actual architecture of this AI dinner planner is aggressively unexciting. I didn't build this to experiment with the latest frontend frameworks or to manage a complex cloud infrastructure bill. I built it to solve a persistent household friction, and that meant choosing a stack that stays out of its own way.
Under the hood, the app is powered by Python and FastAPI. I opted for server-rendered HTML enhanced with a little HTMX to keep the interface feeling snappy without the overhead of a heavy JavaScript framework. For styling, I used Tailwind, and the entire data layer lives in SQLite. The whole thing runs in Docker on a physical box in my house, tucked safely behind a Cloudflare tunnel.
There is no React, no convoluted build step, and no monthly subscription for hosting. It is boring technology on purpose. In my view, the interesting part of a project shouldn't be the stack you used to build it; it should be the fact that the tool actually works. The real success isn't the code—it’s that nobody in my house asks 'what's for dinner?' anymore.
The Philosophy of the Stack
- Complex React/Next.js frontend
- Expensive monthly cloud hosting
- Fragile browser-automation scripts
- LLM-driven arithmetic
- A 'fragile demo' mindset
- Boring, stable Python & FastAPI
- Self-hosted Docker on local hardware
- High-contrast OCR workarounds
- Deterministic Python logic for math
- A finished tool for daily life
The Blueprint for Killing the Dinner Question
- Separate Planning from Math: Use AI for creative suggestions, but let deterministic code handle quantities and scheduling logic.
- The Calendar is the Interface: A meal plan that doesn't account for soccer practice or late work meetings is a plan destined to fail.
- Bypass Bot Detection with 'Stupid' Solutions: Don't waste time scraping grocery sites; use high-contrast image exports and let the store's own OCR do the heavy lifting.
- Build a Feedback Loop: A system only becomes a 'household tool' when it learns to stop suggesting salmon to people who hate fish.
- Boring Tech Wins: Self-hosted Python, SQLite, and HTMX provide a stable, zero-cost infrastructure that doesn't require a cloud bill or a complex build step.
Questions About the Build
Why not just use ChatGPT or a generic meal planning app?
Generic apps don't know your specific calendar, and ChatGPT doesn't know what's in your recipe library or your grocery store's layout. This system bridges those gaps by treating the calendar as the primary data source.
How does the AI know what my family likes?
Every time you 'reroll' a suggestion, the system logs a rejection. Every time you save a plan, it logs an acceptance. These preferences, along with a frequency penalty, are fed back into the LLM prompt to ensure the suggestions get better over time.
Is the code for Yossio Meals open source?
Currently, this is a purpose-built tool for my own household running on my local hardware. It relies on specific integrations like Mealie and OpenRouter, but the philosophy—using structured data and 'boring' tech—is something anyone can replicate.
Build Your Own Reality
I didn't build this to sell a subscription or disrupt an industry. I built it because I wanted to solve a friction point in my own life using the tools I already know. If you're tired of the 'What's for dinner?' loop, stop looking for a better app and start looking at how you can connect your own data silos.