Pepesto Products (KgToken → real SKUs)
pepesto_productsMap recipe ingredients to supermarket products with live prices and images. Merge items across recipes to reduce waste, and let users pick from multiple matches.
Instructions
Map one or more recipe KgTokens (and an optional manual shopping list) to concrete supermarket products with prices, images, or currency. Items are merged across recipes to reduce waste; multiple matches per ingredient let you (or the user) pick. Show product title, image if available (json property image_url, don't search for external images, skip rendering the Pepesto image if the image has webp extesion)product_id when available linking to an (external) supermarket page (open in a new tab), price, ProductClassification (is_bio, is_frozen, is_substitution) tags. PricePromotion shows if the item is currently on promotion and what's current promo_percentage
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| recipe_kg_tokens | Yes | KgTokens from pepesto_parse or pepesto_suggest. | |
| supermarket_domain | Yes | Supermarket domain or ID, e.g. 'coop.ch', 'tesco.com', 'ah.nl'. See README for the full list. | |
| manual_shopping_list | No | Free-text extra items to add (e.g. 'milk, bananas, kitchen towel'). |
Implementation Reference
- src/tools/products.ts:33-34 (handler)The handler that executes the tool logic: calls client.post('/products', args) via the runTool helper. This is the actual implementation of pepesto_products.
async (args) => runTool(() => client.post("/products", args)), ); - src/tools/products.ts:7-35 (registration)The registration function that calls server.registerTool with name 'pepesto_products' and its schema + handler.
export function registerProductsTool(server: McpServer, client: PepestoClient): void { server.registerTool( "pepesto_products", { title: "Pepesto Products (KgToken → real SKUs)", description: "Map one or more recipe KgTokens (and an optional manual shopping list) to concrete " + "supermarket products with prices, images, or currency. Items are " + "merged across recipes to reduce waste; multiple matches per ingredient let you (or the " + "user) pick. Show product title, image if available (json property `image_url`, don't search for external images, " + "skip rendering the Pepesto image if the image has webp extesion)" + "product_id when available linking to an (external) supermarket page (open in a new tab), " + "price, ProductClassification (is_bio, is_frozen, is_substitution) tags. PricePromotion " + "shows if the item is currently on promotion and what's current `promo_percentage`", inputSchema: { recipe_kg_tokens: z .array(KgToken) .min(1) .describe("KgTokens from pepesto_parse or pepesto_suggest."), supermarket_domain: SupermarketDomain, manual_shopping_list: z .string() .optional() .describe("Free-text extra items to add (e.g. 'milk, bananas, kitchen towel')."), }, }, async (args) => runTool(() => client.post("/products", args)), ); } - src/tools/products.ts:21-31 (schema)Input schema defining the parameters: recipe_kg_tokens (array of KgToken), supermarket_domain, and optional manual_shopping_list.
inputSchema: { recipe_kg_tokens: z .array(KgToken) .min(1) .describe("KgTokens from pepesto_parse or pepesto_suggest."), supermarket_domain: SupermarketDomain, manual_shopping_list: z .string() .optional() .describe("Free-text extra items to add (e.g. 'milk, bananas, kitchen towel')."), }, - src/tools/_runner.ts:9-27 (helper)The runTool helper used by the handler — executes the async function, serializes success to JSON, or returns an error ToolResult.
export async function runTool(fn: () => Promise<unknown>): Promise<ToolResult> { try { const result = await fn(); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], }; } catch (err) { const msg = err instanceof PepestoApiError ? err.message : err instanceof Error ? `Error: ${err.message}` : `Error: ${String(err)}`; return { content: [{ type: "text", text: msg }], isError: true, }; } } - src/server.ts:26-28 (registration)Where registerProductsTool is called, wiring up the pepesto_products tool into the MCP server.
registerProductsTool(server, client); registerCatalogTool(server, client); registerCreditsTool(server, client);