Skip to content

Barcode Lookup Inside Claude: UPC to Macros over MCP

Published August 10, 2026

Barcode lookup is the most reliable entry in a food log. The digits identify one product, and that product has a label with numbers on it. No portion guessing, no arguing about whether the chicken was cooked.

It is also the tool people misunderstand fastest, because of one mechanical fact: there is no scanner in a chat window.

You type the digits

lookup_barcode takes a upc argument of 8 to 14 digits. That is it. It does not take a photo of a barcode, and pointing a camera at anything is not part of the flow. You read the number off the packet and type or paste it.

That sounds like a downside and partly it is. What you get in exchange is that the identification step cannot go wrong. An image-based scanner that misreads a digit gives you a confident answer about a different product. Typed digits either resolve or they do not.

For barcodes that repeat, meaning the things in your cupboard every week, this stops being a chore after the first pass, because you save them. More on that below.

What happens when the tool runs

Two stages, in order.

The catalog. The lookup goes to our food catalog first, which is where verified and provenance-tracked rows live.

Open Food Facts. On a catalog miss, the lookup falls back to Open Food Facts, a crowd-sourced product database with wide international coverage. This is the part that makes barcode lookup usable outside the US, where a catalog built primarily from US sources will miss a great deal of supermarket own-brand stock.

Know what the fallback is, though. Open Food Facts entries are contributed by the public. Most are fine. Some have a transcription error in one field, some are years out of date because the manufacturer reformulated, and some have a per-serving figure entered in the per-100 g field, which is the error that will quietly inflate or deflate your day. If a fallback row looks implausible, say 900 kcal per 100 g for a yoghurt, do not log it. Read the label instead.

The production concerns of calling Open Food Facts directly at volume are covered in Open Food Facts API rate limits, and the REST equivalent of this lookup is in the barcode lookup endpoint guide.

UPC-A, EAN-13, and the leading zero

The digit-count rule exists because barcode formats differ and the same product can be written two ways.

  • UPC-A is 12 digits, standard in the US and Canada.
  • EAN-13 is 13 digits, standard in Europe and most of the rest of the world.
  • EAN-8 is 8 digits, used on small packages.
  • GTIN-14 is 14 digits, usually a case or outer-carton code rather than the retail unit.

A UPC-A code is an EAN-13 with a leading zero. 012345678905 and 0012345678905 are the same product. Databases are inconsistent about which form they store, so if a 12-digit lookup misses, try it with a leading zero, and if a 13-digit code starting in zero misses, try it without. Ask the assistant to do both before concluding the product is absent:

You: Look up 012345678905. If that misses, try it with a leading zero too.

If you scanned a 14-digit code off a shipping carton, that is the outer case, not the retail item. Find the code on the individual package.

Sanity-check a row before you trust it

Because the fallback is crowd-contributed, it is worth knowing the one arithmetic check that catches most bad rows. It takes no tools and the assistant can do it on request.

Protein and carbohydrate supply roughly 4 kcal per gram; fat supplies roughly 9. So for any row, multiply the macros out and compare the result to the stated calorie figure:

(protein_g x 4) + (carbs_g x 4) + (fat_g x 9)  vs  kcal

Within about 10% is normal. Fibre, sugar alcohols, and the rounding that labels are legally allowed to do all account for small gaps, and alcohol at roughly 7 kcal per gram accounts for larger ones in anything containing it.

A gap of 40% or more usually means one of three specific mistakes: a per-serving figure sitting in a per-100 g field, a decimal point in the wrong place, or grams and milligrams confused in a fat entry. All three are transcription errors, and all three are common in any database that accepts public contributions.

You: Cross-check that row with the 4/4/9 rule before you log it.

Add it to your profile file as a standing instruction and it happens automatically. This is the highest-value habit in this whole workflow and it costs nothing.

The broader question of data quality (provenance, verification, what a verified row actually means) is covered in the verified foods filter guide.

What comes back, and which fields matter

A barcode lookup returns a product name, a set of macros per 100 g, and, when the catalog holds the product, a food_id you can hand to calculate_portion and get_food_nutrition.

Three practical notes on reading it.

Per 100 g is the unit, always. Not per serving, not per pack. Everything downstream is a multiplication you or the tool does. If a number in a reply is already per-pack, the assistant did the multiplication, which is fine, but you should know which one you are looking at.

Macros are four fields; nutrients are many. The lookup gives calories, protein, fat and carbohydrate, which is what a food log needs. Sodium, fibre, sugar and micronutrients come from get_food_nutrition on the food_id, and that only exists for catalog rows. If you are tracking sodium, the usual reason someone needs more than four fields, a fallback row may not carry it. Micronutrient coverage in general is discussed in the vitamin and mineral data guide.

A name match is not a confirmation. If you ask for a barcode and get back a product whose name does not sound like the thing in your hand, do not log it. Barcodes get reused across regions and repackaged products more than you would expect.

Multipacks, and other digits that are not what you want

A few recurring confusions worth naming.

Multipacks. A box of six yoghurts has its own barcode, and the individual pots often have another. Looking up the outer box gives you the box, and the macros will be per 100 g either way, but the weight you need is one pot, not the box. Find the pot weight on the pot.

Variety packs. One barcode, several different products inside. Whatever comes back is an average or a single component, and neither is the crisps you actually ate. Look up the individual bag.

Store loyalty and shelf labels. The long number on the shelf edge or on a reduced-price sticker is an internal code, not a GTIN. It will not resolve anywhere and that is correct behaviour.

Non-food barcodes. A lookup on shampoo will miss. The tool is not going to tell you that it is shampoo; it is going to tell you it found nothing.

Loose produce with a PLU. The four or five digit code on a sticker on an apple is a price-lookup code for a till, not a GTIN. Search by name instead.

Logging from a barcode

The tool returns macros per 100 g. What you ate is a portion, so there are two shapes of follow-up.

The whole pack. That is a 170 g pot, I ate all of it. Multiply the per-100 g row by 1.7. The assistant can use calculate_portion if the product resolved to a catalog food_id; for a fallback row it is arithmetic on the returned values.

Part of the pack. I had 60 g of the 500 g bag. Same arithmetic, smaller multiplier. Do not accept "one serving" as a weight. The serving size on a label is a manufacturer's choice and it is frequently not the amount any human eats. If the pack says 3 servings and you had half the pack, you had 1.5 servings, and saying so is better than rounding to 2.

The pantry pass

This is the workflow the tool is genuinely good at, and it is a one-off job that pays out for months.

Take a shelf. Read the barcode of every repeating item into the chat in one go:

You: Look these up and write each one into my pantry file with its barcode, name, and macros per 100 g: 5000112637922, 8710398515162, 4056489261025, 20134078.

Then keep the results in a file your client reads. The same profile file from how to make Claude your personal dietitian works:

## Pantry (per 100 g)
| Barcode | Item | kcal | P | F | C |
|---|---|---|---|---|---|
| 5000112637922 | ... | ... | ... | ... | ... |

From then on, logging a pantry item costs zero tool calls. The assistant reads the row and scales it. You only look up what is new.

Watch the call budget on the first pass. Twenty items is 20 calls. On the paid plan, 20 a minute is the limit, so a shelf is about a minute. On the 7-day trial it is 5 a minute against a 200-call total that never resets, so a large pantry pass is a meaningful share of the trial. Do a shelf, not the whole kitchen. The limits are on MCP pricing and the reasoning is in rate limiting an MCP server.

One thing the file does not survive: reformulation. Manufacturers change recipes and keep the barcode. Re-check a saved row if a product visibly changes, and treat anything you saved a year ago as an estimate.

When there is no barcode

Loose produce, the bakery counter, a butcher's tray, restaurant food. No barcode, so search_foods by name and accept that you are logging a generic row. For an apple that is completely fine; the variance between apples is larger than the variance between database rows for apple. For a bakery pastry it is a guess, and the guess is usually low, because commercial baked goods carry more fat than a generic row suggests.

For a plate of restaurant food, the estimate has a different shape entirely, and a later post in this series covers it.

Connecting, if you have not

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" }
    }
  }
}

Those are the two clients to use. Browser sign-in for Claude.ai, Claude Desktop and Claude mobile is off on this server until OAuth is enabled, so a guide that tells you to add this server inside a Claude app and sign in is describing something that does not work yet. The MCP page states the current position, and the docs carry the argument reference.

What we have not measured

We have not measured hit rate. Not for the catalog, not for the Open Food Facts fallback, and not by region. A pantry-scan measurement (a fixed basket of products, and how many resolve at each stage) is a reasonable thing to publish and we have not published it. Anything you read claiming a hit-rate percentage for this server is not from us.

What is documented is the lookup order, the accepted digit counts, and the failure behaviour. Those are mechanical and you can verify them on your own shelf in about a minute.

Frequently Asked Questions

Can I scan a barcode with my camera in the chat?

No. The tool takes 8 to 14 digits as text. You read the number off the packet and type or paste it. The upside is that identification cannot silently go wrong the way a misread scan can.

What happens when the catalog does not have the product?

The lookup falls back to Open Food Facts, which has wide international coverage of own-brand stock. Treat those rows with some care: they are crowd-contributed, occasionally out of date after a reformulation, and occasionally carry a per-serving figure in the per-100 g field.

My 12-digit barcode does not resolve. What now?

Try it with a leading zero. UPC-A is 12 digits and EAN-13 is 13, and a UPC-A code is an EAN-13 with a leading zero, so databases disagree about which form they store. A 14-digit code is usually an outer carton, not the retail item.

How do I avoid looking up the same foods every week?

Do one pantry pass, then have the assistant write each barcode, name and per-100 g row into a file the client reads. Logging a saved item then costs no tool calls. Re-check a row if the product is reformulated.

Is the hit rate published?

No. We have not measured hit rate for the catalog or the fallback, and not by region. The lookup order, the accepted digit counts and the failure behaviour are documented because those are mechanical; a hit-rate figure would need a measurement we have not run.

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