Skip to content

A Weekly Grocery List Built From a Calorie Target

Published August 27, 2026

There is no shortage of tools that turn a calorie target into a week of meals and a shopping list. Most are free, most take fifteen seconds, and most produce something usable.

What they do not give you is a list whose quantities you can trace. The plan says "chicken breast" and the list says "chicken breast", and how much you need is a number somebody's model produced. Buy to it and you find out at the end of the week whether it was right.

This is the version where the list is a sum of gram weights that each resolved against a food catalog. It takes longer. It is worth it for one specific reason: when the week does not work, you can see which step was wrong.

Start from the plan, not from the list

A shopping list is a derived artifact. You cannot build a good one directly, because "how much chicken do I need" has no answer until you know how many meals contain chicken and at what weight.

So the order is: targets, then day templates, then a week, then the sum. The first three steps are the subject of meal planning with Claude and a real nutrition database, and the important shortcut from that post applies here too: build three or four day templates from about twenty foods and rotate them, rather than planning seven distinct days. A naive seven-distinct-day plan is a couple of hundred tool calls, which throttles against 20 a minute and would consume the entire 200-call trial budget.

Once you have a week in gram weights, the list is arithmetic.

The sum

You: Roll the week into a shopping list. Group by aisle, give me total grams per item, and then the pack sizes I actually have to buy.

Two columns matter, and the gap between them is the whole point of doing it this way.

What the plan needs. 820 g plain skyr. 1,240 g chicken thigh. 1,400 g dry red lentils. 420 g olive oil.

What the shop sells. Two 500 g tubs of skyr. Chicken in whatever the tray weighs, which is not 1,240 g. Two 750 g bags of lentils. A 500 ml bottle of oil.

Now look at the first line. The plan needs 820 g and you are buying 1,000 g. You have 180 g of skyr spare, and if you do nothing about it, one of two things happens: it goes off, or you eat it and the week silently ran over target.

This is the number that free generators hide, and it is not a small effect. Across a full list the rounding-up is routinely a meaningful fraction of a day's food.

Doing something about the remainder

Three approaches, and the best one depends on the item.

Plan the remainder in. Ask for it explicitly:

You: Adjust the plan so the quantities land on pack sizes. I would rather eat 100 g more skyr on Thursday than throw it away.

This is the right move for anything perishable with a fixed pack size. It shifts the plan slightly and keeps the totals honest, because the extra is in the plan rather than in a gap.

Carry it forward. Dry goods keep. 350 g of lentils left over is next week's opening stock, not waste, as long as your next list accounts for it, which means the list has to know what is in the cupboard.

Absorb it deliberately. Sometimes the honest answer is that this week runs 150 kcal a day over because of pack sizes, you know it, and the weekly average is what you are steering by anyway.

What not to do is leave the gap unexamined, decide the tracking is broken when the scale disagrees with the plan, and conclude the numbers were wrong. The numbers were fine. The 180 g of skyr was the problem.

Buy protein first

Same ordering logic as planning, for the same reason. Protein is the binding constraint and the expensive line, so it should be decided first and the rest of the list should fill in around it.

Practically this means the list gets built in three passes. Protein sources to hit the weekly protein total. Fats, meaning oil, nuts and dairy, to the fat floor. Then carbohydrate and vegetables to fill the remaining calories, which is the flexible part and the part that can move to whatever is cheap or in season.

One thing this workflow does not do is price anything. There is no price data in the catalog and no cost optimisation in any of the tools. If you want a cheap week, you supply the price knowledge and ask for substitutions:

You: Swap the chicken thigh for something cheaper with similar protein density and keep the macros within 5%.

That is a question the tools can answer well, because protein density per 100 g is exactly what a catalog lookup gives you. Which item is cheap this week is something only you know.

The twenty-food core

The thing that makes this whole workflow cheap, in tool calls and in effort, is that a week of eating is built from far fewer distinct foods than it appears to be.

Roughly twenty items covers most people's normal week: two or three protein sources, one or two dairy items, two or three carbohydrate staples, a fat source, a handful of vegetables, some fruit, and a couple of flavour items. Everything else is variation on top.

Resolve those twenty once and write them into your profile file with per-100 g values and their food_id:

## Core foods (per 100 g)
| Food | kcal | P | F | C | food_id |
|---|---|---|---|---|---|
| Chicken thigh, cooked, skinless | ... | ... | ... | ... | ... |
| Skyr, plain | ... | ... | ... | ... | ... |
| Oats, dry | ... | ... | ... | ... | ... |

That file is now the substrate for everything: planning a day, summing a list, logging a meal. All of it becomes arithmetic the assistant does without a tool call. Twenty calls, once, and then the marginal cost of a planned week is close to zero.

Keep the food_id alongside the macros. It is what lets you pull the full nutrient panel later if you start caring about sodium or fibre, without searching again. And re-resolve the list occasionally rather than never, because a catalog is maintained and rows do get corrected.

Turning the list into the week's log

The last step, and the one that closes the loop: the same plan that produced the list is the thing you log against.

You: Use the week's plan as the expected log. Each evening I will tell you what actually happened and you mark the differences.

Now your log has two columns: planned and actual. At the end of the week the interesting output is not the total, it is the delta: which meals moved, in which direction, and whether the pattern is systematic. Consistently eating more than planned at dinner is information. A single big Thursday is noise.

This is also how you find out whether the pack-size rounding is being absorbed or eaten. If actual runs above planned by roughly the size of your rounding gap every week, you have your answer.

Batch cooking is the highest-leverage step

The list looks very different once you decide to cook four servings at a time rather than seven distinct dinners.

Total a recipe once with calculate_recipe, get the per-serving row, save it, and that one calculation covers four logged meals. The shopping list for three batch recipes plus breakfasts is short, cheap, and contains almost no partial packs, because batch quantities round to pack sizes much more naturally than single servings do.

The recipe mechanics, including the cooking-yield trap that makes per-serving numbers wrong if you weigh the finished dish carelessly, are in recipe macros without a spreadsheet.

Adherence research is fairly consistent that the pattern people sustain beats the pattern that is optimal on paper. Three recipes and a fixed breakfast is a pattern people sustain.

Where the week will actually go wrong

Not in the arithmetic.

You will not eat exactly as planned. Something comes up, dinner happens out, the Thursday recipe does not get made. Estimating restaurant meal macros covers the meal you did not plan; the general answer is to plan the rest of that day around it rather than abandon the week.

Produce weights are nominal. A "200 g onion" is whatever onion you picked up. For vegetables this is a rounding error. For protein and fat it is not, which is why those two get weighed and the vegetables do not.

Own-brand items may not resolve. A supermarket own-brand product that the catalog and the Open Food Facts fallback both miss needs its label read instead. Barcode lookup inside Claude covers the lookup path and the fallback's failure modes.

The target might be wrong. Everything above is precision against a formula-derived calorie number. Hold it two weeks, watch a weekly average weight, adjust, and write the new figure down.

You will get bored of the twenty foods. This is the failure mode nobody plans for, and it arrives around week five. The fix is to rotate one or two items a week rather than rebuild the list: resolve the new ones, retire the ones you are tired of, keep the structure. A core list is meant to be a living file, not a diet.

Connect it

Claude Code:

claude mcp add --transport http calorie-api \
  https://calorieapiadmin.com/mcp \
  --header "X-API-Key: YOUR_KEY"

Cursor:

{
  "mcpServers": {
    "calorie-api": {
      "url": "https://calorieapiadmin.com/mcp",
      "headers": { "X-API-Key": "YOUR_KEY" }
    }
  }
}

Browser sign-in for Claude apps is off on this server until OAuth is enabled, so those are the two clients. The MCP page is the overview, the docs the tool reference, MCP pricing the plan and 7-day trial.

What we have not measured

We have not built a week this way, shopped it, eaten it, and measured the gap between planned and actual intake. That is the measurement that would tell you whether the extra effort over a free generator pays, and we have not run it.

We have also not measured how much the pack-size rounding typically adds across a real list. The effect is arithmetic and you can see it on your own list in a minute; the typical size of it across many lists is a claim we have not earned.

What is stated above is mechanism: where each quantity comes from, which step introduces the gap, and what the tools do and do not know. Prices they do not know at all.

Frequently Asked Questions

Why not just use a free meal plan and grocery list generator?

They are fast and usually usable. What they do not give you is a traceable quantity: when the week does not work you cannot tell which step was wrong. Here every quantity is a sum of gram weights that each resolved against a food catalog.

What is pack-size rounding and why does it matter?

The plan needs 820 g of skyr and the shop sells 500 g tubs, so you buy 1000 g. The spare 180 g either goes to waste or gets eaten, and if it gets eaten the week quietly ran over target. Across a whole list this is routinely a meaningful fraction of a day of food.

How do I handle the leftover amounts?

Plan them in by adjusting the plan to land on pack sizes, carry dry goods forward as next week's opening stock, or knowingly absorb the overshoot in the weekly average. What does not work is leaving the gap unexamined and then blaming the numbers.

Can it optimise my list for price?

No. There is no price data in the catalog and no cost optimisation in any tool. You can ask for a swap to something with similar protein density and it will answer that well, but which item is cheap this week is knowledge you have to supply.

What is the single biggest simplification?

Batch cooking. Total a recipe once, save the per-serving row, and that one calculation covers four logged meals. Batch quantities also round to pack sizes far more naturally than single servings do, so the list contains fewer partial packs.

← Back to all articles

Start building with the Calorie API

Get a free API key and access 4M+ foods with search, barcode lookup, and full macro data.