bulk_search
Check availability for multiple domain names simultaneously. Search up to 100 domains in parallel to verify registration status and compare pricing across registrars.
Instructions
Check availability for multiple domain names at once.
Efficiently searches up to 100 domains in parallel with rate limiting. Use a single TLD for best performance.
Returns:
Availability status for each domain
Pricing where available
Summary statistics
Example:
bulk_search(["vibecoding", "myapp", "coolstartup"], "io")
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| domains | Yes | List of domain names to check. Don't include extensions. Max 100. | |
| tld | No | TLD to check for all domains (e.g., 'com'). Defaults to 'com'. | |
| registrar | No | Optional: specific registrar to use. |
Implementation Reference
- src/tools/bulk_search.ts:95-142 (handler)executeBulkSearch: Main handler function for bulk_search tool. Parses input, executes bulk domain search, computes statistics and insights, handles errors.export async function executeBulkSearch( input: BulkSearchInput, ): Promise<BulkSearchResponse> { try { const { domains, tld, registrar } = bulkSearchSchema.parse(input); const results = await bulkSearchDomains(domains, tld, registrar); const available = results.filter((r) => r.available); const taken = results.filter((r) => !r.available); const insights: string[] = []; if (available.length > 0) { insights.push( `✅ ${available.length} of ${domains.length} domains available`, ); const cheapest = available .filter((r) => r.price_first_year !== null) .sort((a, b) => a.price_first_year! - b.price_first_year!)[0]; if (cheapest) { insights.push( `💰 Best price: ${cheapest.domain} at $${cheapest.price_first_year}/year`, ); } } else { insights.push(`❌ All ${domains.length} domains are taken`); insights.push( '💡 Try different variations or alternative TLDs', ); } return { results, summary: { total: domains.length, available: available.length, taken: taken.length, errors: domains.length - results.length, }, insights, }; } catch (error) { throw wrapError(error); } }
- src/tools/bulk_search.ts:16-35 (schema)bulkSearchSchema: Zod validation schema for bulk_search input (domains array, optional tld and registrar).export const bulkSearchSchema = z.object({ domains: z .array(z.string()) .min(1) .max(100) .describe( "List of domain names to check (e.g., ['vibecoding', 'myapp', 'coolstartup']). Max 100 domains.", ), tld: z .string() .optional() .default('com') .describe("Single TLD to check for all domains (e.g., 'com'). Defaults to 'com'."), registrar: z .string() .optional() .describe( "Optional: specific registrar to use (e.g., 'porkbun'). Leave empty for fastest source.", ), });
- src/server.ts:58-66 (registration)Server TOOLS array registering bulkSearchTool among other tools for MCP server.const TOOLS: Tool[] = [ searchDomainTool as Tool, bulkSearchTool as Tool, compareRegistrarsTool as Tool, suggestDomainsTool as Tool, suggestDomainsSmartTool as Tool, tldInfoTool as Tool, checkSocialsTool as Tool, ];
- src/server.ts:170-175 (registration)executeToolCall switch case dispatching 'bulk_search' tool calls to executeBulkSearch handler.case 'bulk_search': return executeBulkSearch({ domains: args.domains as string[], tld: (args.tld as string) || 'com', registrar: args.registrar as string | undefined, });
- bulkSearchDomains: Core helper function implementing batched concurrent domain availability checks using searchSingleDomain.export async function bulkSearchDomains( domains: string[], tld: string = 'com', registrar?: string, maxConcurrent: number = 5, ): Promise<DomainResult[]> { const startTime = Date.now(); const results: DomainResult[] = []; logger.info('Bulk search started', { count: domains.length, tld, registrar, }); // Process in batches for (let i = 0; i < domains.length; i += maxConcurrent) { const batch = domains.slice(i, i + maxConcurrent); const batchPromises = batch.map(async (domain) => { try { const normalizedDomain = validateDomainName(domain); const { result } = await searchSingleDomain( normalizedDomain, tld, registrar ? [registrar] : undefined, ); return result; } catch (error) { logger.warn(`Failed to check ${domain}.${tld}`, { error: error instanceof Error ? error.message : String(error), }); return null; } }); const batchResults = await Promise.all(batchPromises); for (const result of batchResults) { if (result) results.push(result); } } const duration = Date.now() - startTime; logger.info('Bulk search completed', { checked: domains.length, results: results.length, duration_ms: duration, }); return results; }