Skip to main content
Glama

company_research_exa

Analyze companies by retrieving comprehensive data on operations, financials, news, and industry insights. Ideal for researching businesses and organizations with precise, actionable results.

Instructions

Research companies using Exa AI - finds comprehensive information about businesses, organizations, and corporations. Provides insights into company operations, news, financial information, and industry analysis.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
companyNameYesName of the company to research
numResultsNoNumber of search results to return (default: 5)

Implementation Reference

  • Registration of the 'company_research' tool, which performs company research using the Exa AI API. This matches the 'company_research_exa' tool.
    toolRegistry["company_research"] = { name: "company_research", description: "Research companies using Exa AI - performs targeted searches of company websites to gather comprehensive information about businesses. Returns detailed information from company websites including about pages, pricing, FAQs, blogs, and other relevant content. Specify the company URL and optionally target specific sections of their website.", schema: { query: z.string().describe("Company website URL (e.g., 'exa.ai' or 'https://exa.ai')"), subpages: z.number().optional().describe("Number of subpages to crawl (default: 10)"), subpageTarget: z.array(z.string()).optional().describe("Specific sections to target (e.g., ['about', 'pricing', 'faq', 'blog']). If not provided, will crawl the most relevant pages.") }, handler: async ({ query, numResults, subpages, subpageTarget }, extra) => { const requestId = `company_research-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`; const logger = createRequestLogger(requestId, 'company_research'); logger.start(query); try { // Create a fresh axios instance for each request const axiosInstance = axios.create({ baseURL: API_CONFIG.BASE_URL, headers: { 'accept': 'application/json', 'content-type': 'application/json', 'x-api-key': process.env.EXA_API_KEY || '' }, timeout: 25000 }); // Extract domain from query if it's a URL let domain = query; if (query.includes('http')) { try { const url = new URL(query); domain = url.hostname.replace('www.', ''); } catch (e) { logger.log(`Warning: Could not parse URL from query: ${query}`); } } const searchRequest: ExaSearchRequest = { query, category: "company", includeDomains: [query], type: "auto", numResults: 1, contents: { text: { maxCharacters: API_CONFIG.DEFAULT_MAX_CHARACTERS }, livecrawl: 'always', subpages: subpages || 10, } }; // Add subpage targets if provided if (subpageTarget && subpageTarget.length > 0) { searchRequest.contents.subpageTarget = subpageTarget; logger.log(`Targeting specific sections: ${subpageTarget.join(', ')}`); } logger.log(`Researching company: ${domain}`); logger.log("Sending company research request to Exa API"); const response = await axiosInstance.post<ExaSearchResponse>( API_CONFIG.ENDPOINTS.SEARCH, searchRequest, { timeout: 25000 } ); logger.log("Received company research response from Exa API"); if (!response.data || !response.data.results) { logger.log("Warning: Empty or invalid response from Exa API for company research"); return { content: [{ type: "text" as const, text: "No company information found. Please try a different query." }] }; } logger.log(`Found ${response.data.results.length} results about the company`); const result = { content: [{ type: "text" as const, text: JSON.stringify(response.data, null, 2) }] }; logger.complete(); return result; } catch (error) { logger.error(error); if (axios.isAxiosError(error)) { // Handle Axios errors specifically const statusCode = error.response?.status || 'unknown'; const errorMessage = error.response?.data?.message || error.message; logger.log(`Axios error (${statusCode}): ${errorMessage}`); return { content: [{ type: "text" as const, text: `Company research error (${statusCode}): ${errorMessage}` }], isError: true, }; } // Handle generic errors return { content: [{ type: "text" as const, text: `Company research error: ${error instanceof Error ? error.message : String(error)}` }], isError: true, }; } }, enabled: false // Disabled by default };
  • The handler function executes company research by querying the Exa AI search API, targeting company websites and subpages.
    handler: async ({ query, numResults, subpages, subpageTarget }, extra) => { const requestId = `company_research-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`; const logger = createRequestLogger(requestId, 'company_research'); logger.start(query); try { // Create a fresh axios instance for each request const axiosInstance = axios.create({ baseURL: API_CONFIG.BASE_URL, headers: { 'accept': 'application/json', 'content-type': 'application/json', 'x-api-key': process.env.EXA_API_KEY || '' }, timeout: 25000 }); // Extract domain from query if it's a URL let domain = query; if (query.includes('http')) { try { const url = new URL(query); domain = url.hostname.replace('www.', ''); } catch (e) { logger.log(`Warning: Could not parse URL from query: ${query}`); } } const searchRequest: ExaSearchRequest = { query, category: "company", includeDomains: [query], type: "auto", numResults: 1, contents: { text: { maxCharacters: API_CONFIG.DEFAULT_MAX_CHARACTERS }, livecrawl: 'always', subpages: subpages || 10, } }; // Add subpage targets if provided if (subpageTarget && subpageTarget.length > 0) { searchRequest.contents.subpageTarget = subpageTarget; logger.log(`Targeting specific sections: ${subpageTarget.join(', ')}`); } logger.log(`Researching company: ${domain}`); logger.log("Sending company research request to Exa API"); const response = await axiosInstance.post<ExaSearchResponse>( API_CONFIG.ENDPOINTS.SEARCH, searchRequest, { timeout: 25000 } ); logger.log("Received company research response from Exa API"); if (!response.data || !response.data.results) { logger.log("Warning: Empty or invalid response from Exa API for company research"); return { content: [{ type: "text" as const, text: "No company information found. Please try a different query." }] }; } logger.log(`Found ${response.data.results.length} results about the company`); const result = { content: [{ type: "text" as const, text: JSON.stringify(response.data, null, 2) }] }; logger.complete(); return result; } catch (error) { logger.error(error); if (axios.isAxiosError(error)) { // Handle Axios errors specifically const statusCode = error.response?.status || 'unknown'; const errorMessage = error.response?.data?.message || error.message; logger.log(`Axios error (${statusCode}): ${errorMessage}`); return { content: [{ type: "text" as const, text: `Company research error (${statusCode}): ${errorMessage}` }], isError: true, }; } // Handle generic errors return { content: [{ type: "text" as const, text: `Company research error: ${error instanceof Error ? error.message : String(error)}` }], isError: true, }; } },
  • Zod schema defining input parameters for the company_research tool.
    schema: { query: z.string().describe("Company website URL (e.g., 'exa.ai' or 'https://exa.ai')"), subpages: z.number().optional().describe("Number of subpages to crawl (default: 10)"), subpageTarget: z.array(z.string()).optional().describe("Specific sections to target (e.g., ['about', 'pricing', 'faq', 'blog']). If not provided, will crawl the most relevant pages.") },
  • Type definitions for ExaSearchRequest and ExaSearchResponse used by the company_research tool.
    export interface ExaSearchRequest { query: string; type: string; category?: string; includeDomains?: string[]; excludeDomains?: string[]; startPublishedDate?: string; endPublishedDate?: string; numResults: number; contents: { text: { maxCharacters?: number; } | boolean; livecrawl?: 'always' | 'fallback'; subpages?: number; subpageTarget?: string[]; }; } export interface ExaCrawlRequest { ids: string[]; text: boolean; livecrawl?: 'always' | 'fallback'; } export interface ExaSearchResult { id: string; title: string; url: string; publishedDate: string; author: string; text: string; image?: string; favicon?: string; score?: number; } export interface ExaSearchResponse { requestId: string; autopromptString: string; resolvedSearchType: string; results: ExaSearchResult[]; }
  • API configuration for Exa.ai endpoints and defaults used in the company_research handler.
    export const API_CONFIG = { BASE_URL: 'https://api.exa.ai', ENDPOINTS: { SEARCH: '/search' }, DEFAULT_NUM_RESULTS: 5, DEFAULT_MAX_CHARACTERS: 3000 } as const;

Other Tools

Related Tools

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/jackedelic/exa-mcp-server'

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