Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| OFF_COUNTRY | No | Country subdomain (default: world) | world |
| OFF_USER_ID | No | Open Food Facts username (for write operations) | |
| OFF_PASSWORD | No | Open Food Facts password (for write operations) | |
| OFF_USER_AGENT | Yes | User-Agent string, e.g. "AppName/1.0 (email@example.com)" |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_product | Get product information from Open Food Facts by barcode. Reads the primary database directly (no sync lag), so this is always current even when search_products returns stale results. Prefer this over search whenever you have a barcode. If this returns "product not found", the product genuinely isn't in the database — you can add it with add_or_edit_product. |
| search_products_standard | Search Open Food Facts with structured filters. Best for simple keyword queries and brand/category filtering. Returns exact result counts and well-populated products. If you have a barcode, use get_product instead. How search works: strict AND against a keyword index built from product_name, generic_name, brands, categories, origins, labels. One unmatched query word → zero results. Tips:
If you get zero results, try dropping words or using search_products_lucene which has more flexible text matching. |
| search_products_lucene | Search Open Food Facts using the Search-a-licious Elasticsearch backend. Powered by Lucene query syntax with full boolean logic and negation support. Use this instead of search_products_standard when you need:
Trade-offs vs search_products_standard:
Response format matches search_products_standard: { count, page, page_size, page_count, products: [...] } |
| autocomplete | Get autocomplete suggestions for Open Food Facts taxonomy entries (brands, categories, labels, etc.). |
| add_or_edit_product | Add a new product or edit an existing one on Open Food Facts. Requires OFF_USER_ID and OFF_PASSWORD. The more fields you fill, the more useful the entry. At minimum provide product_name, brands, and categories — these feed the search index, and a sparse entry won't be findable. If you have a photo of the pack, transcribe everything you can read: ingredients, nutrition, origins, traceability stamps, recycling icons, certifications. Fields that drive derived data:
Pitfalls learned the hard way:
Recommended workflow for adding a product from photos:
For products with only prepared nutrition (jelly mixes, powdered drinks, etc.), use nutrition_prepared instead of nutrition. For values printed as "< 0.5g" on the packet, pass the string "< 0.5" — the less-than modifier will be preserved. Nutrition fields mirror the label columns: nutrition (per 100g as sold), nutrition_per_serving (per serving as sold), nutrition_prepared (per 100g prepared), nutrition_prepared_per_serving (per serving prepared). OFF auto-derives per-serving from per-100g + serving_size, so nutrition_per_serving is only needed when the label shows explicit per-serving values you want to preserve. |
| upload_image | Upload a product image to Open Food Facts. Requires OFF_USER_ID and OFF_PASSWORD. Prefer more photos over fewer. Panels with text (ingredients, nutrition, certifications, recycling instructions) are highest value as OFF can OCR them. Plain sides with just a colour or logo are lowest value but still worth uploading if you have them. Use the most appropriate imagefield (front, ingredients, nutrition, packaging). Use "other" for additional photos — this uploads without selecting the image as a display image, which is useful when a good display image already exists or for supplementary angles. The OFF server auto-selects images for front/nutrition/ingredients/packaging on upload unless one is already selected. If you get "status not ok" but a positive imgid, the image uploaded successfully but was not selected (e.g. a display image already exists). For images on disk, base64-encode them first (e.g. via shell: |
| select_image | Select, crop, and rotate a previously uploaded product image on Open Food Facts. Requires OFF_USER_ID and OFF_PASSWORD. |
| call_api | Make a direct call to any Open Food Facts API endpoint. Use get_api_docs to see available endpoints. Auth credentials are included automatically for write operations if configured. Two body modes for writes:
Example v3 packagings write: method: PATCH endpoint: /api/v3/product/0123456789012 json_body: {"fields":"packagings","product":{"packagings":[{"number_of_units":1,"shape":{"id":"en:bag"},"material":{"id":"en:plastic"},"recycling":{"id":"en:recycle"}}]}} WARNING: Do NOT use old-style prepared nutrition params like nutriment_fat_prepared — they have a known server bug that stores data incorrectly. Use new-style params instead: nutrition_input_sets_prepared_100g_nutrients_fat_value_string=0.5 |
| get_api_docs | Get Open Food Facts API documentation. Useful for understanding available endpoints before using call_api. |
| get_skill | Get the OFF upload skill document. This describes the recommended process for bulk uploading food packaging photos to Open Food Facts. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |