Skip to main content
Glama
jonathan-politzki

Smartlead Simplified MCP Server

statistics.ts16 kB
import { AxiosInstance } from 'axios'; import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'; import { isCampaignStatisticsParams, isCampaignStatisticsByDateParams, isWarmupStatsByEmailParams, isCampaignTopLevelAnalyticsParams, isCampaignTopLevelAnalyticsByDateParams, isCampaignLeadStatisticsParams, isCampaignMailboxStatisticsParams, isDownloadCampaignDataParams, isViewDownloadStatisticsParams } from '../types/statistics.js'; import { trackDownload, getDownloadStats, getDownloadRecords } from '../utils/download-tracker.js'; // Handler for statistics-related tools export async function handleStatisticsTool( toolName: string, args: unknown, apiClient: AxiosInstance, withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T> ) { switch (toolName) { case 'smartlead_get_campaign_statistics': { return handleCampaignStatistics(args, apiClient, withRetry); } case 'smartlead_get_campaign_statistics_by_date': { return handleCampaignStatisticsByDate(args, apiClient, withRetry); } case 'smartlead_get_warmup_stats_by_email': { return handleWarmupStatsByEmail(args, apiClient, withRetry); } case 'smartlead_get_campaign_top_level_analytics': { return handleCampaignTopLevelAnalytics(args, apiClient, withRetry); } case 'smartlead_get_campaign_top_level_analytics_by_date': { return handleCampaignTopLevelAnalyticsByDate(args, apiClient, withRetry); } case 'smartlead_get_campaign_lead_statistics': { return handleCampaignLeadStatistics(args, apiClient, withRetry); } case 'smartlead_get_campaign_mailbox_statistics': { return handleCampaignMailboxStatistics(args, apiClient, withRetry); } case 'smartlead_download_campaign_data': { return handleDownloadCampaignData(args, apiClient, withRetry); } case 'smartlead_view_download_statistics': { return handleViewDownloadStatistics(args); } default: throw new Error(`Unknown statistics tool: ${toolName}`); } } // Individual handlers for each tool async function handleCampaignStatistics( args: unknown, apiClient: AxiosInstance, withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T> ) { if (!isCampaignStatisticsParams(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for smartlead_get_campaign_statistics' ); } const { campaign_id, ...queryParams } = args; try { const response = await withRetry( async () => apiClient.get(`/campaigns/${campaign_id}/statistics`, { params: queryParams }), 'get campaign statistics' ); return { content: [ { type: 'text', text: JSON.stringify(response.data, null, 2), }, ], isError: false, }; } catch (error: any) { return { content: [{ type: 'text', text: `API Error: ${error.response?.data?.message || error.message}` }], isError: true, }; } } async function handleCampaignStatisticsByDate( args: unknown, apiClient: AxiosInstance, withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T> ) { if (!isCampaignStatisticsByDateParams(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for smartlead_get_campaign_statistics_by_date' ); } const { campaign_id, start_date, end_date } = args; try { const response = await withRetry( async () => apiClient.get(`/campaigns/${campaign_id}/analytics-by-date`, { params: { start_date, end_date } }), 'get campaign statistics by date' ); return { content: [ { type: 'text', text: JSON.stringify(response.data, null, 2), }, ], isError: false, }; } catch (error: any) { return { content: [{ type: 'text', text: `API Error: ${error.response?.data?.message || error.message}` }], isError: true, }; } } async function handleWarmupStatsByEmail( args: unknown, apiClient: AxiosInstance, withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T> ) { if (!isWarmupStatsByEmailParams(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for smartlead_get_warmup_stats_by_email' ); } const { email_account_id } = args; try { const response = await withRetry( async () => apiClient.get(`/email-accounts/${email_account_id}/warmup-stats`), 'get warmup stats by email' ); return { content: [ { type: 'text', text: JSON.stringify(response.data, null, 2), }, ], isError: false, }; } catch (error: any) { return { content: [{ type: 'text', text: `API Error: ${error.response?.data?.message || error.message}` }], isError: true, }; } } async function handleCampaignTopLevelAnalytics( args: unknown, apiClient: AxiosInstance, withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T> ) { if (!isCampaignTopLevelAnalyticsParams(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for smartlead_get_campaign_top_level_analytics' ); } const { campaign_id } = args; try { const response = await withRetry( async () => apiClient.get(`/campaigns/${campaign_id}/analytics`), 'get campaign top level analytics' ); return { content: [ { type: 'text', text: JSON.stringify(response.data, null, 2), }, ], isError: false, }; } catch (error: any) { return { content: [{ type: 'text', text: `API Error: ${error.response?.data?.message || error.message}` }], isError: true, }; } } async function handleCampaignTopLevelAnalyticsByDate( args: unknown, apiClient: AxiosInstance, withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T> ) { if (!isCampaignTopLevelAnalyticsByDateParams(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for smartlead_get_campaign_top_level_analytics_by_date' ); } const { campaign_id, start_date, end_date } = args; try { const response = await withRetry( async () => apiClient.get(`/campaigns/${campaign_id}/top-level-analytics-by-date`, { params: { start_date, end_date } }), 'get campaign top level analytics by date' ); return { content: [ { type: 'text', text: JSON.stringify(response.data, null, 2), }, ], isError: false, }; } catch (error: any) { return { content: [{ type: 'text', text: `API Error: ${error.response?.data?.message || error.message}` }], isError: true, }; } } async function handleCampaignLeadStatistics( args: unknown, apiClient: AxiosInstance, withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T> ) { if (!isCampaignLeadStatisticsParams(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for smartlead_get_campaign_lead_statistics' ); } const { campaign_id, ...queryParams } = args; try { const response = await withRetry( async () => apiClient.get(`/campaigns/${campaign_id}/lead-statistics`, { params: queryParams }), 'get campaign lead statistics' ); return { content: [ { type: 'text', text: JSON.stringify(response.data, null, 2), }, ], isError: false, }; } catch (error: any) { return { content: [{ type: 'text', text: `API Error: ${error.response?.data?.message || error.message}` }], isError: true, }; } } async function handleCampaignMailboxStatistics( args: unknown, apiClient: AxiosInstance, withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T> ) { if (!isCampaignMailboxStatisticsParams(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for smartlead_get_campaign_mailbox_statistics' ); } const { campaign_id, ...queryParams } = args; try { const response = await withRetry( async () => apiClient.get(`/campaigns/${campaign_id}/mailbox-statistics`, { params: queryParams }), 'get campaign mailbox statistics' ); return { content: [ { type: 'text', text: JSON.stringify(response.data, null, 2), }, ], isError: false, }; } catch (error: any) { return { content: [{ type: 'text', text: `API Error: ${error.response?.data?.message || error.message}` }], isError: true, }; } } // New function to handle the download and tracking async function handleDownloadCampaignData( args: unknown, apiClient: AxiosInstance, withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T> ) { if (!isDownloadCampaignDataParams(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for smartlead_download_campaign_data' ); } const { campaign_id, download_type, format, user_id } = args; try { let endpoint = ''; let transformFn = (data: any) => data; // Determine the API endpoint based on download type switch (download_type) { case 'analytics': endpoint = `/campaigns/${campaign_id}/analytics`; break; case 'leads': endpoint = `/campaigns/${campaign_id}/leads`; break; case 'sequence': endpoint = `/campaigns/${campaign_id}/sequence`; break; case 'full_export': endpoint = `/campaigns/${campaign_id}/export`; break; default: throw new McpError( ErrorCode.InvalidParams, `Invalid download_type: ${download_type}` ); } // Fetch the data const response = await withRetry( async () => apiClient.get(endpoint), `download campaign ${download_type}` ); let responseData = response.data; // If format is CSV, convert the JSON data to CSV if (format === 'csv') { responseData = convertToCSV(responseData); } // Track the download const downloadId = trackDownload( campaign_id, download_type, format, user_id ); // Add download metadata to the response const result = { data: responseData, download_metadata: { download_id: downloadId, timestamp: new Date().toISOString(), campaign_id, download_type, format } }; return { content: [ { type: 'text', text: format === 'json' ? JSON.stringify(result, null, 2) : result.data, // CSV data is already stringified }, ], isError: false, }; } catch (error: any) { return { content: [{ type: 'text', text: `API Error: ${error.response?.data?.message || error.message}` }], isError: true, }; } } // Helper function to convert JSON to CSV function convertToCSV(data: any): string { if (!data || typeof data !== 'object') { return ''; } // Handle array of objects if (Array.isArray(data)) { if (data.length === 0) return ''; // Get all possible headers from all objects const headers = new Set<string>(); data.forEach(item => { if (item && typeof item === 'object') { Object.keys(item).forEach(key => headers.add(key)); } }); const headerRow = Array.from(headers).join(','); const rows = data.map(item => { if (!item || typeof item !== 'object') return ''; return Array.from(headers) .map(header => { const cell = item[header] ?? ''; // Escape strings with quotes if they contain commas return typeof cell === 'string' && cell.includes(',') ? `"${cell.replace(/"/g, '""')}"` : String(cell); }) .join(','); }); return [headerRow, ...rows].join('\n'); } // Handle single object const headers = Object.keys(data).join(','); const values = Object.values(data) .map(val => { if (typeof val === 'string' && val.includes(',')) { return `"${val.replace(/"/g, '""')}"`; } return String(val); }) .join(','); return [headers, values].join('\n'); } // New function to handle viewing download statistics async function handleViewDownloadStatistics(args: unknown) { if (!isViewDownloadStatisticsParams(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for smartlead_view_download_statistics' ); } const { time_period = 'all', group_by = 'type' } = args; try { // Get all download records const allRecords = getDownloadRecords(); // Filter records by time period const now = new Date(); const filteredRecords = allRecords.filter(record => { const recordDate = new Date(record.timestamp); switch (time_period) { case 'today': return recordDate.toDateString() === now.toDateString(); case 'week': { const oneWeekAgo = new Date(); oneWeekAgo.setDate(now.getDate() - 7); return recordDate >= oneWeekAgo; } case 'month': { const oneMonthAgo = new Date(); oneMonthAgo.setMonth(now.getMonth() - 1); return recordDate >= oneMonthAgo; } case 'all': default: return true; } }); // Get basic statistics const stats = { totalDownloads: filteredRecords.length, timePeriod: time_period, uniqueUsers: new Set(filteredRecords.map(r => r.userId || r.machineId)).size }; // Group by specified field let groupedData: Record<string, number> = {}; switch (group_by) { case 'type': groupedData = filteredRecords.reduce((acc, record) => { acc[record.downloadType] = (acc[record.downloadType] || 0) + 1; return acc; }, {} as Record<string, number>); break; case 'format': groupedData = filteredRecords.reduce((acc, record) => { acc[record.format] = (acc[record.format] || 0) + 1; return acc; }, {} as Record<string, number>); break; case 'campaign': groupedData = filteredRecords.reduce((acc, record) => { const campaignKey = `campaign_${record.campaignId}`; acc[campaignKey] = (acc[campaignKey] || 0) + 1; return acc; }, {} as Record<string, number>); break; case 'date': groupedData = filteredRecords.reduce((acc, record) => { const date = record.timestamp.split('T')[0]; acc[date] = (acc[date] || 0) + 1; return acc; }, {} as Record<string, number>); break; } // Compile the result const result = { ...stats, groupedBy: group_by, groups: groupedData, // Include recent downloads for reference recentDownloads: filteredRecords .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()) .slice(0, 5) }; return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], isError: false, }; } catch (error: any) { return { content: [{ type: 'text', text: `Error retrieving download statistics: ${error.message}` }], isError: true, }; } }

Implementation Reference

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/jonathan-politzki/smartlead-mcp-server'

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