search_ingredients
Discover which ingredients are available for wine pairing. Search by name to get ingredient IDs, names, and groups.
Instructions
Search for ingredients in the SommelierX database. Returns ingredient names, IDs, and groups. Use this to discover available ingredients before using pair_wine_with_ingredients. Best for: "What mushroom ingredients are available?" | Auth: API key (Bearer sk_live_...) or x402 payment (USDC on Base) | Price: $0.005/call
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search term for ingredients (e.g. "mushroom", "cheese", "salmon") | |
| language | No | Language code for results (e.g. "en", "nl", "fr"). Defaults to "en". |
Implementation Reference
- src/tools/search-ingredients.ts:1-88 (handler)The executeSearchIngredients function (line 36-56) is the main handler that calls the SommelierX API /api/v1/ingredients with search and language params, then formats results via formatIngredientResults (line 61-88).
/** * Tool: search_ingredients * * Search for ingredients in the SommelierX database. * Useful for discovering available ingredients before using * the pair_wine_with_ingredients tool. */ import { z } from 'zod'; import type { SommelierXClient } from '../client.js'; import type { ServerConfig } from '../config.js'; import type { IngredientListResult, IngredientItem } from './types.js'; /** Zod schema for tool input validation. */ export const searchIngredientsSchema = z.object({ query: z .string() .min(2, 'Search query must be at least 2 characters') .max(100) .describe('Search term for ingredients (e.g. "mushroom", "cheese", "salmon")'), language: z .string() .min(2) .max(10) .optional() .describe('Language code for results (e.g. "en", "nl", "fr"). Defaults to "en".'), }); export type SearchIngredientsInput = z.infer<typeof searchIngredientsSchema>; /** * Execute the search_ingredients tool. * * Calls /api/v1/ingredients?search=... and formats the results. */ export async function executeSearchIngredients( client: SommelierXClient, config: ServerConfig, input: SearchIngredientsInput, ): Promise<string> { const language = input.language ?? config.defaultLanguage; let result: IngredientListResult; try { result = await client.get<IngredientListResult>('/api/v1/ingredients', { search: input.query, language, perPage: '20', }); } catch (error: unknown) { const message = error instanceof Error ? error.message : 'Unknown error'; return `Error searching ingredients: ${message}`; } return formatIngredientResults(input.query, result.data, result.total); } /** * Format the ingredient search results into a human-readable string. */ function formatIngredientResults( query: string, ingredients: IngredientItem[], total: number, ): string { const lines: string[] = []; lines.push(`Ingredient search results for "${query}" (${total} total):`); lines.push(''); if (ingredients.length === 0) { lines.push('No ingredients found matching your search.'); lines.push('Try a different search term or language.'); return lines.join('\n'); } for (const ingredient of ingredients) { const groupSuffix = ingredient.group ? ` [${ingredient.group}]` : ''; lines.push(`- ${ingredient.name} (id: ${ingredient.id})${groupSuffix}`); } if (total > ingredients.length) { lines.push(''); lines.push(`Showing ${ingredients.length} of ${total} results. Refine your search for more specific results.`); } return lines.join('\n'); } - The searchIngredientsSchema Zod schema defines the input validation for the search_ingredients tool: a required 'query' (min 2 chars) and an optional 'language' parameter.
/** Zod schema for tool input validation. */ export const searchIngredientsSchema = z.object({ query: z .string() .min(2, 'Search query must be at least 2 characters') .max(100) .describe('Search term for ingredients (e.g. "mushroom", "cheese", "salmon")'), language: z .string() .min(2) .max(10) .optional() .describe('Language code for results (e.g. "en", "nl", "fr"). Defaults to "en".'), }); - src/index.ts:121-132 (registration)The tool is registered with MCP server.tool() at line 123-132 under the name 'search_ingredients' with its schema.shape and a handler that parses input and calls executeSearchIngredients.
// ── Tool 5: search_ingredients ── server.tool( 'search_ingredients', 'Search for ingredients in the SommelierX database. Returns ingredient names, IDs, and groups. Use this to discover available ingredients before using pair_wine_with_ingredients. Best for: "What mushroom ingredients are available?" | Auth: API key (Bearer sk_live_...) or x402 payment (USDC on Base) | Price: $0.005/call', searchIngredientsSchema.shape, async (input) => { const parsed = searchIngredientsSchema.parse(input); const result = await executeSearchIngredients(client, config, parsed); return { content: [{ type: 'text' as const, text: result }] }; }, ); - src/tools/index.ts:25-28 (registration)Barrel re-export of searchIngredientsSchema and executeSearchIngredients from the search-ingredients module for centralized tool registration.
export { searchIngredientsSchema, executeSearchIngredients, } from './search-ingredients.js'; - src/tools/types.ts:71-85 (helper)Type definitions used by the search_ingredients tool: IngredientItem (id, name, group, description) and IngredientListResult (paginated list with data, total, page, perPage).
/** Ingredient from search/list. */ export interface IngredientItem { id: number; name: string; group?: string; description?: string; } /** Paginated ingredient list. */ export interface IngredientListResult { data: IngredientItem[]; total: number; page: number; perPage: number; }