web_search_exa
Perform real-time web searches and scrape content from specific URLs using AI-powered retrieval. Configure result counts and access relevant website content for research or data extraction.
Instructions
Search the web using Exa AI - performs real-time web searches and can scrape content from specific URLs. Supports configurable result counts and returns the content from the most relevant websites.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| numResults | No | Number of search results to return (default: 5) | |
| query | Yes | Search query |
Implementation Reference
- src/tools/index.ts:206-215 (handler)Handler execution logic for the web_search_exa tool. Validates input with Zod schema, calls ExaClient.search(), formats results with formatSearchResults, and returns MCP-compatible response.case 'web_search_exa': { const params = webSearchSchema.parse(args); const results = await client.search(params); return { content: [{ type: "text", text: formatSearchResults(results) }] }; }
- src/tools/index.ts:18-33 (schema)Zod input validation schema for web_search_exa tool parameters.const webSearchSchema = z.object({ query: z.string().describe("Search query for finding information on the web"), num_results: z.number().optional().default(10).describe("Number of results to return (default: 10, max: 100)"), include_domains: z.array(z.string()).optional().describe("Only include results from these domains"), exclude_domains: z.array(z.string()).optional().describe("Exclude results from these domains"), start_crawl_date: z.string().optional().describe("Start date for crawled content (YYYY-MM-DD)"), end_crawl_date: z.string().optional().describe("End date for crawled content (YYYY-MM-DD)"), start_published_date: z.string().optional().describe("Start date for published content (YYYY-MM-DD)"), end_published_date: z.string().optional().describe("End date for published content (YYYY-MM-DD)"), use_autoprompt: z.boolean().optional().default(true).describe("Let Exa AI optimize the search query"), type: z.enum(['keyword', 'neural', 'magic']).optional().default('neural').describe("Search type: 'keyword' for exact match, 'neural' for semantic search, 'magic' for best results"), category: z.string().optional().describe("Filter by content category (news, blog, research, etc.)"), include_text: z.boolean().optional().default(false).describe("Include extracted text content from pages"), include_highlights: z.boolean().optional().default(false).describe("Include highlighted snippets from pages"), include_summary: z.boolean().optional().default(false).describe("Include AI-generated summaries of pages") });
- src/tools/index.ts:81-155 (registration)MCP Tool registration including name, description, and JSON inputSchema for web_search_exa.{ name: 'web_search_exa', description: 'Search the web using Exa AI for up-to-date information', inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query for finding information on the web" }, num_results: { type: "number", description: "Number of results to return (default: 10, max: 100)", default: 10 }, include_domains: { type: "array", items: { type: "string" }, description: "Only include results from these domains" }, exclude_domains: { type: "array", items: { type: "string" }, description: "Exclude results from these domains" }, start_crawl_date: { type: "string", description: "Start date for crawled content (YYYY-MM-DD)" }, end_crawl_date: { type: "string", description: "End date for crawled content (YYYY-MM-DD)" }, start_published_date: { type: "string", description: "Start date for published content (YYYY-MM-DD)" }, end_published_date: { type: "string", description: "End date for published content (YYYY-MM-DD)" }, use_autoprompt: { type: "boolean", description: "Let Exa AI optimize the search query", default: true }, type: { type: "string", enum: ["keyword", "neural", "magic"], description: "Search type: 'keyword' for exact match, 'neural' for semantic search, 'magic' for best results", default: "neural" }, category: { type: "string", description: "Filter by content category (news, blog, research, etc.)" }, include_text: { type: "boolean", description: "Include extracted text content from pages", default: false }, include_highlights: { type: "boolean", description: "Include highlighted snippets from pages", default: false }, include_summary: { type: "boolean", description: "Include AI-generated summaries of pages", default: false } }, required: ["query"] } },
- src/client.ts:23-72 (helper)Core search implementation in ExaClient that maps tool params to Exa JS SDK searchAndContents call and handles errors.async search(params: { query: string; num_results?: number; include_domains?: string[]; exclude_domains?: string[]; start_crawl_date?: string; end_crawl_date?: string; start_published_date?: string; end_published_date?: string; use_autoprompt?: boolean; type?: 'keyword' | 'neural' | 'magic'; category?: string; include_text?: boolean; include_highlights?: boolean; include_summary?: boolean; }) { try { const searchParams: any = { query: params.query, numResults: params.num_results || 10, useAutoprompt: params.use_autoprompt ?? true, type: params.type || 'neural' }; if (params.include_domains) searchParams.includeDomains = params.include_domains; if (params.exclude_domains) searchParams.excludeDomains = params.exclude_domains; if (params.start_crawl_date) searchParams.startCrawlDate = params.start_crawl_date; if (params.end_crawl_date) searchParams.endCrawlDate = params.end_crawl_date; if (params.start_published_date) searchParams.startPublishedDate = params.start_published_date; if (params.end_published_date) searchParams.endPublishedDate = params.end_published_date; if (params.category) searchParams.category = params.category; const searchResponse = await this.client.searchAndContents( searchParams.query, { ...searchParams, text: params.include_text ? { maxCharacters: 2000, includeHtmlTags: false } : undefined, highlights: params.include_highlights ? { numSentences: 3, highlightsPerUrl: 3 } : undefined, summary: params.include_summary ? { query: params.query } : undefined } ); return searchResponse.results; } catch (error) { throw new ExaError( error instanceof Error ? error.message : 'Failed to search', 'SEARCH_ERROR' ); } }