search_deals
Search for deals across multiple sources using text queries and filters like price, category, rating, and store to find specific products or offers.
Instructions
Search for deals across multiple sources based on text query and filters
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search query for deals (e.g., "gaming laptop", "iPhone", "kitchen appliances") | |
| category | No | Category filter (e.g., "electronics", "clothing", "home") | |
| minPrice | No | Minimum price filter | |
| maxPrice | No | Maximum price filter | |
| minRating | No | Minimum rating filter (0-5) | |
| store | No | Store/retailer filter (e.g., "amazon", "best buy") | |
| sortBy | No | Sort criteria | |
| sortOrder | No | Sort order | |
| limit | No | Maximum number of results (1-100) | |
| sources | No | Specific sources to search (e.g., ["slickdeals", "rapidapi"]) |
Implementation Reference
- src/server.ts:286-313 (handler)Main handler function for the 'search_deals' tool. Parses input arguments using SearchParamsSchema, calls aggregator.searchDeals, and returns a formatted JSON response with deal results.private async handleSearchDeals(args: any) { const params = SearchParamsSchema.parse(args); const deals = await this.aggregator.searchDeals(params); return { content: [ { type: 'text', text: JSON.stringify({ success: true, results: deals.length, deals: deals.map(deal => ({ id: deal.id, title: deal.title, price: deal.price, originalPrice: deal.originalPrice, discountPercentage: deal.discountPercentage, rating: deal.rating, store: deal.store, url: deal.url, source: deal.source, verified: deal.verified })) }, null, 2), }, ], }; }
- src/server.ts:124-178 (registration)Tool registration in getAvailableTools(), including name, description, and detailed inputSchema for MCP tool listing.{ name: 'search_deals', description: 'Search for deals across multiple sources based on text query and filters', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query for deals (e.g., "gaming laptop", "iPhone", "kitchen appliances")', }, category: { type: 'string', description: 'Category filter (e.g., "electronics", "clothing", "home")', }, minPrice: { type: 'number', description: 'Minimum price filter', }, maxPrice: { type: 'number', description: 'Maximum price filter', }, minRating: { type: 'number', description: 'Minimum rating filter (0-5)', }, store: { type: 'string', description: 'Store/retailer filter (e.g., "amazon", "best buy")', }, sortBy: { type: 'string', enum: ['price', 'rating', 'popularity', 'date'], description: 'Sort criteria', }, sortOrder: { type: 'string', enum: ['asc', 'desc'], description: 'Sort order', }, limit: { type: 'number', description: 'Maximum number of results (1-100)', minimum: 1, maximum: 100, }, sources: { type: 'array', items: { type: 'string' }, description: 'Specific sources to search (e.g., ["slickdeals", "rapidapi"])', }, }, required: ['query'], }, },
- src/types.ts:29-42 (schema)Zod schema definition for SearchParams used to validate and parse tool arguments in the handler.export const SearchParamsSchema = z.object({ query: z.string(), category: z.string().optional(), minPrice: z.number().optional(), maxPrice: z.number().optional(), minRating: z.number().optional(), store: z.string().optional(), sortBy: z.enum(['price', 'rating', 'popularity', 'date']).optional(), sortOrder: z.enum(['asc', 'desc']).optional(), limit: z.number().min(1).max(100).default(20), sources: z.array(z.string()).optional() }); export type SearchParams = z.infer<typeof SearchParamsSchema>;
- src/services/aggregator.ts:19-40 (helper)Core aggregator logic that parallelizes searches across selected providers, collects results, and applies sorting/filtering.async searchDeals(params: SearchParams): Promise<Deal[]> { const selectedProviders = params.sources && params.sources.length > 0 ? params.sources.filter((source: string) => this.providers.has(source)) : Array.from(this.providers.keys()); const searchPromises = selectedProviders.map(async (providerName: string) => { const provider = this.providers.get(providerName); if (!provider) return []; try { return await provider.searchDeals(params); } catch (error) { console.error(`Error searching deals from ${providerName}:`, error); return []; } }); const results = await Promise.all(searchPromises); const allDeals = results.flat(); return this.sortAndFilterDeals(allDeals, params); }