/**
* GoHighLevel Contact Tools
* Implements all contact management functionality for the MCP server
*/
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { GHLApiClient } from '../clients/ghl-api-client.js';
import {
MCPCreateContactParams,
MCPSearchContactsParams,
MCPUpdateContactParams,
MCPAddContactTagsParams,
MCPRemoveContactTagsParams,
// Task Management
MCPGetContactTasksParams,
MCPCreateContactTaskParams,
MCPGetContactTaskParams,
MCPUpdateContactTaskParams,
MCPDeleteContactTaskParams,
MCPUpdateTaskCompletionParams,
// Note Management
MCPGetContactNotesParams,
MCPCreateContactNoteParams,
MCPGetContactNoteParams,
MCPUpdateContactNoteParams,
MCPDeleteContactNoteParams,
// Advanced Operations
MCPUpsertContactParams,
MCPGetDuplicateContactParams,
MCPGetContactsByBusinessParams,
MCPGetContactAppointmentsParams,
// Bulk Operations
MCPBulkUpdateContactTagsParams,
MCPBulkUpdateContactBusinessParams,
// Followers Management
MCPAddContactFollowersParams,
MCPRemoveContactFollowersParams,
// Campaign Management
MCPAddContactToCampaignParams,
MCPRemoveContactFromCampaignParams,
MCPRemoveContactFromAllCampaignsParams,
// Workflow Management
MCPAddContactToWorkflowParams,
MCPRemoveContactFromWorkflowParams,
GHLContact,
GHLSearchContactsResponse,
GHLContactTagsResponse,
GHLTask,
GHLNote,
GHLAppointment,
GHLUpsertContactResponse,
GHLBulkTagsResponse,
GHLBulkBusinessResponse,
GHLFollowersResponse
} from '../types/ghl-types.js';
/**
* Contact Tools class
* Provides comprehensive contact management capabilities
*/
export class ContactTools {
constructor(private ghlClient: GHLApiClient) {}
/**
* Get tool definitions for all contact operations
*/
getToolDefinitions(): Tool[] {
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: string, params: any): Promise<any> {
try {
switch (toolName) {
// Basic Contact Management
case 'create_contact':
return await this.createContact(params as MCPCreateContactParams);
case 'search_contacts':
return await this.searchContacts(params as MCPSearchContactsParams);
case 'get_contact':
return await this.getContact(params.contactId);
case 'update_contact':
return await this.updateContact(params as MCPUpdateContactParams);
case 'delete_contact':
return await this.deleteContact(params.contactId);
case 'add_contact_tags':
return await this.addContactTags(params as MCPAddContactTagsParams);
case 'remove_contact_tags':
return await this.removeContactTags(params as MCPRemoveContactTagsParams);
// Task Management
case 'get_contact_tasks':
return await this.getContactTasks(params as MCPGetContactTasksParams);
case 'create_contact_task':
return await this.createContactTask(params as MCPCreateContactTaskParams);
case 'get_contact_task':
return await this.getContactTask(params as MCPGetContactTaskParams);
case 'update_contact_task':
return await this.updateContactTask(params as MCPUpdateContactTaskParams);
case 'delete_contact_task':
return await this.deleteContactTask(params as MCPDeleteContactTaskParams);
case 'update_task_completion':
return await this.updateTaskCompletion(params as MCPUpdateTaskCompletionParams);
// Note Management
case 'get_contact_notes':
return await this.getContactNotes(params as MCPGetContactNotesParams);
case 'create_contact_note':
return await this.createContactNote(params as MCPCreateContactNoteParams);
case 'get_contact_note':
return await this.getContactNote(params as MCPGetContactNoteParams);
case 'update_contact_note':
return await this.updateContactNote(params as MCPUpdateContactNoteParams);
case 'delete_contact_note':
return await this.deleteContactNote(params as MCPDeleteContactNoteParams);
// Advanced Operations
case 'upsert_contact':
return await this.upsertContact(params as MCPUpsertContactParams);
case 'get_duplicate_contact':
return await this.getDuplicateContact(params as MCPGetDuplicateContactParams);
case 'get_contacts_by_business':
return await this.getContactsByBusiness(params as MCPGetContactsByBusinessParams);
case 'get_contact_appointments':
return await this.getContactAppointments(params as MCPGetContactAppointmentsParams);
// Bulk Operations
case 'bulk_update_contact_tags':
return await this.bulkUpdateContactTags(params as MCPBulkUpdateContactTagsParams);
case 'bulk_update_contact_business':
return await this.bulkUpdateContactBusiness(params as MCPBulkUpdateContactBusinessParams);
// Followers Management
case 'add_contact_followers':
return await this.addContactFollowers(params as MCPAddContactFollowersParams);
case 'remove_contact_followers':
return await this.removeContactFollowers(params as MCPRemoveContactFollowersParams);
// Campaign Management
case 'add_contact_to_campaign':
return await this.addContactToCampaign(params as MCPAddContactToCampaignParams);
case 'remove_contact_from_campaign':
return await this.removeContactFromCampaign(params as MCPRemoveContactFromCampaignParams);
case 'remove_contact_from_all_campaigns':
return await this.removeContactFromAllCampaigns(params as MCPRemoveContactFromAllCampaignsParams);
// Workflow Management
case 'add_contact_to_workflow':
return await this.addContactToWorkflow(params as MCPAddContactToWorkflowParams);
case 'remove_contact_from_workflow':
return await this.removeContactFromWorkflow(params as MCPRemoveContactFromWorkflowParams);
default:
throw new Error(`Unknown tool: ${toolName}`);
}
} catch (error) {
console.error(`Error executing contact tool ${toolName}:`, error);
throw error;
}
}
// Implementation methods...
// Basic Contact Management
private async createContact(params: MCPCreateContactParams): Promise<GHLContact> {
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!;
}
private async searchContacts(params: MCPSearchContactsParams): Promise<GHLSearchContactsResponse> {
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!;
}
private async getContact(contactId: string): Promise<GHLContact> {
const response = await this.ghlClient.getContact(contactId);
if (!response.success) {
throw new Error(response.error?.message || 'Failed to get contact');
}
return response.data!;
}
private async updateContact(params: MCPUpdateContactParams): Promise<GHLContact> {
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!;
}
private async deleteContact(contactId: string): Promise<{ succeded: boolean }> {
const response = await this.ghlClient.deleteContact(contactId);
if (!response.success) {
throw new Error(response.error?.message || 'Failed to delete contact');
}
return response.data!;
}
private async addContactTags(params: MCPAddContactTagsParams): Promise<GHLContactTagsResponse> {
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!;
}
private async removeContactTags(params: MCPRemoveContactTagsParams): Promise<GHLContactTagsResponse> {
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
private async getContactTasks(params: MCPGetContactTasksParams): Promise<GHLTask[]> {
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!;
}
private async createContactTask(params: MCPCreateContactTaskParams): Promise<GHLTask> {
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!;
}
private async getContactTask(params: MCPGetContactTaskParams): Promise<GHLTask> {
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!;
}
private async updateContactTask(params: MCPUpdateContactTaskParams): Promise<GHLTask> {
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!;
}
private async deleteContactTask(params: MCPDeleteContactTaskParams): Promise<{ succeded: boolean }> {
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!;
}
private async updateTaskCompletion(params: MCPUpdateTaskCompletionParams): Promise<GHLTask> {
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
private async getContactNotes(params: MCPGetContactNotesParams): Promise<GHLNote[]> {
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!;
}
private async createContactNote(params: MCPCreateContactNoteParams): Promise<GHLNote> {
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!;
}
private async getContactNote(params: MCPGetContactNoteParams): Promise<GHLNote> {
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!;
}
private async updateContactNote(params: MCPUpdateContactNoteParams): Promise<GHLNote> {
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!;
}
private async deleteContactNote(params: MCPDeleteContactNoteParams): Promise<{ succeded: boolean }> {
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
private async upsertContact(params: MCPUpsertContactParams): Promise<GHLUpsertContactResponse> {
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!;
}
private async getDuplicateContact(params: MCPGetDuplicateContactParams): Promise<GHLContact | null> {
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!;
}
private async getContactsByBusiness(params: MCPGetContactsByBusinessParams): Promise<GHLSearchContactsResponse> {
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!;
}
private async getContactAppointments(params: MCPGetContactAppointmentsParams): Promise<GHLAppointment[]> {
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
private async bulkUpdateContactTags(params: MCPBulkUpdateContactTagsParams): Promise<GHLBulkTagsResponse> {
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!;
}
private async bulkUpdateContactBusiness(params: MCPBulkUpdateContactBusinessParams): Promise<GHLBulkBusinessResponse> {
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
private async addContactFollowers(params: MCPAddContactFollowersParams): Promise<GHLFollowersResponse> {
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!;
}
private async removeContactFollowers(params: MCPRemoveContactFollowersParams): Promise<GHLFollowersResponse> {
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
private async addContactToCampaign(params: MCPAddContactToCampaignParams): Promise<{ succeded: boolean }> {
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!;
}
private async removeContactFromCampaign(params: MCPRemoveContactFromCampaignParams): Promise<{ succeded: boolean }> {
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!;
}
private async removeContactFromAllCampaigns(params: MCPRemoveContactFromAllCampaignsParams): Promise<{ succeded: boolean }> {
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
private async addContactToWorkflow(params: MCPAddContactToWorkflowParams): Promise<{ succeded: boolean }> {
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!;
}
private async removeContactFromWorkflow(params: MCPRemoveContactFromWorkflowParams): Promise<{ succeded: boolean }> {
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!;
}
}