Skip to content

Meal Planning with Claude and a Real Nutrition Database

Published August 6, 2026

Most AI meal planners produce a plan that looks right. Four meals, plausible foods, a calorie total at the bottom. The total is the problem: it is asserted, not computed, and the per-food numbers underneath it were recalled rather than looked up. Add them yourself and they often do not sum to the stated total.

Planning against a nutrition server is slower and less pretty. Every food in the plan resolves to a catalog row first, and the totals are arithmetic on those rows. This post builds one day to a target, then a week, and is honest about the call budget that costs.

Assumed setup: the server attached to Claude Code or Cursor with an API key (how to connect), and a profile file with your foods and constraints in it (how to write one). The tool list is in the overview.

Get the target from the tool, not from a rule of thumb

You: I am 34, male, 82 kg, 180 cm, lifting four times a week, desk job otherwise, cutting. Targets please.

One call to calculate_macro_targets with age, sex, weight, height, activity and goal. Out comes a calorie figure and a macro split.

What that is: resting expenditure from a standard formula, scaled by an activity multiplier, adjusted for the goal. What it is not: a measurement of your metabolism. Two people with identical inputs genuinely differ. Treat it as the starting point of a two-week experiment, adjust from the weekly average on the scale, and write the corrected number into your profile file. The REST version of the same calculation is documented in the TDEE and macro calculator guide.

Say it returns 2,150 kcal and 175 g protein. That is the constraint for everything below.

Build one day, food by food

The instruction that matters is the one that forbids guessing:

You: Build me a day at 2,150 kcal and at least 175 g protein from the foods in my profile. Search every food and scale every portion with the tools. Do not state a macro you have not looked up. Show me the per-meal subtotals.

What happens is a loop. For each food: search_foods to get a row and a food_id, then calculate_portion to scale that row to a gram weight. Then the assistant sums the meals, compares to the target, and adjusts weights.

The adjustment step is where the tooling earns its cost. A plan built from recalled numbers cannot be corrected coherently. Change the chicken from 150 g to 200 g and the new total is another guess. A plan built from catalog rows can: the per-100 g values are fixed, so scaling is exact and the assistant can solve toward the target instead of asserting it.

A first pass typically lands somewhere like 2,080 kcal and 168 g protein. Then:

You: Seven grams of protein short. Fix it without adding more than 60 kcal.

That is a real optimisation with a real answer: swap 100 g of the carb toward a lean protein source, rescale, re-total. Two more tool calls, not a rewrite.

The protein-first ordering

One practical ordering that makes the arithmetic converge faster: place protein first, then fat to a floor, then carbohydrate to fill the remaining calories.

The reason is that protein is the constrained resource and the one with the fewest substitutes. Calories are easy to add: oil, rice, bread, anything. Getting 175 g of protein out of foods you will actually eat is the part that binds. If you plan carbohydrate first you end up trying to wedge protein into a calorie budget you already spent.

Published guidance for someone lifting in a deficit tends to land around 1.6 to 2.2 g per kg, which is a range rather than a number. Pick a point, put it in the profile, hold it steady while you adjust calories. Changing two variables at once tells you nothing about either.

Then a week, and the call budget problem

Here is where a naive request goes wrong.

You: Now do the same for seven days, all different.

Count the calls. A day of four meals with four distinct foods each is 16 foods. Each needs a search and a portion scale, so 32 calls. Seven distinct days is 224 calls.

On the paid plan that is fine in total, since the monthly budget is 10,000 successful calls, but the rate limit is 20 a minute, so the assistant will be throttled partway through and the request will stall. On the 7-day trial it is worse: 5 calls a minute, and 200 calls total that never reset. A single naive week of planning would spend your entire trial budget and still not finish.

Three ways to plan a week that do not do that.

Reuse the foods. You do not eat 112 distinct foods a week. Build three or four day templates from a fixed set of about 20 foods, resolve those 20 once, and rotate the templates. That is 40 calls for the whole week, and it matches how people actually eat.

Cache the rows in your file. Once a food is resolved, its per-100 g macros do not change. Ask the assistant to write them into your profile file:

## Resolved foods (per 100 g)
- Skyr, plain: 63 kcal, 11 g P, 0.2 g F, 4 g C, food_id: <id>
- Oats, dry: 379 kcal, 13 g P, 6.5 g F, 67 g C, food_id: <id>

Now scaling a known food is arithmetic the assistant can do without a call, and you keep the food_id for when you do want the full nutrient breakdown. Re-resolve occasionally rather than never, because a catalog is not frozen.

Plan per meal, not per week. Total a recipe once with calculate_recipe (up to 40 ingredients, with a serving count) and eat it four times. One call set, four logged meals. The per-serving output is exactly the number you need, and batch cooking is the highest-adherence pattern there is anyway.

A worked day, so the shape is concrete

What a solved day looks like at 2,150 kcal and 175 g protein, for someone who eats vegetarian on weekdays and lifts in the evening. Every weight below is a weight the assistant scaled with the portion tool after resolving the food:

  • Breakfast. 250 g plain skyr, 60 g dry oats, 120 g banana, 15 g peanut butter. Around 640 kcal, high fifties in protein.
  • Lunch. 250 g cooked red lentils, 200 g roasted vegetables, 20 g olive oil, 40 g feta. Around 620 kcal, high twenties in protein.
  • Pre-training. 30 g whey in water, 80 g rice cakes. Around 420 kcal, around 27 g protein.
  • Dinner. 200 g firm tofu, 150 g cooked rice (dry weight 55 g), 200 g greens, 10 g sesame oil. Around 470 kcal, around 30 g protein.

Those subtotals are indicative of the structure, not quoted figures from a run. The exact numbers depend on which catalog rows resolve for your brand of skyr and your tofu, which is the entire point of doing the lookups rather than reading someone else's plan.

The structural lesson is in the third line. Without the shake, that day lands somewhere in the 140s for protein and no rearrangement of the other three meals fixes it inside the calorie budget. A concentrated protein source is doing work that whole foods cannot do at 2,150 kcal for an 82 kg person. If you will not use one, the honest answer is that your protein target has to come down or your calories have to go up.

Constraints the tools do not enforce

search_foods has a verified_only flag and a result limit. It does not have an allergen filter, a diet filter, or any notion of what you will not eat. Those constraints live in your profile file and are enforced by the assistant reading them, which means they are enforced about as reliably as any instruction in a prompt.

For a preference like disliking cottage cheese, that is fine. For an allergy it is not good enough. An assistant that has read no shellfish in a profile file will comply almost all of the time, and almost all of the time is the wrong standard for anaphylaxis. Read the ingredient list on anything you have not eaten before, every time, regardless of what the plan says. The tool that would let you filter a search by allergen is a REST-side capability, documented in the allergen filter guide, and it is not on the MCP surface.

The same applies to anything therapeutic. A renal diet has potassium and phosphate limits the tools do not model. A coeliac diet needs a gluten-free certification the catalog does not assert. If your diet is managing a diagnosis, the plan needs a qualified human to review it before you eat from it.

The shopping list falls out of the plan

Because the plan is in gram weights rather than in "some chicken", the list is a sum:

You: Roll the week up into a shopping list, in the units a shop sells.

820 g of skyr becomes two 500 g tubs. 1.4 kg of dry lentils becomes two 750 g bags. The rounding up is where planned intake and purchased food diverge, and it is worth seeing so you can plan what happens to the remainder. A dedicated walkthrough of that step is coming later in this series.

What a database does not fix

It does not know if you will eat it. A plan that hits 175 g of protein from foods you find joyless has an adherence problem that no amount of accuracy addresses. This is why the dislikes line in your profile matters as much as the targets line.

It does not handle restaurants well. A planned week collides with a Thursday dinner out. The move is to plan the rest of the day light and estimate the meal, not to abandon the week.

It is not clinical. Therapeutic diets (renal, coeliac, insulin-dosed diabetes, an eating-disorder history, pregnancy) need a qualified human reviewing the plan. A calorie total does not capture what those diets are managing.

It does not make the target correct. Everything above is precision against a target that came from a formula. Precision against a wrong target is still wrong. The two-week adjust loop is not optional.

What we have not measured

We have not built a week against a target, eaten it as written, and measured the error between planned and actual intake. We have not measured how often the catalog holds every food in a plan, or how far the assistant's portion assumptions land from weighed reality. There is no macro-error figure from us.

The call arithmetic above is arithmetic, and the limits are configured values you can read off MCP pricing and the nutrition://limits resource on the server. Those we can stand behind. A measured macro error we cannot, yet.

Frequently Asked Questions

Why is a tool-backed meal plan better than a prompted one?

Because it can be corrected. A plan built from recalled macros cannot be adjusted coherently: change a portion and the new total is another guess. A plan built from catalog rows has fixed per-100 g values, so rescaling is exact and the assistant can solve toward the target.

Will planning a full week hit the rate limit?

A naive week of seven distinct days is around 224 tool calls, which throttles against 20 calls a minute and would exhaust the 200-call trial budget entirely. Reuse about 20 foods across three or four day templates instead, which is roughly 40 calls.

Should I plan protein or calories first?

Protein first, then a fat floor, then carbohydrate to fill the remaining calories. Protein is the binding constraint with the fewest substitutes. Calories are easy to add at the end; wedging protein into a spent calorie budget is not.

Can I stop re-searching foods I eat every week?

Yes. Have the assistant write resolved per-100 g values and the food id into your profile file. Scaling a known food then needs no call. Re-resolve occasionally, since a catalog is not frozen.

Are the calorie targets it produces accurate for me?

They are a formula estimate scaled by an activity level, not a measurement. Hold the target two weeks, track a weekly average weight, adjust, and write the corrected figure down. Precision against a wrong target is still wrong.

← 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.