smart_search_cocktails
Search cocktails by ingredients, flavors, or similarity using batch processing to retrieve complete recipes with measurements, instructions, and specifications.
Instructions
🚀 PREFERRED TOOL: Advanced cocktail search with intelligent batch processing and complete recipes.
🎯 BATCH PROCESSING SYSTEM:
High Performance: Parallel processing with 5-10x speed improvement
Smart Caching: Automatic caching for 70%+ faster repeated searches
Error Resilience: Individual failures don't break entire batch operations
Flexible Limits: Configure result count (default: 20, max: 50)
📋 Use Cases:
General searches: "gin cocktails", "winter drinks", "classic cocktails"
Similarity queries: "cocktails like Manhattan", "similar to Negroni"
Ingredient-based: "cocktails with bourbon", "drinks using Campari"
Flavor profiles: "bitter cocktails", "sweet drinks", "herbal spirits"
Complex filtering: combine ingredients, ABV ranges, glass types, methods
Batch comparisons: Multiple ingredient searches simultaneously
🔄 Batch Processing Examples:
Single search: {query: "Manhattan"} → Complete recipe + similar cocktails
Multi-ingredient: {ingredient: "gin", must_include: ["vermouth", "bitters"]}
Similarity batch: {similar_to: "Negroni", limit: 10} → 10 similar cocktails
Complex filter: {preferred_flavors: ["bitter"], abv_min: 25, limit: 15}
📊 Response Format: Returns structured data with complete recipes including:
Ingredients with precise measurements in oz (auto-converted from ml)
Step-by-step preparation instructions
Cocktail specifications (ABV, glass, method, garnish)
Direct links to cocktail database pages
Performance metrics (processing time, cache hits)
Similar cocktail recommendations with full recipes
⚡ Performance Features:
Parallel API processing for multiple results
Intelligent caching system with TTL management
Batch fetching of complete recipe details
Error isolation and fallback handling
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | 🔍 Natural language search query (e.g., "Negroni", "gin cocktails", "bitter drinks") | |
| similar_to | No | 🔄 Find cocktails similar to this name (e.g., "Manhattan", "Negroni"). Triggers similarity batch processing. | |
| similar_to_id | No | 🆔 Find cocktails similar to this ID. Use similar_to (by name) unless you have the specific ID. | |
| ingredient | No | 🥃 Primary ingredient filter (e.g., "gin", "whiskey", "campari"). Combines with other filters for batch processing. | |
| must_include | No | ✅ Required ingredients array. Batch processes cocktails containing ALL these ingredients. | |
| must_exclude | No | ❌ Excluded ingredients array. Filters out cocktails with ANY of these ingredients. | |
| preferred_flavors | No | 🎯 Flavor profile preferences: ["bitter", "sweet", "sour", "spicy", "herbal"]. Improves batch ranking. | |
| preferred_strength | No | 💪 Alcohol strength preference. Filters batch results by ABV ranges. | |
| abv_min | No | 📊 Minimum ABV percentage. Lower bound for batch filtering. | |
| abv_max | No | 📊 Maximum ABV percentage. Upper bound for batch filtering. | |
| glass_type | No | 🥂 Required glassware (e.g., "coupe", "rocks", "martini"). Filters entire batch. | |
| preparation_method | No | 🔧 Required method (e.g., "shake", "stir", "build"). Filters batch by technique. | |
| limit | No | 🎛️ Maximum results to return (default: 20, max: 50). Controls batch size for optimal performance. |
Implementation Reference
- src/types.ts:221-235 (schema)Type definition for input parameters of the smart_search_cocktails toolexport interface SmartSearchCocktailsParams { query?: string; similar_to?: string; similar_to_id?: number; ingredient?: string; must_include?: string[]; must_exclude?: string[]; preferred_flavors?: string[]; preferred_strength?: 'light' | 'medium' | 'strong'; abv_min?: number; abv_max?: number; glass_type?: string; preparation_method?: string; limit?: number; }
- src/bar-assistant-mcp-server.ts:870-1073 (registration)Tool registration in ListToolsRequestSchema handler, defining name, description, inputSchema, and outputSchemaname: 'smart_search_cocktails', description: `🚀 PREFERRED TOOL: Advanced cocktail search with intelligent batch processing and complete recipes. **🎯 BATCH PROCESSING SYSTEM:** - **High Performance**: Parallel processing with 5-10x speed improvement - **Smart Caching**: Automatic caching for 70%+ faster repeated searches - **Error Resilience**: Individual failures don't break entire batch operations - **Flexible Limits**: Configure result count (default: 20, max: 50) **📋 Use Cases:** - General searches: "gin cocktails", "winter drinks", "classic cocktails" - Similarity queries: "cocktails like Manhattan", "similar to Negroni" - Ingredient-based: "cocktails with bourbon", "drinks using Campari" - Flavor profiles: "bitter cocktails", "sweet drinks", "herbal spirits" - Complex filtering: combine ingredients, ABV ranges, glass types, methods - Batch comparisons: Multiple ingredient searches simultaneously **🔄 Batch Processing Examples:** - Single search: {query: "Manhattan"} → Complete recipe + similar cocktails - Multi-ingredient: {ingredient: "gin", must_include: ["vermouth", "bitters"]} - Similarity batch: {similar_to: "Negroni", limit: 10} → 10 similar cocktails - Complex filter: {preferred_flavors: ["bitter"], abv_min: 25, limit: 15} **📊 Response Format:** Returns structured data with complete recipes including: - Ingredients with precise measurements in oz (auto-converted from ml) - Step-by-step preparation instructions - Cocktail specifications (ABV, glass, method, garnish) - Direct links to cocktail database pages - Performance metrics (processing time, cache hits) - Similar cocktail recommendations with full recipes **⚡ Performance Features:** - Parallel API processing for multiple results - Intelligent caching system with TTL management - Batch fetching of complete recipe details - Error isolation and fallback handling`, inputSchema: { type: 'object', properties: { // Core search parameters query: { type: 'string', description: '🔍 Natural language search query (e.g., "Negroni", "gin cocktails", "bitter drinks")', }, similar_to: { type: 'string', description: '🔄 Find cocktails similar to this name (e.g., "Manhattan", "Negroni"). Triggers similarity batch processing.', }, similar_to_id: { type: 'number', description: '🆔 Find cocktails similar to this ID. Use similar_to (by name) unless you have the specific ID.', }, // Ingredient filtering (supports batch processing) ingredient: { type: 'string', description: '🥃 Primary ingredient filter (e.g., "gin", "whiskey", "campari"). Combines with other filters for batch processing.', }, must_include: { type: 'array', items: { type: 'string' }, description: '✅ Required ingredients array. Batch processes cocktails containing ALL these ingredients.', }, must_exclude: { type: 'array', items: { type: 'string' }, description: '❌ Excluded ingredients array. Filters out cocktails with ANY of these ingredients.', }, // Advanced filtering (enhances batch results) preferred_flavors: { type: 'array', items: { type: 'string' }, description: '🎯 Flavor profile preferences: ["bitter", "sweet", "sour", "spicy", "herbal"]. Improves batch ranking.', }, preferred_strength: { type: 'string', enum: ['light', 'medium', 'strong'], description: '💪 Alcohol strength preference. Filters batch results by ABV ranges.', }, abv_min: { type: 'number', description: '📊 Minimum ABV percentage. Lower bound for batch filtering.', }, abv_max: { type: 'number', description: '📊 Maximum ABV percentage. Upper bound for batch filtering.', }, // Presentation filtering glass_type: { type: 'string', description: '🥂 Required glassware (e.g., "coupe", "rocks", "martini"). Filters entire batch.', }, preparation_method: { type: 'string', description: '🔧 Required method (e.g., "shake", "stir", "build"). Filters batch by technique.', }, // Batch control parameters limit: { type: 'number', description: '🎛️ Maximum results to return (default: 20, max: 50). Controls batch size for optimal performance.', default: 20, minimum: 1, maximum: 50, }, }, }, outputSchema: { type: 'object', description: '🎯 Batch processing response with complete cocktail data and performance metrics', properties: { search_results: { type: 'object', properties: { total_found: { type: 'number', description: 'Total cocktails found matching criteria' }, returned: { type: 'number', description: 'Number of cocktails returned (limited by batch size)' }, search_type: { type: 'string', description: 'Type of search performed (query, similarity, ingredient, etc.)' } } }, cocktails: { type: 'array', description: 'Complete cocktail recipes with full details', items: { type: 'object', properties: { id: { type: 'number' }, name: { type: 'string' }, description: { type: 'string' }, ingredients: { type: 'array', items: { type: 'object', properties: { name: { type: 'string' }, formatted: { type: 'string', description: 'Human-readable amount with units' }, amount: { type: 'string' }, optional: { type: 'boolean' } } } }, instructions: { type: 'array', items: { type: 'object', properties: { step: { type: 'number' }, instruction: { type: 'string' } } } }, details: { type: 'object', properties: { abv: { type: 'number', description: 'Alcohol by volume percentage' }, glass: { type: 'string', description: 'Recommended glassware' }, method: { type: 'string', description: 'Preparation method' }, garnish: { type: 'string', description: 'Garnish instructions' }, direct_link: { type: 'string', description: 'URL to full recipe page' }, tags: { type: 'array', items: { type: 'string' } } } } } } }, similar_cocktails: { type: 'array', description: 'Additional similar cocktails (when using similarity search)', items: { $ref: '#/properties/cocktails/items' } }, performance_metrics: { type: 'object', description: 'Batch processing performance data', properties: { processing_time_ms: { type: 'number' }, api_calls_made: { type: 'number' }, cache_hits: { type: 'number' }, cache_misses: { type: 'number' }, batch_processing_used: { type: 'boolean' }, parallel_requests: { type: 'number' } } }, search_metadata: { type: 'object', properties: { enhanced_query: { type: 'string', description: 'Processed natural language query' }, applied_filters: { type: 'array', items: { type: 'string' } }, search_strategy: { type: 'string', description: 'Batch processing strategy used' } } } } }, },
- src/bar-assistant-mcp-server.ts:1304-1305 (registration)Dispatch to handler in CallToolRequestSchema switch statementcase 'smart_search_cocktails': return await this.handleSmartSearchCocktails(args as any);
- Main handler function that implements the smart_search_cocktails tool logic, including caching, similarity search, cocktail search, recipe fetching, and response formattingprivate async handleSmartSearchCocktails(args: SmartSearchCocktailsParams) { const startTime = Date.now(); try { // Parse natural language query if provided let enhancedArgs = { ...args }; if (args.query && typeof args.query === 'string') { const parsedQuery = QueryParser.parse(args.query); enhancedArgs = QueryParser.enhanceSearchArgs(args, parsedQuery); } // Check cache for search results const cacheKey = JSON.stringify(enhancedArgs); const cachedResult = this.cacheManager.getCachedSearch(cacheKey); if (cachedResult) { return cachedResult; } // Handle similarity queries first (by name or ID) if (enhancedArgs.similar_to || enhancedArgs.similar_to_id) { const result = await this.handleSimilaritySearch(enhancedArgs, startTime); // Cache similarity search results this.cacheManager.setCachedSearch(cacheKey, result); return result; } // Perform the main search const { results, searchType, appliedFilters } = await this.performCocktailSearch(enhancedArgs); // Build structured response const structuredData: ResponseSchemas.CocktailSearchResponse = { results: await this.fetchCompleteRecipes(results.slice(0, enhancedArgs.limit || 20)), query: { terms: enhancedArgs.query || undefined, filters: appliedFilters, search_type: searchType }, metadata: this.createResponseMetadata('bar_assistant_api', results.length, startTime) }; // Build human-readable response const humanText = this.formatSearchResultsText(structuredData, enhancedArgs); const result = this.createStructuredResponse(humanText, structuredData); // Cache regular search results this.cacheManager.setCachedSearch(cacheKey, result); return result; } catch (error) { const errorData: ResponseSchemas.ErrorResponse = { error: error instanceof Error ? error.message : String(error), error_code: 'SEARCH_ERROR', suggestions: [ 'Check your search criteria and try again', 'Try broader search terms', 'Remove some filters', 'Check ingredient spelling' ], query: args, metadata: this.createResponseMetadata('error', 0, startTime) }; const errorText = `# Smart Search Error\n\n` + `Sorry, I encountered an error while searching for cocktails.\n\n` + `**Error:** ${errorData.error}\n\n` + `**Suggestions:**\n${errorData.suggestions?.map(s => `• ${s}`).join('\n')}`; return this.createStructuredResponse(errorText, errorData); } }
- Helper method that performs the core cocktail search with filtering and returns structured results used by the main handlerprivate async performCocktailSearch(args: any) { // Build search parameters const searchParams: SearchCocktailsParams = { limit: args.limit || 20, }; let searchType = 'general'; const appliedFilters: Record<string, any> = {}; // Handle basic queries if (args.query) { searchParams.query = args.query; searchType = 'name'; appliedFilters.query = args.query; } if (args.ingredient) { searchParams.ingredient = args.ingredient; searchType = 'ingredient'; appliedFilters.ingredient = args.ingredient; } // Handle ABV filtering if (args.abv_min !== undefined) { searchParams.abv_min = args.abv_min; appliedFilters.abv_min = args.abv_min; } if (args.abv_max !== undefined) { searchParams.abv_max = args.abv_max; appliedFilters.abv_max = args.abv_max; } // Convert strength preferences to ABV ranges if (args.preferred_strength && !args.abv_min && !args.abv_max) { searchType = 'strength'; appliedFilters.preferred_strength = args.preferred_strength; switch (args.preferred_strength) { case 'light': searchParams.abv_max = 15; break; case 'medium': searchParams.abv_min = 15; searchParams.abv_max = 30; break; case 'strong': searchParams.abv_min = 30; break; } } // Handle flavor-based searches if (args.preferred_flavors?.length > 0) { searchType = 'flavor'; appliedFilters.preferred_flavors = args.preferred_flavors; if (!args.ingredient) { const flavorIngredientMap: { [key: string]: string } = { 'bitter': 'campari', 'sweet': 'vermouth', 'sour': 'lemon', 'herbal': 'chartreuse', 'spicy': 'ginger', }; for (const flavor of args.preferred_flavors) { if (flavorIngredientMap[flavor.toLowerCase()]) { searchParams.ingredient = flavorIngredientMap[flavor.toLowerCase()]; break; } } } } // Handle must_include ingredients if (args.must_include?.length > 0) { appliedFilters.must_include = args.must_include; if (!searchParams.ingredient) { searchParams.ingredient = args.must_include[0]; } } // Handle exclusions if (args.must_exclude?.length > 0) { appliedFilters.must_exclude = args.must_exclude; } // Glass and method filters if (args.glass_type) appliedFilters.glass_type = args.glass_type; if (args.preparation_method) appliedFilters.preparation_method = args.preparation_method; // Perform the search let results = await this.barClient.searchCocktails(searchParams); let filteredResults = results.data; // Apply post-search filtering filteredResults = this.applyAdvancedFilters(filteredResults, args); return { results: filteredResults, searchType, appliedFilters }; }