Skip to main content
Glama
zhdenny

Bar Assistant MCP Server

by zhdenny

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

TableJSON Schema
NameRequiredDescriptionDefault
queryNoπŸ” Natural language search query (e.g., "Negroni", "gin cocktails", "bitter drinks")
similar_toNoπŸ”„ Find cocktails similar to this name (e.g., "Manhattan", "Negroni"). Triggers similarity batch processing.
similar_to_idNoπŸ†” Find cocktails similar to this ID. Use similar_to (by name) unless you have the specific ID.
ingredientNoπŸ₯ƒ Primary ingredient filter (e.g., "gin", "whiskey", "campari"). Combines with other filters for batch processing.
must_includeNoβœ… Required ingredients array. Batch processes cocktails containing ALL these ingredients.
must_excludeNo❌ Excluded ingredients array. Filters out cocktails with ANY of these ingredients.
preferred_flavorsNo🎯 Flavor profile preferences: ["bitter", "sweet", "sour", "spicy", "herbal"]. Improves batch ranking.
preferred_strengthNoπŸ’ͺ Alcohol strength preference. Filters batch results by ABV ranges.
abv_minNoπŸ“Š Minimum ABV percentage. Lower bound for batch filtering.
abv_maxNoπŸ“Š Maximum ABV percentage. Upper bound for batch filtering.
glass_typeNoπŸ₯‚ Required glassware (e.g., "coupe", "rocks", "martini"). Filters entire batch.
preparation_methodNoπŸ”§ Required method (e.g., "shake", "stir", "build"). Filters batch by technique.
limitNoπŸŽ›οΈ Maximum results to return (default: 20, max: 50). Controls batch size for optimal performance.

Implementation Reference

  • Type definition for input parameters of the smart_search_cocktails tool
    export 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;
    }
  • Tool registration in ListToolsRequestSchema handler, defining name, description, inputSchema, and outputSchema
                name: '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' }
                      }
                    }
                  }
                },
              },
  • Dispatch to handler in CallToolRequestSchema switch statement
    case '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 formatting
    private 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 handler
    private 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
      };
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zhdenny/bar-assistant-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server