Skip to main content
Glama
association-tools.tsโ€ข13.5 kB
import { Tool } from '@modelcontextprotocol/sdk/types.js'; import { GHLApiClient } from '../clients/ghl-api-client.js'; import { MCPCreateAssociationParams, MCPUpdateAssociationParams, MCPGetAllAssociationsParams, MCPGetAssociationByIdParams, MCPGetAssociationByKeyParams, MCPGetAssociationByObjectKeyParams, MCPDeleteAssociationParams, MCPCreateRelationParams, MCPGetRelationsByRecordParams, MCPDeleteRelationParams } from '../types/ghl-types.js'; export class AssociationTools { constructor(private apiClient: GHLApiClient) {} getTools(): Tool[] { return [ // Association Management Tools { name: 'ghl_get_all_associations', description: 'Get all associations for a sub-account/location with pagination. Returns system-defined and user-defined associations.', inputSchema: { type: 'object', properties: { locationId: { type: 'string', description: 'GoHighLevel location ID (will use default if not provided)' }, skip: { type: 'number', description: 'Number of records to skip for pagination', default: 0 }, limit: { type: 'number', description: 'Maximum number of records to return (max 100)', default: 20 } } } }, { name: 'ghl_create_association', description: 'Create a new association that defines relationship types between entities like contacts, custom objects, and opportunities.', inputSchema: { type: 'object', properties: { locationId: { type: 'string', description: 'GoHighLevel location ID (will use default if not provided)' }, key: { type: 'string', description: 'Unique key for the association (e.g., "student_teacher")' }, firstObjectLabel: { description: 'Label for the first object in the association (e.g., "student")' }, firstObjectKey: { description: 'Key for the first object (e.g., "custom_objects.children")' }, secondObjectLabel: { description: 'Label for the second object in the association (e.g., "teacher")' }, secondObjectKey: { description: 'Key for the second object (e.g., "contact")' } }, required: ['key', 'firstObjectLabel', 'firstObjectKey', 'secondObjectLabel', 'secondObjectKey'] } }, { name: 'ghl_get_association_by_id', description: 'Get a specific association by its ID. Works for both system-defined and user-defined associations.', inputSchema: { type: 'object', properties: { associationId: { type: 'string', description: 'The ID of the association to retrieve' } }, required: ['associationId'] } }, { name: 'ghl_update_association', description: 'Update the labels of an existing association. Only user-defined associations can be updated.', inputSchema: { type: 'object', properties: { associationId: { type: 'string', description: 'The ID of the association to update' }, firstObjectLabel: { description: 'New label for the first object in the association' }, secondObjectLabel: { description: 'New label for the second object in the association' } }, required: ['associationId', 'firstObjectLabel', 'secondObjectLabel'] } }, { name: 'ghl_delete_association', description: 'Delete a user-defined association. This will also delete all relations created with this association.', inputSchema: { type: 'object', properties: { associationId: { type: 'string', description: 'The ID of the association to delete' } }, required: ['associationId'] } }, { name: 'ghl_get_association_by_key', description: 'Get an association by its key name. Useful for finding both standard and user-defined associations.', inputSchema: { type: 'object', properties: { keyName: { type: 'string', description: 'The key name of the association to retrieve' }, locationId: { type: 'string', description: 'GoHighLevel location ID (will use default if not provided)' } }, required: ['keyName'] } }, { name: 'ghl_get_association_by_object_key', description: 'Get associations by object keys like contacts, custom objects, and opportunities.', inputSchema: { type: 'object', properties: { objectKey: { type: 'string', description: 'The object key to search for (e.g., "custom_objects.car", "contact", "opportunity")' }, locationId: { type: 'string', description: 'GoHighLevel location ID (optional)' } }, required: ['objectKey'] } }, // Relation Management Tools { name: 'ghl_create_relation', description: 'Create a relation between two entities using an existing association. Links specific records together.', inputSchema: { type: 'object', properties: { locationId: { type: 'string', description: 'GoHighLevel location ID (will use default if not provided)' }, associationId: { type: 'string', description: 'The ID of the association to use for this relation' }, firstRecordId: { type: 'string', description: 'ID of the first record (e.g., contact ID if contact is first object in association)' }, secondRecordId: { type: 'string', description: 'ID of the second record (e.g., custom object record ID if custom object is second object)' } }, required: ['associationId', 'firstRecordId', 'secondRecordId'] } }, { name: 'ghl_get_relations_by_record', description: 'Get all relations for a specific record ID with pagination and optional filtering by association IDs.', inputSchema: { type: 'object', properties: { recordId: { type: 'string', description: 'The record ID to get relations for' }, locationId: { type: 'string', description: 'GoHighLevel location ID (will use default if not provided)' }, skip: { type: 'number', description: 'Number of records to skip for pagination', default: 0 }, limit: { type: 'number', description: 'Maximum number of records to return', default: 20 }, associationIds: { type: 'array', items: { type: 'string' }, description: 'Optional array of association IDs to filter relations' } }, required: ['recordId'] } }, { name: 'ghl_delete_relation', description: 'Delete a specific relation between two entities.', inputSchema: { type: 'object', properties: { relationId: { type: 'string', description: 'The ID of the relation to delete' }, locationId: { type: 'string', description: 'GoHighLevel location ID (will use default if not provided)' } }, required: ['relationId'] } } ]; } async executeAssociationTool(name: string, args: any): Promise<any> { try { switch (name) { case 'ghl_get_all_associations': { const params: MCPGetAllAssociationsParams = args; const result = await this.apiClient.getAssociations({ locationId: params.locationId || '', skip: params.skip || 0, limit: params.limit || 20 }); return { success: true, data: result.data, message: `Retrieved ${result.data?.associations?.length || 0} associations` }; } case 'ghl_create_association': { const params: MCPCreateAssociationParams = args; const result = await this.apiClient.createAssociation({ locationId: params.locationId || '', key: params.key, firstObjectLabel: params.firstObjectLabel, firstObjectKey: params.firstObjectKey, secondObjectLabel: params.secondObjectLabel, secondObjectKey: params.secondObjectKey }); return { success: true, data: result.data, message: `Association '${params.key}' created successfully` }; } case 'ghl_get_association_by_id': { const params: MCPGetAssociationByIdParams = args; const result = await this.apiClient.getAssociationById(params.associationId); return { success: true, data: result.data, message: `Association retrieved successfully` }; } case 'ghl_update_association': { const params: MCPUpdateAssociationParams = args; const result = await this.apiClient.updateAssociation(params.associationId, { firstObjectLabel: params.firstObjectLabel, secondObjectLabel: params.secondObjectLabel }); return { success: true, data: result.data, message: `Association updated successfully` }; } case 'ghl_delete_association': { const params: MCPDeleteAssociationParams = args; const result = await this.apiClient.deleteAssociation(params.associationId); return { success: true, data: result.data, message: `Association deleted successfully` }; } case 'ghl_get_association_by_key': { const params: MCPGetAssociationByKeyParams = args; const result = await this.apiClient.getAssociationByKey({ keyName: params.keyName, locationId: params.locationId || '' }); return { success: true, data: result.data, message: `Association with key '${params.keyName}' retrieved successfully` }; } case 'ghl_get_association_by_object_key': { const params: MCPGetAssociationByObjectKeyParams = args; const result = await this.apiClient.getAssociationByObjectKey({ objectKey: params.objectKey, locationId: params.locationId }); return { success: true, data: result.data, message: `Association with object key '${params.objectKey}' retrieved successfully` }; } case 'ghl_create_relation': { const params: MCPCreateRelationParams = args; const result = await this.apiClient.createRelation({ locationId: params.locationId || '', associationId: params.associationId, firstRecordId: params.firstRecordId, secondRecordId: params.secondRecordId }); return { success: true, data: result.data, message: `Relation created successfully between records` }; } case 'ghl_get_relations_by_record': { const params: MCPGetRelationsByRecordParams = args; const result = await this.apiClient.getRelationsByRecord({ recordId: params.recordId, locationId: params.locationId || '', skip: params.skip || 0, limit: params.limit || 20, associationIds: params.associationIds }); return { success: true, data: result.data, message: `Retrieved ${result.data?.relations?.length || 0} relations for record` }; } case 'ghl_delete_relation': { const params: MCPDeleteRelationParams = args; const result = await this.apiClient.deleteRelation({ relationId: params.relationId, locationId: params.locationId || '' }); return { success: true, data: result.data, message: `Relation deleted successfully` }; } default: throw new Error(`Unknown association tool: ${name}`); } } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), message: `Failed to execute ${name}` }; } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/clickmediapropy/gohighlevel-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server