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., "@fooddbsearch 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: Open Food Facts 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.
| Name | Required | Description | Default |
|---|---|---|---|
| by | Yes | ||
| note | No | ||
| decision | Yes | ||
| observation_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose the consequential behavior: accept means the value is served from the next snapshot onward, reject means it is never served. It omits auth/permission requirements and any note about reversibility or rate limits, but the side-effect disclosure is genuinely valuable for a mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the accept/reject consequences front-loaded and the `by` clarification appended. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the outcome semantics of accept/reject are well covered. However, for an unannotated mutation tool the definition should also establish prerequisites (is the observation required to be pending?), the meaning of `observation_id`, and the role of `note`, none of which appear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 4 parameters, so the description must compensate. It explains `by` ('names who decided') and implicitly the two `decision` enum values, but leaves `observation_id` and the optional `note` completely undefined, covering only roughly half the surface.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a precise verb (accept/reject) and resource (a pending value under review), and clarifies the outcome of each branch. It does not explicitly name or differentiate from the sibling review_queue, but the semantics of the operation are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit statement of when to use this versus alternatives (e.g., 'call after review_queue returns a pending observation'). The phrase 'pending value' only weakly implies the precondition, leaving the agent to infer when the tool is applicable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_foodC
One product by its fooddb id.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No | ||
| product_id | Yes | ||
| include_off | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses only cardinality (one product), saying nothing about behavior when the id is not found, how the snapshot parameter affects results, or what include_off changes. For a tool with zero annotation coverage this is a substantial gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single fragment is front-loaded and wastes no words, which fits the conciseness dimension. But its brevity crosses into under-specification rather than disciplined economy, so it cannot score highly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. Still, for a three-parameter tool with 0% schema coverage and no annotations, the description leaves two parameters and all failure/mutation behavior undocumented, which is inadequate for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across three parameters. The description clarifies only product_id by naming it a 'fooddb id', which adds slight meaning beyond the schema title 'Product Id'. The snapshot and include_off parameters are entirely unexplained in both schema and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The fragment 'One product by its fooddb id' identifies the resource (a product) and the lookup key (fooddb id), so the core operation is inferable. However, it omits an explicit verb and does nothing to separate it from close siblings such as get_product_by_barcode or get_record_product. Purpose is understandable but minimally specified.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no stated prerequisites, and no mention of alternatives among the eight sibling tools. The agent must infer from the name alone that this is the id-based lookup versus the barcode-based one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_product_by_barcodeC
Products with this barcode (GTIN-8, -12, -13 or -14).
| Name | Required | Description | Default |
|---|---|---|---|
| barcode | Yes | ||
| snapshot | No | ||
| include_off | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It implies a read-only lookup by barcode, but says nothing about permissions, rate limits, whether results are cached, or what snapshot/include_off do. The barcode format note is useful context but does not cover behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single fragment with no wasted words, but it is under-specified rather than concise. For a three-parameter tool with no annotations, it fails to front-load essential usage and parameter information. Brevity here comes at the cost of completeness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained in the description. However, the tool has three parameters, zero schema description coverage, no annotations, and no usage guidance, and the description addresses only one parameter's format. It is not complete enough for an agent to reliably select and call this tool without further assumptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for three undocumented parameters. It only partially explains the barcode parameter by naming GTIN variants and completely omits the snapshot and include_off parameters. This leaves major gaps for an agent trying to invoke the tool correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the resource (products) and the lookup key (barcode) but does not state the action with a clear verb. It adds barcode format variants, which helps distinguish the input domain, but it remains a noun phrase rather than a full statement of what the tool does. It does not differentiate itself from siblings such as get_record_product.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives like search_foods or get_record_product. The description only lists acceptable barcode types, leaving usage context entirely to inference. No exclusions or prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_record_productC
The product a source record (e.g. "fdc:174289", "off:0…") belongs to.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No | ||
| record_id | Yes | ||
| include_off | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It says nothing about whether this is a read-only lookup, what a null/unknown record returns, what the 'snapshot' date or 'include_off' flag change about the result, or whether missing records error or return empty.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence with the key concept (source record → product) front-loaded and no wasted words. But the terseness crosses into under-specification rather than purposeful brevity, so it is adequate rather than good.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With three parameters at 0% schema coverage, no annotations, and no output schema explanation needed (one exists), the description is too thin for the tool's complexity. An agent cannot confidently supply snapshot or include_off, or know the failure behavior on an unknown record.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, yet it only illustrates the record_id format ('fdc:…', 'off:…'). The other two parameters, snapshot (date) and include_off (boolean, default false), get no explanation at all, leaving more than half the parameters semantically opaque.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies a relationship lookup — given a source record, return the parent product — and gives concrete record_id examples ('fdc:174289', 'off:0…'). However, it is phrased as a noun fragment with no explicit verb and does not differentiate itself from lookups like get_food or get_product_by_barcode, so an agent must guess at boundaries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this tool versus the many siblings (get_food, get_product_by_barcode, search_foods), nor any precondition or exclusion. The example ID prefixes imply the input comes from a source record, but the routing decision is left entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
health_reportA
Data freshness: each fetcher's last successful check and the snapshot age, against its schedule.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden; it does disclose the report's semantic content (last successful check, snapshot age, schedule comparison), which implies a read-only diagnostic. However, it never states that the call is non-mutating, whether it hits the network, or how fresh its own data is — gaps that matter for a staleness-diagnostic tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One compact sentence, front-loaded with the subject and then the specifics. No filler, no repetition of the name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description needn't enumerate return fields, yet it helpfully signals the key ones. For a zero-parameter, zero-annotation report tool the definition is essentially complete; only the read-only/side-effect statement is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4; there is nothing for the description to compensate for on this dimension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (a data-freshness report) and its contents — each fetcher's last successful check and snapshot age versus schedule — which is far more specific than the bare name 'health_report'. It is clearly distinct from the food/catalog siblings, though it uses a label-style fragment rather than an explicit verb.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this versus anything else, nor any precondition such as 'call before trusting snapshot data'. The only guidance is implicit in the field list. No sibling overlaps, but the description still leaves invocation timing entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| image | Yes | ||
| reader | No | ||
| submit | No | ||
| barcode | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load and does so well: it discloses local processing, the reader default chain ($FOODDB__BACKEND__LABEL_READER then claude-cli), the cost implication of subscription usage, and the exact data-egress path (SUBMIT_URL + SUBMIT_KEY) when submit is true. It omits whether a read persists to the local DB and what happens on reader failure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core action and output before the environment/egress details. The env-var references add density but each sentence carries real behavioral information, so little is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the description covers the important non-obvious behavior: local-first processing and the conditional submission flow. It is incomplete only on the undocumented name/barcode params and persistence side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate and only partly does: it documents image format (base64 JPEG/PNG/WebP), reader defaults, and submit semantics. The name and barcode parameters are never mentioned anywhere, leaving 2 of 5 parameters semantically opaque.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource (read a nutrition label photo) plus the output shape (per-100 values) and an execution constraint (on this machine). An agent can distinguish this from get_product_by_barcode or get_food. It stops short of naming any sibling explicitly, which is the only thing keeping it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies when to use it (you have a label photo to convert) and describes the submit condition that changes tool behavior, but never contrasts it against siblings like get_product_by_barcode or says when NOT to use it. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
review_queueD
Values a failed check held back, grouped per source record, next to the values served now.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It vaguely implies a read/report operation by mentioning held-back values grouped per source record, but does not disclose read/write safety, permissions, rate limits, or pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single sentence is short and not verbose, but it is cryptic and under-specified rather than front-loaded with actionable information. Its brevity does not earn its place because it fails to communicate the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need less description, but the description still omits purpose, usage guidance, and parameter meaning. For a tool with no annotations and a 0%-documented parameter, this leaves the agent without enough context to confidently select or invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has one parameter, limit, and schema description coverage is 0%. The description does not mention limit or explain its meaning, range, or impact, so it adds no parameter semantics beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description does not state a clear verb or action for the tool. It describes some data relationship ('failed check held back... next to values served now') but never says what review_queue actually does, so an agent cannot distinguish it from siblings like decide_review or health_report.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives. The description gives no indication of when this tool should be selected over other review-related sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_foodsC
Search foods and products by name.
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | ||
| limit | No | ||
| snapshot | No | ||
| include_off | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and says nothing about permissions, pagination, result ordering, or how the snapshot/include_off options change behavior. The only implicit signal is that this is a read operation because it is a search.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or redundancy. The terseness is a symptom of under-specification rather than wasteful structure, so the sentence itself is well-formed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value documentation is not required. However, for a four-parameter search tool with zero annotation coverage and zero schema description coverage, the description leaves too much undocumented, especially the non-obvious include_off and snapshot parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for four parameters. The description's 'by name' maps only to q; the cryptic include_off flag, the snapshot date, and the limit cap are left entirely unexplained in both the schema and the description, forcing the agent to guess what include_off toggles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource ('Search foods and products') plus the search dimension ('by name'), so an agent knows exactly what the call does. It does not, however, distinguish itself from siblings like get_food or get_product_by_barcode, which are lookups for individual items rather than queries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use or when-not-to-use guidance. The phrase 'by name' weakly implies the tool is for name-based lookup rather than barcode lookup, but the agent is left to infer that get_product_by_barcode or get_food are the alternatives for other access patterns.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| by | Yes | ||
| note | No | ||
| food_ids | Yes | ||
| product_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does disclose one important trait beyond the schema: the split is sticky ("Matching never joins them with the rest again"), and it notes that `by` records the decision-maker. However, it never states whether the operation is reversible, what happens to the original product if it is emptied, or whether special permissions are required — meaningful gaps for a write operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, purpose front-loaded, no filler. The middle sentence ("Matching never joins them with the rest again") is a little cryptic in phrasing, which slightly blunts the structure, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. Given a 4-parameter mutation tool with zero annotation coverage and 0% schema description coverage, the description covers purpose and one key behavior but leaves parameter semantics and mutation side effects (reversibility, fate of the source product, auth) insufficiently specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry all parameter meaning. It explains only `by` ("names who decided"); `note` is entirely undocumented, and `food_ids`/`product_id` are only loosely implied by "source records out of a product." Half the parameters remain opaque.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete verb+resource: moving source records out of a product into their own product, framed as undoing a bad merge. That is specific enough to distinguish it from the read-oriented siblings (get_food, search_foods, get_product_by_barcode). It stops short of naming the counterpart merge operation or any sibling, so it is clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Undo a wrong merge" implies the triggering situation, so usage is inferable, but there is no explicit when-to-use vs. when-not, no mention of prerequisites (e.g., needing review-queue approval, given the decide_review/review_queue siblings), and no named alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.1.0- First observed
decide_review - First observed
get_food - First observed
get_product_by_barcode - First observed
get_record_product - First observed
health_report - First observed
read_label - First observed
review_queue - First observed
search_foods - First observed
split_product
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
USDA FoodData Central nutrient lookup, FDA recall watch, EU FMCG labelling via remote MCP
Barcode lookup, nutrition search, and product comparison for 3M+ crowd-sourced food products.
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 gradedqualityDmaintenanceEnables LLMs to search for food products and retrieve detailed nutritional information from the Open Food Facts database using product names or barcodes.-
- 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