fooddb
OfficialSummary: This server exposes the fooddb nutrition database over MCP — search foods, look up products by barcode, id or source record, monitor data freshness, work the review queue, and read nutrition labels from photos.
Search foods (
search_foods): query by name (min 2 chars), up to 100 results, optionally including the Open Food Facts layer.Look up products by barcode/GTIN-8/12/13/14 (
get_product_by_barcode), by fooddb id (get_food), or by source record id such asfdc:174289(get_record_product).Query a point in time: all lookups accept an optional
snapshotdate to read historical data.Toggle OFF data: every lookup takes
include_off(default false) to include or exclude Open Food Facts products.Check data health (
health_report): each fetcher's last successful run and snapshot age versus its schedule.Work the review queue: list values held back by failed checks next to currently served values (
review_queue, up to 1000), then accept or reject them (decide_review), attributing the decision viabyand an optional note.Fix wrong merges (
split_product): move source records out of a product into their own so matching never rejoins them.Read nutrition labels (
read_label): parse a base64 JPEG/PNG/WebP into per-100 values locally via claude-cli, codex-cli, openrouter or demo, with an optionalsubmitflag to send the read and photo for human review.
Fetches the Danish Frida food composition dataset from a figshare record for ingestion into the nutrition database.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fooddb search for hummus and show calories per 100g"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
fooddb
A food nutrition database that you host yourself. It merges USDA FoodData Central, seven national food tables and Open Food Facts into one dataset. Every value keeps its source and its licence. You query it through a REST API, an MCP server or a CLI.
Why fooddb compares it with Open Food Facts, OpenNutrition and the hosted nutrition APIs.
Where the data comes from
flowchart LR
subgraph src["Sources"]
off["Open Food Facts<br/>delta files"]
dump["OFF full dump"]
fdc["USDA FoodData Central"]
tabs["National tables: BLS, CIQUAL,<br/>CoFID, Frida, Matvaretabellen,<br/>MEXT, TFDA"]
fin["Fineli — switched off"]
reg["Recipe registry"]
end
fetch["Fetchers — stream the file,<br/>then ingest.run"]
store[("food + observation")]
check["Checks + review queue"]
snap["Snapshot build, 02:30 UTC<br/>incremental: only changed products"]
serve["REST API · MCP · export<br/>monthly ODbL dump"]
eait["eait local copy"]
off -->|"every 6 h"| fetch
dump -.->|"manual, one-off"| fetch
fdc -->|"weekly, on a new release"| fetch
tabs -->|"weekly, on a new version"| fetch
fin -.->|"a manual mirror is pending"| fetch
reg -->|"computed from ingredient records"| fetch
fetch --> store --> check -->|"accepted values only"| snap --> serve
serve -->|"checks built_at hourly"| eaitSource | Country | Licence | What is fetched | How often | Contributes | Records, prod 15 Oct 2026 |
Open Food Facts | worldwide | ODbL-1.0 | JSONL delta files at | deltas every 6 h | barcoded products — the | 3,028,974 |
USDA FoodData Central | US | CC0-1.0 | JSON zips under | weekly; only a new release downloads | generic foods, dishes and branded products | 8,156 |
BLS | Germany | CC-BY-4.0 | the workbook zip linked from | weekly; only a changed zip downloads | the German composition table | 7,140 |
CIQUAL | France | etalab-2.0 | the Excel table linked from | weekly; only a new release downloads | the French composition table | 3,484 |
CoFID | UK | OGL-UK-3.0 | the dataset workbook on the | weekly; only a new attachment downloads | the UK composition table | 2,885 |
MEXT | Japan | mext-free-use | three Excel tables from | weekly; only a new release downloads | the Japanese composition table — no English names, so eait does not use it yet | 2,538 |
Matvaretabellen | Norway | NLOD-2.0 |
| weekly; only a changed file downloads | the Norwegian composition table | 2,121 |
TFDA | Taiwan | OGDL-Taiwan-1.0 | the CSV zip of | weekly; only a new version downloads | the Taiwanese composition table — no English names, so eait does not use it yet | 2,116 |
Frida | Denmark | CC-BY-4.0 |
| weekly; only a new version downloads | the Danish composition table | 1,381 |
Fineli | Finland | CC-BY-4.0 | the open-data zip at | off — fineli.fi refuses automated downloads, so a manual mirror is pending | the Finnish composition table | — |
Recipes | — | the ingredients' | computed from ingredient records, never typed in | rebuilt with each snapshot | dish values from their ingredients | 40 |
Agent-written names | ru, es | AGPL-3.0 | nothing fetched — | with the code | Russian and Spanish names for core records, loaded as | 500 × 2 (pilot) |
The same worker writes the monthly ODbL dump of the OFF layer (1st of the month, 04:00 UTC) and prunes the request log daily (03:15 UTC). docs/architecture.md has every part of this in detail — the fetchers, the checks, the queue, the snapshot and the jobs table.
Related MCP server: USDA Nutrition Database MCP Server
Install and look up a food
You need a Linux or macOS machine with git, make, Docker with Compose v2, and curl.
git clone https://github.com/eait-fit/fooddb.git && cd fooddb && make installThe install builds the stack and waits until the API answers. On the first start, the worker downloads the sources, which takes 1 to 7 minutes. Then look up an apple pie with one request:
curl "http://127.0.0.1:8000/v1/foods?q=apple+pie&limit=1"Or with one make command:
make search q="apple pie"Both return the same data, shortened here:
{"items": [{
"id": 17335,
"records": ["matvaretabellen:05.131"],
"name": {"value": "Pie, apple", "source": "matvaretabellen", "licence": "NLOD-2.0", "record": "matvaretabellen:05.131"},
"per_100": {
"ENERC_KCAL": {"value": 214.0, "unit": "kcal", "basis": "100g", "source": "matvaretabellen", "licence": "NLOD-2.0"},
"PROCNT": {"value": 2.6, "unit": "g", "basis": "100g", "source": "matvaretabellen", "licence": "NLOD-2.0"}
}
}]}Look up a packaged product with GET /v1/products/{barcode}. Say which country you are searching
for and the answer favours that country's tables: ?country=de ranks BLS records first among
equal matches. To connect an AI agent, add the MCP
server: claude mcp add --transport http fooddb http://127.0.0.1:8000/mcp.
docs/deploy.md: TLS, upgrades, backups and API keys
docs/usage.md: every endpoint, the response shape, MCP, the CLI and local sync
You can also use the hosted instance at food-api.eait.fit. Get a key in its customer portal.
Review by an agent
A value that fails a check waits in the review queue — the queue /admin/review shows a person.
An agent can work it autonomously over the HTTP API with fooddb-review, one stdlib-only Python
file (src/fooddb/reviewcli.py) that runs anywhere python3 does. It needs a key with the
review scope, read from the environment and never echoed:
export FOODDB__REVIEW__KEY=fdb_… # fooddb keys create --name agent --scope review
export FOODDB__REVIEW__URL=https://food-api.eait.fit # the default; --url overrides
fooddb-review facets # how many records wait, per source and per check
fooddb-review queue --source recipe --limit 2 # two records of the recipe slice, as JSON
fooddb-review queue --source recipe --detail # each record's values and why its checks failed
fooddb-review decide 42 43 --accept --by agent # one JSON line per id; accept serves the value
# from the next snapshot on, reject never serves itqueue filters with --source and --check and pages with --limit/--offset; decide keeps
going past a value that is no longer pending. A decision is recorded under --by, plus the key's
name when the two differ. python3 src/fooddb/reviewcli.py --help works without installing.
Contribute
CONTRIBUTING.md: the local dev setup (
./dev), tests and the PR processdocs/architecture.md: the parts and the data flow, with diagrams
docs/design.md: the pipeline, the data model and the sources
docs/decisions.md: what is settled and what is still open
docs/data-licence.md: the licence of each source and the ODbL rules
Issues: bugs and planned work
SECURITY.md: report a vulnerability privately
The code is under AGPL-3.0. The data keeps the licence of its source.
Available Tools
9 toolsdecide_reviewA
Accept a pending value (served from the next snapshot on) or reject it (never served). by names who decided.
Inputs: by (required), decision (required), observation_id (required), note. Returns: object
get_foodC
One product by its fooddb id.
Inputs: product_id (required), snapshot, include_off. Returns: object
get_product_by_barcodeC
Products with this barcode (GTIN-8, -12, -13 or -14).
Inputs: barcode (required), snapshot, include_off. Returns: object
get_record_productC
The product a source record (e.g. "fdc:174289", "off:0…") belongs to.
Inputs: record_id (required), snapshot, include_off. Returns: object
health_reportA
Data freshness: each fetcher's last successful check and the snapshot age, against its schedule.
Inputs: no named parameters. Returns: object
read_labelA
Read a nutrition label photo (base64 JPEG, PNG or WebP) into per-100 values, on this machine.
reader defaults to $FOODDB__BACKEND__LABEL_READER, else claude-cli: your own Claude subscription pays.
Nothing leaves this machine except to the model, unless submit is true: then the read and the photo
go to $FOODDB__BACKEND__SUBMIT_URL with the key in $FOODDB__BACKEND__SUBMIT_KEY, where they wait for review.
Inputs: image (required), name, reader, submit, +1 more. Returns: object
review_queueD
Values a failed check held back, grouped per source record, next to the values served now.
Inputs: limit. Returns: object
search_foodsC
Search foods and products by name.
Inputs: q (required), limit, snapshot, include_off. Returns: object
split_productB
Undo a wrong merge: move source records out of a product into one of their own. Matching never
joins them with the rest again. by names who decided.
Inputs: by (required), food_ids (required), product_id (required), note. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
The four retrieval tools (search_foods, get_food, get_product_by_barcode, get_record_product) are distinguished by lookup key, which is reasonably clear, though get_food vs get_record_product could be momentarily confused since both return a single product. review_queue and decide_review are clearly complementary read/act pairs. Overall purposes are mostly distinct.
Most tools follow a clean verb_noun pattern (search_foods, get_food, decide_review, split_product, read_label), with get_* forms used consistently for lookups. health_report and review_queue break the verb_noun convention as noun phrases, a minor deviation. No mixed casing; all snake_case.
Nine tools is well-scoped for a food database with a curation/review workflow. Each tool covers a distinct lookup path or workflow step, and none feels redundant or filler.
Retrieval is thorough (name, barcode, id, source record) and the review/merge/label-reading lifecycle is covered. However there is no direct tool to edit or create product/nutrient values, and no listing/trigger for fetchers, so manual data management has minor gaps.
Maintenance
Related MCP Connectors
Look up a packaged food by barcode, search and compare products, and check listed allergens.
Food and nutrition data: search, macros, and comparisons
Proof-backed nutrition for foods, chain menus, barcodes, supplements. Agents add what's missing.
USDA FoodData Central nutrient lookup, FDA recall watch, EU FMCG labelling via remote MCP
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to access the Open Food Facts database to query detailed food product information, nutritional data, and environmental scores. Supports product lookup by barcode, smart search with filtering, nutritional analysis, product comparison, and dietary recommendations to help users make informed food choices.51MIT
- FlicenseNot gradedqualityDmaintenanceProvides intelligent access to the USDA nutrition database through AI assistants, enabling users to search foods, compare nutritional content, find foods high in specific nutrients, and query authoritative nutrition data across 7,146+ food items through natural language.1-
- AlicenseAqualityDmaintenanceEnables natural language access to USDA's FoodData Central database with 1M+ foods, supporting search, nutrition facts, food comparison, and daily value calculations.8MIT
- AlicenseAqualityDmaintenanceEnables searching and retrieving nutrition data from the USDA FoodData Central API, with tools for food search, nutrient lookups, and bulk operations.167 npmMIT