search_companies
Search for companies by name or ticker symbol across multiple stock exchanges to identify matching entities for financial analysis.
Instructions
Find companies by partial name or ticker on an exchange and return best matches
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| stockExchange | Yes | Stock exchange: amex, nasdaq, nyse, us-all, lse, moex, bist, hkex | |
| year | No | ||
| month | No | ||
| day | No | ||
| query | Yes | Search term (partial ticker or company name) | |
| limit | No | Maximum results |
Implementation Reference
- src/core.ts:426-479 (handler)Handler function for 'search_companies' tool: fetches market data for the specified exchange and date, filters companies matching the query using calculateMatchScore, sorts by score descending, limits results, and returns formatted response.async ({ stockExchange, year, month, day, query, limit, }: { stockExchange: StockExchange; year?: number; month?: number; day?: number; query: string; limit?: number; }) => { try { const formattedDate = getDate(year, month, day); const marketDataResponse = await fetchMarketData( stockExchange, formattedDate, ); const searchTerm = query.toLowerCase(); const matches = marketDataResponse.securities.data .filter( (item: any[]) => item[INDICES.TYPE] !== "sector" && item[INDICES.SECTOR], ) .map((item: any[]) => ({ ticker: item[INDICES.TICKER], name: item[INDICES.NAME_ENG], sector: item[INDICES.SECTOR], score: calculateMatchScore( item[INDICES.TICKER], item[INDICES.NAME_ENG], searchTerm, ), })) .filter((match) => match.score > 0) .sort((a, b) => b.score - a.score) .slice(0, limit); return createResponse({ info: INFO, date: formattedDate, exchange: stockExchange.toUpperCase(), currency: EXCHANGE_INFO[stockExchange as StockExchange].currency, query, matches, }); } catch (error) { return createErrorResponse(error); } },
- src/core.ts:411-424 (schema)Input schema for 'search_companies' tool defining parameters: stockExchange, optional date components (year, month, day), required query string, optional limit (1-50, default 10).inputSchema: { stockExchange: exchangeSchema, ...dateSchema, query: z .string() .describe("Search term (partial ticker or company name)"), limit: z .number() .int() .min(1) .max(50) .default(10) .describe("Maximum results"), },
- src/core.ts:405-480 (registration)Full registration of the 'search_companies' MCP tool including name, title, description, input schema, and handler function.server.registerTool( "search_companies", { title: "Search companies", description: "Find companies by partial name or ticker on an exchange and return best matches", inputSchema: { stockExchange: exchangeSchema, ...dateSchema, query: z .string() .describe("Search term (partial ticker or company name)"), limit: z .number() .int() .min(1) .max(50) .default(10) .describe("Maximum results"), }, }, async ({ stockExchange, year, month, day, query, limit, }: { stockExchange: StockExchange; year?: number; month?: number; day?: number; query: string; limit?: number; }) => { try { const formattedDate = getDate(year, month, day); const marketDataResponse = await fetchMarketData( stockExchange, formattedDate, ); const searchTerm = query.toLowerCase(); const matches = marketDataResponse.securities.data .filter( (item: any[]) => item[INDICES.TYPE] !== "sector" && item[INDICES.SECTOR], ) .map((item: any[]) => ({ ticker: item[INDICES.TICKER], name: item[INDICES.NAME_ENG], sector: item[INDICES.SECTOR], score: calculateMatchScore( item[INDICES.TICKER], item[INDICES.NAME_ENG], searchTerm, ), })) .filter((match) => match.score > 0) .sort((a, b) => b.score - a.score) .slice(0, limit); return createResponse({ info: INFO, date: formattedDate, exchange: stockExchange.toUpperCase(), currency: EXCHANGE_INFO[stockExchange as StockExchange].currency, query, matches, }); } catch (error) { return createErrorResponse(error); } }, );
- src/core.ts:101-115 (helper)Helper function to compute a match score (0-100) for a search term against a stock ticker and company name, prioritizing exact ticker match, prefix, contains, then name contains.function calculateMatchScore( ticker: string, name: string, searchTerm: string, ): number { const tickerLower = ticker.toLowerCase(); const nameLower = name.toLowerCase(); if (tickerLower === searchTerm) return 100; if (tickerLower.startsWith(searchTerm)) return 90; if (tickerLower.includes(searchTerm)) return 80; if (nameLower.includes(searchTerm)) return 70; return 0; }