autotask_search_contacts
Search contacts by name, email, or company ID. Optionally filter by active status and page size (max 200).
Instructions
Search contacts by name, email, or company. Max 200/page.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| searchTerm | No | Search term for contact name or email | |
| companyID | No | Filter by company ID | |
| isActive | No | Filter by active status (1=active, 0=inactive) | |
| page | No | ||
| pageSize | No | Max 200 |
Implementation Reference
- src/handlers/tool.handler.ts:797-799 (handler)Dispatch handler for 'autotask_search_contacts' - calls searchContacts on the AutotaskService
['autotask_search_contacts', async (a) => { const r = await s.searchContacts(a); return { result: r, message: `Found ${r.length} contacts` }; }], - Schema/definition for 'autotask_search_contacts' tool with input parameters (searchTerm, companyID, isActive, page, pageSize)
{ name: 'autotask_search_contacts', description: 'Search contacts by name, email, or company. Max 200/page.', inputSchema: { type: 'object', properties: { searchTerm: { type: 'string', description: 'Search term for contact name or email' }, companyID: { type: 'number', description: 'Filter by company ID' }, isActive: { type: 'number', description: 'Filter by active status (1=active, 0=inactive)' }, page: { type: 'number', minimum: 1 }, pageSize: { type: 'number', description: 'Max 200', minimum: 1, maximum: 200 } }, required: [] } }, - The actual service method that performs the Autotask API query to search contacts, building filters for searchTerm (firstName/lastName/email OR), companyID, and isActive
async searchContacts(options: AutotaskQueryOptions = {}): Promise<AutotaskContact[]> { const http = await this.ensureClient(); try { this.logger.debug('Searching contacts with options:', options); const filters: QueryFilter[] = []; if (options.searchTerm) { filters.push({ op: 'or', items: [ { op: 'contains', field: 'firstName', value: options.searchTerm }, { op: 'contains', field: 'lastName', value: options.searchTerm }, { op: 'contains', field: 'emailAddress', value: options.searchTerm } ] }); } if (options.companyID !== undefined) { filters.push({ op: 'eq', field: 'companyID', value: options.companyID }); } if (options.isActive !== undefined) { filters.push({ op: 'eq', field: 'isActive', value: options.isActive }); } const pageSize = Math.min(options.pageSize || 25, 200); const contacts = await http.query<AutotaskContact>( 'Contacts', filters.length > 0 ? filters : MATCH_ALL, { maxRecords: pageSize } ); this.logger.info(`Retrieved ${contacts.length} contacts (pageSize ${pageSize})`); return contacts; } catch (error) { this.logger.error('Failed to search contacts:', error); throw error; } } - src/types/autotask.ts:23-34 (helper)Type definition for AutotaskContact used by the searchContacts method
export interface AutotaskContact { id?: number; companyID?: number; firstName?: string; lastName?: string; emailAddress?: string; phone?: string; title?: string; isActive?: number; // Note: autotask-node uses number, not boolean createDate?: string; lastModifiedDate?: string; [key: string]: any; - src/mcp/server.ts:171-184 (registration)Registration of tools with the MCP server - calls toolHandler.listTools() and toolHandler.callTool()
// List available tools server.setRequestHandler(ListToolsRequestSchema, async () => { try { this.logger.debug('Handling list tools request'); const tools = await 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'}` ); } });