UNPKG

ghl-mcp-server

Version:

GoHighLevel MCP Server for Claude Desktop and ChatGPT integration

805 lines (804 loc) 35.3 kB
"use strict"; /** * GoHighLevel Contact Tools * Implements all contact management functionality for the MCP server */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ContactTools = void 0; /** * Contact Tools class * Provides comprehensive contact management capabilities */ class ContactTools { ghlClient; constructor(ghlClient) { this.ghlClient = ghlClient; } /** * Get tool definitions for all contact operations */ getToolDefinitions() { return [ // Basic Contact Management { name: 'create_contact', description: 'Create a new contact in GoHighLevel', inputSchema: { type: 'object', properties: { firstName: { type: 'string', description: 'Contact first name' }, lastName: { type: 'string', description: 'Contact last name' }, email: { type: 'string', description: 'Contact email address' }, phone: { type: 'string', description: 'Contact phone number' }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags to assign to contact' }, source: { type: 'string', description: 'Source of the contact' } }, required: ['email'] } }, { name: 'search_contacts', description: 'Search for contacts with advanced filtering options', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query string' }, email: { type: 'string', description: 'Filter by email address' }, phone: { type: 'string', description: 'Filter by phone number' }, limit: { type: 'number', description: 'Maximum number of results (default: 25)' } } } }, { name: 'get_contact', description: 'Get detailed information about a specific contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' } }, required: ['contactId'] } }, { name: 'update_contact', description: 'Update contact information', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, firstName: { type: 'string', description: 'Contact first name' }, lastName: { type: 'string', description: 'Contact last name' }, email: { type: 'string', description: 'Contact email address' }, phone: { type: 'string', description: 'Contact phone number' }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags to assign to contact' } }, required: ['contactId'] } }, { name: 'delete_contact', description: 'Delete a contact from GoHighLevel', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' } }, required: ['contactId'] } }, { name: 'add_contact_tags', description: 'Add tags to a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags to add' } }, required: ['contactId', 'tags'] } }, { name: 'remove_contact_tags', description: 'Remove tags from a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags to remove' } }, required: ['contactId', 'tags'] } }, // Task Management { name: 'get_contact_tasks', description: 'Get all tasks for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' } }, required: ['contactId'] } }, { name: 'create_contact_task', description: 'Create a new task for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, title: { type: 'string', description: 'Task title' }, body: { type: 'string', description: 'Task description' }, dueDate: { type: 'string', description: 'Due date (ISO format)' }, completed: { type: 'boolean', description: 'Task completion status' }, assignedTo: { type: 'string', description: 'User ID to assign task to' } }, required: ['contactId', 'title', 'dueDate'] } }, { name: 'get_contact_task', description: 'Get a specific task for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, taskId: { type: 'string', description: 'Task ID' } }, required: ['contactId', 'taskId'] } }, { name: 'update_contact_task', description: 'Update a task for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, taskId: { type: 'string', description: 'Task ID' }, title: { type: 'string', description: 'Task title' }, body: { type: 'string', description: 'Task description' }, dueDate: { type: 'string', description: 'Due date (ISO format)' }, completed: { type: 'boolean', description: 'Task completion status' }, assignedTo: { type: 'string', description: 'User ID to assign task to' } }, required: ['contactId', 'taskId'] } }, { name: 'delete_contact_task', description: 'Delete a task for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, taskId: { type: 'string', description: 'Task ID' } }, required: ['contactId', 'taskId'] } }, { name: 'update_task_completion', description: 'Update task completion status', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, taskId: { type: 'string', description: 'Task ID' }, completed: { type: 'boolean', description: 'Completion status' } }, required: ['contactId', 'taskId', 'completed'] } }, // Note Management { name: 'get_contact_notes', description: 'Get all notes for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' } }, required: ['contactId'] } }, { name: 'create_contact_note', description: 'Create a new note for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, body: { type: 'string', description: 'Note content' }, userId: { type: 'string', description: 'User ID creating the note' } }, required: ['contactId', 'body'] } }, { name: 'get_contact_note', description: 'Get a specific note for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, noteId: { type: 'string', description: 'Note ID' } }, required: ['contactId', 'noteId'] } }, { name: 'update_contact_note', description: 'Update a note for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, noteId: { type: 'string', description: 'Note ID' }, body: { type: 'string', description: 'Note content' }, userId: { type: 'string', description: 'User ID updating the note' } }, required: ['contactId', 'noteId', 'body'] } }, { name: 'delete_contact_note', description: 'Delete a note for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, noteId: { type: 'string', description: 'Note ID' } }, required: ['contactId', 'noteId'] } }, // Advanced Contact Operations { name: 'upsert_contact', description: 'Create or update contact based on email/phone (smart merge)', inputSchema: { type: 'object', properties: { firstName: { type: 'string', description: 'Contact first name' }, lastName: { type: 'string', description: 'Contact last name' }, email: { type: 'string', description: 'Contact email address' }, phone: { type: 'string', description: 'Contact phone number' }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags to assign to contact' }, source: { type: 'string', description: 'Source of the contact' }, assignedTo: { type: 'string', description: 'User ID to assign contact to' } } } }, { name: 'get_duplicate_contact', description: 'Check for duplicate contacts by email or phone', inputSchema: { type: 'object', properties: { email: { type: 'string', description: 'Email to check for duplicates' }, phone: { type: 'string', description: 'Phone to check for duplicates' } } } }, { name: 'get_contacts_by_business', description: 'Get contacts associated with a specific business', inputSchema: { type: 'object', properties: { businessId: { type: 'string', description: 'Business ID' }, limit: { type: 'number', description: 'Maximum number of results' }, skip: { type: 'number', description: 'Number of results to skip' }, query: { type: 'string', description: 'Search query' } }, required: ['businessId'] } }, { name: 'get_contact_appointments', description: 'Get all appointments for a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' } }, required: ['contactId'] } }, // Bulk Operations { name: 'bulk_update_contact_tags', description: 'Bulk add or remove tags from multiple contacts', inputSchema: { type: 'object', properties: { contactIds: { type: 'array', items: { type: 'string' }, description: 'Array of contact IDs' }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags to add or remove' }, operation: { type: 'string', enum: ['add', 'remove'], description: 'Operation to perform' }, removeAllTags: { type: 'boolean', description: 'Remove all existing tags before adding new ones' } }, required: ['contactIds', 'tags', 'operation'] } }, { name: 'bulk_update_contact_business', description: 'Bulk update business association for multiple contacts', inputSchema: { type: 'object', properties: { contactIds: { type: 'array', items: { type: 'string' }, description: 'Array of contact IDs' }, businessId: { type: 'string', description: 'Business ID (null to remove from business)' } }, required: ['contactIds'] } }, // Followers Management { name: 'add_contact_followers', description: 'Add followers to a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, followers: { type: 'array', items: { type: 'string' }, description: 'Array of user IDs to add as followers' } }, required: ['contactId', 'followers'] } }, { name: 'remove_contact_followers', description: 'Remove followers from a contact', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, followers: { type: 'array', items: { type: 'string' }, description: 'Array of user IDs to remove as followers' } }, required: ['contactId', 'followers'] } }, // Campaign Management { name: 'add_contact_to_campaign', description: 'Add contact to a marketing campaign', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, campaignId: { type: 'string', description: 'Campaign ID' } }, required: ['contactId', 'campaignId'] } }, { name: 'remove_contact_from_campaign', description: 'Remove contact from a specific campaign', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, campaignId: { type: 'string', description: 'Campaign ID' } }, required: ['contactId', 'campaignId'] } }, { name: 'remove_contact_from_all_campaigns', description: 'Remove contact from all campaigns', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' } }, required: ['contactId'] } }, // Workflow Management { name: 'add_contact_to_workflow', description: 'Add contact to a workflow', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, workflowId: { type: 'string', description: 'Workflow ID' }, eventStartTime: { type: 'string', description: 'Event start time (ISO format)' } }, required: ['contactId', 'workflowId'] } }, { name: 'remove_contact_from_workflow', description: 'Remove contact from a workflow', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'Contact ID' }, workflowId: { type: 'string', description: 'Workflow ID' }, eventStartTime: { type: 'string', description: 'Event start time (ISO format)' } }, required: ['contactId', 'workflowId'] } } ]; } /** * Execute a contact tool with the given parameters */ async executeTool(toolName, params) { try { switch (toolName) { // Basic Contact Management case 'create_contact': return await this.createContact(params); case 'search_contacts': return await this.searchContacts(params); case 'get_contact': return await this.getContact(params.contactId); case 'update_contact': return await this.updateContact(params); case 'delete_contact': return await this.deleteContact(params.contactId); case 'add_contact_tags': return await this.addContactTags(params); case 'remove_contact_tags': return await this.removeContactTags(params); // Task Management case 'get_contact_tasks': return await this.getContactTasks(params); case 'create_contact_task': return await this.createContactTask(params); case 'get_contact_task': return await this.getContactTask(params); case 'update_contact_task': return await this.updateContactTask(params); case 'delete_contact_task': return await this.deleteContactTask(params); case 'update_task_completion': return await this.updateTaskCompletion(params); // Note Management case 'get_contact_notes': return await this.getContactNotes(params); case 'create_contact_note': return await this.createContactNote(params); case 'get_contact_note': return await this.getContactNote(params); case 'update_contact_note': return await this.updateContactNote(params); case 'delete_contact_note': return await this.deleteContactNote(params); // Advanced Operations case 'upsert_contact': return await this.upsertContact(params); case 'get_duplicate_contact': return await this.getDuplicateContact(params); case 'get_contacts_by_business': return await this.getContactsByBusiness(params); case 'get_contact_appointments': return await this.getContactAppointments(params); // Bulk Operations case 'bulk_update_contact_tags': return await this.bulkUpdateContactTags(params); case 'bulk_update_contact_business': return await this.bulkUpdateContactBusiness(params); // Followers Management case 'add_contact_followers': return await this.addContactFollowers(params); case 'remove_contact_followers': return await this.removeContactFollowers(params); // Campaign Management case 'add_contact_to_campaign': return await this.addContactToCampaign(params); case 'remove_contact_from_campaign': return await this.removeContactFromCampaign(params); case 'remove_contact_from_all_campaigns': return await this.removeContactFromAllCampaigns(params); // Workflow Management case 'add_contact_to_workflow': return await this.addContactToWorkflow(params); case 'remove_contact_from_workflow': return await this.removeContactFromWorkflow(params); default: throw new Error(`Unknown tool: ${toolName}`); } } catch (error) { console.error(`Error executing contact tool ${toolName}:`, error); throw error; } } // Implementation methods... // Basic Contact Management async createContact(params) { const response = await this.ghlClient.createContact({ locationId: this.ghlClient.getConfig().locationId, firstName: params.firstName, lastName: params.lastName, email: params.email, phone: params.phone, tags: params.tags, source: params.source }); if (!response.success) { throw new Error(response.error?.message || 'Failed to create contact'); } return response.data; } async searchContacts(params) { const response = await this.ghlClient.searchContacts({ locationId: this.ghlClient.getConfig().locationId, query: params.query, limit: params.limit, filters: { ...(params.email && { email: params.email }), ...(params.phone && { phone: params.phone }) } }); if (!response.success) { throw new Error(response.error?.message || 'Failed to search contacts'); } return response.data; } async getContact(contactId) { const response = await this.ghlClient.getContact(contactId); if (!response.success) { throw new Error(response.error?.message || 'Failed to get contact'); } return response.data; } async updateContact(params) { const response = await this.ghlClient.updateContact(params.contactId, { firstName: params.firstName, lastName: params.lastName, email: params.email, phone: params.phone, tags: params.tags }); if (!response.success) { throw new Error(response.error?.message || 'Failed to update contact'); } return response.data; } async deleteContact(contactId) { const response = await this.ghlClient.deleteContact(contactId); if (!response.success) { throw new Error(response.error?.message || 'Failed to delete contact'); } return response.data; } async addContactTags(params) { const response = await this.ghlClient.addContactTags(params.contactId, params.tags); if (!response.success) { throw new Error(response.error?.message || 'Failed to add contact tags'); } return response.data; } async removeContactTags(params) { const response = await this.ghlClient.removeContactTags(params.contactId, params.tags); if (!response.success) { throw new Error(response.error?.message || 'Failed to remove contact tags'); } return response.data; } // Task Management async getContactTasks(params) { const response = await this.ghlClient.getContactTasks(params.contactId); if (!response.success) { throw new Error(response.error?.message || 'Failed to get contact tasks'); } return response.data; } async createContactTask(params) { const response = await this.ghlClient.createContactTask(params.contactId, { title: params.title, body: params.body, dueDate: params.dueDate, completed: params.completed || false, assignedTo: params.assignedTo }); if (!response.success) { throw new Error(response.error?.message || 'Failed to create contact task'); } return response.data; } async getContactTask(params) { const response = await this.ghlClient.getContactTask(params.contactId, params.taskId); if (!response.success) { throw new Error(response.error?.message || 'Failed to get contact task'); } return response.data; } async updateContactTask(params) { const response = await this.ghlClient.updateContactTask(params.contactId, params.taskId, { title: params.title, body: params.body, dueDate: params.dueDate, completed: params.completed, assignedTo: params.assignedTo }); if (!response.success) { throw new Error(response.error?.message || 'Failed to update contact task'); } return response.data; } async deleteContactTask(params) { const response = await this.ghlClient.deleteContactTask(params.contactId, params.taskId); if (!response.success) { throw new Error(response.error?.message || 'Failed to delete contact task'); } return response.data; } async updateTaskCompletion(params) { const response = await this.ghlClient.updateTaskCompletion(params.contactId, params.taskId, params.completed); if (!response.success) { throw new Error(response.error?.message || 'Failed to update task completion'); } return response.data; } // Note Management async getContactNotes(params) { const response = await this.ghlClient.getContactNotes(params.contactId); if (!response.success) { throw new Error(response.error?.message || 'Failed to get contact notes'); } return response.data; } async createContactNote(params) { const response = await this.ghlClient.createContactNote(params.contactId, { body: params.body, userId: params.userId }); if (!response.success) { throw new Error(response.error?.message || 'Failed to create contact note'); } return response.data; } async getContactNote(params) { const response = await this.ghlClient.getContactNote(params.contactId, params.noteId); if (!response.success) { throw new Error(response.error?.message || 'Failed to get contact note'); } return response.data; } async updateContactNote(params) { const response = await this.ghlClient.updateContactNote(params.contactId, params.noteId, { body: params.body, userId: params.userId }); if (!response.success) { throw new Error(response.error?.message || 'Failed to update contact note'); } return response.data; } async deleteContactNote(params) { const response = await this.ghlClient.deleteContactNote(params.contactId, params.noteId); if (!response.success) { throw new Error(response.error?.message || 'Failed to delete contact note'); } return response.data; } // Advanced Operations async upsertContact(params) { const response = await this.ghlClient.upsertContact({ locationId: this.ghlClient.getConfig().locationId, firstName: params.firstName, lastName: params.lastName, name: params.name, email: params.email, phone: params.phone, address1: params.address, city: params.city, state: params.state, country: params.country, postalCode: params.postalCode, website: params.website, timezone: params.timezone, companyName: params.companyName, tags: params.tags, customFields: params.customFields, source: params.source, assignedTo: params.assignedTo }); if (!response.success) { throw new Error(response.error?.message || 'Failed to upsert contact'); } return response.data; } async getDuplicateContact(params) { const response = await this.ghlClient.getDuplicateContact(params.email, params.phone); if (!response.success) { throw new Error(response.error?.message || 'Failed to check for duplicate contact'); } return response.data; } async getContactsByBusiness(params) { const response = await this.ghlClient.getContactsByBusiness(params.businessId, { limit: params.limit, skip: params.skip, query: params.query }); if (!response.success) { throw new Error(response.error?.message || 'Failed to get contacts by business'); } return response.data; } async getContactAppointments(params) { const response = await this.ghlClient.getContactAppointments(params.contactId); if (!response.success) { throw new Error(response.error?.message || 'Failed to get contact appointments'); } return response.data; } // Bulk Operations async bulkUpdateContactTags(params) { const response = await this.ghlClient.bulkUpdateContactTags(params.contactIds, params.tags, params.operation, params.removeAllTags); if (!response.success) { throw new Error(response.error?.message || 'Failed to bulk update contact tags'); } return response.data; } async bulkUpdateContactBusiness(params) { const response = await this.ghlClient.bulkUpdateContactBusiness(params.contactIds, params.businessId); if (!response.success) { throw new Error(response.error?.message || 'Failed to bulk update contact business'); } return response.data; } // Followers Management async addContactFollowers(params) { const response = await this.ghlClient.addContactFollowers(params.contactId, params.followers); if (!response.success) { throw new Error(response.error?.message || 'Failed to add contact followers'); } return response.data; } async removeContactFollowers(params) { const response = await this.ghlClient.removeContactFollowers(params.contactId, params.followers); if (!response.success) { throw new Error(response.error?.message || 'Failed to remove contact followers'); } return response.data; } // Campaign Management async addContactToCampaign(params) { const response = await this.ghlClient.addContactToCampaign(params.contactId, params.campaignId); if (!response.success) { throw new Error(response.error?.message || 'Failed to add contact to campaign'); } return response.data; } async removeContactFromCampaign(params) { const response = await this.ghlClient.removeContactFromCampaign(params.contactId, params.campaignId); if (!response.success) { throw new Error(response.error?.message || 'Failed to remove contact from campaign'); } return response.data; } async removeContactFromAllCampaigns(params) { const response = await this.ghlClient.removeContactFromAllCampaigns(params.contactId); if (!response.success) { throw new Error(response.error?.message || 'Failed to remove contact from all campaigns'); } return response.data; } // Workflow Management async addContactToWorkflow(params) { const response = await this.ghlClient.addContactToWorkflow(params.contactId, params.workflowId, params.eventStartTime); if (!response.success) { throw new Error(response.error?.message || 'Failed to add contact to workflow'); } return response.data; } async removeContactFromWorkflow(params) { const response = await this.ghlClient.removeContactFromWorkflow(params.contactId, params.workflowId, params.eventStartTime); if (!response.success) { throw new Error(response.error?.message || 'Failed to remove contact from workflow'); } return response.data; } } exports.ContactTools = ContactTools;