Skip to main content
Glama
caleb-conner

Open Food Facts MCP Server

by caleb-conner

get_product_suggestions

Find food products matching dietary preferences like vegan, gluten-free, or organic within specific categories using nutritional scoring.

Instructions

Get product suggestions based on dietary preferences or restrictions

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
categoryYesProduct category to search within
dietary_preferencesNoDietary preferences or restrictions
max_resultsNoMaximum number of suggestions (default: 10)
min_nutriscoreNoMinimum Nutri-Score grade (a, b, c, d, e)

Implementation Reference

  • Main handler function executing the tool: destructures params, builds search query for category and nutriscore, calls client.searchProducts, filters by dietary preferences, formats suggestions, returns formatted text response.
    async handleGetProductSuggestions(params: any) { const { category, dietary_preferences = [], max_results = 10, min_nutriscore } = params; const searchParams: any = { categories: category, page_size: Math.min(max_results * 2, 100), // Get extra to filter sort_by: 'popularity', }; if (min_nutriscore) { const validGrades = ['a', 'b', 'c', 'd', 'e']; const minIndex = validGrades.indexOf(min_nutriscore); const allowedGrades = validGrades.slice(0, minIndex + 1); searchParams.nutrition_grades = allowedGrades.join(','); } const response = await this.client.searchProducts(searchParams); let filteredProducts = response.products; // Filter by dietary preferences if (dietary_preferences.length > 0) { filteredProducts = this.filterByDietaryPreferences(filteredProducts, dietary_preferences); } const suggestions = filteredProducts .slice(0, max_results) .map((product, index) => `${index + 1}. ${this.formatProductSuggestion(product)}`) .join('\n\n'); return { content: [ { type: "text" as const, text: `Product suggestions in ${category}:\n\n${suggestions}`, }, ], }; }
  • Tool schema definition including input schema with parameters: category (required), dietary_preferences, max_results, min_nutriscore.
    { name: "get_product_suggestions", description: "Get product suggestions based on dietary preferences or restrictions", inputSchema: { type: "object", properties: { category: { type: "string", description: "Product category to search within", }, dietary_preferences: { type: "array", items: { type: "string", enum: ["vegan", "vegetarian", "gluten-free", "organic", "low-fat", "low-sugar", "high-protein"], }, description: "Dietary preferences or restrictions", }, max_results: { type: "number", description: "Maximum number of suggestions (default: 10)", minimum: 1, maximum: 50, }, min_nutriscore: { type: "string", description: "Minimum Nutri-Score grade (a, b, c, d, e)", enum: ["a", "b", "c", "d", "e"], }, }, required: ["category"], }, },
  • src/index.ts:57-58 (registration)
    Registration in the MCP server request handler switch statement, dispatching to the handler function.
    case 'get_product_suggestions': return await handlers.handleGetProductSuggestions(args);
  • Helper method to filter products based on dietary preferences by checking labels, categories, and ingredients.
    private filterByDietaryPreferences(products: Product[], preferences: string[]): Product[] { return products.filter(product => { const labels = (product.labels || '').toLowerCase(); const categories = (product.categories || '').toLowerCase(); const ingredients = (product.ingredients_text || '').toLowerCase(); return preferences.every(pref => { switch (pref) { case 'vegan': return labels.includes('vegan') || categories.includes('vegan'); case 'vegetarian': return labels.includes('vegetarian') || categories.includes('vegetarian'); case 'gluten-free': return labels.includes('gluten') && labels.includes('free'); case 'organic': return labels.includes('organic') || labels.includes('bio'); case 'low-fat': return labels.includes('low-fat') || labels.includes('light'); case 'low-sugar': return labels.includes('sugar-free') || labels.includes('no-sugar'); case 'high-protein': return labels.includes('high-protein') || labels.includes('protein'); default: return true; } }); }); }
  • Helper method to format individual product suggestions including summary and scores.
    private formatProductSuggestion(product: Product): string { const summary = this.formatProductSummary(product); const scores = []; if (product.nutriscore_grade) scores.push(`Nutri-Score: ${product.nutriscore_grade.toUpperCase()}`); if (product.nova_group) scores.push(`Processing: NOVA ${product.nova_group}`); if (product.ecoscore_grade) scores.push(`Eco: ${product.ecoscore_grade.toUpperCase()}`); return summary + (scores.length > 0 ? `\nScores: ${scores.join(' | ')}` : ''); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/caleb-conner/open-food-facts-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server