Upload ALL photos — See upload_image tool description for imagefield guidance. Use the most appropriate imagefield (front, nutrition, ingredients, packaging), and other for additional photos that don't fit a specific panel or where a good display image already exists.
Strip EXIF metadata before uploading — especially GPS location. Phone photos embed the GPS coordinates where they were taken (plus device make/model). Uploading these to a public database leaks where the photographer lives/shops. Always strip metadata before upload. Note that sips -r (below) preserves EXIF, so rotating is not enough on its own. If ImageMagick is available, magick in.jpg -rotate <deg> -strip -resize 1400x -quality 82 out.jpg rotates, strips all metadata, and downscales in one pass. To verify a file is clean, magick identify -verbose out.jpg | grep -iE 'gps|exif:' should return nothing. (Beware: on macOS, mdls may report stale cached GPS from Spotlight even after stripping — trust a raw check like identify/exiftool over mdls.)
Rotate images so text reads correctly before uploading. If a photo is rotated (upside down, sideways, etc.), rotate it so text is upright. The magick ... -rotate above handles this; alternatively on macOS sips -r <degrees> "/path/to/photo.jpg" rotates in place clockwise (but does NOT strip EXIF — see above). Common rotations: 180° for upside-down, 90° or 270° for sideways. This makes OCR and human review much easier on the OFF website.
Image upload requires base64 data, not file paths. Encode images via shell-exec-mcp. The recommended pattern using tool-sandbox-mcp:
First, discover the exact tool names (they depend on how MCPs are wired):
const tools = await tool('list_tools', {});
return tools.filter(t => t.name.includes('shell') || t.name.includes('openfoodfacts'));
Then encode and upload:
const shell = await tool('tunnel__shell-exec__execute', {
command: 'base64 -i "/path/to/photo.jpg"',
timeout: 10000
});
const b64 = shell.stdout.replace(/\n/g, '');
const result = await tool('openfoodfacts__upload_image', {
barcode: '1234567890123',
imagefield: 'front',
image_data: b64
});
If one photo covers multiple panels (e.g. nutrition AND ingredients on the same side), upload it once then use select_image to assign it to the additional imagefield.
upload_image only stores the raw image; select_image is what assigns it as the displayed front/nutrition/ingredients panel. For a sparse product with no display images, select_image the front too, or it won't show one. Conversely, for an established product that already has good community-selected display images, don't reassign its panels — just upload your photos as additional raw images (upload_image alone) and leave the existing selections alone.
upload_image and select_image also take an lc (language) parameter; pass the product's language (e.g. lc: "de" for German packaging) to keep it consistent with the language used in add_or_edit_product.