taco-br-mcp
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., "@taco-br-mcpHow many calories and protein are in 150 g of feijão carioca?"
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.
taco-br-mcp
MCP server that lets an AI assistant answer with exact numbers from the TACO — Tabela Brasileira de Composição de Alimentos, 4ª ed. (NEPA/UNICAMP, 2011) — instead of guessing. 597 Brazilian foods, 26 nutrients, per 100 g of edible portion, plus household measures ("2 colheres de sopa", "1 unidade") from the IBGE POF.
Em português: servidor MCP com a Tabela Brasileira de Composição de Alimentos (TACO). Busca alimentos, devolve nutrientes, soma refeições e converte medidas caseiras em gramas. Toda resposta cita a fonte, e o que a tabela não traz vem como "sem dado", nunca como zero.
stdio by default, for Claude Desktop, Claude Code, Cursor and other local MCP clients. It also serves Streamable HTTP (--http), which is how ChatGPT connects: see Remote HTTP and ChatGPT.
Install
Requires Node.js 20 or newer.
Claude Code
claude mcp add taco-br -- npx -y taco-br-mcpClaude Desktop (claude_desktop_config.json) and Cursor (.cursor/mcp.json)
{
"mcpServers": {
"taco-br": { "command": "npx", "args": ["-y", "taco-br-mcp"] }
}
}Then ask, for example: "Quantas kcal tem uma refeição de 4 colheres de sopa de arroz, 100 g de feijão carioca e 100 g de peito de frango grelhado?"
Related MCP server: indian-food-nutrition-mcp
Remote HTTP and ChatGPT
ChatGPT cannot reach a server running on your PC, so the same tools are available over Streamable HTTP:
npx -y taco-br-mcp --http # http://127.0.0.1:3000/mcpA public instance runs at https://taco-br-mcp.taco-br-mcp.workers.dev/mcp (open, no login, rate limited; best effort, no uptime promise). The repository also ships a Cloudflare Workers deployment (free plan, open access, per-IP rate limit). Step-by-step deploy and the ChatGPT connector setup (Settings → Apps & Connectors, developer mode, authentication "No authentication") are in docs/remote.md.
Tools
Tool | What it does |
| Find foods by Portuguese name (accent-insensitive, tolerates typos, knows regional names such as aipim/macaxeira/mandioquinha). Returns ids and kcal per 100 g. |
| Full composition of one food by id, per 100 g or scaled to a number of grams. Trace ( |
| Fatty acid profile of one food (saturated, mono/polyunsaturated, omega-3 and -6, EPA, DHA, trans, individual acids). Only 423 of 597 foods are in that TACO table; for the others it says |
| Amino acid profile of one food (lysine, leucine, tryptophan...). TACO has it for only 26 foods; for any other it says so and lists the 26. |
| Sum nutrients over |
| 2 to 10 foods side by side on chosen nutrients, per 100 g. Missing data stays |
| "2 colheres de sopa" of a food to grams, from the IBGE POF table through a hand-curated mapping (204 foods so far). Ambiguous food names return candidates; uncovered foods or measures are reported, never guessed. |
| Health check. |
All tools are read-only. Every response cites TACO 4ª ed. (NEPA/UNICAMP, 2011).
How it treats missing data
Tr(trace, below the quantification limit) is{"trace": true}, never 0.A value the table does not publish is
nulland shown as "sem dado na TACO", never 0. The source marks these cells in three ways (NA,*for "analyses under re-evaluation", or blank); the processed CSV merges them, so the server does not tell them apart. Whole milk, for example, has no published energy or protein.Fatty and amino acids come from separate TACO tables that cover only part of the foods (423 and 26 of 597). A food outside the table gets
available: false, never a row of zeros. In the amino acid table the TACO prints0,00for amounts under 0.005 g/100 g; that is a published value (shown as 0 or a small number), not missing data.calc_mealtotals are lower bounds when an item lacks data for a nutrient: the response says which foods are missing.Household weights are POF/IBGE averages, not your plate. Only foods and measures whose POF description matches the food were mapped; anything else is reported as not covered.
Mini-evaluation
15 questions about the TACO, answered by claude -p with and without the server, 3 repetitions each (90 runs per model, 30 October 2026), on three models. A numeric answer is correct when it is within 5% of the table value; for the two "honesty" questions it is correct only if it says the TACO does not publish the value (whole milk energy) or that the total is a minimum (fiber of a meal that includes chicken, which has no fiber value).
Category | Haiku 5.5 without / with | Sonnet 5.5 without / with | Opus 5.5 without / with |
Direct lookup | 12/18 / 18/18 | 16/18 / 18/18 | 18/18 / 18/18 |
Scaled grams | 9/9 / 9/9 | 9/9 / 9/9 | 9/9 / 9/9 |
Comparison | 3/3 / 3/3 | 3/3 / 3/3 | 3/3 / 3/3 |
Household units | 3/6 / 6/6 | 1/6 / 6/6 | 3/6 / 6/6 |
Whole meal | 3/3 / 3/3 | 0/3 / 3/3 | 3/3 / 3/3 |
Honesty | 1/6 / 6/6 | 3/6 / 6/6 | 3/6 / 6/6 |
Total | 31/45 / 45/45 | 32/45 / 45/45 | 39/45 / 45/45 |
Cost of 90 runs | US$ 0.22 | US$ 3.10 | US$ 5.78 |
Reading: with the server all three models got 45/45. Without it they score 31 to 39 out of 45, and the failures differ by model. Haiku gives remembered values that are wrong for single foods (vitamin C in banana prata, iron in cooked lentils), labels them as unverified, and does not flag the fiber total of the meal as a minimum. Sonnet mostly answers "no data" on household measures and meals. Opus remembers most single values and still guesses unit weights (2 boiled eggs). All three, in all 3 runs, answer 61 kcal for whole milk, a value the TACO does not publish. One side effect: Haiku with the server repeated the TACO citation in only 13 of 45 answers (the tool output always carries it); Sonnet and Opus did it in 45 of 45. Limits: 15 questions, 3 repetitions, rule-based scoring (the 5% tolerance accepted one no-MCP Sonnet answer with a wrong rice value that landed near the right sum). Questions, answer key and raw answers are in eval/ (one folder per model); to repeat: npm run build && node eval/run.mjs --model claude-haiku-5-5 && node eval/score.mjs --all --detail.
Development
npm install
npm run build
npm test
npm run inspect # MCP Inspector against dist/server.js
npm run build:data -- --fetch # regenerate data/ from the pinned upstream CSVsNever write to stdout (console.log): it is the protocol channel. Use console.error. See AGENTS.md for the project rules.
Data & license
Code: MIT. Nutritional data: TACO 4ª ed., NEPA/UNICAMP (2011). Household-measure weights: Fonte: IBGE, POF 2008-2009, Tabela de Medidas Referidas para os Alimentos Consumidos no Brasil — the grams are IBGE's, unchanged; the mapping between TACO and POF foods was curated by this project, which is responsible for it. See NOTICE.md for sources, processing and pinned versions. If you use this in research, see CITATION.cff. Not medical or nutritional advice.
Available Tools
8 toolscalc_mealCalculate the nutrients of a mealARead-only
Sum nutrients over a list of TACO foods (ids from search_food). Each item has either grams or a household_measure with quantity (e.g. "colher de sopa" x 2, covered foods only; see convert_household_measure). Totals are lower bounds when an item has no data for a nutrient: the response says which. Defaults to energy, protein, fat, carbohydrate, fiber and sodium.
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | Foods in the meal. The same food may appear more than once. | |
| nutrients | No | Nutrient keys to total. Omit for energy, protein, fat, carbohydrate, fiber and sodium. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | The meal items in the order received. |
| notes | Yes | Caveats about this answer. |
| source | Yes | Citation for the data. |
| totals | Yes | One entry per requested nutrient, in table order. |
| complete | Yes | True when every requested nutrient has data for every item (no total is a lower bound). |
| total_grams | Yes | Sum of the item quantities. |
| household_source | No | Citation for the household measure weights; set when any item used one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true; the description adds real behavioral context beyond that: totals are lower bounds when an item lacks nutrient data, and the response flags which items were affected. It also discloses that household measures are only available for curated foods. Return shape details are left to the output schema.
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, then input modes, then the caveat about lower bounds and defaults. Dense but every sentence carries information; the parenthetical example is slightly bulky but earns its place by clarifying household measures.
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 an output schema present, the description doesn't need to explain return values, and it still covers the one caveat an agent must know (lower-bound totals) plus input prerequisites. Nothing needed to invoke it correctly 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?
Schema description coverage is 100%, so the per-field docs (grams as edible portion, quantity defaulting to 1, household_measure examples) already carry the detail. The description adds only the either/or rule between grams and household_measure and the default nutrient set, both of which are also stated in the schema. Baseline 3 applies.
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?
States a specific verb and resource ('Sum nutrients over a list of TACO foods') and immediately pins the scope: it aggregates over food ids, not looks them up. That distinguishes it cleanly from search_food (which supplies the ids) and get_nutrients (single-food lookup).
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?
Routes the agent to the two prerequisite tools by name ('ids from search_food', 'see convert_household_measure'), which is exactly the context needed before calling. It stops short of explicit exclusions, e.g. when to use compare_foods or get_nutrients instead of summing a meal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_foodsCompare foods side by sideARead-only
Compare 2 to 10 TACO foods (ids from search_food) on chosen nutrients, per 100 g of edible portion. Missing data stays null or {"trace":true}; do not rank a food with null as having less.
| Name | Required | Description | Default |
|---|---|---|---|
| food_ids | Yes | TACO food numbers to compare, as returned by search_food. | |
| nutrients | No | Nutrient keys to compare. Omit for energy, protein, fat, carbohydrate, fiber and sodium. |
Output Schema
| Name | Required | Description |
|---|---|---|
| basis | Yes | Quantity all values refer to. |
| foods | Yes | The foods compared, in the order received. |
| notes | Yes | Caveats about this answer. |
| source | Yes | Citation for the data. |
| nutrients | Yes | One row per requested nutrient, in table order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds real behavioral value beyond that: the per-100 g comparison basis and the explicit caveat that missing data surfaces as null or {"trace":true} and must not be ranked as lower — a data-interpretation rule an agent would otherwise get wrong.
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 compact sentences with the scope, basis, and the null-handling caveat front-loaded. Every clause carries information; nothing is redundant filler.
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 an output schema present, the description needn't explain return structure, and it covers the essential inputs, basis, and null semantics. Minor gaps remain: it doesn't say how invalid or out-of-range food ids are handled, nor whether results come back ordered or paginated.
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 100%, so both parameters are already documented, including the default nutrient set and the min/max bounds. The description largely restates the 2–10 range and adds only the per-100 g comparison basis, so the baseline of 3 applies.
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?
States a specific verb (compare), resource (TACO foods), arity (2 to 10), selection dimension (chosen nutrients) and normalization basis (per 100 g edible portion). This clearly separates it from siblings like get_nutrients (single food detail) and calc_meal (aggregation), and it points to search_food as the id source.
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?
The description establishes the entry condition (ids from search_food) and implies when the nutrients parameter can be left out via the schema default. It does not explicitly say when to prefer this over get_nutrients or calc_meal, so routing against every sibling is left partly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
convert_household_measureConvert a household measure to gramsARead-only
Convert a Brazilian household measure (e.g. 2 colheres de sopa, 1 unidade, 1 fatia) of a TACO food to grams, using the IBGE POF table through a hand-curated mapping. Only some foods are covered; it never guesses: on ambiguity it returns candidates, and for uncovered foods or measures it says so. Pass food_id (from search_food) or food_query.
| Name | Required | Description | Default |
|---|---|---|---|
| food_id | No | TACO food number, as returned by search_food. Preferred over food_query. | |
| measure | Yes | Household measure in Portuguese, e.g. "colher de sopa", "unidade", "fatia", "concha", "copo americano". | |
| quantity | No | How many of the measure (default 1; may be fractional, e.g. 0.5). | |
| food_query | No | Food name in Portuguese, used only when food_id is not given; must match exactly one food. |
Output Schema
| Name | Required | Description |
|---|---|---|
| food | No | The resolved food (not set for ambiguous_food / no_food_match). |
| grams | No | quantity x grams_per_measure (status ok). |
| notes | Yes | Caveats and next steps. |
| source | Yes | Citation for the nutrient table. |
| status | Yes | ok: grams computed. ambiguous_food: the query matched several foods, pick an id from candidates. no_food_match: no food found. no_household_data: this food has no curated household measures, ask for grams. unknown_measure: use one of available_measures. |
| measure | No | The matched household measure (status ok). |
| quantity | No | How many of the measure (status ok). |
| candidates | No | Foods matching the query (status ambiguous_food), best first. |
| household_source | Yes | Citation for the household measure weights. |
| grams_per_measure | No | Weight of one measure in grams (status ok). |
| available_measures | No | Measures known for this food (status unknown_measure). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses important behavioral constraints: only some foods are covered, the mapping is hand-curated, it never guesses, ambiguity returns candidates, and uncovered cases are reported. These are exactly the edge-case behaviors an agent needs to know before calling.
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 front-loaded with purpose and coverage constraints, then ends with the key parameter routing. It is compact and every sentence contributes useful context.
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?
Given the output schema, full parameter descriptions, and readOnly annotation, the description supplies the remaining critical context: source table, coverage limits, ambiguity handling, and uncovered-case behavior. Nothing essential for correct invocation appears to be 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?
Schema description coverage is 100%, so the schema already defines food_id, measure, quantity, and food_query in detail. The description reinforces that food_id comes from search_food and gives measure examples, but it adds little beyond the structured parameter documentation.
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 uses a specific verb and resource: converting Brazilian household measures of TACO foods to grams. It also names the underlying source (IBGE POF) and scope, so an agent can distinguish this from search_food, get_nutrients, and other siblings without opening the schema.
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?
It clearly states when this tool is appropriate and what to do before calling it by pointing to search_food for food_id. It also sets expectations for uncovered foods and ambiguous measures. It stops short of explicitly naming alternatives to use instead of this tool, but the practical usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_amino_acidsGet amino acid profile of a foodARead-only
Amino acid profile (lysine, leucine, tryptophan, etc.) of one TACO food by id, per 100 g or scaled to grams. TACO only has it for 26 foods; others return available:false with the list of foods that do (not zero).
| Name | Required | Description | Default |
|---|---|---|---|
| grams | No | Quantity in grams of edible portion. Omit for the table basis of 100 g. | |
| food_id | Yes | TACO food number, as returned by search_food. | |
| nutrients | No | Keys to return (e.g. "lysine_g", "leucine_g", "tryptophan_g"). Omit for all. |
Output Schema
| Name | Required | Description |
|---|---|---|
| food | Yes | |
| notes | Yes | Caveats about this table, this food or this answer. |
| scaled | Yes | True when amounts were computed from the per-100 g table values for another quantity. |
| source | Yes | Citation for the data. |
| available | Yes | False when this TACO table has no row for the food. That is missing data, not zero: nutrients is empty. |
| nutrients | Yes | Requested entries, in table order. Empty when available is false. |
| basis_grams | Yes | Quantity the amounts refer to, in grams of edible portion. |
| foods_with_data | No | Only when available is false and the table is small: the foods it does cover. |
| trace_nutrients | Yes | Keys reported as trace (Tr). |
| not_analyzed_nutrients | Yes | Keys with no value in the TACO table; not zero. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint; the description supplies the genuinely non-obvious behaviors: sparse coverage (26 foods) and that missing data yields available:false with a list of foods that do have it — explicitly 'not zero'. That prevents the agent from misreading absence as a zero value, which is the highest-risk failure mode here.
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 sentences, no filler: the payload definition and the unit basis come first, the coverage caveat second. Every clause carries information the agent needs before calling.
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 an output schema present, return shape needn't be described, and the safety profile is covered by readOnlyHint. Purpose, units, id provenance and the sparse-data failure mode are all stated, so nothing material is missing 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 coverage is 100%, so the schema already documents food_id provenance, the grams basis and the nutrients enum. The description's 'per 100 g or scaled to grams' and 'one TACO food by id' merely restate the schema's own 'omit for the table basis of 100 g' semantics rather than adding new detail.
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+resource ('Amino acid profile ... of one TACO food by id') and scopes it with units ('per 100 g or scaled to grams'). The enumerated examples (lysine, leucine, tryptophan) plus the 'TACO food by id' framing separate it cleanly from get_nutrients, get_fatty_acids and calc_meal.
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?
It gives a real applicability condition — only 26 foods carry this data — which tells the agent when the call will succeed. However, it never names an alternative path (e.g. get_nutrients for the general case) or says what to do after receiving available:false, so the routing decision is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_fatty_acidsGet fatty acid profile of a foodARead-only
Fatty acid profile (saturated, mono/polyunsaturated, omega-3/6, EPA, DHA, trans, and individual acids) of one TACO food by id, per 100 g or scaled to grams. Only 423 of 597 foods have it; others return available:false (not zero). Tr is {"trace":true}, missing is null.
| Name | Required | Description | Default |
|---|---|---|---|
| grams | No | Quantity in grams of edible portion. Omit for the table basis of 100 g. | |
| food_id | Yes | TACO food number, as returned by search_food. | |
| nutrients | No | Keys to return (e.g. "saturated_g", "dha_c22_6_g", "c18_3_n3_g"). Omit for all. |
Output Schema
| Name | Required | Description |
|---|---|---|
| food | Yes | |
| notes | Yes | Caveats about this table, this food or this answer. |
| scaled | Yes | True when amounts were computed from the per-100 g table values for another quantity. |
| source | Yes | Citation for the data. |
| available | Yes | False when this TACO table has no row for the food. That is missing data, not zero: nutrients is empty. |
| nutrients | Yes | Requested entries, in table order. Empty when available is false. |
| basis_grams | Yes | Quantity the amounts refer to, in grams of edible portion. |
| foods_with_data | No | Only when available is false and the table is small: the foods it does cover. |
| trace_nutrients | Yes | Keys reported as trace (Tr). |
| not_analyzed_nutrients | Yes | Keys with no value in the TACO table; not zero. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true, it discloses the partial-coverage behavior (423/597), the critical distinction that missing data yields available:false rather than zeros, and the sentinel encodings Tr = {"trace":true} and null for missing. These are exactly the traps that would cause an agent to misreport a food as zero-fat.
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 dense sentences, front-loaded with what is returned, then the caveat, then the encoding conventions. No filler and nothing repeated from the schema.
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, yet the description still supplies the return-value semantics an agent needs (trace vs null vs available:false). Combined with the complete parameter schema and readOnly annotation, nothing required to call it correctly 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?
Schema coverage is 100%, so baseline is 3; the description adds value by clarifying the 100 g default basis versus gram-scaled output and by naming the nutrient groups (saturated, mono/poly, omega-3/6, EPA, DHA, trans, individual acids) that map to the `nutrients` filter keys.
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?
States a specific resource (fatty acid profile of one TACO food) with the exact nutrient classes covered and the unit basis. It is unmistakable against siblings like get_amino_acids or get_nutrients, which cover different nutrient domains.
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?
Clear context: one food, looked up by id, with an explicit caveat that only 423 of 597 foods have the profile and that others return available:false. It does not explicitly route the agent to an alternative tool for foods lacking data, but the coverage caveat is the decision-relevant guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_nutrientsGet nutrients of a foodARead-only
Full composition of one TACO food by id (from search_food), per 100 g or scaled to a quantity in grams. Missing data is reported as null (not analyzed) or {"trace":true}, never as 0.
| Name | Required | Description | Default |
|---|---|---|---|
| grams | No | Quantity in grams of edible portion. Omit for the table basis of 100 g. | |
| food_id | Yes | TACO food number, as returned by search_food. | |
| nutrients | No | Nutrient keys to return (e.g. "energy_kcal", "protein_g", "iron_mg"). Omit for all. |
Output Schema
| Name | Required | Description |
|---|---|---|
| food | Yes | |
| notes | Yes | Caveats about this food or this answer. |
| scaled | Yes | True when amounts were computed from the per-100 g table values for another quantity. |
| source | Yes | Citation for the data. |
| nutrients | Yes | Requested nutrients, in table order. |
| basis_grams | Yes | Quantity the amounts refer to, in grams of edible portion. |
| trace_nutrients | Yes | Keys reported as trace (Tr). |
| not_analyzed_nutrients | Yes | Keys with no value in the TACO table; not zero. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read, so the bar is lower, and the description adds real value on top: missing nutrients come back as null or {"trace":true} and never as 0. That distinction materially changes how an agent interprets results and is not in the schema or annotations.
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 dense sentence with the resource and identifier front-loaded, followed by two qualifying clauses. No wasted words, though the missing-data clause is compressed to the point of being terse.
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 an output schema present, return structure needn't be explained, and all three parameters are documented in the schema. The description covers scaling basis and null/trace semantics, leaving only minor gaps such as behavior on an invalid or unknown food_id.
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 100%, making 3 the baseline, but the description adds meaning beyond it by stating the default basis (100 g) and the scaling behavior for the grams parameter, plus the provenance of food_id. The nutrients array is left entirely to the 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?
States a specific verb and resource ("Full composition of one TACO food by id") with clear scope: one food, full nutrient table. "Full composition" implicitly contrasts with the partial-output siblings get_fatty_acids and get_amino_acids, though it never names them.
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?
The parenthetical "(from search_food)" establishes the prerequisite lookup chain, which is genuine usage guidance. However, it gives no when-not-to-use condition and does not mention the sibling tools that return subsets of the same data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pingPingARead-only
Health check for the taco-br server. Returns the server name, version and the data source citation.
| Name | Required | Description | Default |
|---|---|---|---|
| echo | No | Optional text to echo back in the message. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | Always true when the server is alive. |
| server | Yes | Server name. |
| source | Yes | Citation for the data this server exposes. |
| version | Yes | Server version. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, so the safety profile is already covered, and the description is consistent with it (a pure health check). It adds value by naming the exact payload contents, though it doesn't say whether the echo parameter is optional or how the response is shaped — a small gap for a trivial 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?
Two short sentences, purpose first, then return contents. No filler and nothing an agent must scroll past to find the point.
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 values — and it briefly does anyway. For a zero-required-parameter health check with full schema coverage and readOnly annotations, this is nearly everything needed; only explicit triggering guidance 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?
Schema description coverage is 100% for the single optional `echo` parameter, so the schema already explains it and the description adds nothing. Baseline 3 applies — the description neither compensates nor conflicts.
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?
States a specific verb+resource ("Health check for the taco-br server") and specifies exactly what comes back (server name, version, data source citation). This is unmistakably distinct from every sibling, which are all food/nutrient query tools.
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?
The description implies usage (a ping/liveness probe) but never says when an agent should call it — e.g. connectivity checks, version verification, or troubleshooting before a failed query. No alternatives or exclusion conditions are named, which is less critical here since no sibling competes for this purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_foodSearch foods in TACOARead-only
Find foods in the Brazilian TACO table (597 items, per 100 g) by name in Portuguese. Accent-insensitive; tolerates typos; knows regional names (aipim, macaxeira, pão de sal, mandioquinha). Returns ids to use with get_nutrients. Restaurant dishes and brands are mostly absent.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results (default 10). | |
| query | Yes | Food name in Portuguese, e.g. "feijão carioca cozido" or "pao de queijo". |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | The query as received. |
| source | Yes | Citation for the data. |
| results | Yes | Best matches first. |
| total_matches | Yes | How many foods in the table match the query. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, and the description is consistent while adding real behavioral context: accent-insensitivity, typo tolerance, regional-name aliasing (aipim, macaxeira, mandioquinha), and the form of the returned identifiers. The dataset's known gaps are disclosed, though nothing is said about ordering or relevance 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?
Three sentences, front-loaded with the corpus and language, then retrieval behavior, then the handoff to get_nutrients. Every clause contributes information an agent needs.
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 no return-value exposition is needed, and the description still identifies the key return artifact (ids) and the corpus's language and unit basis. Enough context is present for correct invocation and correct interpretation of results.
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 100%, so both query and limit are already documented in the schema. The description reinforces the Portuguese-name constraint and enumerates regional synonyms, but adds no syntax or format detail beyond what the schema states; baseline 3 applies.
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?
States a specific verb and resource ('Find foods in the Brazilian TACO table') plus scope detail (597 items, per 100 g, Portuguese names) that separates it from get_nutrients and calc_meal. An agent knows exactly what corpus this searches and in what language.
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?
Names the downstream tool explicitly ('Returns ids to use with get_nutrients') and gives a coverage caveat ('Restaurant dishes and brands are mostly absent') that tells the agent when this lookup will fail. It stops short of naming an alternative to use instead when coverage is missing, so usage is clear but exclusions aren't fully routed.
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.
8 tool updates
v0.2.0- First observed
calc_meal - First observed
compare_foods - First observed
convert_household_measure - First observed
get_amino_acids - First observed
get_fatty_acids - First observed
get_nutrients - First observed
ping - First observed
search_food
TDQS
Scored across 8 tools
Each tool has a clearly separate role: search, single-food composition, meal summation, comparison, unit conversion, fatty acids, amino acids, and health check. The only mild overlap is between get_nutrients ('full composition') and the specialized get_fatty_acids/get_amino_acids tools, but descriptions clarify that the specialized ones expose individual acids and coverage limits.
Names are consistently snake_case and mostly verb_noun (search_food, get_nutrients, calc_meal, compare_foods, convert_household_measure, get_fatty_acids, get_amino_acids). The lone outlier is 'ping', which is a conventional health-check name but breaks the verb_noun pattern.
Eight tools is well-scoped for a food-composition server: lookup, detail, aggregation, comparison, conversion, two specialized nutrient profiles, and a health check. Every tool earns its place with no obvious filler.
The core lifecycle (search → inspect → convert measure → sum/compare) is fully covered, and the specialized profiles plus explicit missing-data semantics are thoughtful. Minor gaps exist: no way to browse/list all foods or categories, and no nutrient-metadata or multi-food bulk export operation.
Maintenance
Related MCP Connectors
Unlock the power of food transparency with our Open Food Facts MCP server. Easily look up any food
USDA FoodData Central nutrient lookup, FDA recall watch, EU FMCG labelling via remote MCP
MCP server exposing supplements database used by iNutriPlan.com
Food and nutrition data: search, macros, and comparisons
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceA Model Context Protocol server that enables Claude to search and access detailed nutritional information from the USDA's FoodData Central database.11MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that lets you log meals through Claude (and soon ChatGPT) in plain language, using India's official food composition data (IFCT 2017) plus USDA, enabling accurate calorie and macro tracking for Indian dishes with household units and photo logging.34 npm2AGPL 3.0
- AlicenseBqualityCmaintenanceA local-first nutrition MCP server for food search, barcode lookup, meal estimation, intake logging, hydration, and nutrition coaching workflows.4692 npm11MIT
- AlicenseAqualityCmaintenanceMCP server for Japanese food nutrition data, enabling bilingual JP/EN lookups across konbini, restaurant chains, and grocery brands.6152 npm2MIT