Skip to main content
Glama
media-tools.tsโ€ข9.26 kB
import { GHLApiClient } from '../clients/ghl-api-client.js'; import { MCPGetMediaFilesParams, MCPUploadMediaFileParams, MCPDeleteMediaParams, GHLGetMediaFilesRequest, GHLUploadMediaFileRequest, GHLDeleteMediaRequest } from '../types/ghl-types.js'; export interface Tool { name: string; description: string; inputSchema: { type: string; properties: Record<string, any>; required: string[]; }; } /** * MediaTools class for GoHighLevel Media Library API endpoints * Handles file management operations including listing, uploading, and deleting files/folders */ export class MediaTools { constructor(private ghlClient: GHLApiClient) {} /** * Get all available Media Library tool definitions */ getToolDefinitions(): Tool[] { return [ { name: 'get_media_files', description: 'Get list of files and folders from the media library with filtering and search capabilities', inputSchema: { type: 'object', properties: { offset: { type: 'number', description: 'Number of files to skip in listing', minimum: 0 }, limit: { type: 'number', description: 'Number of files to show in the listing (max 100)', minimum: 1, maximum: 100 }, sortBy: { type: 'string', description: 'Field to sort the file listing by (e.g., createdAt, name, size)', default: 'createdAt' }, sortOrder: { type: 'string', description: 'Direction to sort files (asc or desc)', enum: ['asc', 'desc'], default: 'desc' }, type: { type: 'string', description: 'Filter by type (file or folder)', enum: ['file', 'folder'] }, query: { type: 'string', description: 'Search query text to filter files by name' }, altType: { type: 'string', description: 'Context type (location or agency)', enum: ['location', 'agency'], default: 'location' }, altId: { type: 'string', description: 'Location or Agency ID (uses default location if not provided)' }, parentId: { type: 'string', description: 'Parent folder ID to list files within a specific folder' } }, required: [] } }, { name: 'upload_media_file', description: 'Upload a file to the media library or add a hosted file URL (max 25MB for direct uploads)', inputSchema: { type: 'object', properties: { file: { type: 'string', description: 'File data (binary) for direct upload' }, hosted: { type: 'boolean', description: 'Set to true if providing a fileUrl instead of direct file upload', default: false }, fileUrl: { type: 'string', description: 'URL of hosted file (required if hosted=true)' }, name: { type: 'string', description: 'Custom name for the uploaded file' }, parentId: { type: 'string', description: 'Parent folder ID to upload file into' }, altType: { type: 'string', description: 'Context type (location or agency)', enum: ['location', 'agency'], default: 'location' }, altId: { type: 'string', description: 'Location or Agency ID (uses default location if not provided)' } }, required: [] } }, { name: 'delete_media_file', description: 'Delete a specific file or folder from the media library', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'ID of the file or folder to delete' }, altType: { type: 'string', description: 'Context type (location or agency)', enum: ['location', 'agency'], default: 'location' }, altId: { type: 'string', description: 'Location or Agency ID (uses default location if not provided)' } }, required: ['id'] } } ]; } /** * Execute a media tool by name with given arguments */ async executeTool(name: string, args: any): Promise<any> { switch (name) { case 'get_media_files': return this.getMediaFiles(args as MCPGetMediaFilesParams); case 'upload_media_file': return this.uploadMediaFile(args as MCPUploadMediaFileParams); case 'delete_media_file': return this.deleteMediaFile(args as MCPDeleteMediaParams); default: throw new Error(`Unknown media tool: ${name}`); } } /** * GET MEDIA FILES */ private async getMediaFiles(params: MCPGetMediaFilesParams = {}): Promise<{ success: boolean; files: any[]; total?: number; message: string }> { try { const requestParams: GHLGetMediaFilesRequest = { sortBy: params.sortBy || 'createdAt', sortOrder: params.sortOrder || 'desc', altType: params.altType || 'location', altId: params.altId || this.ghlClient.getConfig().locationId, ...(params.offset !== undefined && { offset: params.offset }), ...(params.limit !== undefined && { limit: params.limit }), ...(params.type && { type: params.type }), ...(params.query && { query: params.query }), ...(params.parentId && { parentId: params.parentId }) }; const response = await this.ghlClient.getMediaFiles(requestParams); if (!response.success || !response.data) { const errorMsg = response.error?.message || 'Unknown API error'; throw new Error(`API request failed: ${errorMsg}`); } const files = Array.isArray(response.data.files) ? response.data.files : []; return { success: true, files, total: response.data.total, message: `Retrieved ${files.length} media files/folders` }; } catch (error) { throw new Error(`Failed to get media files: ${error instanceof Error ? error.message : String(error)}`); } } /** * UPLOAD MEDIA FILE */ private async uploadMediaFile(params: MCPUploadMediaFileParams): Promise<{ success: boolean; fileId: string; url?: string; message: string }> { try { // Validate upload parameters if (params.hosted && !params.fileUrl) { throw new Error('fileUrl is required when hosted=true'); } if (!params.hosted && !params.file) { throw new Error('file is required when hosted=false or not specified'); } const uploadData: GHLUploadMediaFileRequest = { altType: params.altType || 'location', altId: params.altId || this.ghlClient.getConfig().locationId, ...(params.hosted !== undefined && { hosted: params.hosted }), ...(params.fileUrl && { fileUrl: params.fileUrl }), ...(params.file && { file: params.file }), ...(params.name && { name: params.name }), ...(params.parentId && { parentId: params.parentId }) }; const response = await this.ghlClient.uploadMediaFile(uploadData); if (!response.success || !response.data) { const errorMsg = response.error?.message || 'Unknown API error'; throw new Error(`API request failed: ${errorMsg}`); } return { success: true, fileId: response.data.fileId, url: response.data.url, message: `File uploaded successfully with ID: ${response.data.fileId}` }; } catch (error) { throw new Error(`Failed to upload media file: ${error instanceof Error ? error.message : String(error)}`); } } /** * DELETE MEDIA FILE */ private async deleteMediaFile(params: MCPDeleteMediaParams): Promise<{ success: boolean; message: string }> { try { const deleteParams: GHLDeleteMediaRequest = { id: params.id, altType: params.altType || 'location', altId: params.altId || this.ghlClient.getConfig().locationId }; const response = await this.ghlClient.deleteMediaFile(deleteParams); if (!response.success) { const errorMsg = response.error?.message || 'Unknown API error'; throw new Error(`API request failed: ${errorMsg}`); } return { success: true, message: `Media file/folder deleted successfully` }; } catch (error) { throw new Error(`Failed to delete media file: ${error instanceof Error ? error.message : String(error)}`); } } }

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