search_companies
Find companies in Autotask by name with optional filtering by active status and customizable result limits for efficient business management.
Instructions
Search for companies in Autotask with optional filters
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| isActive | No | Filter by active status | |
| pageSize | No | Number of results to return (default: 50, max: 200) | |
| searchTerm | No | Search term for company name |
Implementation Reference
- src/handlers/tool.handler.ts:53-76 (schema)MCP tool schema definition for 'search_companies', including input schema with optional searchTerm, isActive, and pageSize parameters.{ name: 'search_companies', description: 'Search for companies in Autotask with optional filters', inputSchema: { type: 'object', properties: { searchTerm: { type: 'string', description: 'Search term for company name' }, isActive: { type: 'boolean', description: 'Filter by active status' }, pageSize: { type: 'number', description: 'Number of results to return (default: 50, max: 200)', minimum: 1, maximum: 200 } }, required: [] } },
- src/handlers/tool.handler.ts:1076-1079 (handler)Handler logic in callTool method that executes the search_companies tool by calling AutotaskService.searchCompanies with input arguments.case 'search_companies': result = await this.autotaskService.searchCompanies(args); message = `Found ${result.length} companies`; break;
- Core implementation of company search logic, featuring default full pagination for accuracy or user-specified pageSize limit, using AutotaskClient.accounts.list API.async searchCompanies(options: AutotaskQueryOptions = {}): Promise<AutotaskCompany[]> { const client = await this.ensureClient(); try { this.logger.debug('Searching companies with options:', options); // PAGINATION BY DEFAULT for data accuracy // Only limit results when user explicitly provides pageSize if (options.pageSize !== undefined && options.pageSize > 0) { // User wants limited results const queryOptions = { ...options, pageSize: Math.min(options.pageSize, 500) // Respect user limit, max 500 per request }; this.logger.debug('Single page request with user-specified limit:', queryOptions); const result = await client.accounts.list(queryOptions as any); const companies = (result.data as AutotaskCompany[]) || []; this.logger.info(`Retrieved ${companies.length} companies (limited by user to ${options.pageSize})`); return companies; } else { // DEFAULT: Get ALL matching companies via pagination for complete accuracy const allCompanies: AutotaskCompany[] = []; const pageSize = 500; // Use max safe page size for efficiency let currentPage = 1; let hasMorePages = true; while (hasMorePages) { const queryOptions = { ...options, pageSize: pageSize, page: currentPage }; this.logger.debug(`Fetching companies page ${currentPage}...`); const result = await client.accounts.list(queryOptions as any); const companies = (result.data as AutotaskCompany[]) || []; if (companies.length === 0) { hasMorePages = false; } else { allCompanies.push(...companies); // Check if we got a full page - if not, we're done if (companies.length < pageSize) { hasMorePages = false; } else { currentPage++; } } // Safety check to prevent infinite loops if (currentPage > 50) { this.logger.warn('Company pagination safety limit reached at 50 pages (25,000 companies)'); hasMorePages = false; } } this.logger.info(`Retrieved ${allCompanies.length} companies across ${currentPage} pages (COMPLETE dataset for accuracy)`); return allCompanies; } } catch (error) { this.logger.error('Failed to search companies:', error); throw error; } }
- src/mcp/server.ts:64-134 (registration)MCP server registration of tool handlers: setRequestHandler for ListToolsRequestSchema and CallToolRequestSchema using toolHandler.listTools() and toolHandler.callTool() which include search_companies.private setupHandlers(): void { this.logger.info('Setting up MCP request handlers...'); // List available resources this.server.setRequestHandler(ListResourcesRequestSchema, async () => { try { this.logger.debug('Handling list resources request'); const resources = await this.resourceHandler.listResources(); return { resources }; } catch (error) { this.logger.error('Failed to list resources:', error); throw new McpError( ErrorCode.InternalError, `Failed to list resources: ${error instanceof Error ? error.message : 'Unknown error'}` ); } }); // Read a specific resource this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => { try { this.logger.debug(`Handling read resource request for: ${request.params.uri}`); const content = await this.resourceHandler.readResource(request.params.uri); return { contents: [content] }; } catch (error) { this.logger.error(`Failed to read resource ${request.params.uri}:`, error); throw new McpError( ErrorCode.InternalError, `Failed to read resource: ${error instanceof Error ? error.message : 'Unknown error'}` ); } }); // List available tools this.server.setRequestHandler(ListToolsRequestSchema, async () => { try { this.logger.debug('Handling list tools request'); const tools = await this.toolHandler.listTools(); return { tools }; } catch (error) { this.logger.error('Failed to list tools:', error); throw new McpError( ErrorCode.InternalError, `Failed to list tools: ${error instanceof Error ? error.message : 'Unknown error'}` ); } }); // Call a tool this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { this.logger.debug(`Handling tool call: ${request.params.name}`); const result = await this.toolHandler.callTool( request.params.name, request.params.arguments || {} ); return { content: result.content, isError: result.isError }; } catch (error) { this.logger.error(`Failed to call tool ${request.params.name}:`, error); throw new McpError( ErrorCode.InternalError, `Failed to call tool: ${error instanceof Error ? error.message : 'Unknown error'}` ); } }); this.logger.info('MCP request handlers set up successfully'); }