suggestRecipes
Input a food product name or barcode to receive AI-generated recipe suggestions using OpenFoodFacts data.
Instructions
Get AI recipe suggestions using a product
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| nameOrBarcode | Yes |
Implementation Reference
- src/tools/index.ts:151-170 (handler)The actual tool handler for 'suggestRecipes' - accepts nameOrBarcode, looks up the product, and calls createRecipeSuggestionRequest + requestSampling to generate AI recipes.
server.registerTool('suggestRecipes', { description: 'Get AI recipe suggestions using a product', inputSchema: productSchema }, async ({ nameOrBarcode }) => { if (!nameOrBarcode?.trim()) { return { content: [{ type: 'text' as const, text: 'Provide a product.' }], isError: true }; } const productData = await findProduct(nameOrBarcode); if (!productData?.product) { return { content: [{ type: 'text' as const, text: `"${nameOrBarcode}" not found.` }], isError: true }; } try { const res = await requestSampling(server, createRecipeSuggestionRequest(productData.product)); return { content: [{ type: 'text' as const, text: `# Recipes using ${productData.product.product_name}\n\n${getResponseText(res)}` }] }; } catch (e: any) { return { content: [{ type: 'text' as const, text: `Recipe generation failed: ${e.message}` }], isError: true }; } }); - src/tools/index.ts:50-50 (schema)Input schema for suggestRecipes: { nameOrBarcode: z.string() }
const productSchema = { nameOrBarcode: z.string() }; - src/tools/index.ts:151-170 (registration)Registration of 'suggestRecipes' tool via server.registerTool with description and inputSchema.
server.registerTool('suggestRecipes', { description: 'Get AI recipe suggestions using a product', inputSchema: productSchema }, async ({ nameOrBarcode }) => { if (!nameOrBarcode?.trim()) { return { content: [{ type: 'text' as const, text: 'Provide a product.' }], isError: true }; } const productData = await findProduct(nameOrBarcode); if (!productData?.product) { return { content: [{ type: 'text' as const, text: `"${nameOrBarcode}" not found.` }], isError: true }; } try { const res = await requestSampling(server, createRecipeSuggestionRequest(productData.product)); return { content: [{ type: 'text' as const, text: `# Recipes using ${productData.product.product_name}\n\n${getResponseText(res)}` }] }; } catch (e: any) { return { content: [{ type: 'text' as const, text: `Recipe generation failed: ${e.message}` }], isError: true }; } }); - createRecipeSuggestionRequest builds a SamplingRequest with system prompt for generating 4 recipe types (low-calorie, protein-rich, quick & easy, family-friendly) using product data.
export function createRecipeSuggestionRequest(productData: any): SamplingRequest { const productName = productData.product_name || "this product"; const category = productData.categories || "food item"; const ingredients = productData.ingredients_text || ""; const nutriments = productData.nutriments || {}; const allergens = productData.allergens || ""; const brands = productData.brands || ""; return { messages: [ { role: "user", content: { type: "text", text: `Generate recipe suggestions for ${productName} (${brands}). ` + `Nutritional profile: Energy ${nutriments.energy_100g || "unknown"} kcal, ` + `Fat ${nutriments.fat_100g || "unknown"}g, ` + `Proteins ${nutriments.proteins_100g || "unknown"}g, ` + `Carbs ${nutriments.carbohydrates_100g || "unknown"}g.\n\n` + `Category: ${category}\nIngredients: ${ingredients}\nAllergens: ${allergens}` } } ], modelPreferences: { hints: [{ name: "claude-3" }, { name: "gpt-4o" }], intelligencePriority: 0.8, speedPriority: 0.5 }, systemPrompt: `You are a creative culinary nutritionist. Generate 4 recipe suggestions: 1. LOW-CALORIE: Light meal focusing on weight management 2. PROTEIN-RICH: Recipe for fitness enthusiasts 3. QUICK & EASY: Minimal prep and cooking time 4. FAMILY-FRIENDLY: Balanced meal for all ages For each recipe, provide: - Recipe name - Ingredient list with measurements - Brief preparation steps - Approximate nutrition per serving - Health benefit highlight`, includeContext: "thisServer", temperature: 0.7, maxTokens: 3500 }; } - requestSampling sends the sampling/createMessage request to the LLM client via MCP protocol, used by the suggestRecipes handler.
export async function requestSampling( mcpServer: McpServer, request: SamplingRequest ): Promise<CreateMessageResult> { try { const response = await mcpServer.server.request({ method: "sampling/createMessage", params: { messages: request.messages, modelPreferences: request.modelPreferences, systemPrompt: request.systemPrompt, includeContext: request.includeContext, temperature: request.temperature, maxTokens: request.maxTokens, stopSequences: request.stopSequences, metadata: request.metadata } }, CreateMessageResultSchema); return response as CreateMessageResult; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); throw new Error(`Sampling request failed: ${errorMessage}`); } }