searchByCategory
Find food products by category (e.g., beverages, snacks, dairy) from OpenFoodFacts database. Specify category to retrieve product listings.
Instructions
Search products within a specific food category (e.g., beverages, snacks, dairy, cereals)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| category | Yes | Food category (e.g., "beverages", "snacks", "dairy", "organic") | |
| page | No | ||
| pageSize | No |
Implementation Reference
- src/tools/helpers.ts:76-94 (handler)The actual implementation of searchByCategory. It takes a category string (e.g., 'beverages'), converts it to a slug, calls the Open Food Facts category API, maps results using mapToSearchProduct, and returns a SearchResult with pagination info.
export async function searchByCategory(category: string, page: number, pageSize: number): Promise<SearchResult> { const categorySlug = category.toLowerCase().replace(/\s+/g, '-'); const url = `${BASE_URL}/category/${categorySlug}/${page}.json`; const response = await fetch(url); if (!response.ok) { throw new Error(`Failed to search by category: ${response.status}`); } const data = await response.json(); return { products: (data.products || []).map(mapToSearchProduct), count: data.count || 0, page, pageSize, pageCount: Math.ceil((data.count || 0) / pageSize) }; } - src/tools/category-tools.ts:47-57 (registration)Registration of the 'searchByCategory' tool on the MCP server via server.registerTool(). Defines the description and uses categorySchema for input validation. The handler calls the searchByCategory helper and returns the JSON-stringified result.
server.registerTool('searchByCategory', { description: 'Search products within a specific food category (e.g., beverages, snacks, dairy, cereals)', inputSchema: categorySchema }, async ({ category, page, pageSize }) => { try { const results = await searchByCategory(category, page ?? 1, pageSize ?? 10); return { content: [{ type: 'text' as const, text: JSON.stringify(results, null, 2) }] }; } catch (error: any) { return { content: [{ type: 'text' as const, text: `Error: ${error.message}` }], isError: true }; } }); - src/tools/category-tools.ts:11-15 (schema)Input schema for searchByCategory defined with Zod: category (string), page (number, default 1), pageSize (number, default 10).
const categorySchema = { category: z.string().describe('Food category (e.g., "beverages", "snacks", "dairy", "organic")'), page: z.number().default(1), pageSize: z.number().default(10) }; - src/tools/helpers.ts:57-69 (helper)Helper function mapToSearchProduct used by searchByCategory to map raw product data from the API into the SearchProductResult format.
export function mapToSearchProduct(p: any): SearchProductResult { return { id: p._id || p.code, name: p.product_name || 'Unknown', brand: p.brands || 'Unknown', barcode: p.code || '', imageUrl: p.image_url || '', nutriScore: p.nutriscore_grade || '', ecoScore: p.ecoscore_grade || '', novaGroup: p.nova_group || 0, categories: p.categories || '' }; } - src/tools/category-tools.ts:108-108 (registration)Log line confirming registration of the searchByCategory tool (and others).
logger.info("Category tools registered: searchByCategory, searchByBrand, advancedSearch, autocomplete");