from mcp.server.fastmcp import FastMCP
import openfoodfacts
# Initialize FastMCP server
mcp = FastMCP("Open Food Facts")
# Initialize Open Food Facts API
# User agent is required by Open Food Facts API policy along with some intent/app name
api = openfoodfacts.API(user_agent="OpenFoodFactsMCP/1.0")
@mcp.tool()
def get_product_by_barcode(barcode: str) -> str:
"""
Get information about a product using its barcode.
Returns a formatted string with product details or error message.
Args:
barcode: The barcode of the product (e.g., "3017620422003")
"""
try:
# Fetch only necessary fields to keep payload light
product_data = api.product.get(
barcode,
fields=["code", "product_name", "brands", "categories", "ingredients_text", "nutriscore_grade"]
)
if not product_data:
return f"No product found for barcode: {barcode}"
# The SDK might return the product directly or inside a wrapper,
# based on typical API response structure `product.get` usually returns the product dict directly
# strictly checking if it's a valid product dict
code = product_data.get('code', 'N/A')
name = product_data.get('product_name', 'Unknown Product')
brands = product_data.get('brands', 'Unknown Brand')
categories = product_data.get('categories', 'N/A')
ingredients = product_data.get('ingredients_text', 'Not listed')
nutriscore = product_data.get('nutriscore_grade', 'N/A').upper()
return (
f"Product Code: {code}\n"
f"Name: {name}\n"
f"Brand: {brands}\n"
f"Nutri-Score: {nutriscore}\n"
f"Categories: {categories}\n"
f"Ingredients: {ingredients}"
)
except Exception as e:
return f"Error fetching product: {str(e)}"
@mcp.tool()
def search_products(query: str, page_size: int = 5) -> str:
"""
Search for products by text query.
Args:
query: Search term (e.g., "chocolate", "mineral water")
page_size: Number of results to return (default 5)
"""
try:
result = api.product.text_search(query, page_size=page_size)
if not result or 'products' not in result:
return f"No products found for query: {query}"
products = result['products']
if not products:
return f"No products found for query: {query}"
output = [f"Found {result.get('count', 0)} results. Top {len(products)}:\n"]
for p in products:
code = p.get('code', 'N/A')
name = p.get('product_name', 'Unknown')
brand = p.get('brands', 'Unknown')
output.append(f"- [{code}] {name} ({brand})")
return "\n".join(output)
except Exception as e:
return f"Error searching products: {str(e)}"
if __name__ == "__main__":
mcp.run()