search
Search for gift cards, esims, mobile topups, and other products by query, country, and category. Optimize results using filters like language and pagination to streamline your shopping experience with cryptocurrencies.
Instructions
Search for gift cards, esims, mobile topups and more. It's suggested to use the categories tool before searching for products, to have a better understanding of what's available.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| beta_flags | No | Beta feature flags | |
| cart | No | Cart identifier | |
| category | No | Filter by category (e.g., 'gaming', 'entertainment') | |
| col | No | Column layout parameter | |
| country | No | Country code (e.g., 'US', 'IT', 'GB') | |
| do_recommend | No | Enable recommendations | |
| language | No | Language code for results (e.g., 'en') | |
| limit | No | Maximum number of results to return | |
| prefcc | No | Preferred country code parameter | |
| query | Yes | Search query (e.g., 'Amazon', 'Netflix', 'AT&T' or '*' for all the available products) | |
| rec | No | Recommendation parameter | |
| sec | No | Security parameter | |
| skip | No | Number of results to skip (for pagination) | |
| src | No | Source of the request |
Implementation Reference
- src/handlers/tools.ts:41-61 (handler)MCP tool handler function that executes the search by calling SearchService.search and returns formatted JSON text response or error.async (args) => { try { const searchResults = await SearchService.search(args.query, args); return { content: [ { type: "text" as const, text: JSON.stringify(searchResults, null, 2) } ] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: "text" as const, text: JSON.stringify({ error: errorMessage }, null, 2), }, ], isError: true, }; } }
- src/schemas/search.ts:9-24 (schema)Input schema definition (SearchOptions) for validating arguments to the search tool.export const SearchOptions = { query: z.string().describe("Search query (e.g., 'Amazon', 'Netflix', 'AT&T' or '*' for all the available products)"), country: z.string().optional().describe("Country code (e.g., 'US', 'IT', 'GB')"), language: z.string().optional().describe("Language code for results (e.g., 'en')"), limit: z.number().optional().describe("Maximum number of results to return"), skip: z.number().optional().describe("Number of results to skip (for pagination)"), category: z.string().optional().describe("Filter by category (e.g., 'gaming', 'entertainment')"), beta_flags: z.string().optional().describe("Beta feature flags"), cart: z.string().optional().describe("Cart identifier"), do_recommend: z.number().optional().describe("Enable recommendations"), rec: z.number().optional().describe("Recommendation parameter"), sec: z.number().optional().describe("Security parameter"), col: z.number().optional().describe("Column layout parameter"), prefcc: z.number().optional().describe("Preferred country code parameter"), src: z.string().optional().describe("Source of the request"), };
- src/handlers/tools.ts:37-62 (registration)Registration of the 'search' tool with the MCP server, specifying name, description, input schema, and handler.server.tool( "search", "Search for gift cards, esims, mobile topups and more. It's suggested to use the `categories` tool before searching for products, to have a better understanding of what's available.", SearchOptions, async (args) => { try { const searchResults = await SearchService.search(args.query, args); return { content: [ { type: "text" as const, text: JSON.stringify(searchResults, null, 2) } ] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: "text" as const, text: JSON.stringify({ error: errorMessage }, null, 2), }, ], isError: true, }; } } );
- src/services/search.ts:19-28 (helper)SearchService static method that validates options and delegates to publicApiClient.search.public static async search( query: string, options: Partial<SearchOptionsType> = {} ): Promise<SearchResults> { // Validate options const validatedOptions = SearchOptionsSchema.parse(options); // Use the public API client to perform the search return publicApiClient.search(query, validatedOptions); }
- src/utils/api/public.ts:37-65 (helper)Core implementation of search in PublicApiClient: builds query params for Bitrefill /omni endpoint, makes GET request, transforms response to standardized SearchResults.public async search( query: string, options: Partial<SearchOptionsType> = {} ): Promise<SearchResults> { // Build query parameters const params = new URLSearchParams({ q: query, limit: String(options.limit || 25), skip: String(options.skip || 0), src: "mcp", col: "1", prefcc: "1", }); // Add optional parameters if provided if (options.category) params.set("category", options.category); if (options.country) params.set("country", options.country); if (options.language) params.set("hl", options.language); // Use the endpoint with query parameters const endpoint = `omni?${params.toString()}`; const data = await this.makeRequest<BitrefillSearchResponse>( endpoint, { method: "GET" } ); return this.transformApiResponse(data, options); }