@cyanheads/openfoodfacts-mcp-server 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Developer Protocol
2
2
 
3
3
  **Server:** openfoodfacts-mcp-server
4
- **Version:** 0.2.0
4
+ **Version:** 0.3.0
5
5
  **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.11.0`
6
6
  **Engines:** Bun ≥1.3.0, Node ≥24.0.0
7
7
  **MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
@@ -178,7 +178,7 @@ src/
178
178
  openfoodfacts-service.ts # Open Food Facts API client (HTTP, rate limiting, retry)
179
179
  types.ts # Domain types
180
180
  taxonomy/
181
- taxonomy-service.ts # Embedded tag vocabulary (categories, labels, allergens, etc.)
181
+ taxonomy-service.ts # Tag vocabulary — live resolution, offline sample, merge/fallback policy
182
182
  mcp-server/
183
183
  tools/definitions/
184
184
  get-product.tool.ts # off_get_product
package/CLAUDE.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Developer Protocol
2
2
 
3
3
  **Server:** openfoodfacts-mcp-server
4
- **Version:** 0.2.0
4
+ **Version:** 0.3.0
5
5
  **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.11.0`
6
6
  **Engines:** Bun ≥1.3.0, Node ≥24.0.0
7
7
  **MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
@@ -178,7 +178,7 @@ src/
178
178
  openfoodfacts-service.ts # Open Food Facts API client (HTTP, rate limiting, retry)
179
179
  types.ts # Domain types
180
180
  taxonomy/
181
- taxonomy-service.ts # Embedded tag vocabulary (categories, labels, allergens, etc.)
181
+ taxonomy-service.ts # Tag vocabulary — live resolution, offline sample, merge/fallback policy
182
182
  mcp-server/
183
183
  tools/definitions/
184
184
  get-product.tool.ts # off_get_product
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  <div align="center">
9
9
 
10
- [![Version](https://img.shields.io/badge/Version-0.2.0-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Docker](https://img.shields.io/badge/Docker-ghcr.io-2496ED?style=flat-square&logo=docker&logoColor=white)](https://github.com/users/cyanheads/packages/container/package/openfoodfacts-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/@cyanheads/openfoodfacts-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/openfoodfacts-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^7.0.2-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.0-blueviolet.svg?style=flat-square)](https://bun.sh/)
10
+ [![Version](https://img.shields.io/badge/Version-0.3.0-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Docker](https://img.shields.io/badge/Docker-ghcr.io-2496ED?style=flat-square&logo=docker&logoColor=white)](https://github.com/users/cyanheads/packages/container/package/openfoodfacts-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/@cyanheads/openfoodfacts-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/openfoodfacts-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^7.0.2-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.0-blueviolet.svg?style=flat-square)](https://bun.sh/)
11
11
 
12
12
  </div>
13
13
 
@@ -36,7 +36,7 @@ Four tools for working with [Open Food Facts](https://world.openfoodfacts.org/)
36
36
  | `off_get_product` | Fetch a packaged food product by barcode. Returns name, brand, quantity, ingredients, allergens, additives, Nutri-Score, NOVA group, Green-Score, nutrition per 100g/serving, categories, labels, and data completeness. |
37
37
  | `off_search_products` | Search by text query and/or structured tag filters (category, brand, label, allergen, additive, Nutri-Score grade, NOVA group, country). Returns summary rows with barcodes for follow-up lookups. |
38
38
  | `off_compare_products` | Side-by-side nutrition and scoring comparison for 2–10 products by barcode. Returns a normalized table of energy, macros, salt, Nutri-Score, NOVA, and Green-Score. |
39
- | `off_browse_taxonomy` | Browse and search the canonical tag vocabulary (categories, labels, allergens, additives, countries, NOVA groups, Nutri-Score grades) for use as filter values in `off_search_products`. |
39
+ | `off_browse_taxonomy` | Resolve a human term to the canonical tag ID (categories, labels, allergens, additives, countries, NOVA groups, Nutri-Score grades) that `off_search_products` filters on, against the live Open Food Facts taxonomy. |
40
40
 
41
41
  ### `off_get_product`
42
42
 
@@ -82,13 +82,16 @@ Side-by-side nutrition and scoring comparison for 2–10 barcodes.
82
82
 
83
83
  ### `off_browse_taxonomy`
84
84
 
85
- Browse the canonical Open Food Facts tag vocabulary before building `off_search_products` filters.
85
+ Resolve a human term to the canonical Open Food Facts tag ID before building `off_search_products` filters.
86
86
 
87
87
  - Facets: `categories`, `labels`, `allergens`, `additives`, `countries`, `nova_groups`, `nutrition_grades`
88
- - Optional `search` parameter: case-insensitive substring match against tag ID or display name (e.g., `"gluten"` → `en:gluten`, `en:no-gluten`, `en:no-added-gluten`)
89
- - Taxonomy is served from a curated in-process vocabulary — no live network call, so lookups are instant and offline
90
- - The categories facet is broad — pass a `search` term to narrow it to the relevant tags
91
- - `limit` controls results returned (1–100, default 20)
88
+ - With a `search` term, the five open facets resolve against the live Open Food Facts taxonomy — tens of thousands of category tags, not a fixed local list. Matching is case-insensitive substring against tag ID or display name (e.g., `"gluten"` → `en:no-gluten`, `en:gluten-free`)
89
+ - Upstream tags are often plural (`"kombucha"` → `en:kombuchas`) — pass the returned `id` through unchanged rather than constructing one
90
+ - `nova_groups` and `nutrition_grades` are closed vocabularies answered offline and returned complete. Their IDs are bare (`1`–`4`, `a`–`e`), matching what `off_search_products` accepts
91
+ - Live results are merged behind an in-process sample that also serves offline operation. If Open Food Facts is unreachable or the taxonomy budget is spent, the tool answers from that sample and says so rather than failing — an empty result is never presented as an authoritative "no such tag"
92
+ - Omitting `search` lists only the offline sample. The upstream taxonomy endpoint suggests against a term and cannot enumerate a facet, so an unfiltered call is not a view of the full vocabulary and reports no facet total
93
+ - `limit` controls results returned (1–100, default 20). There is no offset or page input — the upstream endpoint offers no cursor, so narrow the term instead
94
+ - Taxonomy lookups carry their own ~10 requests/min client-side budget, separate from the search budget
92
95
 
93
96
  ---
94
97
 
@@ -106,10 +109,10 @@ Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp
106
109
  Open Food Facts-specific:
107
110
 
108
111
  - No API key required — the identifying `User-Agent` header (required by OFF terms) is baked into the service layer
109
- - Token-bucket rate limiting per endpoint class: product reads (~100/min), search (~10/min). A local refusal says so — it never reports itself as an Open Food Facts rate limit
112
+ - Token-bucket rate limiting per endpoint class: product reads (~100/min), search (~10/min), taxonomy resolution (~10/min). A local refusal says so — it never reports itself as an Open Food Facts rate limit
110
113
  - Automatic retry (3 attempts, 500ms base) for transient failures only — 5xx, timeouts, and 429 (honoring `Retry-After`), with HTML error page detection for 503 during high load. A 4xx is never retried; the upstream's own explanation is surfaced instead
111
114
  - Nutriments normalized from raw hyphenated keys (`energy-kcal_100g`) to underscore form — the `_100g` and `_serving` variants of every nutrient on the record, with the macros as named fields and the rest in an open map that carries each nutrient's own unit (micronutrients are reported in grams, so calcium `0.071` is 71 mg)
112
- - Embedded tag taxonomy for `off_browse_taxonomy` — curated 200+ category subset, full allergen/label/additive vocabularies
115
+ - Live tag resolution for `off_browse_taxonomy` against the Open Food Facts taxonomy, merged behind a small in-process sample that covers offline operation and is authoritative for E-number lookups, which the upstream suggester answers poorly
113
116
 
114
117
  Agent-friendly output:
115
118
 
@@ -240,6 +243,7 @@ All configuration is validated at startup via Zod schemas in `src/config/server-
240
243
  | `OFF_BASE_URL` | Open Food Facts API base URL. Override for local testing against a mock server. | `https://world.openfoodfacts.org` |
241
244
  | `OFF_RATE_LIMIT_PRODUCT` | Product read rate limit (requests/min). | `100` |
242
245
  | `OFF_RATE_LIMIT_SEARCH` | Search rate limit (requests/min). | `10` |
246
+ | `OFF_RATE_LIMIT_TAXONOMY` | Taxonomy resolution rate limit (requests/min). A spent budget falls back to the offline sample rather than failing. | `10` |
243
247
  | `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
244
248
  | `MCP_HTTP_PORT` | HTTP server port. | `3010` |
245
249
  | `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
@@ -292,7 +296,7 @@ The Dockerfile defaults to HTTP transport, stateless session mode, and logs to `
292
296
  | `src/config` | Server-specific environment variable parsing and validation with Zod. |
293
297
  | `src/mcp-server/tools` | Tool definitions (`*.tool.ts`). |
294
298
  | `src/services/openfoodfacts` | Open Food Facts API client — HTTP, rate limiting, retry, field normalization. |
295
- | `src/services/taxonomy` | Embedded tag vocabulary service for `off_browse_taxonomy`. |
299
+ | `src/services/taxonomy` | Tag vocabulary service for `off_browse_taxonomy` — live resolution, offline sample, merge and fallback policy. |
296
300
  | `tests/` | Unit and integration tests mirroring `src/`. |
297
301
 
298
302
  ## Development guide
@@ -0,0 +1,19 @@
1
+ ---
2
+ summary: "off_browse_taxonomy resolves search terms against the live Open Food Facts taxonomy instead of a 79-entry embedded list, and nova_groups tag IDs are now bare digits that round-trip into off_search_products."
3
+ breaking: false
4
+ security: false
5
+ ---
6
+
7
+ # 0.3.0 — 2026-07-26
8
+
9
+ ## Added
10
+
11
+ - **`off_browse_taxonomy`** — a search term now resolves against the live Open Food Facts taxonomy (`search.openfoodfacts.org/autocomplete`) for the five open facets (`categories`, `labels`, `allergens`, `additives`, `countries`), merged behind the embedded offline sample. Fixes ordinary terms (hummus, tofu, kombucha, pizzas) dead-ending on the 79-entry embedded category list. ([#14](https://github.com/cyanheads/openfoodfacts-mcp-server/issues/14))
12
+ - **`OFF_RATE_LIMIT_TAXONOMY`** env var (default `10`/min) — taxonomy resolution's own rate-limit tier, separate from the search budget.
13
+ - **`off_browse_taxonomy`** enrichment gains a `notice` field: names whether an answer came from the offline sample, a failed live lookup, or a genuine no-match, so an empty result is never read as an authoritative "no such tag."
14
+
15
+ ## Changed
16
+
17
+ - **`off_browse_taxonomy`** — `nova_groups` tag IDs are now bare digits (`1`–`4`) instead of `en:1`–`en:4`, matching what `off_search_products`' `nova_group` enum accepts and the bare-letter convention `nutrition_grades` already used. The previous IDs were rejected outright by `off_search_products`. ([#15](https://github.com/cyanheads/openfoodfacts-mcp-server/issues/15))
18
+ - **`off_browse_taxonomy`** — `total_in_facet` is now omitted for the five live facets, since the autocomplete endpoint reports no match total and cannot be enumerated. Still returned for the closed `nova_groups`/`nutrition_grades` vocabularies.
19
+ - **`off_browse_taxonomy`** — `annotations.openWorldHint` flips to `true`.
@@ -7,6 +7,7 @@ declare const ServerConfigSchema: z.ZodObject<{
7
7
  baseUrl: z.ZodDefault<z.ZodString>;
8
8
  rateLimitProduct: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
9
9
  rateLimitSearch: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
10
+ rateLimitTaxonomy: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
10
11
  }, z.core.$strip>;
11
12
  export type ServerConfig = z.infer<typeof ServerConfigSchema>;
12
13
  /** Lazy-parsed server config from environment variables. */
@@ -1 +1 @@
1
- {"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAG3C,QAAA,MAAM,kBAAkB;;;;iBAiBtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,4DAA4D;AAC5D,wBAAgB,eAAe,IAAI,YAAY,CAO9C"}
1
+ {"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAG3C,QAAA,MAAM,kBAAkB;;;;;iBAuBtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,4DAA4D;AAC5D,wBAAgB,eAAe,IAAI,YAAY,CAQ9C"}
@@ -21,6 +21,12 @@ const ServerConfigSchema = z.object({
21
21
  .min(1)
22
22
  .default(10)
23
23
  .describe('Search rate limit (requests/min)'),
24
+ rateLimitTaxonomy: z.coerce
25
+ .number()
26
+ .int()
27
+ .min(1)
28
+ .default(10)
29
+ .describe('Taxonomy resolution rate limit (requests/min)'),
24
30
  });
25
31
  let _config;
26
32
  /** Lazy-parsed server config from environment variables. */
@@ -29,6 +35,7 @@ export function getServerConfig() {
29
35
  baseUrl: 'OFF_BASE_URL',
30
36
  rateLimitProduct: 'OFF_RATE_LIMIT_PRODUCT',
31
37
  rateLimitSearch: 'OFF_RATE_LIMIT_SEARCH',
38
+ rateLimitTaxonomy: 'OFF_RATE_LIMIT_TAXONOMY',
32
39
  });
33
40
  return _config;
34
41
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,OAAO,CAAC,iCAAiC,CAAC;SAC1C,QAAQ,CAAC,8BAA8B,CAAC;IAC3C,gBAAgB,EAAE,CAAC,CAAC,MAAM;SACvB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,GAAG,CAAC;SACZ,QAAQ,CAAC,wCAAwC,CAAC;IACrD,eAAe,EAAE,CAAC,CAAC,MAAM;SACtB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,kCAAkC,CAAC;CAChD,CAAC,CAAC;AAIH,IAAI,OAAiC,CAAC;AAEtC,4DAA4D;AAC5D,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,cAAc,CAAC,kBAAkB,EAAE;QAC7C,OAAO,EAAE,cAAc;QACvB,gBAAgB,EAAE,wBAAwB;QAC1C,eAAe,EAAE,uBAAuB;KACzC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,OAAO,CAAC,iCAAiC,CAAC;SAC1C,QAAQ,CAAC,8BAA8B,CAAC;IAC3C,gBAAgB,EAAE,CAAC,CAAC,MAAM;SACvB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,GAAG,CAAC;SACZ,QAAQ,CAAC,wCAAwC,CAAC;IACrD,eAAe,EAAE,CAAC,CAAC,MAAM;SACtB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,kCAAkC,CAAC;IAC/C,iBAAiB,EAAE,CAAC,CAAC,MAAM;SACxB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,+CAA+C,CAAC;CAC7D,CAAC,CAAC;AAIH,IAAI,OAAiC,CAAC;AAEtC,4DAA4D;AAC5D,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,cAAc,CAAC,kBAAkB,EAAE;QAC7C,OAAO,EAAE,cAAc;QACvB,gBAAgB,EAAE,wBAAwB;QAC1C,eAAe,EAAE,uBAAuB;QACxC,iBAAiB,EAAE,yBAAyB;KAC7C,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -24,6 +24,7 @@ export declare const offBrowseTaxonomyTool: import("@cyanheads/mcp-ts-core").Too
24
24
  }, z.core.$strip>>;
25
25
  total_in_facet: z.ZodOptional<z.ZodNumber>;
26
26
  }, z.core.$strip>, undefined, {
27
+ readonly notice: z.ZodOptional<z.ZodString>;
27
28
  readonly truncated: z.ZodOptional<z.ZodBoolean>;
28
29
  readonly shown: z.ZodOptional<z.ZodNumber>;
29
30
  readonly cap: z.ZodOptional<z.ZodNumber>;
@@ -1 +1 @@
1
- {"version":3,"file":"browse-taxonomy.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/browse-taxonomy.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGjD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;EA+HhC,CAAC"}
1
+ {"version":3,"file":"browse-taxonomy.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/browse-taxonomy.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGjD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;EAiJhC,CAAC"}
@@ -6,11 +6,11 @@ import { tool, z } from '@cyanheads/mcp-ts-core';
6
6
  import { getTaxonomyService } from '../../../services/taxonomy/taxonomy-service.js';
7
7
  export const offBrowseTaxonomyTool = tool('off_browse_taxonomy', {
8
8
  title: 'Browse Food Facts Taxonomy',
9
- description: 'Browse and search the canonical tag vocabulary for Open Food Facts filter facets. Returns tag IDs and display names for use as filter values in off_search_products. Covers categories, labels/certifications, allergens, additives, countries, NOVA groups, and Nutri-Score grades. Tag IDs use the "en:" prefix convention (e.g. "en:organic", "en:gluten-free", "en:milk"). Use these tag IDs as filter values, not plain English terms.',
9
+ description: '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 live Open Food Facts vocabulary, which holds tens of thousands of tags; omitting it lists only the offline sample this server ships, which is a small slice of every facet except NOVA groups and Nutri-Score grades. Most tag IDs use the "en:" prefix (e.g. "en:organic", "en:gluten-free", "en:milk"); 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 upstream ("kombucha" resolves to "en:kombuchas"), so use the returned id rather than constructing one.',
10
10
  annotations: {
11
11
  readOnlyHint: true,
12
12
  idempotentHint: true,
13
- openWorldHint: false,
13
+ openWorldHint: true,
14
14
  },
15
15
  input: z.object({
16
16
  facet: z
@@ -23,18 +23,18 @@ export const offBrowseTaxonomyTool = tool('off_browse_taxonomy', {
23
23
  'nova_groups',
24
24
  'nutrition_grades',
25
25
  ])
26
- .describe('"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.'),
26
+ .describe('"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.'),
27
27
  search: z
28
28
  .string()
29
29
  .optional()
30
- .describe('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).'),
30
+ .describe('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.'),
31
31
  limit: z
32
32
  .number()
33
33
  .int()
34
34
  .min(1)
35
35
  .max(100)
36
36
  .default(20)
37
- .describe('Maximum entries to return (1–100, default 20). The categories facet is broad; a search term narrows it to the relevant tags.'),
37
+ .describe('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.'),
38
38
  }),
39
39
  output: z.object({
40
40
  facet: z.string().describe('The facet name that was queried (echoes the input).'),
@@ -43,7 +43,7 @@ export const offBrowseTaxonomyTool = tool('off_browse_taxonomy', {
43
43
  .object({
44
44
  id: z
45
45
  .string()
46
- .describe('Canonical tag ID (e.g. "en:organic"). Use this value in off_search_products filter parameters.'),
46
+ .describe('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.'),
47
47
  name: z.string().describe('Human-readable display name (e.g. "Organic").'),
48
48
  products: z
49
49
  .number()
@@ -55,33 +55,50 @@ export const offBrowseTaxonomyTool = tool('off_browse_taxonomy', {
55
55
  total_in_facet: z
56
56
  .number()
57
57
  .optional()
58
- .describe('Total entries in this facet before search filtering. Large for categories.'),
58
+ .describe('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.'),
59
59
  }),
60
60
  enrichment: {
61
+ notice: z
62
+ .string()
63
+ .optional()
64
+ .describe('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.'),
61
65
  truncated: z.boolean().optional().describe('True when more tags exist beyond the limit.'),
62
66
  shown: z.number().optional().describe('Number of tags returned.'),
63
67
  cap: z.number().optional().describe('The limit that was applied.'),
64
68
  },
65
- handler(input, ctx) {
69
+ async handler(input, ctx) {
66
70
  const svc = getTaxonomyService();
67
- const result = svc.search(input.facet, input.search && input.search.trim().length > 0 ? input.search.trim() : undefined, input.limit);
71
+ // The service trims and treats a blank term as absent, so the raw input goes through as given.
72
+ const result = await svc.search(input.facet, input.search, input.limit, ctx);
68
73
  ctx.log.info('Taxonomy browsed', {
69
74
  facet: input.facet,
70
75
  search: input.search,
71
76
  returned: result.tags.length,
72
- total: result.total_in_facet,
77
+ matched: result.matched_in_facet,
73
78
  });
74
79
  // Disclose truncation only when matching rows were dropped by the limit. Compare the
75
80
  // returned count against the filtered-match count, not the full facet size — otherwise a
76
81
  // filtered search (including a zero-match one) falsely reports truncation against the
77
82
  // pre-filter vocabulary total.
83
+ //
84
+ // `notice` is one slot, and ctx.enrich.truncated() writes it from `guidance`, so the service's
85
+ // caveat is routed through that argument when both apply rather than being emitted separately
86
+ // and silently overwritten. It is the more useful next move than the generic raise-the-limit
87
+ // default: on an unfiltered browse the answer is to pass a search term, not a larger cap.
78
88
  if (result.tags.length < result.matched_in_facet) {
79
- ctx.enrich.truncated({ shown: result.tags.length, cap: input.limit });
89
+ ctx.enrich.truncated({
90
+ shown: result.tags.length,
91
+ cap: input.limit,
92
+ ...(result.notice && { guidance: result.notice }),
93
+ });
94
+ }
95
+ else if (result.notice) {
96
+ ctx.enrich.notice(result.notice);
80
97
  }
81
98
  return {
82
99
  facet: result.facet,
83
100
  tags: result.tags,
84
- total_in_facet: result.total_in_facet,
101
+ ...(result.total_in_facet !== undefined && { total_in_facet: result.total_in_facet }),
85
102
  };
86
103
  },
87
104
  format: (result) => {
@@ -89,14 +106,16 @@ export const offBrowseTaxonomyTool = tool('off_browse_taxonomy', {
89
106
  `## ${result.facet} (${result.tags.length} entries${result.total_in_facet !== undefined ? ` of ${result.total_in_facet} total` : ''})\n`,
90
107
  ];
91
108
  if (result.tags.length === 0) {
92
- lines.push('No matching tags found. Try a different search term.');
109
+ // No claim about the vocabulary is made here — whether nothing matched or the live lookup
110
+ // failed is the notice's to say, and it reaches this surface as a trailer either way.
111
+ lines.push('No tags returned for this query.');
93
112
  return [{ type: 'text', text: lines.join('\n') }];
94
113
  }
95
114
  for (const tag of result.tags) {
96
115
  const products = tag.products !== undefined ? ` (~${tag.products.toLocaleString()} products)` : '';
97
116
  lines.push(`- \`${tag.id}\` — ${tag.name}${products}`);
98
117
  }
99
- lines.push('\n*Use the `id` values (e.g. "en:organic") as filter parameters in off_search_products.*');
118
+ lines.push('\n*Pass an `id` through to off_search_products exactly as shown — "en:organic" for most facets, bare "1"–"4" for NOVA groups, bare "a"–"e" for Nutri-Score grades.*');
100
119
  return [{ type: 'text', text: lines.join('\n') }];
101
120
  },
102
121
  });
@@ -1 +1 @@
1
- {"version":3,"file":"browse-taxonomy.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/browse-taxonomy.tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browse-taxonomy.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/browse-taxonomy.tool.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
23
23
  }, import("zod/v4/core").$strip>>;
24
24
  total_in_facet: import("zod").ZodOptional<import("zod").ZodNumber>;
25
25
  }, import("zod/v4/core").$strip>, undefined, {
26
+ readonly notice: import("zod").ZodOptional<import("zod").ZodString>;
26
27
  readonly truncated: import("zod").ZodOptional<import("zod").ZodBoolean>;
27
28
  readonly shown: import("zod").ZodOptional<import("zod").ZodNumber>;
28
29
  readonly cap: import("zod").ZodOptional<import("zod").ZodNumber>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAK9B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAK9B,CAAC"}
@@ -22,6 +22,7 @@ export declare class OpenFoodFactsService {
22
22
  private readonly baseUrl;
23
23
  private readonly productLimiter;
24
24
  private readonly searchLimiter;
25
+ private readonly taxonomyLimiter;
25
26
  constructor(config: ServerConfig);
26
27
  /**
27
28
  * Fetch a product by barcode.
@@ -70,6 +71,20 @@ export declare class OpenFoodFactsService {
70
71
  * facets into the Lucene `q`.
71
72
  */
72
73
  private searchProductsByTags;
74
+ /**
75
+ * Resolve a term against a live Open Food Facts taxonomy through the search-a-licious
76
+ * autocomplete endpoint, returning its suggestions in upstream order. Ranking, filtering, and
77
+ * what to do when the call fails are the caller's to decide — this method only fetches.
78
+ *
79
+ * `size` caps the options returned and is the endpoint's only paging knob: it accepts no offset
80
+ * or cursor, and passing one is ignored rather than rejected, so there is no way to reach past
81
+ * the first `size` suggestions. The endpoint is a suggester over display names, not an
82
+ * enumerator — it reports no match total and answers an empty list for an empty term.
83
+ */
84
+ suggestTaxonomy(taxonomyName: string, term: string, size: number, ctx: Context): Promise<{
85
+ id: string;
86
+ name: string;
87
+ }[]>;
73
88
  /**
74
89
  * Build the search-a-licious Lucene `q` from a text query plus tag filters. Recognized
75
90
  * `field:"value"` facet clauses become hard AND filters; the free-text query adds relevance
@@ -1 +1 @@
1
- {"version":3,"file":"openfoodfacts-service.d.ts","sourceRoot":"","sources":["../../../src/services/openfoodfacts/openfoodfacts-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAItD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EACV,UAAU,EAKV,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAwBpB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AA0OhD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAc;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAc;IAE5C,YAAY,MAAM,EAAE,YAAY,EAI/B;IAED;;;;OAIG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgB1E;IAED;;;OAGG;IACG,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgB5B;IAED;;;;;OAKG;YACW,YAAY;IAgC1B;;;OAGG;YACW,WAAW;IAgBzB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAMxE;IAED;;;;OAIG;YACW,oBAAoB;IAmElC;;;;OAIG;YACW,oBAAoB;IAyClC;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,cAAc;CAoBvB;AAMD,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAED,wBAAgB,uBAAuB,IAAI,oBAAoB,CAO9D"}
1
+ {"version":3,"file":"openfoodfacts-service.d.ts","sourceRoot":"","sources":["../../../src/services/openfoodfacts/openfoodfacts-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAItD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAEV,UAAU,EAKV,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAwBpB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAkPhD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAc;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAc;IAC5C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAc;IAE9C,YAAY,MAAM,EAAE,YAAY,EAQ/B;IAED;;;;OAIG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgB1E;IAED;;;OAGG;IACG,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgB5B;IAED;;;;;OAKG;YACW,YAAY;IAgC1B;;;OAGG;YACW,WAAW;IAgBzB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAMxE;IAED;;;;OAIG;YACW,oBAAoB;IAmElC;;;;OAIG;YACW,oBAAoB;IAyClC;;;;;;;;;OASG;IACG,eAAe,CACnB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,OAAO,GACX,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAkCzC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,cAAc;CAoBvB;AAMD,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAED,wBAAgB,uBAAuB,IAAI,oBAAoB,CAO9D"}
@@ -173,8 +173,15 @@ const SEARCH_FIELDS = 'code,product_name,brands,nutriscore_grade,nova_group,ecos
173
173
  /**
174
174
  * Text search endpoint — search.openfoodfacts.org uses Elasticsearch and actually filters by the
175
175
  * query text. The /api/v2/search endpoint silently ignores search_terms and returns all products.
176
+ * The same host serves the taxonomy autocomplete used to resolve tag IDs.
176
177
  */
177
178
  const TEXT_SEARCH_BASE_URL = 'https://search.openfoodfacts.org';
179
+ /**
180
+ * Largest `size` the autocomplete endpoint honors. Live-verified: it returns exactly the requested
181
+ * option count up to 200 and caps below the request above that (500 answered 249), so a request is
182
+ * clamped here rather than sent and silently under-served.
183
+ */
184
+ const MAX_AUTOCOMPLETE_SIZE = 200;
178
185
  /**
179
186
  * Reserved characters in search-a-licious's Lucene-style `q` syntax (field:value clauses, boolean
180
187
  * operators, wildcards, ranges, grouping). Live-verified: an unescaped colon in free text is
@@ -228,10 +235,15 @@ export class OpenFoodFactsService {
228
235
  baseUrl;
229
236
  productLimiter;
230
237
  searchLimiter;
238
+ taxonomyLimiter;
231
239
  constructor(config) {
232
240
  this.baseUrl = config.baseUrl;
233
241
  this.productLimiter = new RateLimiter(config.rateLimitProduct);
234
242
  this.searchLimiter = new RateLimiter(config.rateLimitSearch);
243
+ // Taxonomy resolution gets its own budget rather than sharing the search one: browsing the
244
+ // vocabulary to build a filter would otherwise spend the budget for the search that filter is
245
+ // for, and the two are answered by different endpoints with different costs upstream.
246
+ this.taxonomyLimiter = new RateLimiter(config.rateLimitTaxonomy);
235
247
  }
236
248
  /**
237
249
  * Fetch a product by barcode.
@@ -426,6 +438,38 @@ export class OpenFoodFactsService {
426
438
  signal: ctx.signal,
427
439
  });
428
440
  }
441
+ /**
442
+ * Resolve a term against a live Open Food Facts taxonomy through the search-a-licious
443
+ * autocomplete endpoint, returning its suggestions in upstream order. Ranking, filtering, and
444
+ * what to do when the call fails are the caller's to decide — this method only fetches.
445
+ *
446
+ * `size` caps the options returned and is the endpoint's only paging knob: it accepts no offset
447
+ * or cursor, and passing one is ignored rather than rejected, so there is no way to reach past
448
+ * the first `size` suggestions. The endpoint is a suggester over display names, not an
449
+ * enumerator — it reports no match total and answers an empty list for an empty term.
450
+ */
451
+ async suggestTaxonomy(taxonomyName, term, size, ctx) {
452
+ this.taxonomyLimiter.check('taxonomy', ctx);
453
+ return await withRetry(async () => {
454
+ const url = new URL(`${TEXT_SEARCH_BASE_URL}/autocomplete`);
455
+ url.searchParams.set('q', term);
456
+ url.searchParams.set('taxonomy_names', taxonomyName);
457
+ url.searchParams.set('size', String(Math.min(size, MAX_AUTOCOMPLETE_SIZE)));
458
+ ctx.log.debug('Resolving taxonomy term', { taxonomyName, term, url: url.toString() });
459
+ const data = await parseJsonBody(await this.fetchSearch(url.toString(), ctx, 'OFF:suggestTaxonomy', {
460
+ taxonomy_name: taxonomyName,
461
+ term,
462
+ }), ctx, { taxonomy_name: taxonomyName, term });
463
+ // An option missing either half is unusable as a filter value or a display name, so it is
464
+ // dropped rather than passed on with an invented placeholder.
465
+ return (data.options ?? []).flatMap((option) => option.id && option.text ? [{ id: option.id, name: option.text }] : []);
466
+ }, {
467
+ operation: `OFF:suggestTaxonomy:${taxonomyName}`,
468
+ context: ctx,
469
+ baseDelayMs: 500,
470
+ signal: ctx.signal,
471
+ });
472
+ }
429
473
  /**
430
474
  * Build the search-a-licious Lucene `q` from a text query plus tag filters. Recognized
431
475
  * `field:"value"` facet clauses become hard AND filters; the free-text query adds relevance
@@ -1 +1 @@
1
- {"version":3,"file":"openfoodfacts-service.js","sourceRoot":"","sources":["../../../src/services/openfoodfacts/openfoodfacts-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openfoodfacts-service.js","sourceRoot":"","sources":["../../../src/services/openfoodfacts/openfoodfacts-service.ts"],"names":[],"mappings":"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"}
@@ -92,6 +92,25 @@ export type RawTextSearchHit = {
92
92
  ecoscore_grade?: string;
93
93
  categories_tags?: string[];
94
94
  };
95
+ /**
96
+ * One suggestion from GET https://search.openfoodfacts.org/autocomplete — the live taxonomy
97
+ * resolver. `id` is the canonical tag ID (`en:hummus`) and `text` its display name; `taxonomy_name`
98
+ * echoes which vocabulary the suggestion came from, which matters only when several are requested
99
+ * at once. Typed optional per this file's convention that no upstream field is assumed present.
100
+ */
101
+ export type RawTaxonomyOption = {
102
+ id?: string;
103
+ text?: string;
104
+ taxonomy_name?: string;
105
+ };
106
+ /**
107
+ * Response envelope from GET https://search.openfoodfacts.org/autocomplete. The endpoint is a
108
+ * suggester, not an enumerator: it reports no match total, accepts no offset or cursor, and answers
109
+ * HTTP 200 with an empty `options` list for an empty query or an unknown taxonomy name.
110
+ */
111
+ export type RawAutocompleteResponse = {
112
+ options?: RawTaxonomyOption[];
113
+ };
95
114
  /**
96
115
  * Search parameters shared by both search backends. A `query` (with or without tag filters) routes
97
116
  * to search.openfoodfacts.org, where any tag filters are folded into the Lucene `q`; tag filters
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/openfoodfacts/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/openfoodfacts/types.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,11 @@
1
1
  /**
2
- * @fileoverview Embedded taxonomy service for Open Food Facts tag vocabularies.
3
- * Returns curated tag IDs and display names for facets used in search filters.
4
- * No network calls — the OFF taxonomy endpoint returns 503 for anonymous bots.
2
+ * @fileoverview Taxonomy service for Open Food Facts tag vocabularies. Resolves a search term
3
+ * against the live search-a-licious autocomplete endpoint and merges the result with an embedded
4
+ * vocabulary, which also serves unfiltered browsing, the two fixed facets, and offline operation.
5
5
  * @module services/taxonomy/taxonomy-service
6
6
  */
7
+ import type { Context } from '@cyanheads/mcp-ts-core';
8
+ import type { OpenFoodFactsService } from '../../services/openfoodfacts/openfoodfacts-service.js';
7
9
  export type TaxonomyEntry = {
8
10
  id: string;
9
11
  name: string;
@@ -13,19 +15,34 @@ export type Facet = 'categories' | 'labels' | 'allergens' | 'additives' | 'count
13
15
  export type TaxonomySearchResult = {
14
16
  facet: string;
15
17
  tags: TaxonomyEntry[];
16
- /** Full facet size before any search filter — the vocabulary total. */
17
- total_in_facet: number;
18
18
  /**
19
- * Count of entries matching the search filter, before the `limit` cap.
20
- * Equals `total_in_facet` when no search term is given. Drives the truncation
21
- * decision so a filtered result is never reported as truncated against the
22
- * full facet size.
19
+ * Full facet size before any search filter. Present only for the closed vocabularies, whose
20
+ * entries are enumerable here. The live facets have no knowable total — the autocomplete endpoint
21
+ * reports no match count and cannot be enumerated — and reporting the offline sample size as the
22
+ * facet total is what presented 79 entries as the size of the Open Food Facts category taxonomy.
23
+ */
24
+ total_in_facet?: number;
25
+ /**
26
+ * Count of entries matching the search term, before the `limit` cap. Drives the truncation
27
+ * decision so a filtered result is never reported as truncated against the full facet size.
23
28
  */
24
29
  matched_in_facet: number;
30
+ /**
31
+ * Agent-facing caveat about how this answer was produced — that the vocabulary listed is the
32
+ * offline sample, that the live vocabulary could not be reached, or that nothing matched. Absent
33
+ * when the live resolution answered normally.
34
+ */
35
+ notice?: string;
25
36
  };
26
37
  export declare class TaxonomyService {
27
- /** Return tags for a given facet, optionally filtered by a substring search term. */
28
- search(facet: Facet, search: string | undefined, limit: number): TaxonomySearchResult;
38
+ private readonly off;
39
+ constructor(off: OpenFoodFactsService);
40
+ /**
41
+ * Resolve tags for a facet. With a search term, the live Open Food Facts vocabulary is queried
42
+ * and its suggestions merged behind the embedded matches; without one, the embedded sample is
43
+ * listed, because the upstream endpoint suggests against a term and cannot enumerate a facet.
44
+ */
45
+ search(facet: Facet, search: string | undefined, limit: number, ctx: Context): Promise<TaxonomySearchResult>;
29
46
  }
30
47
  export declare function initTaxonomyService(): void;
31
48
  export declare function getTaxonomyService(): TaxonomyService;
@@ -1 +1 @@
1
- {"version":3,"file":"taxonomy-service.d.ts","sourceRoot":"","sources":["../../../src/services/taxonomy/taxonomy-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,KAAK,GACb,YAAY,GACZ,QAAQ,GACR,WAAW,GACX,WAAW,GACX,WAAW,GACX,aAAa,GACb,kBAAkB,CAAC;AA4PvB,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,uEAAuE;IACvE,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,qBAAa,eAAe;IAC1B,qFAAqF;IACrF,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAiBpF;CACF;AAMD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD"}
1
+ {"version":3,"file":"taxonomy-service.d.ts","sourceRoot":"","sources":["../../../src/services/taxonomy/taxonomy-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mDAAmD,CAAC;AAG9F,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,KAAK,GACb,YAAY,GACZ,QAAQ,GACR,WAAW,GACX,WAAW,GACX,WAAW,GACX,aAAa,GACb,kBAAkB,CAAC;AA+RvB,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAhC,YAA6B,GAAG,EAAE,oBAAoB,EAAI;IAE1D;;;;OAIG;IACG,MAAM,CACV,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,oBAAoB,CAAC,CAuF/B;CACF;AAMD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD"}
@@ -1,12 +1,20 @@
1
1
  /**
2
- * @fileoverview Embedded taxonomy service for Open Food Facts tag vocabularies.
3
- * Returns curated tag IDs and display names for facets used in search filters.
4
- * No network calls — the OFF taxonomy endpoint returns 503 for anonymous bots.
2
+ * @fileoverview Taxonomy service for Open Food Facts tag vocabularies. Resolves a search term
3
+ * against the live search-a-licious autocomplete endpoint and merges the result with an embedded
4
+ * vocabulary, which also serves unfiltered browsing, the two fixed facets, and offline operation.
5
5
  * @module services/taxonomy/taxonomy-service
6
6
  */
7
+ import { getOpenFoodFactsService } from '../../services/openfoodfacts/openfoodfacts-service.js';
7
8
  /* -------------------------------------------------------------------------- */
8
9
  /* Embedded vocabulary */
9
10
  /* -------------------------------------------------------------------------- */
11
+ /**
12
+ * Offline sample of each facet, and the whole vocabulary for the two fixed facets. For the live
13
+ * facets this is a small, hand-maintained slice of a much larger upstream taxonomy — it is merged
14
+ * ahead of live suggestions rather than replaced by them, because the autocomplete endpoint matches
15
+ * on display names and answers an E-number query with unrelated E-numbers, so `additives` searches
16
+ * that resolve correctly here would regress on a live-only path.
17
+ */
10
18
  const TAXONOMY = {
11
19
  categories: [
12
20
  { id: 'en:beverages', name: 'Beverages' },
@@ -228,11 +236,19 @@ const TAXONOMY = {
228
236
  { id: 'en:russia', name: 'Russia' },
229
237
  { id: 'en:turkey', name: 'Turkey' },
230
238
  ],
239
+ /**
240
+ * Bare digits, matching the bare grade letters `nutrition_grades` emits and the value
241
+ * `off_search_products` accepts for `nova_group`. The `en:`-prefixed form these once carried was
242
+ * not a valid filter value anywhere: the tool's own Zod enum rejects it outright, and while the
243
+ * tag backend normalizes `nova_groups_tags=en:1` to the same 136,019 matches as `=1`, the text
244
+ * backend does not — `nova_group:en:1` is live-verified answering zero hits flagged
245
+ * `is_count_exact: true`, a confident false "no such product" rather than an error.
246
+ */
231
247
  nova_groups: [
232
- { id: 'en:1', name: 'NOVA 1 — Unprocessed or minimally processed foods' },
233
- { id: 'en:2', name: 'NOVA 2 — Processed culinary ingredients' },
234
- { id: 'en:3', name: 'NOVA 3 — Processed foods' },
235
- { id: 'en:4', name: 'NOVA 4 — Ultra-processed food and drink products' },
248
+ { id: '1', name: 'NOVA 1 — Unprocessed or minimally processed foods' },
249
+ { id: '2', name: 'NOVA 2 — Processed culinary ingredients' },
250
+ { id: '3', name: 'NOVA 3 — Processed foods' },
251
+ { id: '4', name: 'NOVA 4 — Ultra-processed food and drink products' },
236
252
  ],
237
253
  nutrition_grades: [
238
254
  { id: 'a', name: 'Nutri-Score A — Highest nutritional quality' },
@@ -242,26 +258,122 @@ const TAXONOMY = {
242
258
  { id: 'e', name: 'Nutri-Score E — Lowest nutritional quality' },
243
259
  ],
244
260
  };
261
+ /* -------------------------------------------------------------------------- */
262
+ /* Service */
263
+ /* -------------------------------------------------------------------------- */
264
+ /**
265
+ * search-a-licious taxonomy name per facet. `nova_groups` and `nutrition_grades` have no live
266
+ * counterpart — the autocomplete endpoint serves no such taxonomy and answers HTTP 200 with an
267
+ * empty option list when named one — and both vocabularies are closed and complete above, so the
268
+ * embedded entries are the whole truth for them rather than a sample.
269
+ */
270
+ const LIVE_TAXONOMY_NAME = {
271
+ categories: 'category',
272
+ labels: 'label',
273
+ allergens: 'allergen',
274
+ additives: 'additive',
275
+ countries: 'country',
276
+ };
277
+ /** The facet's documented match rule: case-insensitive substring against tag ID or display name. */
278
+ function matchesTerm(entry, term) {
279
+ const needle = term.toLowerCase();
280
+ return entry.id.toLowerCase().includes(needle) || entry.name.toLowerCase().includes(needle);
281
+ }
245
282
  export class TaxonomyService {
246
- /** Return tags for a given facet, optionally filtered by a substring search term. */
247
- search(facet, search, limit) {
248
- const all = TAXONOMY[facet];
249
- const filtered = search && search.trim().length > 0
250
- ? all.filter((t) => t.id.toLowerCase().includes(search.toLowerCase()) ||
251
- t.name.toLowerCase().includes(search.toLowerCase()))
252
- : all;
283
+ off;
284
+ constructor(off) {
285
+ this.off = off;
286
+ }
287
+ /**
288
+ * Resolve tags for a facet. With a search term, the live Open Food Facts vocabulary is queried
289
+ * and its suggestions merged behind the embedded matches; without one, the embedded sample is
290
+ * listed, because the upstream endpoint suggests against a term and cannot enumerate a facet.
291
+ */
292
+ async search(facet, search, limit, ctx) {
293
+ const embedded = TAXONOMY[facet];
294
+ const term = search?.trim();
295
+ const taxonomyName = LIVE_TAXONOMY_NAME[facet];
296
+ if (!taxonomyName) {
297
+ const matched = term ? embedded.filter((entry) => matchesTerm(entry, term)) : embedded;
298
+ return {
299
+ facet,
300
+ tags: matched.slice(0, limit),
301
+ total_in_facet: embedded.length,
302
+ matched_in_facet: matched.length,
303
+ };
304
+ }
305
+ if (!term) {
306
+ return {
307
+ facet,
308
+ tags: embedded.slice(0, limit),
309
+ matched_in_facet: embedded.length,
310
+ notice: `This is this server's offline ${facet} sample (${embedded.length} entries), not the Open Food Facts ` +
311
+ `${facet} taxonomy, which is far larger and cannot be listed in full — pass a search term to resolve ` +
312
+ 'one against the live vocabulary.',
313
+ };
314
+ }
315
+ const offline = embedded.filter((entry) => matchesTerm(entry, term));
316
+ /**
317
+ * The live call is the enrichment, not the answer of record: a caller asking for `en:organic`
318
+ * during an Open Food Facts outage is better served by the offline match plus a caveat than by
319
+ * a failure, and a caller whose term matches nothing offline needs to be told the vocabulary
320
+ * went unchecked rather than reading an empty list as "no such tag". Both are the failure this
321
+ * degradation exists to prevent, so the throw is absorbed here and reported in `notice`.
322
+ */
323
+ let live;
324
+ try {
325
+ // One past the limit, so a full page can be told apart from an exactly-full one and reported
326
+ // as truncated. The endpoint offers no offset, so this is the only way to know more exist.
327
+ live = await this.off.suggestTaxonomy(taxonomyName, term, limit + 1, ctx);
328
+ }
329
+ catch (error) {
330
+ const cause = error instanceof Error ? error.message : String(error);
331
+ ctx.log.warning('Live taxonomy resolution failed — falling back to the offline sample', {
332
+ facet,
333
+ term,
334
+ error: cause,
335
+ });
336
+ return {
337
+ facet,
338
+ tags: offline.slice(0, limit),
339
+ matched_in_facet: offline.length,
340
+ notice: `The live Open Food Facts ${facet} vocabulary could not be reached ` +
341
+ `(${cause}). These ${offline.length} result(s) come ` +
342
+ `from this server's offline sample of ${embedded.length} entries, so a term the sample does not ` +
343
+ 'cover reads as no match here even when the tag exists upstream. Retry for an authoritative answer.',
344
+ };
345
+ }
346
+ /**
347
+ * Held to the same substring rule the facet documents. Upstream matches whole words against
348
+ * display names and falls back to loosely-related suggestions when nothing matches — an
349
+ * E-number query returns a page of unrelated E-numbers — so unfiltered pass-through would
350
+ * answer `e330` with tags that do not contain it. Measured across ordinary terms (cheese,
351
+ * kombucha, olive oil, organic, tofu, …) this drops nothing and removes only that noise.
352
+ */
353
+ const seen = new Set(offline.map((entry) => entry.id));
354
+ const merged = [...offline];
355
+ for (const entry of live) {
356
+ if (!seen.has(entry.id) && matchesTerm(entry, term)) {
357
+ seen.add(entry.id);
358
+ merged.push(entry);
359
+ }
360
+ }
253
361
  return {
254
362
  facet,
255
- tags: filtered.slice(0, limit),
256
- total_in_facet: all.length,
257
- matched_in_facet: filtered.length,
363
+ tags: merged.slice(0, limit),
364
+ matched_in_facet: merged.length,
365
+ ...(merged.length === 0 && {
366
+ notice: `No ${facet} tag matched "${term}" in the Open Food Facts vocabulary. Matching is on whole words in ` +
367
+ 'the tag name, so try a single simpler word (e.g. "hummus" rather than "hummus dip"); note also that ' +
368
+ 'many category tags are plural upstream ("kombucha" resolves to en:kombuchas).',
369
+ }),
258
370
  };
259
371
  }
260
372
  }
261
373
  /* --- Init/accessor pattern --- */
262
374
  let _service;
263
375
  export function initTaxonomyService() {
264
- _service = new TaxonomyService();
376
+ _service = new TaxonomyService(getOpenFoodFactsService());
265
377
  }
266
378
  export function getTaxonomyService() {
267
379
  if (!_service) {
@@ -1 +1 @@
1
- {"version":3,"file":"taxonomy-service.js","sourceRoot":"","sources":["../../../src/services/taxonomy/taxonomy-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"taxonomy-service.js","sourceRoot":"","sources":["../../../src/services/taxonomy/taxonomy-service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyanheads/openfoodfacts-mcp-server",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "mcpName": "io.github.cyanheads/openfoodfacts-mcp-server",
5
5
  "description": "Look up food products by barcode, search by ingredient or nutrition filter, compare products side-by-side, and browse the canonical tag vocabulary via MCP. STDIO or Streamable HTTP.",
6
6
  "type": "module",
package/server.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/cyanheads/openfoodfacts-mcp-server",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.2.0",
9
+ "version": "0.3.0",
10
10
  "remotes": [
11
11
  {
12
12
  "type": "streamable-http",
@@ -19,7 +19,7 @@
19
19
  "registryBaseUrl": "https://registry.npmjs.org",
20
20
  "identifier": "@cyanheads/openfoodfacts-mcp-server",
21
21
  "runtimeHint": "bun",
22
- "version": "0.2.0",
22
+ "version": "0.3.0",
23
23
  "packageArguments": [
24
24
  {
25
25
  "type": "positional",
@@ -52,6 +52,13 @@
52
52
  "isRequired": false,
53
53
  "default": "10"
54
54
  },
55
+ {
56
+ "name": "OFF_RATE_LIMIT_TAXONOMY",
57
+ "description": "Taxonomy resolution rate limit (requests/min). Applies to the live tag-vocabulary lookups off_browse_taxonomy makes; a spent budget falls back to the offline sample rather than failing.",
58
+ "format": "string",
59
+ "isRequired": false,
60
+ "default": "10"
61
+ },
55
62
  {
56
63
  "name": "MCP_LOG_LEVEL",
57
64
  "description": "Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').",
@@ -69,7 +76,7 @@
69
76
  "registryBaseUrl": "https://registry.npmjs.org",
70
77
  "identifier": "@cyanheads/openfoodfacts-mcp-server",
71
78
  "runtimeHint": "bun",
72
- "version": "0.2.0",
79
+ "version": "0.3.0",
73
80
  "packageArguments": [
74
81
  {
75
82
  "type": "positional",
@@ -102,6 +109,13 @@
102
109
  "isRequired": false,
103
110
  "default": "10"
104
111
  },
112
+ {
113
+ "name": "OFF_RATE_LIMIT_TAXONOMY",
114
+ "description": "Taxonomy resolution rate limit (requests/min). Applies to the live tag-vocabulary lookups off_browse_taxonomy makes; a spent budget falls back to the offline sample rather than failing.",
115
+ "format": "string",
116
+ "isRequired": false,
117
+ "default": "10"
118
+ },
105
119
  {
106
120
  "name": "MCP_HTTP_HOST",
107
121
  "description": "The hostname for the HTTP server.",