CCM
/MCP
SkillsMCPMarketplacesDigestToolsAdvertise

This week in Claude

Every Monday: Claude Code, Agent SDK, MCP, and the Anthropic platform moves worth your time.

Skills by Category
Frontend DevelopmentBackend & APIsTesting & QASecurityDevOps & CI/CDGit & Pull RequestsDocumentationCode Review & QualityAI & Agent BuildingSkill Development
MCP Servers by Category
Sales & MarketingWeb & Browser AutomationDatabasesAI & LLM ToolsCloud & InfrastructureCommunication & MessagingDeveloper ToolsDesign & CreativeDocuments & KnowledgeSearch & Web Crawling
Marketplaces by Category
AI Agents & OrchestrationLLM IntegrationDevelopment ToolsFrontend & UIBackend & APIsDatabasesTesting & Code QualityDevOps & CloudSecurity & ComplianceGit & Version Control

Claude Code Marketplaces

Discover Claude Code plugins, extensions, and tools. Automatically updated directory of Anthropic Claude AI marketplaces with development tools, productivity plugins, and integrations.

Resources

  • Browse Skills
  • Browse MCP Servers
  • Browse Marketplaces
  • Skill index
  • MCP index
  • Marketplace index
  • Plugins Reference

Community

  • About
  • Tools
  • Feedback
  • Privacy Policy
  • Advertise

Built for the Claude Code community with Claude Code by mertbuilds.com

Independent project, not affiliated with Anthropic
cyanheads avatar

openfoodfacts-mcp-server

cyanheads/openfoodfacts-mcp-server
HTTP

Barcode lookup, nutrition search, and product comparison for 3M+ crowd-sourced food products.

CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
ego lite browserego lite browser
ego lite browser
Fastest browser for AI agents to run web automation tasks, always free.
Download Free life-time →
belt - the only tool your agent needs
belt - the only tool your agent needs
belt cli automatically finds the best tools and skills for your agent. image, video, music, tts...
one prompt install →
Open Steps
Open Steps
Free an open-source skills that make AI coding agents easier to understand, verify, and control.
Download for free →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Agent, connect blockchain
Agent, connect blockchain
Connect your Claude agent to live crypto prices and trading routes via 1inch
Get the MCP →
Granola, the best AI meeting recorder
Granola, the best AI meeting recorder
Notes, actions and memory. Without a meeting bot. First month 100% off.
Download for free →
CodeHealth MCP ServerCodeHealth MCP Server
CodeHealth MCP Server
Protect your code quality, stop the AI slop.
Try For Free →
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
ego lite browserego lite browser
ego lite browser
Fastest browser for AI agents to run web automation tasks, always free.
Download Free life-time →
belt - the only tool your agent needs
belt - the only tool your agent needs
belt cli automatically finds the best tools and skills for your agent. image, video, music, tts...
one prompt install →
Open Steps
Open Steps
Free an open-source skills that make AI coding agents easier to understand, verify, and control.
Download for free →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Agent, connect blockchain
Agent, connect blockchain
Connect your Claude agent to live crypto prices and trading routes via 1inch
Get the MCP →
Granola, the best AI meeting recorder
Granola, the best AI meeting recorder
Notes, actions and memory. Without a meeting bot. First month 100% off.
Download for free →
CodeHealth MCP ServerCodeHealth MCP Server
CodeHealth MCP Server
Protect your code quality, stop the AI slop.
Try For Free →

@cyanheads/openfoodfacts-mcp-server

Look up food products by barcode, search by keyword, tag, allergen, or nutrition filter, compare products side-by-side, and browse the canonical tag vocabulary via MCP. STDIO or Streamable HTTP.

4 Tools

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

Public Hosted Server: https://openfoodfacts.caseyjhand.com/mcp


Overview

Food product data from Open Food Facts, a crowd-sourced database of 3M+ packaged food products. Look up items by barcode, search by text and nutrition/allergen/label tags, compare products side-by-side, and resolve everyday terms to the canonical tag vocabulary from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.

Tools

ToolDescription
off_get_productFetch a packaged food product by barcode. Returns name, brand, quantity, ingredients, declared and trace allergens, additives, the vegan/vegetarian/palm-oil analysis, Nutri-Score, NOVA group, Green-Score, nutrition per 100g/serving, categories, labels, countries of sale, and data completeness.
off_search_productsSearch by text query, structured tag filters (category, brand, labels, allergen, trace, vegan/vegetarian/palm-oil verdict, additive, Nutri-Score grade, NOVA group, country), allergen and trace exclusions, and numeric per-100 g nutrient thresholds. Returns summary rows with barcodes for follow-up lookups.
off_compare_productsSide-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.
off_browse_taxonomyResolve 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.

Capability reference

off_get_product tool

  • Accepts every barcode Open Food Facts serves: digits only, 4–40 digits after any leading zeros — EAN-13, EAN-8, UPC-A, UPC-E, and the shorter and longer codes the database also holds
  • Returns ingredients (raw text and parsed list with percent estimates, vegan/vegetarian flags, and each entry's sub-ingredients nested under it — wheat flour under "cereal", palm oil under "vegetable oils" — up to three levels deep), all 14 major allergens as tag IDs, E-number additives, Nutri-Score (a–e, unknown, not-applicable), NOVA 1–4, Green-Score (a-plus, a–f, unknown, not-applicable), every nutrient Open Food Facts holds per 100g and per serving, the serving size those per-serving figures are measured against, categories/labels/packaging/origins/countries of sale as canonical tag IDs, front image URL, and data completeness score (0–1)
  • traces_tags carries the "may contain" allergen warning separately from the declared allergens_tags; ["en:none"] is the label stating no traces, while an empty array means not yet entered — never trace-free
  • ingredients_analysis_tags carries the vegan, vegetarian, and palm-oil verdicts Open Food Facts computes itself, including its "maybe" states, rather than leaving the per-ingredient flags to be aggregated by the caller
  • Optional fields parameter restricts the response to a subset (e.g., scores only, or nutrition only); a field that cannot be read on its own arrives with what it depends on — nutriments brings the serving size its per-serving figures are measured against — and requested_fields echoes the full set that was fetched
  • Open Food Facts is crowd-sourced — a missing field means "not yet entered by contributors," not that the attribute is absent from the actual product
  • A barcode no contributor has recorded raises the not_found error carrying a recovery hint — it is never returned as an empty result

off_search_products tool

  • Full-text query plus structured tag filters — categories_tag, brands_tag, labels_tag (one label, or an array that must all apply), allergens_tag, traces_tag (the "may contain" warning), ingredients_analysis_tag (one of the 12 vegan, vegetarian, and palm-oil verdicts), additives_tag, nutrition_grade (a–e), nova_group (1–4), countries_tag — and numeric nutrient_filters, all combining as AND; tag values are canonical IDs, resolved via off_browse_taxonomy (brands_tag matches an exact slug, not free text)
  • exclude_allergens and exclude_traces drop products that declare an allergen or warn of a trace, on both paths. Each value must be an allergen tag the Open Food Facts vocabulary confirms — an unrecognized one would exclude nothing, so it is rejected before any search is sent. A product with no allergen or trace data entered passes an exclusion, and every response carrying one says so and points to off_get_product for a per-product check
  • Every word of query must match a product's name, generic name, categories, labels, or brand (ingredients and quantity are not searched), in any of the 31 languages the text index analyzes, so a product named only in French or Russian is found by that name; stop words of English, French, Spanish, German, and Italian ("with", "the", "de", "mit") are not required, and query takes at most 24 words
  • On a search carrying query or nutrient_filters, each tag value is resolved to its canonical form before it is sent — a brand name is slugged (Nutella → nutella), and a case variant, synonym, or singular resolves where the Open Food Facts vocabulary confirms it (US → en:united-states, en:peanut → en:peanuts); anything unconfirmed is matched exactly, and an empty result names which values were
  • Numeric nutrient_filters express per-100 g thresholds over energy-kcal, fat, saturated-fat, carbohydrates, sugars, fiber, proteins, salt, and sodium — each a { nutrient, operator, value } triple with lt / lte / gt / gte; pair two entries on one nutrient for a range. They AND with every other filter and are served by the text backend, so supplying one routes the search there even without query
  • additives_tag filters only on searches carrying neither query nor nutrient_filters — both route to a backend with no additives field, so the pairing is rejected up front rather than silently returning zero hits
  • Pagination via page (1-based) and page_size (1–50, default 20); tag-only searches are served through page 10, and text searches serve only the first 10,000 results (page * page_size beyond that); a request past either bound is rejected before it is sent, and last_page reports the deepest page that can be requested
  • total is exact on tag-only searches; text searches stop counting at 10,000 and set total_is_lower_bound: true with the count rendered as 10000+
  • The two paths read different indexes: a search carrying query is answered by a text index that lags the live database, and says so on both response surfaces; a tag-only search reads the live database. A recently contributed product can be missing from the first and present in the second
  • sort_by (last_modified_t, unique_scans_n, created_t, popularity_key) orders newest or highest first on both paths; omitting it leaves text searches relevance-ranked
  • A page past the end of a result set is reported as an exhausted page naming the deepest page that holds products, not as a zero-match search — the broaden-the-filters guidance appears only when nothing matched
  • Returns summary rows (barcode, name, brand, Nutri-Score, NOVA, categories) — chain to off_get_product for full label data; counts reflect contributed products, not the market. Every returned barcode is one off_get_product accepts: a match Open Food Facts stores under a code it cannot serve (00000636) is left off the page and counted in omitted
  • Own client-side budget of ~10 requests/min, kept well inside what Open Food Facts asks of clients

off_compare_products tool

  • Accepts 2–10 barcodes, compared in the order provided
  • Returns a normalized comparison table: energy (kcal/100g), fat, saturated fat, sugars, salt, protein, fiber, Nutri-Score, NOVA group, and Green-Score; missing nutrition data is preserved as null, never imputed
  • not_found lists barcodes with no contributor record (not an error — the product may simply not be entered yet)
  • failed lists barcodes whose fetch itself failed, with a per-barcode reason — kept separate from not_found, and a failed barcode never blocks the rows that did resolve

off_browse_taxonomy tool

  • Facets categories, labels, allergens, additives, countries resolve live against the Open Food Facts taxonomy (case-insensitive substring match on tag ID, display name, or a common synonym — "shellfish" resolves to en:crustaceans); upstream tags are often plural, so pass the returned id through unchanged. Among the live matches, the tag spelling the term itself ranks first (lentil → en:lentils ahead of en:lentil-soups), so a small limit does not cut it
  • nova_groups and nutrition_grades are closed vocabularies, returned complete, with bare "1"–"4" / "a"–"e" ids
  • Live lookups fall back to a small in-process sample when Open Food Facts is unreachable or the budget is spent, and say so rather than failing; omitting search returns only that sample, since Open Food Facts can't enumerate a full facet — no total_in_facet is reported for the open facets
  • limit controls results (1–100, default 20); there is no offset or page — narrow the search term instead
  • Own client-side budget of ~10 requests/min, separate from the search budget

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

Open Food Facts-specific:

  • No API key required — the identifying User-Agent header (required by OFF terms) is baked into the service layer
  • 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. Budgets count upstream requests, so a retried request spends its own slot and a budget exhausted mid-retry surfaces as rate_limited rather than sending. A local refusal says so — it never reports itself as an Open Food Facts rate limit
  • Automatic retry (4 attempts, 500ms base) for transient failures only — 5xx other than 501, timeouts, and 429 (honoring Retry-After), with HTML error page detection for 503 during high load. The HTTP status decides: a 4xx or a 501 is sent once and never retried, and the upstream's own explanation is surfaced instead — a rendered error page served with a refusal is reported as a refusal, not as load
  • 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)
  • 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

Agent-friendly output:

  • Per-serving nutrition always carries its denominator — serving_size as printed plus the parsed serving_quantity/serving_quantity_unit, and an explicit note when Open Food Facts has recorded none
  • Computed scores (Nutri-Score, NOVA, Green-Score) returned as-is with regional caveat notes — not interpreted or normalized to health claims
  • Graceful partial failure — off_compare_products returns resolved rows even when others fail, splitting confirmed-missing barcodes into not_found and failed fetches into failed
  • Every failure carries a declared reason and a recovery hint on both client surfaces — timeouts, upstream outages, upstream rejections, and rate limits each resolve to their own error code and their own next step

Getting started

Public Hosted Instance

A public instance is available at https://openfoodfacts.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:

{
  "mcpServers": {
    "openfoodfacts-mcp-server": {
      "type": "streamable-http",
      "url": "https://openfoodfacts.caseyjhand.com/mcp"
    }
  }
}

Self-Hosted / Local

No API key is required. Add the following to your MCP client configuration file.

{
  "mcpServers": {
    "openfoodfacts-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/openfoodfacts-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with npx (no Bun required):

{
  "mcpServers": {
    "openfoodfacts-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/openfoodfacts-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with Docker:

{
  "mcpServers": {
    "openfoodfacts-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "ghcr.io/cyanheads/openfoodfacts-mcp-server:latest"
      ]
    }
  }
}

For Streamable HTTP, set the transport and start the server:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp

Prerequisites

  • Bun v1.3.0 or higher (or Node.js v24+).
  • No API key needed. The server sends an identifying User-Agent to comply with Open Food Facts' terms of service — this is baked in and requires no configuration.

Installation

  1. Clone the repository:
git clone https://github.com/cyanheads/openfoodfacts-mcp-server.git
  1. Navigate into the directory:
cd openfoodfacts-mcp-server
  1. Install dependencies:
bun install
  1. Configure environment:
cp .env.example .env
# edit .env if you need to override rate limits or the base URL

Configuration

All configuration is validated at startup via Zod schemas in src/config/server-config.ts.

VariableDescriptionDefault
OFF_BASE_URLOpen Food Facts API base URL. Override for local testing against a mock server.https://world.openfoodfacts.org
OFF_RATE_LIMIT_PRODUCTProduct read rate limit (requests/min). Matches the 15 req/min/IP Open Food Facts documents for product reads.15
OFF_RATE_LIMIT_SEARCHSearch rate limit (requests/min).10
OFF_RATE_LIMIT_TAXONOMYTaxonomy resolution rate limit (requests/min), shared by off_browse_taxonomy, tag-value resolution on text searches, and the check on allergen and trace exclusions. A spent budget falls back to the offline sample, or to the tag value as normalized, rather than failing — except that an exclusion it could not check is refused as retryable.10
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_AUTH_MODEAuth mode: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (debug, info, warning, error).info
LOGS_DIRLog file directory (Node.js only).<project-root>/logs
OTEL_ENABLEDEnable OpenTelemetry instrumentation.false

See .env.example for the full list of optional overrides.

Running the server

Local development

  • Build and run:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
    
  • Run checks and tests:

    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
    

Docker

docker build -t openfoodfacts-mcp-server .
docker run --rm -p 3010:3010 openfoodfacts-mcp-server

The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/openfoodfacts-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools and inits services.
src/configServer-specific environment variable parsing and validation with Zod.
src/mcp-server/toolsTool definitions (*.tool.ts).
src/services/openfoodfactsOpen Food Facts API client — HTTP, rate limiting, retry, field normalization.
src/services/taxonomyTag vocabulary service — live resolution, offline sample, merge and fallback policy for off_browse_taxonomy, and tag-value canonicalization for text searches.
tests/Unit and integration tests mirroring src/.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage
  • Register new tools via the barrel in src/mcp-server/tools/definitions/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Attribution

Open Food Facts data is released under the Open Database License (ODbL) 1.0. Downstream use must cite Open Food Facts.

Contributing

Bugs, feature requests, and documentation gaps all belong in an issue — see CONTRIBUTING.md for the forms, what makes a report actionable, and how to tell a server bug from a framework one. Vulnerabilities go through private disclosure, never a public issue.

Working on the code? Both gates must be green:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.

Featured
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
ego lite browserego lite browser
ego lite browser
Fastest browser for AI agents to run web automation tasks, always free.
Download Free life-time →
belt - the only tool your agent needs
belt - the only tool your agent needs
belt cli automatically finds the best tools and skills for your agent. image, video, music, tts...
one prompt install →
Open Steps
Open Steps
Free an open-source skills that make AI coding agents easier to understand, verify, and control.
Download for free →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Agent, connect blockchain
Agent, connect blockchain
Connect your Claude agent to live crypto prices and trading routes via 1inch
Get the MCP →
Granola, the best AI meeting recorder
Granola, the best AI meeting recorder
Notes, actions and memory. Without a meeting bot. First month 100% off.
Download for free →
CodeHealth MCP ServerCodeHealth MCP Server
CodeHealth MCP Server
Protect your code quality, stop the AI slop.
Try For Free →
Categories
Search & Web Crawling
TransportHTTP
UpdatedJul 10, 2026
View on GitHub

More from cyanheads

  • orcid-mcp-server
  • reference-data-mcp-server
  • usaspending-mcp-server
  • exchange-rates-mcp-server
  • national-parks-mcp-server
  • openlibrary-mcp-server
  • protein-mcp-server
  • openstreetmap-mcp-server
  • pubchem-mcp-server
  • who-gho-mcp-server
  • socrata-mcp-server
  • arxiv-mcp-server
  • Pubmed Mcp Server107
  • Clinicaltrialsgov Mcp Server79
  • Openalex Mcp Server7
  • Congressgov Mcp Server1
  • Calculator Mcp Server1
  • Nws Weather Mcp Server1
  • Nhtsa Vehicle Safety Mcp Server1
  • Obsidian Mcp Server582
  • Hn Mcp Server3
  • Git Mcp Server221
  • Secedgar Mcp Server5
  • Pubchem Mcp Server9

Related Search & Web Crawling MCP Servers

View all →
cyanheads avatar
pubchem-mcp-server

cyanheads/pubchem-mcp-server-495646fa

Search PubChem compounds, properties, safety data, bioactivity, and cross-references.
cyanheads avatar
socrata-mcp-server

cyanheads/socrata-mcp-server-9996f211

Search and query government open-data portals (Socrata SODA API).
cyanheads avatar
Uspto Mcp Server

cyanheads/uspto-mcp-server

Search USPTO patent applications, PTAB trial proceedings, and petition decisions.
cyanheads avatar
wikipedia-mcp-server

cyanheads/wikipedia-mcp-server-1519899e

Search Wikipedia, read summaries and full text, target sections, find nearby pages, list languages.
cyclesite avatar
Cyclesite. The UKs Trusted bike marketplace

cyclesite/bikes

MCP server for Cyclesite — UK's used-bike marketplace. Live UK inventory search, sold-price valuation from real completed sales, aggregated stolen-bike check, brand/model catalogue, plus full write-side over OAuth: publish, mark sold, message sellers, save alerts, reserve listings.
h2ejctu avatar
audioknihy.cz Catalog

cz.audioknihy/catalog

Czech audiobook catalog MCP server. Search 12 000+ titles + compare prices across 5 partners.