Skip to content

Calorie Tracking in Claude: A Full Day Logged Through MCP

Published August 3, 2026

This is one day, logged in a terminal, with the tool calls shown. Not a demo of a feature, but the actual shape of the interaction, including the parts that are awkward.

Setup assumed: the nutrition server attached to Claude Code or Cursor with an API key, as in connect a remote MCP server, and a profile file with targets in it, as in how to make Claude your personal dietitian. If you have neither yet, the overview is the place to start.

Targets for the day, from the profile: 2,150 kcal, 175 g protein.

First, the thing nobody tells you

The server does not keep your food log.

There is no log_meal tool. There are eight tools and every one of them answers a question about a food: search it, look up its nutrients, scale it to a weight, total a recipe, read a barcode, estimate a photo, compute targets. None of them writes anything down.

So the running total has to live somewhere else, and you have exactly two options. Either it lives in the conversation, which works for one session and is gone when the thread ends. Or it lives in a file the assistant reads and appends to, which survives.

Use the file. In Claude Code, a markdown file in the working directory is read on startup, so a ## Log heading at the bottom of your profile file is enough:

## Log

### 2026-11-03, target 2150 kcal / 175 g protein
- 08:10 breakfast: 612 kcal, 48 g P
- 13:05 lunch: 705 kcal, 52 g P

This is a worse experience than an app with a database, on the first day. By week three it is better, because it is a text file you can read, grep, correct, and take with you.

Breakfast

You: 220 g skyr, 60 g dry oats, one medium banana, 15 g peanut butter. Search each one.

Four searches and four portion scales. What comes back per food is a row with an identifier and macros per 100 g; the portion tool scales that row to the weight given. The pattern is always the same two steps, and it is worth watching the first few times:

search_foods { "query": "skyr plain", "limit": 5 }
  -> food_id, per_100g { kcal, protein_g, fat_g, carbs_g }

calculate_portion { "food_id": "<id from that search>", "grams": 220 }
  -> kcal, protein_g, fat_g, carbs_g for 220 g

Then the assistant sums four of those and appends a line to the log.

The awkward part. "One medium banana" is not a gram weight, and calculate_portion takes grams. The assistant has to pick a number. A medium banana is usually treated as roughly 115 to 120 g peeled, and it should tell you that is what it did. If it silently converts, ask it to state the assumption. The catalog can give you macros per 100 g of banana with confidence; nobody can tell you what your banana weighed.

This is the single largest source of error in the whole workflow, and it is not the database's fault. A kitchen scale removes it. If you are not going to weigh things, accept that you are logging a range and stop optimising the second decimal place.

The other awkward part. Dry oats and cooked oats are different rows. So are raw and cooked chicken, and dry and cooked rice. Cooked weight includes absorbed water, which dilutes everything per gram. If you weighed it dry, say dry. The catalog has both; only you know which one you put in the bowl.

Lunch, and a catalog miss

You: Shop-bought chicken and rice bowl, the own-brand one. 380 g. Barcode is on the sleeve if that helps.

Two paths here, and the second is better.

Searching by name for a supermarket own-brand ready meal is the weakest case for a name search. You will get generic "chicken and rice" rows, which are not wrong exactly, but they are not the thing you ate either. The sauce is the difference and the sauce is where the fat is.

So use the barcode. lookup_barcode takes 8 to 14 digits. It checks the catalog first and falls back to Open Food Facts when the catalog misses, which covers a lot of European and UK own-brand products that a US-centric catalog will not have. The REST equivalent of that lookup path is documented in the barcode endpoint guide.

When both miss, and they do miss, the honest fallback is:

You: No hit. Read me the label instead: per 100 g it says 138 kcal, 9.2 g protein, 4.1 g fat, 15 g carbs. Scale that to 380 g and log it as label-derived.

Now the number came off the packet and the log says where it came from. That is a better entry than a catalog row for a similar-sounding meal, and marking it means you can find it later if a week's totals look odd.

Do not let the assistant paper over a miss with a plausible generic row. Put it in your profile file as a rule: if the lookup misses, say so and ask for the label.

Dinner, as a recipe

Cooking for the household means the per-serving question, and there is a tool for exactly that.

You: Made a lentil and tomato thing for four: 400 g dry red lentils, 800 g chopped tomatoes, 60 g olive oil, 200 g onion, spices. I ate one serving.

calculate_recipe takes up to 40 ingredients as {food_id, grams} pairs plus a serving count, and returns both the total and the per-serving split. The assistant still has to search each ingredient first to get its id. The ids are not guessable, and a made-up one errors out.

Two things to hold onto. First, "one serving" assumes four equal servings, and servings from one pot are not equal. If you had the big bowl, say so and ask for 1.3 servings. Second, spices are a rounding error and skipping them is fine; oil is not, and 60 g of olive oil is over 500 kcal. Never skip the fat you cooked in. It is the most commonly omitted item in every food log ever kept.

The multi-ingredient arithmetic in REST terms is covered in recipe nutrition for multiple ingredients.

The photo shortcut, and its catch

There is a photo tool, analyze_food_photo, and it is the one place where the mechanism trips people up hardest.

Dropping a picture into the chat does not send it to the tool. MCP clients do not forward an attachment to a server, so the assistant sees your image and the server never does. What the tool takes is an image_base64 argument, raw base64 with no data: prefix, plus a content_type of image/jpeg, image/png or image/webp, with a decoded size up to 2 MB. A URL is not accepted.

In Claude Code, that means the assistant reads a file off disk and encodes it, which works because it has file access:

You: Encode ./lunch.jpg and run it through the photo tool.

So the realistic flow is: photo on your phone, into a synced folder, point the assistant at the path. Which is more friction than an app, and it is the correct amount of friction to expect from a terminal.

Paid accounts get 150 photo estimates a month and 20 a day. The trial includes 10 in total. Treat the output as a starting estimate to correct, not a log entry. The assistant names the foods and guesses the weights, and the weights are the part that is guessed.

The end-of-week read

The reason to keep the log in a file rather than a thread shows up on Sunday.

You: Read the last seven days of the log. Averages for calories and protein, which days missed protein, and one change for next week.

That is a text-processing job on a file, and it needs no tool calls at all. You get averages over the week rather than a reaction to yesterday, which is the right resolution. A single day tells you almost nothing, and daily weight noise has fooled more people than bad databases ever have.

Two things worth asking for specifically. First, the average of the days you actually logged versus the count of days you logged, because a 2,100 kcal average over four logged days out of seven is not a 2,100 kcal week. Second, protein on the days you trained versus the days you did not, which is usually where the shortfall hides.

Closing the day

You: Total for today against target.

Totals summed from the log lines, compared to 2,150 and 175 g. The useful output is not the gap itself but what it implies: if protein landed at 148 g, the fix is a change to tomorrow's breakfast, not a scoop of something at 23:00.

What a day actually costs

Four to six searches, four to six portion scales, one recipe call, maybe a barcode. Call it 12 to 16 tool calls for a carefully logged day.

Against the paid limits of 20 calls a minute, 10,000 successful calls a month and 25 foods per search, that is comfortable. Against the trial, which is 5 a minute, 200 calls total not reset on the first of the month, and 10 foods per search, that is roughly a fortnight of careful logging, which is a fair test of whether you like the workflow. The limits and the reasoning behind their shape are on MCP pricing and in rate limiting an MCP server.

The 5-per-minute trial ceiling is the one you will feel. A four-item meal is eight calls, so it will pause partway through. That is the limiter working, not a failure.

Where this is worse than an app

Being straight about it:

  • No scanner. You type barcode digits by hand. There is no camera in a terminal.
  • No offline. No server, no lookup.
  • No graphs. You have a text file. If you want a chart, ask the assistant to make one from the file.
  • No database of your history, so no streaks and no reminders. The consistency has to come from you.

Where it is better: the numbers are checkable, the log is yours in a format that will still open in ten years, and correcting a bad entry is editing a line rather than fighting a UI.

What we have not measured

We have not weighed a week of food and compared it against what an assistant totalled from the same meals. We have not measured catalog hit rate against a fixed shopping basket, or how often a name search returns the right own-brand product. Those are the two numbers that would tell you how good this actually is, and we have not produced them.

Everything above is the mechanism: which tool ran, what it returned, and where the error comes in. The error, as far as we can tell from the mechanism alone, is dominated by portion estimation rather than by the catalog, which is also what every published review of photo and manual logging finds. That is a reason to buy a scale before buying anything else.

Frequently Asked Questions

Does the MCP server save my daily log?

No. None of the eight tools writes anything down. Keep the running total in a file the client reads automatically, such as a Log section in the markdown profile file Claude Code picks up on startup.

What is the biggest source of error in a logged day?

Portion estimation, not the database. The catalog gives reliable macros per 100 g; nobody can tell you what your banana or your serving of stew weighed. A kitchen scale removes most of the error.

What happens when the catalog does not have my brand?

The barcode tool checks the catalog and then falls back to Open Food Facts. When both miss, read the per-100 g label values out loud, have them scaled to your weight, and mark the entry as label-derived. Do not accept a plausible generic row instead.

How many tool calls does a day of logging use?

Roughly 12 to 16 for a carefully logged day. Paid limits are 20 calls a minute and 10,000 successful calls a month. The trial is 5 a minute and 200 calls total, which is about a fortnight of careful logging.

Do dry and cooked weights matter?

Yes, a lot. Cooked weight includes absorbed water, so cooked rice, oats and pasta are much lower per gram than dry. The catalog holds both rows. Say which one you weighed.

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