Skip to main content
Glama

openfoodfacts-mcp-server

Browse Food Facts Taxonomy

off_browse_taxonomy
Read-onlyIdempotent

Resolve a human term to the canonical Open Food Facts tag ID that off_search_products filters on. Covers categories, labels/certifications, allergens, additives, countries, NOVA groups, and Nutri-Score grades. Pass a search term to resolve against the Open Food Facts vocabulary, which holds tens of thousands of tags; omitting it returns only a small reference list for each facet except NOVA groups and Nutri-Score grades, which are complete. Most tag IDs use the "en:" prefix (e.g. "en:organic", "en:no-gluten", "en:crustaceans"); NOVA groups return bare digits "1"-"4" and Nutri-Score grades bare letters "a"-"e". Pass the id through to off_search_products exactly as returned. Category tags are frequently plural ("kombucha" resolves to "en:kombuchas"), so use the returned id rather than constructing one.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
facetYes"categories" covers food categories (en:cheeses, en:breakfast-cereals). "labels" covers certifications (en:organic, en:fair-trade). "allergens" covers declared allergens (en:milk, en:gluten). "additives" covers E-numbers (en:e322). "countries" covers country-of-sale tags (en:france). "nova_groups" and "nutrition_grades" are closed vocabularies returned complete; the other five are resolved against the Open Food Facts taxonomy.
limitNoMaximum entries to return (1–100, default 20). There is no offset or page input: Open Food Facts offers no cursor for this lookup, so narrow the search term rather than paging. The tag spelling the term itself (e.g. "lentil" → en:lentils) is listed first among the live matches, so it is not the one a small limit cuts.
searchNoTerm to resolve. Matched case-insensitively as a substring of the tag ID, the display name, or a common synonym of either ("shellfish" resolves to en:crustaceans, "gluten free" to en:no-gluten). A single word works best ("hummus", not "hummus dip"). Omit only to see a small reference list — Open Food Facts cannot list the full vocabulary without a term, so an unfiltered call is not a view of the full facet.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
capNoThe limit that was applied.
tagsNoMatching tag entries.
errorNoPresent when the call failed. Absent on success.
facetNoThe facet name that was queried (echoes the input).
shownNoNumber of tags returned.
noticeNoCaveat about the answer — that the listing is a limited reference list rather than the full vocabulary, that Open Food Facts was unreachable, or that nothing matched and why.
truncatedNoTrue when more tags exist beyond the limit.
total_in_facetNoTotal entries in this facet. Present only for nova_groups and nutrition_grades, whose vocabularies are closed and complete. Absent for the other facets: Open Food Facts reports no match total and cannot enumerate them, so no figure would be a real one.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum entries to return (1–100, default 20). There is no offset or page input: Open Food Facts returns only the first `limit` matches for a term and offers no cursor, so narrow the search term rather than paging."New value: +"Maximum entries to return (1–100, default 20). There is no offset or page input: Open Food Facts offers no cursor for this lookup, so narrow the search term rather than paging. The tag spelling the term itself (e.g. \"lentil\" → en:lentils) is listed first among the live matches, so it is not the one a small limit cuts."
    • removedOutput schema / properties / tags / items / properties / products
      Removed value: -{
      -  "description": "Approximate count of products with this tag. Not available for all facets.",
      -  "type": "number"
      -}
  2. Changed1 schema field changed
    • changedInput schema / properties / search / description
      Previous value: -"Term to resolve. Matched case-insensitively as a substring of the tag ID or display name. A single word works best (\"hummus\", not \"hummus dip\"). Omit only to see a small reference list — Open Food Facts cannot list the full vocabulary without a term, so an unfiltered call is not a view of the full facet."New value: +"Term to resolve. Matched case-insensitively as a substring of the tag ID, the display name, or a common synonym of either (\"shellfish\" resolves to en:crustaceans, \"gluten free\" to en:no-gluten). A single word works best (\"hummus\", not \"hummus dip\"). Omit only to see a small reference list — Open Food Facts cannot list the full vocabulary without a term, so an unfiltered call is not a view of the full facet."
  3. Changed11 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedInput schema / properties / facet / description
      Previous value: -"\"categories\" covers food categories (en:cheeses, en:breakfast-cereals). \"labels\" covers certifications (en:organic, en:fair-trade). \"allergens\" covers declared allergens (en:milk, en:gluten). \"additives\" covers E-numbers (en:e322). \"countries\" covers country-of-sale tags (en:france). \"nova_groups\" and \"nutrition_grades\" are closed vocabularies answered offline and returned complete; the other five are resolved against the live Open Food Facts taxonomy."New value: +"\"categories\" covers food categories (en:cheeses, en:breakfast-cereals). \"labels\" covers certifications (en:organic, en:fair-trade). \"allergens\" covers declared allergens (en:milk, en:gluten). \"additives\" covers E-numbers (en:e322). \"countries\" covers country-of-sale tags (en:france). \"nova_groups\" and \"nutrition_grades\" are closed vocabularies returned complete; the other five are resolved against the Open Food Facts taxonomy."
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum entries to return (1–100, default 20). There is no offset or page input: the upstream taxonomy endpoint serves only the first `limit` matches for a term and offers no cursor, so narrow the search term rather than paging."New value: +"Maximum entries to return (1–100, default 20). There is no offset or page input: Open Food Facts returns only the first `limit` matches for a term and offers no cursor, so narrow the search term rather than paging."
    • changedInput schema / properties / search / description
      Previous value: -"Term to resolve. Matched case-insensitively as a substring of the tag ID or display name, against both the live Open Food Facts vocabulary and this server's offline sample. A single word works best (\"hummus\", not \"hummus dip\"). Omit only to see the offline sample — the live vocabulary cannot be listed without a term, so an unfiltered call is not a view of the full facet."New value: +"Term to resolve. Matched case-insensitively as a substring of the tag ID or display name. A single word works best (\"hummus\", not \"hummus dip\"). Omit only to see a small reference list — Open Food Facts cannot list the full vocabulary without a term, so an unfiltered call is not a view of the full facet."
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "facet",
      +      "tags"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode.",
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Caveat about how this answer was produced — that the listing is the offline sample rather than the live vocabulary, that the live vocabulary was unreachable, or that nothing matched and why."New value: +"Caveat about the answer — that the listing is a limited reference list rather than the full vocabulary, that Open Food Facts was unreachable, or that nothing matched and why."
    • changedOutput schema / properties / total_in_facet / description
      Previous value: -"Total entries in this facet. Present only for nova_groups and nutrition_grades, whose vocabularies are closed and complete here. Absent for the live facets: the Open Food Facts taxonomy endpoint reports no match total and cannot be enumerated, so no figure would be a real one."New value: +"Total entries in this facet. Present only for nova_groups and nutrition_grades, whose vocabularies are closed and complete. Absent for the other facets: Open Food Facts reports no match total and cannot enumerate them, so no figure would be a real one."
    • removedOutput schema / required
      Removed value: -[
      -  "facet",
      -  "tags"
      -]
  4. Changed6 schema fields changed
    • changedInput schema / properties / facet / description
      Previous value: -"\"categories\" covers food categories (en:cheeses, en:breakfast-cereals). \"labels\" covers certifications (en:organic, en:fair-trade). \"allergens\" covers declared allergens (en:milk, en:gluten). \"additives\" covers E-numbers (en:e322). \"countries\" covers country-of-sale tags (en:france). \"nova_groups\" and \"nutrition_grades\" return the complete fixed vocabularies."New value: +"\"categories\" covers food categories (en:cheeses, en:breakfast-cereals). \"labels\" covers certifications (en:organic, en:fair-trade). \"allergens\" covers declared allergens (en:milk, en:gluten). \"additives\" covers E-numbers (en:e322). \"countries\" covers country-of-sale tags (en:france). \"nova_groups\" and \"nutrition_grades\" are closed vocabularies answered offline and returned complete; the other five are resolved against the live Open Food Facts taxonomy."
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum entries to return (1–100, default 20). The categories facet is broad; a search term narrows it to the relevant tags."New value: +"Maximum entries to return (1–100, default 20). There is no offset or page input: the upstream taxonomy endpoint serves only the first `limit` matches for a term and offers no cursor, so narrow the search term rather than paging."
    • changedInput schema / properties / search / description
      Previous value: -"Case-insensitive substring filter against tag ID or display name. Example: \"gluten\" returns en:gluten, en:no-gluten. Omit to list all entries for the facet (may be large for categories)."New value: +"Term to resolve. Matched case-insensitively as a substring of the tag ID or display name, against both the live Open Food Facts vocabulary and this server's offline sample. A single word works best (\"hummus\", not \"hummus dip\"). Omit only to see the offline sample — the live vocabulary cannot be listed without a term, so an unfiltered call is not a view of the full facet."
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Caveat about how this answer was produced — that the listing is the offline sample rather than the live vocabulary, that the live vocabulary was unreachable, or that nothing matched and why.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / tags / items / properties / id / description
      Previous value: -"Canonical tag ID (e.g. \"en:organic\"). Use this value in off_search_products filter parameters."New value: +"Canonical tag ID (e.g. \"en:organic\"; bare \"1\"–\"4\" for NOVA groups, bare \"a\"–\"e\" for Nutri-Score grades). Pass this value through to the matching off_search_products filter parameter unchanged."
    • changedOutput schema / properties / total_in_facet / description
      Previous value: -"Total entries in this facet before search filtering. Large for categories."New value: +"Total entries in this facet. Present only for nova_groups and nutrition_grades, whose vocabularies are closed and complete here. Absent for the live facets: the Open Food Facts taxonomy endpoint reports no match total and cannot be enumerated, so no figure would be a real one."
  5. Changed1 schema field changed
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum entries to return (1–100, default 20). Categories has many entries — always provide a search term when browsing categories."New value: +"Maximum entries to return (1–100, default 20). The categories facet is broad; a search term narrows it to the relevant tags."
  6. Changed3 schema fields changed
    • addedOutput schema / properties / cap
      Added value: +{
      +  "description": "The limit that was applied.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / shown
      Added value: +{
      +  "description": "Number of tags returned.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when more tags exist beyond the limit.",
      +  "type": "boolean"
      +}
  7. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, openWorldHint, and idempotentHint. On top of that, the description discloses specific behaviors: omitting the search term yields only a small reference list except for NOVA groups and Nutri-Score grades which are complete; ID prefix conventions vary by facet (en: prefix, bare digits '1'-'4', bare letters 'a'-'e'); and category tags are frequently plural, so callers should trust returned IDs. This adds substantial behavioral context beyond the annotations and never contradicts them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: purpose, facet coverage, search behavior, return-format conventions, and a usage gotcha are each covered once. It is front-loaded with the most important point (resolve for off_search_products) and flows logically through usage to output expectations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich schema, informative annotations, and an output schema, the description fills remaining gaps: what the returned IDs look like per facet, how to pass them into the sibling tool, and what happens when search is omitted. Nothing an agent needs to correctly call and consume the output is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter already has a detailed description. The tool description adds extra semantic value by explaining how 'search' resolves across tag ID, display name, and synonyms, that 'limit' may cut matches but the exact-term match is listed first, and that 'facet' behaviors differ (open vs closed vocabularies). These details go beyond the schema without repeating it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb-resource pairing: 'Resolve a human term to the canonical Open Food Facts tag ID that off_search_products filters on.' It clearly states the tool's scope and distinguishes it from siblings by grounding it as a preprocessing step for off_search_products. The list of covered facets (categories, labels, allergens, additives, countries, NOVA groups, Nutri-Score grades) fully removes ambiguity about what the taxonomy contains.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong contextual guidance: pass a search term to resolve, omit it to get a small reference list, and use the returned id exactly as-is in off_search_products. It doesn't explicitly name when-not-to-use scenarios or alternatives like off_get_product or off_compare_products, but the orientation toward off_search_products makes the intended workflow clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.