@cyanheads/openfoodfacts-mcp-server 0.2.0 → 0.3.1
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 +3 -3
- package/CLAUDE.md +3 -3
- package/README.md +15 -11
- package/changelog/0.3.x/0.3.0.md +19 -0
- package/changelog/0.3.x/0.3.1.md +16 -0
- package/dist/config/server-config.d.ts +13 -0
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +20 -1
- package/dist/config/server-config.js.map +1 -1
- package/dist/mcp-server/tools/definitions/browse-taxonomy.tool.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/browse-taxonomy.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/browse-taxonomy.tool.js +33 -14
- package/dist/mcp-server/tools/definitions/browse-taxonomy.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/services/openfoodfacts/openfoodfacts-service.d.ts +15 -0
- package/dist/services/openfoodfacts/openfoodfacts-service.d.ts.map +1 -1
- package/dist/services/openfoodfacts/openfoodfacts-service.js +44 -0
- package/dist/services/openfoodfacts/openfoodfacts-service.js.map +1 -1
- package/dist/services/openfoodfacts/types.d.ts +19 -0
- package/dist/services/openfoodfacts/types.d.ts.map +1 -1
- package/dist/services/taxonomy/taxonomy-service.d.ts +28 -11
- package/dist/services/taxonomy/taxonomy-service.d.ts.map +1 -1
- package/dist/services/taxonomy/taxonomy-service.js +130 -18
- package/dist/services/taxonomy/taxonomy-service.js.map +1 -1
- package/package.json +1 -1
- package/server.json +21 -7
package/AGENTS.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** openfoodfacts-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
4
|
+
**Version:** 0.3.1
|
|
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
|
|
@@ -79,7 +79,7 @@ import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
|
|
|
79
79
|
|
|
80
80
|
const ServerConfigSchema = z.object({
|
|
81
81
|
baseUrl: z.string().default('https://world.openfoodfacts.org').describe('Open Food Facts API base URL'),
|
|
82
|
-
rateLimitProduct: z.coerce.number().int().min(1).default(
|
|
82
|
+
rateLimitProduct: z.coerce.number().int().min(1).default(15).describe('Product read rate limit (requests/min)'),
|
|
83
83
|
rateLimitSearch: z.coerce.number().int().min(1).default(10).describe('Search rate limit (requests/min)'),
|
|
84
84
|
});
|
|
85
85
|
|
|
@@ -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 #
|
|
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.
|
|
4
|
+
**Version:** 0.3.1
|
|
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
|
|
@@ -79,7 +79,7 @@ import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
|
|
|
79
79
|
|
|
80
80
|
const ServerConfigSchema = z.object({
|
|
81
81
|
baseUrl: z.string().default('https://world.openfoodfacts.org').describe('Open Food Facts API base URL'),
|
|
82
|
-
rateLimitProduct: z.coerce.number().int().min(1).default(
|
|
82
|
+
rateLimitProduct: z.coerce.number().int().min(1).default(15).describe('Product read rate limit (requests/min)'),
|
|
83
83
|
rateLimitSearch: z.coerce.number().int().min(1).default(10).describe('Search rate limit (requests/min)'),
|
|
84
84
|
});
|
|
85
85
|
|
|
@@ -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 #
|
|
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
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/openfoodfacts-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/openfoodfacts-mcp-server) [](https://www.typescriptlang.org/) [](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` |
|
|
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
|
-
|
|
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
|
-
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
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 (~
|
|
112
|
+
- Token-bucket rate limiting per endpoint class: product reads (~15/min), search (~10/min), taxonomy resolution (~10/min). The product and search defaults are the per-IP ceilings Open Food Facts publishes; lower them on a shared outbound IP. 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
|
-
-
|
|
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
|
|
|
@@ -238,8 +241,9 @@ All configuration is validated at startup via Zod schemas in `src/config/server-
|
|
|
238
241
|
| Variable | Description | Default |
|
|
239
242
|
|:---------|:------------|:--------|
|
|
240
243
|
| `OFF_BASE_URL` | Open Food Facts API base URL. Override for local testing against a mock server. | `https://world.openfoodfacts.org` |
|
|
241
|
-
| `OFF_RATE_LIMIT_PRODUCT` | Product read rate limit (requests/min). | `
|
|
244
|
+
| `OFF_RATE_LIMIT_PRODUCT` | Product read rate limit (requests/min). Matches the 15 req/min/IP Open Food Facts documents for product reads. | `15` |
|
|
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` |
|
|
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`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "OFF_RATE_LIMIT_PRODUCT now defaults to 15/min, the per-IP ceiling Open Food Facts publishes for product reads, down from a default that permitted 6.6x that rate."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.3.1 — 2026-07-26
|
|
8
|
+
|
|
9
|
+
## Fixed
|
|
10
|
+
|
|
11
|
+
- **`OFF_RATE_LIMIT_PRODUCT`** — default lowered from `100` to `15` requests/min, matching the 15 req/min/IP Open Food Facts documents for `GET /api/v*/product`. The prior default authorized exceeding the published ceiling, which Open Food Facts answers with an IP ban rather than a throttle. Operators running their own Product Opener instance can still raise it via the env var. ([#21](https://github.com/cyanheads/openfoodfacts-mcp-server/issues/21))
|
|
12
|
+
- **README.md, docs/design.md, docs/idea.md, `server.json`** — corrected the four documentation references that still stated the old `100`/min product-read default.
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- **`docs/design.md`** — documents that the taxonomy tier calls `search.openfoodfacts.org` (search-a-licious), a separate deployment the published Open Food Facts limits do not name and for which no limit is documented, so its `10`/min default is a conservative local choice rather than a mirror of a published figure. The text and tag search paths share one budget, so requests reaching the endpoint the documented 10/min covers stay within it regardless of how a query routes.
|
|
@@ -3,10 +3,23 @@
|
|
|
3
3
|
* @module config/server-config
|
|
4
4
|
*/
|
|
5
5
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
/**
|
|
7
|
+
* Rate-limit defaults sit at the per-IP ceilings Open Food Facts publishes, not above them: 15
|
|
8
|
+
* req/min for product reads (`GET /api/v2/product/…`) and 10 req/min for search
|
|
9
|
+
* (`GET /api/v2/search`). The documented consequence of exceeding either is an IP ban rather than a
|
|
10
|
+
* throttle, so there is no headroom to spend. A shared outbound IP needs a lower number than the
|
|
11
|
+
* published one — that is what the env vars are for, alongside operators running their own Product
|
|
12
|
+
* Opener instance who can raise them.
|
|
13
|
+
*
|
|
14
|
+
* The taxonomy tier is covered by neither published figure: it calls search.openfoodfacts.org
|
|
15
|
+
* (search-a-licious), a separate deployment the published limits do not name and for which no limit
|
|
16
|
+
* is documented. Its default matches the search tier as a conservative stand-in.
|
|
17
|
+
*/
|
|
6
18
|
declare const ServerConfigSchema: z.ZodObject<{
|
|
7
19
|
baseUrl: z.ZodDefault<z.ZodString>;
|
|
8
20
|
rateLimitProduct: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
9
21
|
rateLimitSearch: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
22
|
+
rateLimitTaxonomy: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
10
23
|
}, z.core.$strip>;
|
|
11
24
|
export type ServerConfig = z.infer<typeof ServerConfigSchema>;
|
|
12
25
|
/** 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
|
|
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;;;;;;;;;;;GAWG;AACH,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"}
|
|
@@ -4,6 +4,18 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
6
|
import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
|
|
7
|
+
/**
|
|
8
|
+
* Rate-limit defaults sit at the per-IP ceilings Open Food Facts publishes, not above them: 15
|
|
9
|
+
* req/min for product reads (`GET /api/v2/product/…`) and 10 req/min for search
|
|
10
|
+
* (`GET /api/v2/search`). The documented consequence of exceeding either is an IP ban rather than a
|
|
11
|
+
* throttle, so there is no headroom to spend. A shared outbound IP needs a lower number than the
|
|
12
|
+
* published one — that is what the env vars are for, alongside operators running their own Product
|
|
13
|
+
* Opener instance who can raise them.
|
|
14
|
+
*
|
|
15
|
+
* The taxonomy tier is covered by neither published figure: it calls search.openfoodfacts.org
|
|
16
|
+
* (search-a-licious), a separate deployment the published limits do not name and for which no limit
|
|
17
|
+
* is documented. Its default matches the search tier as a conservative stand-in.
|
|
18
|
+
*/
|
|
7
19
|
const ServerConfigSchema = z.object({
|
|
8
20
|
baseUrl: z
|
|
9
21
|
.string()
|
|
@@ -13,7 +25,7 @@ const ServerConfigSchema = z.object({
|
|
|
13
25
|
.number()
|
|
14
26
|
.int()
|
|
15
27
|
.min(1)
|
|
16
|
-
.default(
|
|
28
|
+
.default(15)
|
|
17
29
|
.describe('Product read rate limit (requests/min)'),
|
|
18
30
|
rateLimitSearch: z.coerce
|
|
19
31
|
.number()
|
|
@@ -21,6 +33,12 @@ const ServerConfigSchema = z.object({
|
|
|
21
33
|
.min(1)
|
|
22
34
|
.default(10)
|
|
23
35
|
.describe('Search rate limit (requests/min)'),
|
|
36
|
+
rateLimitTaxonomy: z.coerce
|
|
37
|
+
.number()
|
|
38
|
+
.int()
|
|
39
|
+
.min(1)
|
|
40
|
+
.default(10)
|
|
41
|
+
.describe('Taxonomy resolution rate limit (requests/min)'),
|
|
24
42
|
});
|
|
25
43
|
let _config;
|
|
26
44
|
/** Lazy-parsed server config from environment variables. */
|
|
@@ -29,6 +47,7 @@ export function getServerConfig() {
|
|
|
29
47
|
baseUrl: 'OFF_BASE_URL',
|
|
30
48
|
rateLimitProduct: 'OFF_RATE_LIMIT_PRODUCT',
|
|
31
49
|
rateLimitSearch: 'OFF_RATE_LIMIT_SEARCH',
|
|
50
|
+
rateLimitTaxonomy: 'OFF_RATE_LIMIT_TAXONOMY',
|
|
32
51
|
});
|
|
33
52
|
return _config;
|
|
34
53
|
}
|
|
@@ -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,
|
|
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;;;;;;;;;;;GAWG;AACH,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,EAAE,CAAC;SACX,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
|
|
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: '
|
|
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:
|
|
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"
|
|
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('
|
|
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).
|
|
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").
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
-
|
|
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*
|
|
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":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAc,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAEzF,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,EAAE;IAC/D,KAAK,EAAE,4BAA4B;IACnC,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"browse-taxonomy.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/browse-taxonomy.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAc,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAEzF,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,EAAE;IAC/D,KAAK,EAAE,4BAA4B;IACnC,WAAW,EACT,s0BAAs0B;IACx0B,WAAW,EAAE;QACX,YAAY,EAAE,IAAI;QAClB,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,IAAI;KACpB;IAED,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,KAAK,EAAE,CAAC;aACL,IAAI,CAAC;YACJ,YAAY;YACZ,QAAQ;YACR,WAAW;YACX,WAAW;YACX,WAAW;YACX,aAAa;YACb,kBAAkB;SACnB,CAAC;aACD,QAAQ,CACP,0cAA0c,CAC3c;QACH,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wXAAwX,CACzX;QACH,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,GAAG,CAAC;aACR,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CACP,sOAAsO,CACvO;KACJ,CAAC;IAEF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;QACjF,IAAI,EAAE,CAAC;aACJ,KAAK,CACJ,CAAC;aACE,MAAM,CAAC;YACN,EAAE,EAAE,CAAC;iBACF,MAAM,EAAE;iBACR,QAAQ,CACP,kMAAkM,CACnM;YACH,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;YAC1E,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,4EAA4E,CAC7E;SACJ,CAAC;aACD,QAAQ,CAAC,qEAAqE,CAAC,CACnF;aACA,QAAQ,CAAC,uBAAuB,CAAC;QACpC,cAAc,EAAE,CAAC;aACd,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,uRAAuR,CACxR;KACJ,CAAC;IAEF,UAAU,EAAE;QACV,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,gMAAgM,CACjM;QACH,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;QACzF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QACjE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;KACnE;IAED,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACtB,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;QACjC,+FAA+F;QAC/F,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAc,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAEtF,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC/B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;YAC5B,OAAO,EAAE,MAAM,CAAC,gBAAgB;SACjC,CAAC,CAAC;QAEH,qFAAqF;QACrF,yFAAyF;QACzF,sFAAsF;QACtF,+BAA+B;QAC/B,EAAE;QACF,+FAA+F;QAC/F,8FAA8F;QAC9F,6FAA6F;QAC7F,0FAA0F;QAC1F,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACjD,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;gBACzB,GAAG,EAAE,KAAK,CAAC,KAAK;gBAChB,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;aAClD,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QAED,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,GAAG,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC;SACtF,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;QACjB,MAAM,KAAK,GAAa;YACtB,MAAM,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,WAAW,MAAM,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,cAAc,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK;SACzI,CAAC;QAEF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,0FAA0F;YAC1F,sFAAsF;YACtF,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;YAC/C,OAAO,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,QAAQ,GACZ,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,KAAK,CAAC,IAAI,CACR,qKAAqK,CACtK,CAAC;QAEF,OAAO,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -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
|
|
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,
|
|
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
|
|
3
|
-
*
|
|
4
|
-
*
|
|
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
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
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
|
-
|
|
28
|
-
|
|
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;
|
|
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
|
|
3
|
-
*
|
|
4
|
-
*
|
|
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: '
|
|
233
|
-
{ id: '
|
|
234
|
-
{ id: '
|
|
235
|
-
{ id: '
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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:
|
|
256
|
-
|
|
257
|
-
|
|
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.
|
|
3
|
+
"version": "0.3.1",
|
|
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.
|
|
9
|
+
"version": "0.3.1",
|
|
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.
|
|
22
|
+
"version": "0.3.1",
|
|
23
23
|
"packageArguments": [
|
|
24
24
|
{
|
|
25
25
|
"type": "positional",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"name": "OFF_RATE_LIMIT_PRODUCT",
|
|
43
|
-
"description": "Product read rate limit (requests/min).",
|
|
43
|
+
"description": "Product read rate limit (requests/min). Matches the 15 req/min/IP Open Food Facts documents for product reads.",
|
|
44
44
|
"format": "string",
|
|
45
45
|
"isRequired": false,
|
|
46
|
-
"default": "
|
|
46
|
+
"default": "15"
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
"name": "OFF_RATE_LIMIT_SEARCH",
|
|
@@ -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.
|
|
79
|
+
"version": "0.3.1",
|
|
73
80
|
"packageArguments": [
|
|
74
81
|
{
|
|
75
82
|
"type": "positional",
|
|
@@ -90,10 +97,10 @@
|
|
|
90
97
|
},
|
|
91
98
|
{
|
|
92
99
|
"name": "OFF_RATE_LIMIT_PRODUCT",
|
|
93
|
-
"description": "Product read rate limit (requests/min).",
|
|
100
|
+
"description": "Product read rate limit (requests/min). Matches the 15 req/min/IP Open Food Facts documents for product reads.",
|
|
94
101
|
"format": "string",
|
|
95
102
|
"isRequired": false,
|
|
96
|
-
"default": "
|
|
103
|
+
"default": "15"
|
|
97
104
|
},
|
|
98
105
|
{
|
|
99
106
|
"name": "OFF_RATE_LIMIT_SEARCH",
|
|
@@ -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.",
|