@cyanheads/openfoodfacts-mcp-server 0.3.8 → 0.4.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 +21 -8
- package/CLAUDE.md +21 -8
- package/Dockerfile +9 -3
- package/README.md +43 -111
- package/changelog/0.3.x/0.3.9.md +24 -0
- package/changelog/0.4.x/0.4.0.md +30 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/browse-taxonomy.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/browse-taxonomy.tool.js +5 -0
- package/dist/mcp-server/tools/definitions/browse-taxonomy.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-products.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/compare-products.tool.js +10 -10
- package/dist/mcp-server/tools/definitions/compare-products.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-product.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-product.tool.js +3 -2
- package/dist/mcp-server/tools/definitions/get-product.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-products.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-products.tool.js +13 -12
- package/dist/mcp-server/tools/definitions/search-products.tool.js.map +1 -1
- package/dist/utils/markdown.d.ts +0 -12
- package/dist/utils/markdown.d.ts.map +1 -1
- package/dist/utils/markdown.js +2 -23
- package/dist/utils/markdown.js.map +1 -1
- package/package.json +10 -9
- package/server.json +3 -3
- package/skills/openfoodfacts-guide/SKILL.md +41 -0
package/AGENTS.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** openfoodfacts-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.
|
|
4
|
+
**Version:** 0.4.0
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.18`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
|
-
**MCP SDK:** `@modelcontextprotocol/server` ^2.
|
|
8
|
-
**Zod:** ^4.6.
|
|
7
|
+
**MCP SDK:** `@modelcontextprotocol/server` ^2.4.0
|
|
8
|
+
**Zod:** ^4.6.7
|
|
9
9
|
|
|
10
10
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
11
11
|
|
|
@@ -239,9 +239,18 @@ src/
|
|
|
239
239
|
|
|
240
240
|
## Skills
|
|
241
241
|
|
|
242
|
-
|
|
242
|
+
Two skill trees live at the project root, written for different readers:
|
|
243
243
|
|
|
244
|
-
|
|
244
|
+
| Tree | For | Written by |
|
|
245
|
+
|:-----|:----|:-----------|
|
|
246
|
+
| `framework-skills/` | The agent developing this server — framework skills (`metadata.audience: external`) plus any development-time skills of the server's own | `init` and the `maintenance` sync (framework skills); you (your own) |
|
|
247
|
+
| `skills/` | The agents that install the server and call its tools — tool chains, identifier sources, gates | You, deliberately, with the `add-skill` skill. Absent by default; usually none is needed |
|
|
248
|
+
|
|
249
|
+
Development skills are modular instructions. Read them directly when a task matches — e.g., `framework-skills/add-tool/SKILL.md` when adding a tool. `bun run list-skills` prints the full registry. Their directory is deliberately not `skills/`: Claude Code and Codex auto-load a plugin's root `skills/`, so a server that ships `.claude-plugin/` or `.codex-plugin/` would hand them to every agent that installs it.
|
|
250
|
+
|
|
251
|
+
A published skill in root `skills/` reaches plugin installs and the `.mcpb` bundle as-is, ships in the npm package and the Docker image, and reaches MCP clients when the server opts in with `createApp({ skills: 'skills' })`. `lint:packaging` validates the tree.
|
|
252
|
+
|
|
253
|
+
**Agent skill directory:** Copy `framework-skills/` into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `framework-skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
245
254
|
|
|
246
255
|
Available skills:
|
|
247
256
|
|
|
@@ -253,6 +262,7 @@ Available skills:
|
|
|
253
262
|
| `add-app-tool` | Scaffold an MCP App tool + paired UI resource |
|
|
254
263
|
| `add-resource` | Scaffold a new resource definition |
|
|
255
264
|
| `add-prompt` | Scaffold a new prompt definition |
|
|
265
|
+
| `add-skill` | Author a skill the server publishes in root `skills/` for the agents that use it — when one earns its place, structure, validation, delivery |
|
|
256
266
|
| `add-service` | Scaffold a new service integration |
|
|
257
267
|
| `add-test` | Scaffold test file for a tool, resource, or service |
|
|
258
268
|
| `field-test` | Exercise tools/resources/prompts with real inputs, verify behavior, report issues |
|
|
@@ -300,7 +310,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
300
310
|
| `bun run audit:fix` | `bun audit fix` — upgrade vulnerable packages to the lowest safe version within existing ranges (`--dry-run` previews, `--latest` rewrites ranges). First response when `devcheck` flags a transitive advisory; then `bun update <name>`, then `bun dedupe` |
|
|
301
311
|
| `bun run audit:refresh` | Delete `bun.lock` and reinstall. Last resort after `audit:fix`, `bun update <name>`, and `bun dedupe` — re-resolves every ranged dep (the framework pin included) and rewrites the lockfile as `lockfileVersion: 2` |
|
|
302
312
|
| `bun run lint:mcp` | Run the MCP definition linter standalone (rule catalog: `api-linter` skill) |
|
|
303
|
-
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |
|
|
313
|
+
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity, `.mcpbignore` coverage, plugin manifests, the published `skills/` tree (run by devcheck) |
|
|
304
314
|
| `bun run list-skills` | Print the skill registry |
|
|
305
315
|
| `bun run tree` | Generate directory structure doc |
|
|
306
316
|
| `bun run format` | Auto-fix formatting (safe fixes only) |
|
|
@@ -318,7 +328,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
318
328
|
|
|
319
329
|
## Bundling
|
|
320
330
|
|
|
321
|
-
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips
|
|
331
|
+
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. `mcpb pack` reads `.mcpbignore`, not `.gitignore`, so every root path the bundle must not ship — source, tests, docs, caches, logs, agent docs, plugin manifests, gitignored local files — needs a root-anchored line there (`/docs/`, never `docs/`, which also strips `node_modules/*/docs/`); `lint:packaging` names each missing or unanchored line. Root `skills/` ships on purpose. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips four classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`framework-skills/`, `skills/`, `.claude/`, `.agents/`, `SKILL.md`); platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on; node-gyp build output beside a `binding.gyp` (`config.gypi`, Makefiles, `obj.target/`, `.deps/`, object files and debug symbols), which records the packing machine's paths — compiled `*.node` addons stay; and build-only package files — the framework's `changelog/`, `scripts/`, `templates/`, `CLAUDE.md`, `AGENTS.md`, and config bases (`biome.json`, `vitest.config.base.mjs`, `config/tsconfig.base.json`), and `better-sqlite3`'s `deps/` and `src/` C sources. A server using DataCanvas therefore ships a portable bundle without the DuckDB native — `@duckdb/node-api` is an optional peer loaded lazily, so canvas tools report an actionable install hint and every other tool works normally. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
322
332
|
|
|
323
333
|
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match, that every `user_config` option is wired into `mcp_config.env` as `"X": "${user_config.X}"` (the host substitutes nothing else — `"${X}"` reaches the server as that literal string), and that an optional string option carries `"default": ""`.
|
|
324
334
|
|
|
@@ -385,7 +395,10 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
385
395
|
- [ ] If wrapping external API: tests include at least one sparse payload case with omitted upstream fields
|
|
386
396
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
387
397
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
398
|
+
- [ ] `plugin.json` + `mcp.json` (Agent Plugins 1.0.0 — read by Codex, Cursor, GitHub Copilot, VS Code, Kiro) populated — `plugin.json` `name` = the unscoped repo name (lowercase `a-z`, `0-9`, `-`, `.` only); `version`, `description`, `author`, `homepage`, `repository`, `license`, `keywords` from `package.json`; no other top-level field, `extensions` included. `mcp.json` holds one `"type": "stdio"` entry keyed by the unscoped name, `npx -y <full package name>`, and the same fixed `env` as `.codex-plugin/mcp.json`. Neither file carries a user-supplied variable (no `""`, no `${…}` besides `${PLUGIN_ROOT}`/`${PLUGIN_DATA}`): keys reach Codex through `.codex-plugin/mcp.json` `env_vars`, which works only while `.codex-plugin/plugin.json` keeps `"mcpServers": "./.codex-plugin/mcp.json"`
|
|
388
399
|
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = the unscoped repo name (never the npm scope — `lint:packaging` enforces this); `interface.shortDescription` from `package.json` description
|
|
389
400
|
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable (API key, contact email, instance URL) is listed in `env_vars` so Codex forwards it from the user's environment. Never write `"KEY": ""` into `env` — an empty value replaces the user's exported key and is read as unset
|
|
390
401
|
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `author`, `repository`, `license`, `keywords` from `package.json`; inline `mcpServers` entry keyed by the unscoped repo name. Every user-supplied variable is declared under `userConfig` (`type`, `title`, `description`; `sensitive: true` for keys and tokens; `required: true` or `default: ""`) and referenced from `env` as `"KEY": "${user_config.<option>}"` — mirror the `user_config` block in `manifest.json`. Never write `"KEY": ""` into `env`
|
|
402
|
+
- [ ] Any new root dev path has a root-anchored line in `.mcpbignore`; `bun run bundle` and `lint:packaging` pass
|
|
403
|
+
- [ ] If the server publishes a skill in root `skills/`: `lint:packaging` passes, and `field-test` verified every gate and identifier claim in it against live tool behavior
|
|
391
404
|
- [ ] `npm run devcheck` passes
|
package/CLAUDE.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** openfoodfacts-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.
|
|
4
|
+
**Version:** 0.4.0
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.18`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
|
-
**MCP SDK:** `@modelcontextprotocol/server` ^2.
|
|
8
|
-
**Zod:** ^4.6.
|
|
7
|
+
**MCP SDK:** `@modelcontextprotocol/server` ^2.4.0
|
|
8
|
+
**Zod:** ^4.6.7
|
|
9
9
|
|
|
10
10
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
11
11
|
|
|
@@ -239,9 +239,18 @@ src/
|
|
|
239
239
|
|
|
240
240
|
## Skills
|
|
241
241
|
|
|
242
|
-
|
|
242
|
+
Two skill trees live at the project root, written for different readers:
|
|
243
243
|
|
|
244
|
-
|
|
244
|
+
| Tree | For | Written by |
|
|
245
|
+
|:-----|:----|:-----------|
|
|
246
|
+
| `framework-skills/` | The agent developing this server — framework skills (`metadata.audience: external`) plus any development-time skills of the server's own | `init` and the `maintenance` sync (framework skills); you (your own) |
|
|
247
|
+
| `skills/` | The agents that install the server and call its tools — tool chains, identifier sources, gates | You, deliberately, with the `add-skill` skill. Absent by default; usually none is needed |
|
|
248
|
+
|
|
249
|
+
Development skills are modular instructions. Read them directly when a task matches — e.g., `framework-skills/add-tool/SKILL.md` when adding a tool. `bun run list-skills` prints the full registry. Their directory is deliberately not `skills/`: Claude Code and Codex auto-load a plugin's root `skills/`, so a server that ships `.claude-plugin/` or `.codex-plugin/` would hand them to every agent that installs it.
|
|
250
|
+
|
|
251
|
+
A published skill in root `skills/` reaches plugin installs and the `.mcpb` bundle as-is, ships in the npm package and the Docker image, and reaches MCP clients when the server opts in with `createApp({ skills: 'skills' })`. `lint:packaging` validates the tree.
|
|
252
|
+
|
|
253
|
+
**Agent skill directory:** Copy `framework-skills/` into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `framework-skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
245
254
|
|
|
246
255
|
Available skills:
|
|
247
256
|
|
|
@@ -253,6 +262,7 @@ Available skills:
|
|
|
253
262
|
| `add-app-tool` | Scaffold an MCP App tool + paired UI resource |
|
|
254
263
|
| `add-resource` | Scaffold a new resource definition |
|
|
255
264
|
| `add-prompt` | Scaffold a new prompt definition |
|
|
265
|
+
| `add-skill` | Author a skill the server publishes in root `skills/` for the agents that use it — when one earns its place, structure, validation, delivery |
|
|
256
266
|
| `add-service` | Scaffold a new service integration |
|
|
257
267
|
| `add-test` | Scaffold test file for a tool, resource, or service |
|
|
258
268
|
| `field-test` | Exercise tools/resources/prompts with real inputs, verify behavior, report issues |
|
|
@@ -300,7 +310,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
300
310
|
| `bun run audit:fix` | `bun audit fix` — upgrade vulnerable packages to the lowest safe version within existing ranges (`--dry-run` previews, `--latest` rewrites ranges). First response when `devcheck` flags a transitive advisory; then `bun update <name>`, then `bun dedupe` |
|
|
301
311
|
| `bun run audit:refresh` | Delete `bun.lock` and reinstall. Last resort after `audit:fix`, `bun update <name>`, and `bun dedupe` — re-resolves every ranged dep (the framework pin included) and rewrites the lockfile as `lockfileVersion: 2` |
|
|
302
312
|
| `bun run lint:mcp` | Run the MCP definition linter standalone (rule catalog: `api-linter` skill) |
|
|
303
|
-
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |
|
|
313
|
+
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity, `.mcpbignore` coverage, plugin manifests, the published `skills/` tree (run by devcheck) |
|
|
304
314
|
| `bun run list-skills` | Print the skill registry |
|
|
305
315
|
| `bun run tree` | Generate directory structure doc |
|
|
306
316
|
| `bun run format` | Auto-fix formatting (safe fixes only) |
|
|
@@ -318,7 +328,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
318
328
|
|
|
319
329
|
## Bundling
|
|
320
330
|
|
|
321
|
-
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips
|
|
331
|
+
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. `mcpb pack` reads `.mcpbignore`, not `.gitignore`, so every root path the bundle must not ship — source, tests, docs, caches, logs, agent docs, plugin manifests, gitignored local files — needs a root-anchored line there (`/docs/`, never `docs/`, which also strips `node_modules/*/docs/`); `lint:packaging` names each missing or unanchored line. Root `skills/` ships on purpose. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips four classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`framework-skills/`, `skills/`, `.claude/`, `.agents/`, `SKILL.md`); platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on; node-gyp build output beside a `binding.gyp` (`config.gypi`, Makefiles, `obj.target/`, `.deps/`, object files and debug symbols), which records the packing machine's paths — compiled `*.node` addons stay; and build-only package files — the framework's `changelog/`, `scripts/`, `templates/`, `CLAUDE.md`, `AGENTS.md`, and config bases (`biome.json`, `vitest.config.base.mjs`, `config/tsconfig.base.json`), and `better-sqlite3`'s `deps/` and `src/` C sources. A server using DataCanvas therefore ships a portable bundle without the DuckDB native — `@duckdb/node-api` is an optional peer loaded lazily, so canvas tools report an actionable install hint and every other tool works normally. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
322
332
|
|
|
323
333
|
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match, that every `user_config` option is wired into `mcp_config.env` as `"X": "${user_config.X}"` (the host substitutes nothing else — `"${X}"` reaches the server as that literal string), and that an optional string option carries `"default": ""`.
|
|
324
334
|
|
|
@@ -385,7 +395,10 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
385
395
|
- [ ] If wrapping external API: tests include at least one sparse payload case with omitted upstream fields
|
|
386
396
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
387
397
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
398
|
+
- [ ] `plugin.json` + `mcp.json` (Agent Plugins 1.0.0 — read by Codex, Cursor, GitHub Copilot, VS Code, Kiro) populated — `plugin.json` `name` = the unscoped repo name (lowercase `a-z`, `0-9`, `-`, `.` only); `version`, `description`, `author`, `homepage`, `repository`, `license`, `keywords` from `package.json`; no other top-level field, `extensions` included. `mcp.json` holds one `"type": "stdio"` entry keyed by the unscoped name, `npx -y <full package name>`, and the same fixed `env` as `.codex-plugin/mcp.json`. Neither file carries a user-supplied variable (no `""`, no `${…}` besides `${PLUGIN_ROOT}`/`${PLUGIN_DATA}`): keys reach Codex through `.codex-plugin/mcp.json` `env_vars`, which works only while `.codex-plugin/plugin.json` keeps `"mcpServers": "./.codex-plugin/mcp.json"`
|
|
388
399
|
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = the unscoped repo name (never the npm scope — `lint:packaging` enforces this); `interface.shortDescription` from `package.json` description
|
|
389
400
|
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable (API key, contact email, instance URL) is listed in `env_vars` so Codex forwards it from the user's environment. Never write `"KEY": ""` into `env` — an empty value replaces the user's exported key and is read as unset
|
|
390
401
|
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `author`, `repository`, `license`, `keywords` from `package.json`; inline `mcpServers` entry keyed by the unscoped repo name. Every user-supplied variable is declared under `userConfig` (`type`, `title`, `description`; `sensitive: true` for keys and tokens; `required: true` or `default: ""`) and referenced from `env` as `"KEY": "${user_config.<option>}"` — mirror the `user_config` block in `manifest.json`. Never write `"KEY": ""` into `env`
|
|
402
|
+
- [ ] Any new root dev path has a root-anchored line in `.mcpbignore`; `bun run bundle` and `lint:packaging` pass
|
|
403
|
+
- [ ] If the server publishes a skill in root `skills/`: `lint:packaging` passes, and `field-test` verified every gate and identifier claim in it against live tool behavior
|
|
391
404
|
- [ ] `npm run devcheck` passes
|
package/Dockerfile
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# output. A stage that compiles a native addon needs the target-arch toolchain
|
|
15
15
|
# and cannot cross-compile this way — drop the flag there.
|
|
16
16
|
# ==============================================================================
|
|
17
|
-
FROM --platform=$BUILDPLATFORM oven/bun:1.4.
|
|
17
|
+
FROM --platform=$BUILDPLATFORM oven/bun:1.4.4 AS build
|
|
18
18
|
|
|
19
19
|
WORKDIR /usr/src/app
|
|
20
20
|
|
|
@@ -29,6 +29,11 @@ RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
|
29
29
|
# Copy the rest of the source code
|
|
30
30
|
COPY . .
|
|
31
31
|
|
|
32
|
+
# The skills a server publishes (`createApp({ skills: 'skills' })`) are read at
|
|
33
|
+
# runtime from the application root. Created when the project has none, so the
|
|
34
|
+
# production stage's copy below holds with or without one.
|
|
35
|
+
RUN mkdir -p skills
|
|
36
|
+
|
|
32
37
|
# Build the application
|
|
33
38
|
RUN bun run build
|
|
34
39
|
|
|
@@ -46,7 +51,7 @@ RUN bun run build
|
|
|
46
51
|
# A clean image rather than `FROM build`: the build stage's node_modules holds
|
|
47
52
|
# devDependencies.
|
|
48
53
|
# ==============================================================================
|
|
49
|
-
FROM --platform=$BUILDPLATFORM oven/bun:1.4.
|
|
54
|
+
FROM --platform=$BUILDPLATFORM oven/bun:1.4.4 AS deps
|
|
50
55
|
|
|
51
56
|
WORKDIR /usr/src/app
|
|
52
57
|
|
|
@@ -114,7 +119,7 @@ RUN rm -rf node_modules/@socketsecurity/bun-security-scanner
|
|
|
114
119
|
# dependencies and build artifacts. Its only Bun invocations are HEALTHCHECK
|
|
115
120
|
# and CMD, which run on the real target at container start.
|
|
116
121
|
# ==============================================================================
|
|
117
|
-
FROM oven/bun:1.4.
|
|
122
|
+
FROM oven/bun:1.4.4-slim AS production
|
|
118
123
|
|
|
119
124
|
WORKDIR /usr/src/app
|
|
120
125
|
|
|
@@ -136,6 +141,7 @@ COPY --from=deps /usr/src/app/node_modules ./node_modules
|
|
|
136
141
|
|
|
137
142
|
# Copy the compiled application code from the build stage
|
|
138
143
|
COPY --from=build /usr/src/app/dist ./dist
|
|
144
|
+
COPY --from=build /usr/src/app/skills ./skills
|
|
139
145
|
|
|
140
146
|
# The 'oven/bun' image already provides a non-root user named 'bun'.
|
|
141
147
|
# We will use this existing user for enhanced security.
|
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
|
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
## Overview
|
|
31
31
|
|
|
32
|
-
Packaged-food data from Open Food Facts, a crowd-sourced database of 3M+ products. Look up items by barcode, search by text, tags, allergens, and nutrient thresholds, compare products side by side, and resolve everyday terms to the canonical tags the filters take.
|
|
32
|
+
Packaged-food data from Open Food Facts, a crowd-sourced database of 3M+ products. Look up items by barcode, search by text, tags, allergens, and nutrient thresholds, compare products side by side, and resolve everyday terms to the canonical tags the filters take.
|
|
33
33
|
|
|
34
34
|
### Tools
|
|
35
35
|
|
|
@@ -40,6 +40,12 @@ Packaged-food data from Open Food Facts, a crowd-sourced database of 3M+ product
|
|
|
40
40
|
| `off_compare_products` | Compare up to 10 products per call by barcode on nutrition (per 100 g, or per 100 ml for liquids), Nutri-Score, NOVA, and Green-Score |
|
|
41
41
|
| `off_browse_taxonomy` | Resolve a human term to the canonical tag ID that `off_search_products` filters on |
|
|
42
42
|
|
|
43
|
+
### Skills
|
|
44
|
+
|
|
45
|
+
| Skill | Description |
|
|
46
|
+
|:------|:------------|
|
|
47
|
+
| `openfoodfacts-guide` | Judgment for calling the tools: allergy checks that never overclaim, choosing among a product's barcodes, where tag IDs come from, grade ranges, free-from searches, and the shared search budget. Served over MCP as `skill://openfoodfacts-guide/SKILL.md` and shipped in the plugin, npm package, and `.mcpb` bundle. |
|
|
48
|
+
|
|
43
49
|
## Capability reference
|
|
44
50
|
|
|
45
51
|
### `off_get_product` <sub>tool</sub>
|
|
@@ -52,16 +58,15 @@ Packaged-food data from Open Food Facts, a crowd-sourced database of 3M+ product
|
|
|
52
58
|
|
|
53
59
|
### `off_search_products` <sub>tool</sub>
|
|
54
60
|
|
|
55
|
-
- `query` (up to 24 words
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
- `query` or `nutrient_filters` routes the search to a text index that lags the live database (flagged in `text_index_snapshot`), serves only the first 10,000 results, and rejects `additives_tag` as `additives_filter_needs_tag_search`; tag-only searches read the live database through page 10, and a page past either bound fails as `page_out_of_range`
|
|
61
|
+
- `query` (up to 24 words, all of which must match the name, generic name, categories, labels, or brand; punctuation separates words, so `milk-chocolate` requires both) plus the tag filters `categories_tag`, `brands_tag`, `labels_tag` (up to 10), `allergens_tag`, `traces_tag`, `ingredients_analysis_tag`, `additives_tag`, `nutrition_grade`, `nova_group`, `countries_tag`, the `exclude_allergens` / `exclude_traces` lists (up to 14 each), and up to 18 `nutrient_filters` (per 100 g, or per 100 ml for liquids), all combined as AND; optional `sort_by`
|
|
62
|
+
- `page_size` defaults to 20 and is served at up to 50 per call; a larger value (up to 10,000) is served at 50 and flagged in `page_size_capped`, and `page` counts pages of 50. Rows carry `barcode`, `product_name`, `brands`, `nutriscore_grade`, `nova_group`, `ecoscore_grade`, and `categories_tags`, plus `total`, `total_is_lower_bound`, `last_page`, `omitted`, and `truncated` (more matches beyond this page). Exclusions add `exclusion_coverage`, since products with no allergen data entered pass them; `nutrient_filters` add `indexed_nutriments` (the index values the filters checked, which can differ from `off_get_product`)
|
|
63
|
+
- `query` or `nutrient_filters` searches a text index that lags the live database (flagged in `text_index_snapshot`), reaches only the first 10,000 results, and rejects `additives_tag` as `additives_filter_needs_tag_search`; tag-only searches read the live database through page 10. A page past either limit fails as `page_out_of_range`
|
|
59
64
|
|
|
60
65
|
---
|
|
61
66
|
|
|
62
67
|
### `off_compare_products` <sub>tool</sub>
|
|
63
68
|
|
|
64
|
-
- 2–100 `barcodes`,
|
|
69
|
+
- 2–100 `barcodes`, one row each in input order; repeated barcodes are compared once, and those past the 10th distinct one are listed in `unprocessed` without being fetched
|
|
65
70
|
- Rows carry `found`, `nutriscore_grade`, `nova_group`, `ecoscore_grade`, energy, fat, saturated fat, sugars, salt, protein, and fiber (per 100 g, or per 100 ml for liquids), and `completeness`; missing values stay absent, never imputed
|
|
66
71
|
- `not_found` lists barcodes with no contributor record and `failed` lists fetches that failed, each with a `reason`; a failed barcode gets no row and never blocks the rest
|
|
67
72
|
|
|
@@ -69,9 +74,9 @@ Packaged-food data from Open Food Facts, a crowd-sourced database of 3M+ product
|
|
|
69
74
|
|
|
70
75
|
### `off_browse_taxonomy` <sub>tool</sub>
|
|
71
76
|
|
|
72
|
-
- `facet` is one of `categories`, `labels`, `allergens`, `additives`, `countries`, `nova_groups`, `nutrition_grades`; `search` matches a substring of the tag ID, name, or a synonym ("shellfish" → `en:crustaceans`); `limit` (default 20) up to 100 per call
|
|
77
|
+
- `facet` is one of `categories`, `labels`, `allergens`, `additives`, `countries`, `nova_groups`, `nutrition_grades`; `search` matches a substring of the tag ID, name, or a synonym ("shellfish" → `en:crustaceans`); `limit` (default 20) returns up to 100 per call (a value up to 200 still returns 100); a cut result says how many matched; no paging
|
|
73
78
|
- Returns `tags[]` of `id` and `name`, where `id` goes to `off_search_products` unchanged; `nova_groups` and `nutrition_grades` come back complete with `total_in_facet`
|
|
74
|
-
- The five open facets resolve against the live Open Food Facts taxonomy and fall back to a small offline sample, with a `notice`, when it is
|
|
79
|
+
- The five open facets resolve against the live Open Food Facts taxonomy and fall back to a small offline sample, with a `notice`, when it is unavailable; omitting `search` returns only that sample
|
|
75
80
|
|
|
76
81
|
## Features
|
|
77
82
|
|
|
@@ -80,129 +85,46 @@ Built on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core): s
|
|
|
80
85
|
Open Food Facts-specific:
|
|
81
86
|
|
|
82
87
|
- No API key; the identifying `User-Agent` Open Food Facts' terms require is built in
|
|
83
|
-
- Per-endpoint request budgets (product 15/min, search 10/min, taxonomy 10/min)
|
|
84
|
-
- Nutriments normalized from hyphenated keys (`energy-kcal_100g` → `energy_kcal_100g`), with
|
|
85
|
-
- Tag filters take canonical IDs (`en:organic`, `en:no-gluten`); on text searches a case variant, synonym, or brand name is canonicalized
|
|
86
|
-
- Every field is contributor-entered, so a missing one means not yet recorded
|
|
88
|
+
- Per-endpoint request budgets (product 15/min, search 10/min, taxonomy 10/min); transient failures retry up to 4 attempts
|
|
89
|
+
- Nutriments normalized from hyphenated keys (`energy-kcal_100g` → `energy_kcal_100g`), with `additional_100g` / `additional_serving` maps that label each nutrient with its unit
|
|
90
|
+
- Tag filters take canonical IDs (`en:organic`, `en:no-gluten`); on text searches a case variant, synonym, or brand name is canonicalized first (`US` → `en:united-states`)
|
|
91
|
+
- Every field is contributor-entered, so a missing one means not yet recorded; Nutri-Score, NOVA, and Green-Score are Open Food Facts' own computed grades, returned as-is, and carry regional formula caveats
|
|
87
92
|
|
|
88
93
|
Agent-friendly output:
|
|
89
94
|
|
|
90
95
|
- Per-serving nutrition carries its denominator: `serving_size`, `serving_quantity`, `serving_quantity_unit`, and a note when none is recorded
|
|
91
96
|
- Graceful partial failure: `off_compare_products` returns resolved rows alongside `not_found` and `failed`
|
|
92
|
-
- Explicit count bounds: `total_is_lower_bound`, `last_page`, and `omitted` on searches
|
|
93
|
-
- Typed failures: each carries a declared `reason` (`upstream_error`, `upstream_timeout`, `upstream_rejected`, `rate_limited`, plus per-tool input reasons) and a recovery hint
|
|
97
|
+
- Explicit count bounds: `total_is_lower_bound`, `last_page`, and `omitted` on searches
|
|
98
|
+
- Typed failures: each carries a declared `reason` (`upstream_error`, `upstream_timeout`, `upstream_rejected`, `rate_limited`, plus per-tool input reasons) and a recovery hint; an incomplete upstream response is a retryable `upstream_error`, never an empty result or a not-found
|
|
94
99
|
|
|
95
100
|
## Getting started
|
|
96
101
|
|
|
97
|
-
|
|
102
|
+
Connect to the hosted instance, no install:
|
|
98
103
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```json
|
|
102
|
-
{
|
|
103
|
-
"mcpServers": {
|
|
104
|
-
"openfoodfacts-mcp-server": {
|
|
105
|
-
"type": "streamable-http",
|
|
106
|
-
"url": "https://openfoodfacts.caseyjhand.com/mcp"
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
104
|
+
```sh
|
|
105
|
+
claude mcp add --transport http openfoodfacts-mcp-server https://openfoodfacts.caseyjhand.com/mcp
|
|
110
106
|
```
|
|
111
107
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
No API key is required. Add the following to your MCP client configuration file.
|
|
108
|
+
Or run it locally:
|
|
115
109
|
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
"mcpServers": {
|
|
119
|
-
"openfoodfacts-mcp-server": {
|
|
120
|
-
"type": "stdio",
|
|
121
|
-
"command": "bunx",
|
|
122
|
-
"args": ["@cyanheads/openfoodfacts-mcp-server@latest"],
|
|
123
|
-
"env": {
|
|
124
|
-
"MCP_TRANSPORT_TYPE": "stdio",
|
|
125
|
-
"MCP_LOG_LEVEL": "info"
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
110
|
+
```sh
|
|
111
|
+
claude mcp add openfoodfacts-mcp-server -- npx -y @cyanheads/openfoodfacts-mcp-server
|
|
130
112
|
```
|
|
131
113
|
|
|
132
|
-
|
|
114
|
+
For other clients, add this to the MCP config file:
|
|
133
115
|
|
|
134
116
|
```json
|
|
135
117
|
{
|
|
136
118
|
"mcpServers": {
|
|
137
119
|
"openfoodfacts-mcp-server": {
|
|
138
|
-
"type": "stdio",
|
|
139
120
|
"command": "npx",
|
|
140
|
-
"args": ["-y", "@cyanheads/openfoodfacts-mcp-server
|
|
141
|
-
"env": {
|
|
142
|
-
"MCP_TRANSPORT_TYPE": "stdio",
|
|
143
|
-
"MCP_LOG_LEVEL": "info"
|
|
144
|
-
}
|
|
121
|
+
"args": ["-y", "@cyanheads/openfoodfacts-mcp-server"]
|
|
145
122
|
}
|
|
146
123
|
}
|
|
147
124
|
}
|
|
148
125
|
```
|
|
149
126
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
```json
|
|
153
|
-
{
|
|
154
|
-
"mcpServers": {
|
|
155
|
-
"openfoodfacts-mcp-server": {
|
|
156
|
-
"type": "stdio",
|
|
157
|
-
"command": "docker",
|
|
158
|
-
"args": [
|
|
159
|
-
"run", "-i", "--rm",
|
|
160
|
-
"-e", "MCP_TRANSPORT_TYPE=stdio",
|
|
161
|
-
"ghcr.io/cyanheads/openfoodfacts-mcp-server:latest"
|
|
162
|
-
]
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
For Streamable HTTP, set the transport and start the server:
|
|
169
|
-
|
|
170
|
-
```sh
|
|
171
|
-
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
|
|
172
|
-
# Server listens at http://localhost:3010/mcp
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Prerequisites
|
|
176
|
-
|
|
177
|
-
- [Bun v1.4.0](https://bun.sh/) or higher (or Node.js v24+).
|
|
178
|
-
- No API key or account. Open Food Facts asks clients to identify themselves, and the server's `User-Agent` does so without configuration.
|
|
179
|
-
|
|
180
|
-
### Installation
|
|
181
|
-
|
|
182
|
-
1. **Clone the repository:**
|
|
183
|
-
|
|
184
|
-
```sh
|
|
185
|
-
git clone https://github.com/cyanheads/openfoodfacts-mcp-server.git
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
2. **Navigate into the directory:**
|
|
189
|
-
|
|
190
|
-
```sh
|
|
191
|
-
cd openfoodfacts-mcp-server
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
3. **Install dependencies:**
|
|
195
|
-
|
|
196
|
-
```sh
|
|
197
|
-
bun install
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
4. **Configure environment:**
|
|
201
|
-
|
|
202
|
-
```sh
|
|
203
|
-
cp .env.example .env
|
|
204
|
-
# edit .env if you need to override rate limits or the base URL
|
|
205
|
-
```
|
|
127
|
+
No API key or account is needed: the server identifies itself to Open Food Facts with its own `User-Agent`. For Docker or a source build, see [Running the server](#running-the-server).
|
|
206
128
|
|
|
207
129
|
## Configuration
|
|
208
130
|
|
|
@@ -225,6 +147,16 @@ See [`.env.example`](./.env.example) for the full list of optional overrides.
|
|
|
225
147
|
|
|
226
148
|
### Local development
|
|
227
149
|
|
|
150
|
+
Requires [Bun v1.4.0](https://bun.sh/) or higher (or Node.js v24+).
|
|
151
|
+
|
|
152
|
+
- **Clone and install:**
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
git clone https://github.com/cyanheads/openfoodfacts-mcp-server.git
|
|
156
|
+
cd openfoodfacts-mcp-server && bun install
|
|
157
|
+
cp .env.example .env # optional: override rate limits or the base URL
|
|
158
|
+
```
|
|
159
|
+
|
|
228
160
|
- **Build and run:**
|
|
229
161
|
|
|
230
162
|
```sh
|
|
@@ -248,22 +180,22 @@ See [`.env.example`](./.env.example) for the full list of optional overrides.
|
|
|
248
180
|
### Docker
|
|
249
181
|
|
|
250
182
|
```sh
|
|
251
|
-
docker
|
|
252
|
-
docker run --rm -p 3010:3010 openfoodfacts-mcp-server
|
|
183
|
+
docker run --rm -p 3010:3010 ghcr.io/cyanheads/openfoodfacts-mcp-server:latest
|
|
253
184
|
```
|
|
254
185
|
|
|
255
|
-
The
|
|
186
|
+
The image defaults to HTTP transport, stateless session mode, and logs to `/var/log/openfoodfacts-mcp-server`. To run it over stdio from an MCP client, use `"command": "docker"` with `"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/openfoodfacts-mcp-server:latest"]`. To build locally, `docker build -t openfoodfacts-mcp-server .`; OpenTelemetry peer dependencies are installed by default — build with `--build-arg OTEL_ENABLED=false` to omit them.
|
|
256
187
|
|
|
257
188
|
## Project structure
|
|
258
189
|
|
|
259
190
|
| Directory | Purpose |
|
|
260
191
|
|:----------|:--------|
|
|
261
|
-
| `src/index.ts` | `createApp()` entry point — registers tools and inits services. |
|
|
192
|
+
| `src/index.ts` | `createApp()` entry point — registers tools and the published skills, and inits services. |
|
|
262
193
|
| `src/config` | Server-specific environment variable parsing and validation with Zod. |
|
|
263
194
|
| `src/mcp-server/tools` | Tool definitions (`*.tool.ts`). |
|
|
264
195
|
| `src/services/openfoodfacts` | Open Food Facts API client — HTTP, rate limiting, retry, field normalization. |
|
|
265
196
|
| `src/services/taxonomy` | Tag vocabulary — live resolution, offline sample, and tag-value canonicalization. |
|
|
266
197
|
| `src/utils` | Markdown escaping for contributor-entered values in text output. |
|
|
198
|
+
| `skills/` | Published Agent Skills for the agents that call the tools. |
|
|
267
199
|
| `tests/` | Unit and integration tests mirroring `src/`. |
|
|
268
200
|
|
|
269
201
|
## Development guide
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Product text and images render through the shared Markdown helpers."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.3.9 — 2026-10-25
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- **Product text** uses the framework's Markdown escaper across lookup, search, comparison tables, and taxonomy output, preserving literal entities, tildes, pipes, and ordinary underscores.
|
|
12
|
+
- **Product images** render as Markdown images for absolute HTTP(S) URLs; unsupported or malformed destinations remain literal text.
|
|
13
|
+
- **Maintenance** syncs framework guidance and audit classification, trims development files from MCPB bundles, documents request-state sealing, and gives client-specific hosted connection examples.
|
|
14
|
+
- **Runtime tests** load the config dependency graph during collection and shorten CPU sampling batches while retaining five samples, the input-size span, and growth thresholds.
|
|
15
|
+
|
|
16
|
+
## Dependencies
|
|
17
|
+
|
|
18
|
+
- **`@cyanheads/mcp-ts-core`** ^0.13.15 → ^0.13.16 (Markdown-safe error, recovery, and enrichment text).
|
|
19
|
+
- **`zod`** ^4.6.5 → ^4.6.7.
|
|
20
|
+
- **`@biomejs/biome`** ^2.5.15 → ^2.6.2.
|
|
21
|
+
- **`ignore`** ^7.0.12 → ^7.0.13.
|
|
22
|
+
- **`tsc-alias`** ^1.9.7 → ^1.9.8.
|
|
23
|
+
- **`vitest`** ^5.0.3 → ^5.0.5.
|
|
24
|
+
- **Bun** 1.4.3 → 1.4.4 (`packageManager`, Docker images, and README badge).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Publishes the openfoodfacts-guide Agent Skill over MCP, renders search notices as block quotes with escaped caller text, and moves to mcp-ts-core 0.13.18 (MCP SDK 2.4; a 0.13.16 HTTP per-request memory leak fixed)."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.0 — 2026-10-28
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **`skill://openfoodfacts-guide/SKILL.md`** served over MCP through `createApp({ skills: 'skills' })`: allergy checks that never overclaim, choosing among a product's barcodes, tag-ID sources, grade ranges, free-from searches, and the shared search budget. `resources/list` gains the skill and the `skill://{+path}` template, and `initialize` advertises the `io.modelcontextprotocol/skills` extension; `tools/list` is unchanged. The skill also ships in the npm package, Docker image, plugin installs, and `.mcpb` bundle.
|
|
12
|
+
- **Root `plugin.json` and `mcp.json`**: the Agent Plugins 1.0.0 pair, alongside the existing `.claude-plugin/` and `.codex-plugin/` manifests.
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- **README** Getting started is shorter (hosted `claude mcp add`, local `npx`, one generic config), and a Skills section lists `openfoodfacts-guide`.
|
|
17
|
+
- **Maintenance** re-syncs framework skills (adds `add-skill`) and scripts, anchors every `.mcpbignore` path to the repo root, copies `skills/` in the Dockerfile, and merges the issue-template environment fields into one table.
|
|
18
|
+
|
|
19
|
+
## Fixed
|
|
20
|
+
|
|
21
|
+
- **`off_search_products` notices** ([#65](https://github.com/cyanheads/openfoodfacts-mcp-server/issues/65)): under mcp-ts-core 0.13.18, which renders a generic enrichment string as a code span, the zero-result, past-the-end, and all-omitted notices rendered in `content[]` as code spans. They now go through `ctx.enrich.notice()` and render as block quotes, like the taxonomy tool's.
|
|
22
|
+
- **Notices are Markdown-escaped where they render**: caller and upstream values echoed in `off_search_products` and `off_browse_taxonomy` notices (query, tag filters, taxonomy term, upstream failure cause) are escaped in the `content[]` block quote, so they can no longer reshape it; `structuredContent.notice` carries them as sent.
|
|
23
|
+
|
|
24
|
+
## Dependencies
|
|
25
|
+
|
|
26
|
+
- **`@cyanheads/mcp-ts-core`** ^0.13.16 → ^0.13.18: MCP SDK ^2.3.1 → ^2.4.0 and the HTTP transport no longer retaining ~71 KiB per request, a leak in 0.3.9's framework 0.13.16 (both 0.13.17); published skills served over MCP and `.mcpb` bundles that drop dev paths and build-only files (0.13.18).
|
|
27
|
+
- **`@biomejs/biome`** ^2.6.2 → ^2.6.3.
|
|
28
|
+
- **`ignore`** ^7.0.13 → ^7.0.14.
|
|
29
|
+
- **`tsc-alias`** ^1.9.8 → ^1.9.9.
|
|
30
|
+
- **`bunfig.toml`** `minimumReleaseAge` 3 days → 1 day.
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ await createApp({
|
|
|
11
11
|
name: 'openfoodfacts-mcp-server',
|
|
12
12
|
title: 'openfoodfacts-mcp-server',
|
|
13
13
|
tools: allToolDefinitions,
|
|
14
|
+
skills: 'skills',
|
|
14
15
|
instructions: 'Query Open Food Facts, a free crowd-sourced database of 3M+ packaged foods: off_get_product looks up one product by barcode (4–40 digits), off_search_products finds products by text or tag filters, off_compare_products puts several side by side on nutrition, and off_browse_taxonomy resolves a human term to the canonical tag ID the other tools filter on — so start there when you have a category or label rather than a barcode. Every field is contributor-entered, so a missing one means "not yet recorded" rather than absent, and the computed Nutri-Score, NOVA, and Green-Score grades carry regional caveats. No API key is required; the data is ODbL 1.0, so cite Open Food Facts wherever you pass it on.',
|
|
15
16
|
sessionMode: 'stateless',
|
|
16
17
|
setup() {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAE9E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,0BAA0B;IAChC,KAAK,EAAE,0BAA0B;IACjC,KAAK,EAAE,kBAAkB;IACzB,YAAY,EACV,ksBAAksB;IACpsB,WAAW,EAAE,WAAW;IACxB,KAAK;QACH,wBAAwB,EAAE,CAAC;QAC3B,mBAAmB,EAAE,CAAC;IACxB,CAAC;CACF,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAE9E,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,0BAA0B;IAChC,KAAK,EAAE,0BAA0B;IACjC,KAAK,EAAE,kBAAkB;IACzB,MAAM,EAAE,QAAQ;IAChB,YAAY,EACV,ksBAAksB;IACpsB,WAAW,EAAE,WAAW;IACxB,KAAK;QACH,wBAAwB,EAAE,CAAC;QAC3B,mBAAmB,EAAE,CAAC;IACxB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -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;AAWjD,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;AAWjD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;EAuKhC,CAAC"}
|
|
@@ -72,6 +72,11 @@ export const offBrowseTaxonomyTool = tool('off_browse_taxonomy', {
|
|
|
72
72
|
.optional()
|
|
73
73
|
.describe(`The limit that was applied — at most ${TAXONOMY_LIMIT_CAP}.`),
|
|
74
74
|
},
|
|
75
|
+
// The notice echoes the search term and an upstream failure cause, so it is escaped here at render
|
|
76
|
+
// time: structuredContent keeps those values as sent.
|
|
77
|
+
enrichmentTrailer: {
|
|
78
|
+
notice: { render: (v) => `> ${mdInline(String(v))}` },
|
|
79
|
+
},
|
|
75
80
|
async handler(input, ctx) {
|
|
76
81
|
const svc = getTaxonomyService();
|
|
77
82
|
const limit = Math.min(input.limit, TAXONOMY_LIMIT_CAP);
|
|
@@ -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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare-products.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/compare-products.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAY,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"compare-products.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/compare-products.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAY,MAAM,+BAA+B,CAAC;AAiL3E,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA+TjC,CAAC"}
|