Skip to main content
Glama
caleb-conner

Open Food Facts MCP Server

by caleb-conner
README.md
# Open Food Facts MCP Server

[![Test Suite](https://github.com/conner/open-food-facts-mcp/workflows/Test%20Suite/badge.svg)](https://github.com/conner/open-food-facts-mcp/actions)
[![codecov](https://codecov.io/gh/conner/open-food-facts-mcp/branch/main/graph/badge.svg)](https://codecov.io/gh/conner/open-food-facts-mcp)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A comprehensive Model Context Protocol (MCP) server that provides AI assistants with access to the Open Food Facts database. Query detailed food product information, nutritional data, and environmental scores to help users make informed food choices.

## ๐ŸŒŸ Features

- **Product Lookup**: Get detailed information by barcode including nutritional facts, ingredients, and scores
- **Smart Search**: Find products with advanced filtering by categories, brands, nutrition grades, and more
- **Nutritional Analysis**: Interpret Nutri-Score, NOVA processing groups, and Eco-Score ratings
- **Product Comparison**: Compare multiple products side-by-side across different criteria
- **Dietary Recommendations**: Get suggestions based on dietary preferences and restrictions
- **Rate Limiting**: Built-in rate limiting respects Open Food Facts API constraints
- **Docker Ready**: Production deployment with Docker and Docker Compose

## ๐Ÿš€ Quick Start

### Docker Deployment (Recommended)

```bash
# Clone and run
git clone https://github.com/conner/open-food-facts-mcp
cd open-food-facts-mcp
docker-compose up --build
```

### Local Development

```bash
# Install dependencies
npm install

# Configure environment
cp .env.example .env

# Build and start
npm run build
npm start

# Development mode
npm run dev
```

## ๐Ÿ”ง Configuration

Configure the server via environment variables:

```bash
# API Configuration
OPEN_FOOD_FACTS_BASE_URL=https://world.openfoodfacts.net
OPEN_FOOD_FACTS_USER_AGENT=YourApp/1.0 (contact@example.com)

# Rate Limits (requests per minute)
RATE_LIMIT_PRODUCTS=100
RATE_LIMIT_SEARCH=10
RATE_LIMIT_FACETS=2
```

## ๐Ÿ›  Available Tools

### `get_product`
Retrieve comprehensive product information by barcode.

```json
{
  "barcode": "3017620422003"
}
```

**Returns**: Product name, brand, nutritional scores, ingredients, nutrition facts, and metadata.

### `search_products`
Search products with advanced filtering capabilities.

```json
{
  "search": "organic chocolate",
  "categories": "snacks",
  "nutrition_grades": "a,b,c",
  "page_size": 10
}
```

**Filters**: Categories, brands, countries, nutrition grades, NOVA groups, sorting options.

### `analyze_product`
Get detailed nutritional analysis and score interpretations.

```json
{
  "barcode": "3017620422003"
}
```

**Returns**: Score explanations, nutritional breakdown with health assessments, and processing level details.

### `compare_products`
Compare multiple products across different aspects.

```json
{
  "barcodes": ["3017620422003", "8712566073219"],
  "focus": "nutrition"
}
```

**Focus Options**: `nutrition`, `environmental`, `processing`, `ingredients`.

### `get_product_suggestions`
Get personalized product recommendations.

```json
{
  "category": "beverages",
  "dietary_preferences": ["vegan", "organic"],
  "min_nutriscore": "b",
  "max_results": 5
}
```

**Dietary Options**: vegan, vegetarian, gluten-free, organic, low-fat, low-sugar, high-protein.

## ๐Ÿค– MCP Integration

Add to your MCP client configuration:

```json
{
  "mcpServers": {
    "open-food-facts": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "open-food-facts-mcp"]
    }
  }
}
```

Or for local development:

```json
{
  "mcpServers": {
    "open-food-facts": {
      "command": "node",
      "args": ["dist/index.js"],
      "cwd": "/path/to/open-food-facts-mcp"
    }
  }
}
```

## ๐Ÿ“Š Data & Scores

### Nutri-Score
- **A-E rating** indicating overall nutritional quality
- **Green (A/B)**: Healthier choices
- **Red (D/E)**: Less healthy options

### NOVA Groups
- **Group 1**: Unprocessed/minimally processed foods
- **Group 2**: Processed culinary ingredients  
- **Group 3**: Processed foods
- **Group 4**: Ultra-processed foods

### Eco-Score
- **A-E rating** for environmental impact
- Considers packaging, transportation, and production methods

## ๐Ÿงช Development

### Testing

```bash
# Run all tests
npm test

# Watch mode
npm run test:watch

# Coverage report
npm run test:coverage

# Validate code quality
npm run validate
```

### Code Quality

```bash
# Type checking
npm run typecheck

# Linting
npm run lint
npm run lint:fix
```

### Project Structure

```
src/
โ”œโ”€โ”€ client.ts       # HTTP client with rate limiting
โ”œโ”€โ”€ handlers.ts     # MCP tool implementations
โ”œโ”€โ”€ index.ts        # MCP server entry point
โ”œโ”€โ”€ tools.ts        # Tool definitions
โ””โ”€โ”€ types.ts        # TypeScript types and schemas

tests/
โ”œโ”€โ”€ client.test.ts      # Client unit tests
โ”œโ”€โ”€ handlers.test.ts    # Handler unit tests
โ”œโ”€โ”€ server.test.ts      # Integration tests
โ”œโ”€โ”€ validation.test.ts  # Schema validation tests
โ”œโ”€โ”€ rate-limiting.test.ts # Rate limiting tests
โ”œโ”€โ”€ e2e.test.ts        # End-to-end tests
โ”œโ”€โ”€ fixtures/          # Test data
โ””โ”€โ”€ utils/            # Test utilities
```

## ๐Ÿ“ˆ Performance

- **Rate Limiting**: Automatic enforcement of API limits
- **Efficient Caching**: Smart request deduplication
- **Batch Operations**: Optimized multi-product comparisons
- **Error Recovery**: Graceful handling of API failures

## ๐Ÿ”’ API Limits

The server respects Open Food Facts API rate limits:

- **Product queries**: 100 requests/minute
- **Search queries**: 10 requests/minute  
- **Facet queries**: 2 requests/minute

Rate limits are enforced automatically with proper error messaging.

## ๐ŸŒ Data Source

All data comes from [Open Food Facts](https://openfoodfacts.org), the largest open food database in the world:

- **900,000+ products** from 150+ countries
- **Collaborative data** maintained by contributors worldwide
- **Open Database License** ensuring free access to food information
- **Real-time updates** from the global community

## ๐Ÿ“ Examples

### Basic Product Information
```
**Nutella**
Brand: Ferrero
Quantity: 400g
Categories: Sweet spreads, Chocolate spreads

Scores:
Nutri-Score: E | NOVA Group: 4 | Eco-Score: D

Ingredients:
Sugar, palm oil, hazelnuts (13%), skimmed milk powder...

Nutrition (per 100g):
Energy: 539 kcal | Fat: 30.9g | Carbs: 57.5g | Sugars: 56.3g
```

### Nutritional Analysis
```
Nutritional Analysis: Nutella

Scores:
โ€ข Nutri-Score E: Very poor nutritional quality
โ€ข NOVA Group 4: Ultra-processed foods  
โ€ข Eco-Score D: High environmental impact

Nutritional Breakdown:
โ€ข Energy: 539 kcal (high)
โ€ข Fat: 30.9g (high)
โ€ข Sugars: 56.3g (high)
โ€ข Salt: 0.107g (low)
```

## ๐Ÿค Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes with tests
4. Run quality checks (`npm run validate`)
5. Commit your changes (`git commit -m 'Add amazing feature'`)
6. Push to the branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request

## ๐Ÿ“„ License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## ๐Ÿ™ Acknowledgments

- [Open Food Facts](https://openfoodfacts.org) for providing the comprehensive food database
- [Model Context Protocol](https://github.com/modelcontextprotocol) for the MCP specification
- The global community of contributors maintaining food data quality

---

**Need help?** Open an issue or check the [examples](examples/usage.md) for detailed usage patterns.

TDQS

A3.5/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose with no ambiguity: analyze_product focuses on nutritional analysis, compare_products on comparisons, get_product on retrieval, get_product_suggestions on recommendations, and search_products on filtered searches. The descriptions make it easy for an agent to select the right tool for each specific task.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (e.g., analyze_product, compare_products, get_product, get_product_suggestions, search_products). This predictability enhances usability and reduces cognitive load for agents navigating the toolset.

Tool Count5/5

With 5 tools, the server is well-scoped for its food product domain, covering core operations like retrieval, search, analysis, comparison, and suggestions. Each tool earns its place without feeling excessive or insufficient for the intended functionality.

Completeness4/5

The toolset provides strong coverage for querying and analyzing food products, including CRUD-like retrieval and search, plus value-added features like analysis and suggestions. A minor gap might be the lack of update or creation tools, but this is reasonable for a read-only data source like Open Food Facts.

Maintenance

ActivityInactive
ResponsivenessNo issues