This is page 2 of 2. Use http://codebase.md/jean-technologies/smartlead-mcp-server-local?lines=false&page={x} to view the full context.
# Directory Structure
```
├── .env.example
├── .gitignore
├── DEVELOPER_ONBOARDING.md
├── Dockerfile
├── jest.config.js
├── llms-install.md
├── mcp_settings_example.json
├── package-lock.json
├── package.json
├── README.md
├── server
│ └── license-server.js
├── smithery.yaml
├── src
│ ├── cli.ts
│ ├── config
│ │ └── feature-config.ts
│ ├── handlers
│ │ ├── campaign.ts
│ │ ├── clientManagement.ts
│ │ ├── email.ts
│ │ ├── lead.ts
│ │ ├── smartDelivery.ts
│ │ ├── smartSenders.ts
│ │ ├── statistics.ts
│ │ └── webhooks.ts
│ ├── index.ts
│ ├── licensing
│ │ ├── index.ts
│ │ └── stripe-integration.js
│ ├── n8n
│ │ └── index.ts
│ ├── registry
│ │ └── tool-registry.ts
│ ├── supergateway-mock.ts
│ ├── supergateway.ts
│ ├── tools
│ │ ├── campaign.ts
│ │ ├── clientManagement.ts
│ │ ├── email.d.ts
│ │ ├── email.ts
│ │ ├── lead.d.ts
│ │ ├── lead.ts
│ │ ├── smartDelivery.d.ts
│ │ ├── smartDelivery.ts
│ │ ├── smartSenders.ts
│ │ ├── statistics.d.ts
│ │ ├── statistics.ts
│ │ └── webhooks.ts
│ ├── types
│ │ ├── campaign.ts
│ │ ├── clientManagement.ts
│ │ ├── common.ts
│ │ ├── email.d.ts
│ │ ├── email.ts
│ │ ├── lead.ts
│ │ ├── smartDelivery.ts
│ │ ├── smartSenders.ts
│ │ ├── statistics.d.ts
│ │ ├── statistics.ts
│ │ ├── supergateway.d.ts
│ │ └── webhooks.ts
│ └── utils
│ └── download-tracker.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/src/handlers/campaign.ts:
--------------------------------------------------------------------------------
```typescript
import { AxiosInstance } from 'axios';
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import {
isCreateCampaignParams,
isUpdateCampaignScheduleParams,
isUpdateCampaignSettingsParams,
isUpdateCampaignStatusParams,
isGetCampaignParams,
isListCampaignsParams,
isSaveCampaignSequenceParams,
isGetCampaignSequenceParams,
isGetCampaignsByLeadParams,
isExportCampaignLeadsParams,
isDeleteCampaignParams,
isGetCampaignAnalyticsByDateParams,
isGetCampaignSequenceAnalyticsParams
} from '../types/campaign.js';
// Handler for campaign-related tools
export async function handleCampaignTool(
toolName: string,
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
switch (toolName) {
case 'smartlead_create_campaign': {
return handleCreateCampaign(args, apiClient, withRetry);
}
case 'smartlead_update_campaign_schedule': {
return handleUpdateCampaignSchedule(args, apiClient, withRetry);
}
case 'smartlead_update_campaign_settings': {
return handleUpdateCampaignSettings(args, apiClient, withRetry);
}
case 'smartlead_update_campaign_status': {
return handleUpdateCampaignStatus(args, apiClient, withRetry);
}
case 'smartlead_get_campaign': {
return handleGetCampaign(args, apiClient, withRetry);
}
case 'smartlead_list_campaigns': {
return handleListCampaigns(args, apiClient, withRetry);
}
case 'smartlead_save_campaign_sequence': {
return handleSaveCampaignSequence(args, apiClient, withRetry);
}
case 'smartlead_get_campaign_sequence': {
return handleGetCampaignSequence(args, apiClient, withRetry);
}
case 'smartlead_get_campaigns_by_lead': {
return handleGetCampaignsByLead(args, apiClient, withRetry);
}
case 'smartlead_export_campaign_leads': {
return handleExportCampaignLeads(args, apiClient, withRetry);
}
case 'smartlead_delete_campaign': {
return handleDeleteCampaign(args, apiClient, withRetry);
}
case 'smartlead_get_campaign_analytics_by_date': {
return handleGetCampaignAnalyticsByDate(args, apiClient, withRetry);
}
case 'smartlead_get_campaign_sequence_analytics': {
return handleGetCampaignSequenceAnalytics(args, apiClient, withRetry);
}
default:
throw new Error(`Unknown campaign tool: ${toolName}`);
}
}
// Individual handlers for each tool
async function handleCreateCampaign(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isCreateCampaignParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_create_campaign'
);
}
try {
const response = await withRetry(
async () => apiClient.post('/campaigns/create', args),
'create campaign'
);
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 handleUpdateCampaignSchedule(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isUpdateCampaignScheduleParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_update_campaign_schedule'
);
}
const { campaign_id, ...scheduleParams } = args;
try {
const response = await withRetry(
async () => apiClient.post(`/campaigns/${campaign_id}/schedule`, scheduleParams),
'update campaign schedule'
);
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 handleUpdateCampaignSettings(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isUpdateCampaignSettingsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_update_campaign_settings'
);
}
const { campaign_id, ...settingsParams } = args;
try {
const response = await withRetry(
async () => apiClient.post(`/campaigns/${campaign_id}/settings`, settingsParams),
'update campaign settings'
);
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 handleUpdateCampaignStatus(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isUpdateCampaignStatusParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_update_campaign_status'
);
}
const { campaign_id, status } = args;
try {
const response = await withRetry(
async () => apiClient.post(`/campaigns/${campaign_id}/status`, { status }),
'update campaign status'
);
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 handleGetCampaign(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGetCampaignParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_campaign'
);
}
try {
const response = await withRetry(
async () => apiClient.get(`/campaigns/${args.campaign_id}`),
'get campaign'
);
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 handleListCampaigns(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isListCampaignsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_list_campaigns'
);
}
try {
const response = await withRetry(
async () => apiClient.get('/campaigns', { params: args }),
'list campaigns'
);
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 handleSaveCampaignSequence(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isSaveCampaignSequenceParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_save_campaign_sequence'
);
}
const { campaign_id, sequence } = args;
try {
const response = await withRetry(
async () => apiClient.post(`/campaigns/${campaign_id}/sequences`, { sequence }),
'save campaign sequence'
);
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 handleGetCampaignSequence(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGetCampaignSequenceParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_campaign_sequence'
);
}
try {
const response = await withRetry(
async () => apiClient.get(`/campaigns/${args.campaign_id}/sequences`),
'get campaign sequence'
);
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 handler implementations for the remaining campaign management API endpoints
async function handleGetCampaignsByLead(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGetCampaignsByLeadParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_campaigns_by_lead'
);
}
try {
const response = await withRetry(
async () => apiClient.get(`/leads/${args.lead_id}/campaigns`),
'get campaigns by lead'
);
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 handleExportCampaignLeads(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isExportCampaignLeadsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_export_campaign_leads'
);
}
try {
const response = await withRetry(
async () => apiClient.get(`/campaigns/${args.campaign_id}/leads-export`, {
responseType: 'text'
}),
'export campaign leads'
);
return {
content: [
{
type: 'text',
text: `CSV Data:\n${response.data}`,
},
],
isError: false,
};
} catch (error: any) {
return {
content: [{
type: 'text',
text: `API Error: ${error.response?.data?.message || error.message}`
}],
isError: true,
};
}
}
async function handleDeleteCampaign(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isDeleteCampaignParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_delete_campaign'
);
}
try {
const response = await withRetry(
async () => apiClient.delete(`/campaigns/${args.campaign_id}`),
'delete campaign'
);
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 handleGetCampaignAnalyticsByDate(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGetCampaignAnalyticsByDateParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_campaign_analytics_by_date'
);
}
const { campaign_id, ...params } = args;
try {
const response = await withRetry(
async () => apiClient.get(`/campaigns/${campaign_id}/analytics-by-date`, {
params
}),
'get campaign 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 handleGetCampaignSequenceAnalytics(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGetCampaignSequenceAnalyticsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_campaign_sequence_analytics'
);
}
const { campaign_id, ...params } = args;
try {
const response = await withRetry(
async () => apiClient.get(`/campaigns/${campaign_id}/sequence-analytics`, {
params
}),
'get campaign sequence 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,
};
}
}
```
--------------------------------------------------------------------------------
/src/handlers/email.ts:
--------------------------------------------------------------------------------
```typescript
import { AxiosInstance } from 'axios';
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import {
isListEmailAccountsParams,
isAddEmailToCampaignParams,
isRemoveEmailFromCampaignParams,
isFetchEmailAccountsParams,
isCreateEmailAccountParams,
isUpdateEmailAccountParams,
isFetchEmailAccountByIdParams,
isUpdateEmailWarmupParams,
isReconnectEmailAccountParams,
isUpdateEmailAccountTagParams,
ListEmailAccountsParams,
AddEmailToCampaignParams,
RemoveEmailFromCampaignParams,
FetchEmailAccountsParams,
UpdateEmailAccountParams,
FetchEmailAccountByIdParams,
UpdateEmailWarmupParams,
UpdateEmailAccountTagParams,
CreateEmailAccountParams
} from '../types/email.js';
// Handler for email-related tools
export async function handleEmailTool(
toolName: string,
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
switch (toolName) {
case 'smartlead_list_email_accounts_campaign': {
return handleListEmailAccountsCampaign(args, apiClient, withRetry);
}
case 'smartlead_add_email_to_campaign': {
return handleAddEmailToCampaign(args, apiClient, withRetry);
}
case 'smartlead_remove_email_from_campaign': {
return handleRemoveEmailFromCampaign(args, apiClient, withRetry);
}
case 'smartlead_fetch_email_accounts': {
return handleFetchEmailAccounts(args, apiClient, withRetry);
}
case 'smartlead_create_email_account': {
return handleCreateEmailAccount(args, apiClient, withRetry);
}
case 'smartlead_update_email_account': {
return handleUpdateEmailAccount(args, apiClient, withRetry);
}
case 'smartlead_fetch_email_account_by_id': {
return handleFetchEmailAccountById(args, apiClient, withRetry);
}
case 'smartlead_update_email_warmup': {
return handleUpdateEmailWarmup(args, apiClient, withRetry);
}
case 'smartlead_reconnect_email_account': {
return handleReconnectEmailAccount(args, apiClient, withRetry);
}
case 'smartlead_update_email_account_tag': {
return handleUpdateEmailAccountTag(args, apiClient, withRetry);
}
default:
throw new Error(`Unknown email tool: ${toolName}`);
}
}
// Individual handlers for each tool
async function handleListEmailAccountsCampaign(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isListEmailAccountsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_list_email_accounts_campaign'
);
}
const params = args as ListEmailAccountsParams;
const { campaign_id, status, limit, offset } = params;
if (!campaign_id) {
throw new McpError(
ErrorCode.InvalidParams,
'campaign_id is required for smartlead_list_email_accounts_campaign'
);
}
// API endpoint: https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts
try {
const response = await withRetry(
async () => apiClient.get(`/campaigns/${campaign_id}/email-accounts`),
'list email accounts for campaign'
);
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,
};
}
}
// Placeholder functions for the other handlers
// These will be implemented once we have the API documentation for these endpoints
async function handleAddEmailToCampaign(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isAddEmailToCampaignParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_add_email_to_campaign'
);
}
const { campaign_id, email_account_id } = args as AddEmailToCampaignParams;
// API endpoint: https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts
try {
const response = await withRetry(
async () => apiClient.post(`/campaigns/${campaign_id}/email-accounts`, {
email_account_ids: [email_account_id]
}),
'add email to campaign'
);
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 handleRemoveEmailFromCampaign(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isRemoveEmailFromCampaignParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_remove_email_from_campaign'
);
}
const { campaign_id, email_account_id } = args as RemoveEmailFromCampaignParams;
// API endpoint: https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts
try {
const response = await withRetry(
async () => apiClient.delete(`/campaigns/${campaign_id}/email-accounts`, {
data: {
email_accounts_ids: [email_account_id]
}
}),
'remove email from campaign'
);
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 handleFetchEmailAccounts(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isFetchEmailAccountsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_fetch_email_accounts'
);
}
const { status, limit, offset, username, client_id } = args as FetchEmailAccountsParams;
// Build query parameters
const queryParams: Record<string, string | number> = {};
if (limit !== undefined) queryParams.limit = limit;
if (offset !== undefined) queryParams.offset = offset;
if (username) queryParams.username = username;
if (client_id) queryParams.client_id = client_id;
// API endpoint: https://server.smartlead.ai/api/v1/email-accounts/
try {
const response = await withRetry(
async () => apiClient.get('/email-accounts/', { params: queryParams }),
'fetch all email accounts'
);
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 handleCreateEmailAccount(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isCreateEmailAccountParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_create_email_account'
);
}
const createParams = args as CreateEmailAccountParams;
// API endpoint: https://server.smartlead.ai/api/v1/email-accounts/save
try {
const response = await withRetry(
async () => apiClient.post('/email-accounts/save', {
id: null, // Set null to create new email account
from_name: createParams.from_name,
from_email: createParams.from_email,
user_name: createParams.user_name,
password: createParams.password,
smtp_host: createParams.smtp_host,
smtp_port: createParams.smtp_port,
imap_host: createParams.imap_host,
imap_port: createParams.imap_port,
max_email_per_day: createParams.max_email_per_day,
custom_tracking_url: createParams.custom_tracking_url,
bcc: createParams.bcc,
signature: createParams.signature,
warmup_enabled: createParams.warmup_enabled,
total_warmup_per_day: createParams.total_warmup_per_day,
daily_rampup: createParams.daily_rampup,
reply_rate_percentage: createParams.reply_rate_percentage,
client_id: createParams.client_id
}),
'create email account'
);
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 handleUpdateEmailAccount(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isUpdateEmailAccountParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_update_email_account'
);
}
const { email_account_id, ...updateParams } = args as UpdateEmailAccountParams;
// API endpoint: https://server.smartlead.ai/api/v1/email-accounts/{email_account_id}
try {
const response = await withRetry(
async () => apiClient.post(`/email-accounts/${email_account_id}`, updateParams),
'update email account'
);
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 handleFetchEmailAccountById(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isFetchEmailAccountByIdParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_fetch_email_account_by_id'
);
}
const { email_account_id } = args as FetchEmailAccountByIdParams;
// API endpoint: https://server.smartlead.ai/api/v1/email-accounts/{account_id}/
try {
const response = await withRetry(
async () => apiClient.get(`/email-accounts/${email_account_id}/`),
'fetch email account by id'
);
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 handleUpdateEmailWarmup(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isUpdateEmailWarmupParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_update_email_warmup'
);
}
const { email_account_id, ...warmupParams } = args as UpdateEmailWarmupParams;
// API endpoint: https://server.smartlead.ai/api/v1/email-accounts/{email_account_id}/warmup
try {
const response = await withRetry(
async () => apiClient.post(`/email-accounts/${email_account_id}/warmup`, warmupParams),
'update email warmup'
);
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 handleReconnectEmailAccount(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isReconnectEmailAccountParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_reconnect_email_account'
);
}
// API endpoint: https://server.smartlead.ai/api/v1/email-accounts/reconnect-failed-email-accounts
try {
const response = await withRetry(
async () => apiClient.post('/email-accounts/reconnect-failed-email-accounts', {}),
'reconnect failed email accounts'
);
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 handleUpdateEmailAccountTag(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isUpdateEmailAccountTagParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_update_email_account_tag'
);
}
const { id, name, color } = args as UpdateEmailAccountTagParams;
// API endpoint: https://server.smartlead.ai/api/v1/email-accounts/tag-manager
try {
const response = await withRetry(
async () => apiClient.post('/email-accounts/tag-manager', {
id,
name,
color
}),
'update email account tag'
);
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,
};
}
}
```
--------------------------------------------------------------------------------
/src/handlers/statistics.ts:
--------------------------------------------------------------------------------
```typescript
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,
};
}
}
```
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
```typescript
#!/usr/bin/env node
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
InitializeRequestSchema,
InitializedNotificationSchema,
ServerCapabilities
} from '@modelcontextprotocol/sdk/types.js';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import axios, { AxiosInstance } from 'axios';
import dotenv from 'dotenv';
import path from 'path';
// Import licensing system
import { validateLicense, trackUsage, isFeatureEnabled, printLicenseStatus, getFeatureToken } from './licensing/index.js';
// Import Supergateway integration
import { createSupergateway } from './supergateway.js';
// Import our modular components
import { campaignTools } from './tools/campaign.js';
// import { emailTools } from './tools/email.js';
import { leadTools } from './tools/lead.js';
import { statisticsTools } from './tools/statistics.js';
import { smartDeliveryTools } from './tools/smartDelivery.js';
import { webhookTools } from './tools/webhooks.js';
import { clientManagementTools } from './tools/clientManagement.js';
import { smartSendersTools } from './tools/smartSenders.js';
import { handleCampaignTool } from './handlers/campaign.js';
// import { handleEmailTool } from './handlers/email.js';
import { handleLeadTool } from './handlers/lead.js';
import { handleStatisticsTool } from './handlers/statistics.js';
import { handleSmartDeliveryTool } from './handlers/smartDelivery.js';
import { handleWebhookTool } from './handlers/webhooks.js';
import { handleClientManagementTool } from './handlers/clientManagement.js';
import { handleSmartSendersTool } from './handlers/smartSenders.js';
import { enabledCategories, featureFlags } from './config/feature-config.js';
import { ToolCategory } from './types/common.js';
import { toolRegistry } from './registry/tool-registry.js';
console.log('Starting Smartlead MCP Server...');
// Load environment variables from .env file in the project root
dotenv.config({ path: path.resolve(process.cwd(), '.env') });
// Check license on startup
(async () => {
// Print detailed license information
await printLicenseStatus();
// Always enable n8n integration regardless of license
featureFlags.n8nIntegration = true;
})().catch(error => {
console.error('License validation error:', error);
// Still ensure n8n integration is enabled even if there's an error
featureFlags.n8nIntegration = true;
});
// Check if Supergateway integration is enabled
const useSupergateway = process.env.USE_SUPERGATEWAY === 'true';
// Define server capabilities
const serverCapabilities: ServerCapabilities = {
tools: {
callTool: true,
listTools: true
},
logging: {
loggingMessage: true
}
};
// Server implementation
const server = new Server(
{
name: 'smartlead-mcp',
version: '1.0.0',
},
{
capabilities: serverCapabilities,
instructions: 'Smartlead MCP Server for accessing Smartlead API functionality'
}
);
// Get API key and URL from environment variables
const SMARTLEAD_API_KEY = process.env.SMARTLEAD_API_KEY;
const SMARTLEAD_API_URL = process.env.SMARTLEAD_API_URL || 'https://server.smartlead.ai/api/v1';
// Check if API key is provided
if (!SMARTLEAD_API_KEY) {
console.error('Error: SMARTLEAD_API_KEY environment variable is required');
process.exit(1);
}
// Configuration for retries and monitoring
const CONFIG = {
retry: {
maxAttempts: Number(process.env.SMARTLEAD_RETRY_MAX_ATTEMPTS) || 3,
initialDelay: Number(process.env.SMARTLEAD_RETRY_INITIAL_DELAY) || 1000,
maxDelay: Number(process.env.SMARTLEAD_RETRY_MAX_DELAY) || 10000,
backoffFactor: Number(process.env.SMARTLEAD_RETRY_BACKOFF_FACTOR) || 2,
},
};
// Initialize Axios instance for API requests
const apiClient: AxiosInstance = axios.create({
baseURL: SMARTLEAD_API_URL,
params: {
api_key: SMARTLEAD_API_KEY,
},
headers: {
'Content-Type': 'application/json',
},
});
let isStdioTransport = true;
function safeLog(
level:
| 'error'
| 'debug'
| 'info'
| 'notice'
| 'warning'
| 'critical'
| 'alert'
| 'emergency',
data: any
): void {
try {
// Always log to stderr for now to avoid protocol interference
const logMessage = typeof data === 'object' ? JSON.stringify(data) : data;
console.error(`[${level}] ${logMessage}`);
// Try to send via proper logging mechanism, but don't throw if it fails
try {
server.sendLoggingMessage({ level, data }).catch(e => {
console.error(`Failed to send log via protocol: ${e.message}`);
});
} catch (e) {
console.error(`Error in logging mechanism: ${e instanceof Error ? e.message : String(e)}`);
}
} catch (e) {
// Last resort fallback if anything in the logging fails
console.error(`[${level}] Failed to format log message: ${e instanceof Error ? e.message : String(e)}`);
try {
console.error(`Original data type: ${typeof data}`);
} catch (_) {
// Ignore any errors in the fallback logging
}
}
}
// Add utility function for delay
function delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// Add retry logic with exponential backoff
async function withRetry<T>(
operation: () => Promise<T>,
context: string,
attempt = 1
): Promise<T> {
try {
return await operation();
} catch (error) {
const isRateLimit =
error instanceof Error &&
(error.message.includes('rate limit') || error.message.includes('429'));
if (isRateLimit && attempt < CONFIG.retry.maxAttempts) {
const delayMs = Math.min(
CONFIG.retry.initialDelay *
Math.pow(CONFIG.retry.backoffFactor, attempt - 1),
CONFIG.retry.maxDelay
);
safeLog(
'warning',
`Rate limit hit for ${context}. Attempt ${attempt}/${CONFIG.retry.maxAttempts}. Retrying in ${delayMs}ms`
);
await delay(delayMs);
return withRetry(operation, context, attempt + 1);
}
throw error;
}
}
// Register all available tools with the registry
function registerTools() {
// Register campaign tools if enabled
if (enabledCategories.campaignManagement) {
toolRegistry.registerMany(campaignTools);
}
// Register email account tools if enabled
// if (enabledCategories.emailAccountManagement) {
// toolRegistry.registerMany(emailTools);
// }
// Register lead management tools if enabled
if (enabledCategories.leadManagement) {
toolRegistry.registerMany(leadTools);
}
// Register campaign statistics tools if enabled
if (enabledCategories.campaignStatistics) {
toolRegistry.registerMany(statisticsTools);
}
// Register smart delivery tools if enabled
if (enabledCategories.smartDelivery) {
toolRegistry.registerMany(smartDeliveryTools);
}
// Register webhook tools if enabled
if (enabledCategories.webhooks) {
toolRegistry.registerMany(webhookTools);
}
// Register client management tools if enabled
if (enabledCategories.clientManagement) {
toolRegistry.registerMany(clientManagementTools);
}
// Register smart senders tools if enabled
if (enabledCategories.smartSenders) {
toolRegistry.registerMany(smartSendersTools);
}
// Add more categories here as they are implemented
// For example:
// if (enabledCategories.emailAccountManagement) {
// toolRegistry.registerMany(emailAccountTools);
// }
}
// Initialize the tool registry
registerTools();
// Tool handlers
server.setRequestHandler(ListToolsRequestSchema, async () => {
safeLog('info', 'Handling listTools request');
try {
// Get license-filtered tools
const tools = await toolRegistry.getEnabledToolsAsync();
// Log license status and available tools count
const license = await validateLicense();
safeLog('info', `Listing ${tools.length} tools available in ${license.level} license tier`);
return {
tools: tools,
};
} catch (error) {
// Fallback to sync method if async fails
safeLog('warning', `License validation failed, using default tool list: ${error}`);
return {
tools: toolRegistry.getEnabledTools(),
};
}
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const startTime = Date.now();
try {
const { name, arguments: args } = request.params;
// Log incoming request with timestamp
safeLog(
'info',
`[${new Date().toISOString()}] Received request for tool: ${name}`
);
// Safe guard for undefined arguments
const toolArgs = args || {};
// Check if the tool exists in the registry
if (!toolRegistry.hasToolWithName(name)) {
return {
content: [{ type: "text", text: `Unknown tool: ${name}` }],
isError: true,
};
}
// Get the tool details to determine which handler to use
const tool = toolRegistry.getByName(name);
if (!tool) {
return {
content: [{ type: "text", text: `Tool ${name} not found in registry` }],
isError: true,
};
}
// Check license for tool access
const licenseResult = await validateLicense();
// For premium features, we can require server-side validation tokens
if (tool.requiresServerValidation && tool.category === 'premium') {
const token = await getFeatureToken();
if (!token) {
return {
content: [{
type: "text",
text: `Tool ${name} requires server-side validation. Please ensure you have a valid Premium license.`
}],
isError: true,
};
}
}
// Track usage for analytics and quota tracking
await trackUsage(process.env.JEAN_LICENSE_KEY, name);
// Check if this tool category is allowed by the license
if (!licenseResult.features.allowedCategories.includes(tool.category)) {
return {
content: [{
type: "text",
text: `Tool ${name} is not available in your current license tier (${licenseResult.level}). Please upgrade to access this feature.`
}],
isError: true,
};
}
// Check for usage quota limits
if (licenseResult.usageCount >= licenseResult.features.maxRequests && licenseResult.level !== 'premium') {
return {
content: [{
type: "text",
text: `You have reached your monthly usage quota (${licenseResult.features.maxRequests} requests). Please upgrade your plan to continue using this service.`
}],
isError: true,
};
}
// Call the appropriate handler based on tool category
switch (tool.category) {
case ToolCategory.CAMPAIGN_MANAGEMENT:
return await handleCampaignTool(name, toolArgs, apiClient, withRetry);
// case ToolCategory.EMAIL_ACCOUNT_MANAGEMENT:
// return await handleEmailTool(name, toolArgs, apiClient, withRetry);
case ToolCategory.LEAD_MANAGEMENT:
return await handleLeadTool(name, toolArgs, apiClient, withRetry);
case ToolCategory.CAMPAIGN_STATISTICS:
return await handleStatisticsTool(name, toolArgs, apiClient, withRetry);
case ToolCategory.SMART_DELIVERY:
return await handleSmartDeliveryTool(name, toolArgs, apiClient, withRetry);
case ToolCategory.WEBHOOKS:
return await handleWebhookTool(name, toolArgs, apiClient, withRetry);
case ToolCategory.CLIENT_MANAGEMENT:
return await handleClientManagementTool(name, toolArgs, apiClient, withRetry);
case ToolCategory.SMART_SENDERS:
return await handleSmartSendersTool(name, toolArgs, apiClient, withRetry);
default:
return {
content: [{ type: "text", text: `Unsupported tool category: ${tool.category}` }],
isError: true,
};
}
} catch (error) {
// Log detailed error information
safeLog('error', {
message: `Request failed: ${
error instanceof Error ? error.message : String(error)
}`,
tool: request.params.name,
arguments: request.params.arguments,
timestamp: new Date().toISOString(),
duration: Date.now() - startTime,
});
return {
content: [
{
type: "text",
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
} finally {
// Log request completion with performance metrics
safeLog('info', `Request completed in ${Date.now() - startTime}ms`);
}
});
// Initialize handler (part of the protocol)
server.setRequestHandler(InitializeRequestSchema, async (request) => {
safeLog('info', `Handling initialize request from ${request.params.clientInfo?.name || 'unknown client'}`);
console.error(`[DEBUG] Initialize request received: ${JSON.stringify(request.params, null, 2)}`);
// Respond with our server info and capabilities
const response = {
serverInfo: {
name: 'smartlead-mcp',
version: '1.0.0',
},
capabilities: serverCapabilities,
instructions: 'Smartlead MCP Server for accessing Smartlead API functionality',
protocolVersion: request.params.protocolVersion || '2024-11-05'
};
console.error(`[DEBUG] Sending initialize response: ${JSON.stringify(response, null, 2)}`);
return response;
});
// Initialized notification (part of the protocol)
server.setNotificationHandler(InitializedNotificationSchema, () => {
safeLog('info', 'Client initialized - ready to handle requests');
console.error('[DEBUG] Received initialized notification from client');
});
// Server startup
async function runServer() {
try {
console.error('Initializing Smartlead MCP Server...');
// Check if we're trying to use n8n integration
const usingN8nMode = process.env.USE_SUPERGATEWAY === 'true' || process.argv.includes('--sse');
if (usingN8nMode) {
// Check license for n8n integration permission
const licenseResult = await validateLicense();
if (!licenseResult.features.n8nIntegration) {
console.error('=============================================================');
console.error('ERROR: Your license does not include n8n integration features');
console.error('This feature requires a Basic or Premium license subscription.');
console.error('Visit https://yourservice.com/pricing to upgrade your plan.');
console.error('=============================================================');
process.exit(1);
} else {
console.error('n8n integration enabled - ' + licenseResult.level.charAt(0).toUpperCase() + licenseResult.level.slice(1) + ' license detected');
}
}
// Use standard stdio transport directly
const transport = new StdioServerTransport();
console.error('Running in stdio mode, logging will be directed to stderr');
// Set up error handling
process.on('uncaughtException', (error) => {
console.error(`[FATAL] Uncaught exception: ${error.message}`);
console.error(error.stack);
// Don't exit - just log the error
});
process.on('unhandledRejection', (reason, promise) => {
console.error(`[FATAL] Unhandled promise rejection: ${reason}`);
// Don't exit - just log the error
});
// Add transport error handler
transport.onerror = (error) => {
console.error(`[ERROR] Transport error: ${error.message}`);
};
// Connect to the transport
await server.connect(transport);
// Set onclose handler
transport.onclose = () => {
console.error('[INFO] Transport was closed. This should only happen when the process is shutting down.');
};
// Now that we're connected, we can send logging messages
safeLog('info', 'Smartlead MCP Server initialized successfully');
safeLog(
'info',
`Configuration: API URL: ${SMARTLEAD_API_URL}`
);
// Log license information
const licenseInfo = await validateLicense();
safeLog('info', `License tier: ${licenseInfo.level} - ${licenseInfo.message}`);
// Log which categories are enabled
const enabledCats = licenseInfo.features.allowedCategories.join(', ');
safeLog('info', `Enabled categories: ${enabledCats}`);
// Log the number of enabled tools
const enabledToolsCount = toolRegistry.getEnabledTools().length;
safeLog('info', `Enabled tools: ${enabledToolsCount}`);
console.error('Smartlead MCP Server running on stdio');
// Keep the process running
process.stdin.resume();
} catch (error) {
console.error('Fatal error running server:', error);
process.exit(1);
}
}
runServer().catch((error: any) => {
console.error('Fatal error running server:', error);
process.exit(1);
});
```
--------------------------------------------------------------------------------
/src/tools/smartDelivery.ts:
--------------------------------------------------------------------------------
```typescript
import { CategoryTool, ToolCategory } from '../types/common.js';
// Smart Delivery Tools
export const GET_REGION_WISE_PROVIDERS_TOOL: CategoryTool = {
name: 'smartlead_get_region_wise_providers',
description: 'Retrieve the list of all Email Providers for spam testing classified by region/country. These provider IDs are required to create manual or automated spam tests.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
// This endpoint doesn't require any specific parameters beyond the API key
// which is handled at the API client level
},
required: [],
},
};
export const CREATE_MANUAL_PLACEMENT_TEST_TOOL: CategoryTool = {
name: 'smartlead_create_manual_placement_test',
description: 'Create a manual placement test using Smartlead mailboxes to test email deliverability across various email providers.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
test_name: {
type: 'string',
description: 'Name of your test',
},
description: {
type: 'string',
description: 'Description for your test to reference later',
},
spam_filters: {
type: 'array',
items: { type: 'string' },
description: 'Array of spam filters to test across, e.g. ["spam_assassin"]',
},
link_checker: {
type: 'boolean',
description: 'Enable to check if domains for links in email body are blacklisted',
},
campaign_id: {
type: 'integer',
description: 'Campaign ID for which you want to select the sequence to test',
},
sequence_mapping_id: {
type: 'integer',
description: 'The ID of the sequence or variant you would like to test',
},
provider_ids: {
type: 'array',
items: { type: 'integer' },
description: 'Array of provider IDs to send test emails to',
},
sender_accounts: {
type: 'array',
items: { type: 'string' },
description: 'Array of email addresses to use as senders',
},
all_email_sent_without_time_gap: {
type: 'boolean',
description: 'Set true to send all emails simultaneously',
},
min_time_btwn_emails: {
type: 'integer',
description: 'Time gap between each email from each mailbox (if time gap enabled)',
},
min_time_unit: {
type: 'string',
description: 'Time unit for the time gap (minutes, hours, days)',
},
is_warmup: {
type: 'boolean',
description: 'Set true to receive positive intent responses and move emails from spam to inbox',
},
},
required: ['test_name', 'spam_filters', 'link_checker', 'campaign_id', 'sequence_mapping_id', 'provider_ids', 'sender_accounts', 'all_email_sent_without_time_gap', 'min_time_btwn_emails', 'min_time_unit', 'is_warmup'],
},
};
export const CREATE_AUTOMATED_PLACEMENT_TEST_TOOL: CategoryTool = {
name: 'smartlead_create_automated_placement_test',
description: 'Create an automated placement test that runs on a schedule using Smart Delivery.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
test_name: {
type: 'string',
description: 'Name of your test',
},
description: {
type: 'string',
description: 'Description for your test to reference later',
},
spam_filters: {
type: 'array',
items: { type: 'string' },
description: 'Array of spam filters to test across, e.g. ["spam_assassin"]',
},
link_checker: {
type: 'boolean',
description: 'Enable to check if domains for links in email body are blacklisted',
},
campaign_id: {
type: 'integer',
description: 'Campaign ID for which you want to select the sequence to test',
},
sequence_mapping_id: {
type: 'integer',
description: 'The ID of the sequence or variant you would like to test',
},
provider_ids: {
type: 'array',
items: { type: 'integer' },
description: 'Array of provider IDs to send test emails to',
},
sender_accounts: {
type: 'array',
items: { type: 'string' },
description: 'Array of email addresses to use as senders',
},
all_email_sent_without_time_gap: {
type: 'boolean',
description: 'Set true to send all emails simultaneously',
},
min_time_btwn_emails: {
type: 'integer',
description: 'Time gap between each email from each mailbox (if time gap enabled)',
},
min_time_unit: {
type: 'string',
description: 'Time unit for the time gap (minutes, hours, days)',
},
is_warmup: {
type: 'boolean',
description: 'Set true to receive positive intent responses and move emails from spam to inbox',
},
schedule_start_time: {
type: 'string',
description: 'Start date and time to schedule or run the test (ISO format)',
},
test_end_date: {
type: 'string',
description: 'End date to stop running your test (YYYY-MM-DD format)',
},
every_days: {
type: 'integer',
description: 'Frequency of how often to run a new test',
},
tz: {
type: 'string',
description: 'Timezone for scheduling',
},
days: {
type: 'array',
items: { type: 'integer' },
description: 'Days of the week to run the test (1-7, where 1 is Monday)',
},
starHour: {
type: 'string',
description: 'Test start time',
},
folder_id: {
type: 'integer',
description: 'Folder ID to assign the test to',
},
},
required: ['test_name', 'spam_filters', 'link_checker', 'campaign_id', 'sequence_mapping_id', 'provider_ids', 'sender_accounts', 'all_email_sent_without_time_gap', 'min_time_btwn_emails', 'min_time_unit', 'is_warmup', 'schedule_start_time', 'test_end_date', 'every_days', 'tz', 'days'],
},
};
export const GET_SPAM_TEST_DETAILS_TOOL: CategoryTool = {
name: 'smartlead_get_spam_test_details',
description: 'Retrieve details of a specific spam test by ID.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to retrieve details for',
},
},
required: ['spam_test_id'],
},
};
export const DELETE_SMART_DELIVERY_TESTS_TOOL: CategoryTool = {
name: 'smartlead_delete_smart_delivery_tests',
description: 'Delete multiple Smart Delivery tests in bulk.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spamTestIds: {
type: 'array',
items: { type: 'integer' },
description: 'Array of spam test IDs to delete',
},
},
required: ['spamTestIds'],
},
};
export const STOP_AUTOMATED_TEST_TOOL: CategoryTool = {
name: 'smartlead_stop_automated_test',
description: 'Stop an active automated test before its end date.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the automated test to stop',
},
},
required: ['spam_test_id'],
},
};
export const LIST_ALL_TESTS_TOOL: CategoryTool = {
name: 'smartlead_list_all_tests',
description: 'List all Smart Delivery tests, either manual or automated.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
testType: {
type: 'string',
enum: ['manual', 'auto'],
description: 'Type of tests to list (manual or auto)',
},
limit: {
type: 'integer',
description: 'Number of tests to retrieve (default: 10)',
},
offset: {
type: 'integer',
description: 'Offset for pagination (default: 0)',
},
},
required: ['testType'],
},
};
export const GET_PROVIDER_WISE_REPORT_TOOL: CategoryTool = {
name: 'smartlead_get_provider_wise_report',
description: 'Get detailed report of a spam test sorted by email providers.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the provider-wise report for',
},
},
required: ['spam_test_id'],
},
};
export const GET_GROUP_WISE_REPORT_TOOL: CategoryTool = {
name: 'smartlead_get_group_wise_report',
description: 'Get detailed report of a spam test sorted by location (region/country).',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the group-wise report for',
},
},
required: ['spam_test_id'],
},
};
export const GET_SENDER_ACCOUNT_WISE_REPORT_TOOL: CategoryTool = {
name: 'smartlead_get_sender_account_wise_report',
description: 'Get detailed report of a spam test sorted by sender accounts with details of each email from each mailbox.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the sender account-wise report for',
},
},
required: ['spam_test_id'],
},
};
export const GET_SPAM_FILTER_DETAILS_TOOL: CategoryTool = {
name: 'smartlead_get_spam_filter_details',
description: 'Get spam filter report per sender mailbox showing each spam score with details leading to the score.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the spam filter details for',
},
},
required: ['spam_test_id'],
},
};
export const GET_DKIM_DETAILS_TOOL: CategoryTool = {
name: 'smartlead_get_dkim_details',
description: 'Check if DKIM authentication passed or failed for each sender mailbox and receiver account.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the DKIM details for',
},
},
required: ['spam_test_id'],
},
};
export const GET_SPF_DETAILS_TOOL: CategoryTool = {
name: 'smartlead_get_spf_details',
description: 'Check if SPF authentication passed or failed for the test.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the SPF details for',
},
},
required: ['spam_test_id'],
},
};
export const GET_RDNS_DETAILS_TOOL: CategoryTool = {
name: 'smartlead_get_rdns_details',
description: 'Check if rDNS was correct for an IP sending the email.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the rDNS details for',
},
},
required: ['spam_test_id'],
},
};
export const GET_SENDER_ACCOUNTS_TOOL: CategoryTool = {
name: 'smartlead_get_sender_accounts',
description: 'Get the list of all sender accounts selected for a specific spam test.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the sender accounts for',
},
},
required: ['spam_test_id'],
},
};
export const GET_BLACKLIST_TOOL: CategoryTool = {
name: 'smartlead_get_blacklist',
description: 'Get the list of all blacklists per IP per email sent.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the blacklist information for',
},
},
required: ['spam_test_id'],
},
};
export const GET_EMAIL_CONTENT_TOOL: CategoryTool = {
name: 'smartlead_get_email_content',
description: 'Get details for the email content (raw, HTML) along with campaign and sequence details.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the email content for',
},
},
required: ['spam_test_id'],
},
};
export const GET_IP_ANALYTICS_TOOL: CategoryTool = {
name: 'smartlead_get_ip_analytics',
description: 'Get total blacklist count identified in the test.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test to get the IP analytics for',
},
},
required: ['spam_test_id'],
},
};
export const GET_EMAIL_HEADERS_TOOL: CategoryTool = {
name: 'smartlead_get_email_headers',
description: 'Get details of the email headers for a specific email.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test',
},
reply_id: {
type: 'integer',
description: 'ID of the email received by the seed account',
},
},
required: ['spam_test_id', 'reply_id'],
},
};
export const GET_SCHEDULE_HISTORY_TOOL: CategoryTool = {
name: 'smartlead_get_schedule_history',
description: 'Get the list and summary of all tests that ran for a particular automated test.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the automated spam test to get the schedule history for',
},
},
required: ['spam_test_id'],
},
};
export const GET_IP_DETAILS_TOOL: CategoryTool = {
name: 'smartlead_get_ip_details',
description: 'Get the list of all blacklists per IP for a specific email.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
spam_test_id: {
type: 'integer',
description: 'ID of the spam test',
},
reply_id: {
type: 'integer',
description: 'ID of the email received by the seed account',
},
},
required: ['spam_test_id', 'reply_id'],
},
};
export const GET_MAILBOX_SUMMARY_TOOL: CategoryTool = {
name: 'smartlead_get_mailbox_summary',
description: 'Get the list of mailboxes used for any Smart Delivery test with overall performance across all tests.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
limit: {
type: 'integer',
description: 'Number of tests to retrieve (default: 10)',
},
offset: {
type: 'integer',
description: 'Offset for pagination (default: 0)',
},
},
},
};
export const GET_MAILBOX_COUNT_TOOL: CategoryTool = {
name: 'smartlead_get_mailbox_count',
description: 'Get the count of all mailboxes used for any spam test.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {},
},
};
export const GET_ALL_FOLDERS_TOOL: CategoryTool = {
name: 'smartlead_get_all_folders',
description: 'Get the list and details of all folders created in Smart Delivery along with tests inside each folder.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
limit: {
type: 'integer',
description: 'Number of folders to retrieve (default: 10)',
},
offset: {
type: 'integer',
description: 'Offset for pagination (default: 0)',
},
name: {
type: 'string',
description: 'Filter folders by name',
},
},
},
};
export const CREATE_FOLDER_TOOL: CategoryTool = {
name: 'smartlead_create_folder',
description: 'Create a folder in Smart Delivery to organize tests.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the folder to create',
},
},
required: ['name'],
},
};
export const GET_FOLDER_BY_ID_TOOL: CategoryTool = {
name: 'smartlead_get_folder_by_id',
description: 'Get details of a specific folder by ID.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
folder_id: {
type: 'integer',
description: 'ID of the folder to retrieve',
},
},
required: ['folder_id'],
},
};
export const DELETE_FOLDER_TOOL: CategoryTool = {
name: 'smartlead_delete_folder',
description: 'Delete a folder from Smart Delivery.',
category: ToolCategory.SMART_DELIVERY,
inputSchema: {
type: 'object',
properties: {
folder_id: {
type: 'integer',
description: 'ID of the folder to delete',
},
},
required: ['folder_id'],
},
};
// Export all tools as an array for easy registration
export const smartDeliveryTools = [
GET_REGION_WISE_PROVIDERS_TOOL,
CREATE_MANUAL_PLACEMENT_TEST_TOOL,
CREATE_AUTOMATED_PLACEMENT_TEST_TOOL,
GET_SPAM_TEST_DETAILS_TOOL,
DELETE_SMART_DELIVERY_TESTS_TOOL,
STOP_AUTOMATED_TEST_TOOL,
LIST_ALL_TESTS_TOOL,
GET_PROVIDER_WISE_REPORT_TOOL,
GET_GROUP_WISE_REPORT_TOOL,
GET_SENDER_ACCOUNT_WISE_REPORT_TOOL,
GET_SPAM_FILTER_DETAILS_TOOL,
GET_DKIM_DETAILS_TOOL,
GET_SPF_DETAILS_TOOL,
GET_RDNS_DETAILS_TOOL,
GET_SENDER_ACCOUNTS_TOOL,
GET_BLACKLIST_TOOL,
GET_EMAIL_CONTENT_TOOL,
GET_IP_ANALYTICS_TOOL,
GET_EMAIL_HEADERS_TOOL,
GET_SCHEDULE_HISTORY_TOOL,
GET_IP_DETAILS_TOOL,
GET_MAILBOX_SUMMARY_TOOL,
GET_MAILBOX_COUNT_TOOL,
GET_ALL_FOLDERS_TOOL,
CREATE_FOLDER_TOOL,
GET_FOLDER_BY_ID_TOOL,
DELETE_FOLDER_TOOL,
];
```
--------------------------------------------------------------------------------
/src/handlers/smartDelivery.ts:
--------------------------------------------------------------------------------
```typescript
import { AxiosInstance } from 'axios';
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import {
isGetRegionWiseProvidersParams,
isCreateManualPlacementTestParams,
isCreateAutomatedPlacementTestParams,
isGetSpamTestDetailsParams,
isDeleteSmartDeliveryTestsParams,
isStopAutomatedTestParams,
isListAllTestsParams,
isProviderWiseReportParams,
isGroupWiseReportParams,
isSenderAccountWiseReportParams,
isSpamFilterDetailsParams,
isDkimDetailsParams,
isSpfDetailsParams,
isRdnsDetailsParams,
isSenderAccountsParams,
isBlacklistParams,
isEmailContentParams,
isIpAnalyticsParams,
isEmailHeadersParams,
isScheduleHistoryParams,
isIpDetailsParams,
isMailboxSummaryParams,
isMailboxCountParams,
isGetAllFoldersParams,
isCreateFolderParams,
isGetFolderByIdParams,
isDeleteFolderParams
} from '../types/smartDelivery.js';
// SmartDelivery API base URL
const SMART_DELIVERY_API_URL = 'https://smartdelivery.smartlead.ai/api/v1';
// Handler for SmartDelivery-related tools
export async function handleSmartDeliveryTool(
toolName: string,
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
switch (toolName) {
case 'smartlead_get_region_wise_providers': {
return handleGetRegionWiseProviders(args, apiClient, withRetry);
}
case 'smartlead_create_manual_placement_test': {
return handleCreateManualPlacementTest(args, apiClient, withRetry);
}
case 'smartlead_create_automated_placement_test': {
return handleCreateAutomatedPlacementTest(args, apiClient, withRetry);
}
case 'smartlead_get_spam_test_details': {
return handleGetSpamTestDetails(args, apiClient, withRetry);
}
case 'smartlead_delete_smart_delivery_tests': {
return handleDeleteSmartDeliveryTests(args, apiClient, withRetry);
}
case 'smartlead_stop_automated_test': {
return handleStopAutomatedTest(args, apiClient, withRetry);
}
case 'smartlead_list_all_tests': {
return handleListAllTests(args, apiClient, withRetry);
}
case 'smartlead_get_provider_wise_report': {
return handleGetProviderWiseReport(args, apiClient, withRetry);
}
case 'smartlead_get_group_wise_report': {
return handleGetGroupWiseReport(args, apiClient, withRetry);
}
case 'smartlead_get_sender_account_wise_report': {
return handleGetSenderAccountWiseReport(args, apiClient, withRetry);
}
case 'smartlead_get_spam_filter_details': {
return handleGetSpamFilterDetails(args, apiClient, withRetry);
}
case 'smartlead_get_dkim_details': {
return handleGetDkimDetails(args, apiClient, withRetry);
}
case 'smartlead_get_spf_details': {
return handleGetSpfDetails(args, apiClient, withRetry);
}
case 'smartlead_get_rdns_details': {
return handleGetRdnsDetails(args, apiClient, withRetry);
}
case 'smartlead_get_sender_accounts': {
return handleGetSenderAccounts(args, apiClient, withRetry);
}
case 'smartlead_get_blacklist': {
return handleGetBlacklist(args, apiClient, withRetry);
}
case 'smartlead_get_email_content': {
return handleGetEmailContent(args, apiClient, withRetry);
}
case 'smartlead_get_ip_analytics': {
return handleGetIpAnalytics(args, apiClient, withRetry);
}
case 'smartlead_get_email_headers': {
return handleGetEmailHeaders(args, apiClient, withRetry);
}
case 'smartlead_get_schedule_history': {
return handleGetScheduleHistory(args, apiClient, withRetry);
}
case 'smartlead_get_ip_details': {
return handleGetIpDetails(args, apiClient, withRetry);
}
case 'smartlead_get_mailbox_summary': {
return handleGetMailboxSummary(args, apiClient, withRetry);
}
case 'smartlead_get_mailbox_count': {
return handleGetMailboxCount(args, apiClient, withRetry);
}
case 'smartlead_get_all_folders': {
return handleGetAllFolders(args, apiClient, withRetry);
}
case 'smartlead_create_folder': {
return handleCreateFolder(args, apiClient, withRetry);
}
case 'smartlead_get_folder_by_id': {
return handleGetFolderById(args, apiClient, withRetry);
}
case 'smartlead_delete_folder': {
return handleDeleteFolder(args, apiClient, withRetry);
}
default:
throw new Error(`Unknown SmartDelivery tool: ${toolName}`);
}
}
// Create a modified client for SmartDelivery API with the correct base URL
function createSmartDeliveryClient(apiClient: AxiosInstance) {
return {
get: (url: string, config?: any) =>
apiClient.get(`${SMART_DELIVERY_API_URL}${url}`, config),
post: (url: string, data?: any, config?: any) =>
apiClient.post(`${SMART_DELIVERY_API_URL}${url}`, data, config),
put: (url: string, data?: any, config?: any) =>
apiClient.put(`${SMART_DELIVERY_API_URL}${url}`, data, config),
delete: (url: string, config?: any) =>
apiClient.delete(`${SMART_DELIVERY_API_URL}${url}`, config)
};
}
// Individual handlers for each tool
async function handleGetRegionWiseProviders(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGetRegionWiseProvidersParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_region_wise_providers'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const response = await withRetry(
async () => smartDeliveryClient.get('/spam-test/seed/providers'),
'get region wise providers'
);
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 handleCreateManualPlacementTest(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isCreateManualPlacementTestParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_create_manual_placement_test'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const response = await withRetry(
async () => smartDeliveryClient.post('/spam-test/manual', args),
'create manual placement test'
);
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 handleCreateAutomatedPlacementTest(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isCreateAutomatedPlacementTestParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_create_automated_placement_test'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const response = await withRetry(
async () => smartDeliveryClient.post('/spam-test/schedule', args),
'create automated placement test'
);
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 handleGetSpamTestDetails(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGetSpamTestDetailsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_spam_test_details'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/${spam_test_id}`),
'get spam test details'
);
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 handleDeleteSmartDeliveryTests(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isDeleteSmartDeliveryTestsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_delete_smart_delivery_tests'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const response = await withRetry(
async () => smartDeliveryClient.post('/spam-test/delete', args),
'delete smart delivery tests'
);
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 handleStopAutomatedTest(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isStopAutomatedTestParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_stop_automated_test'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.put(`/spam-test/${spam_test_id}/stop`),
'stop automated test'
);
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 handleListAllTests(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isListAllTestsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_list_all_tests'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { testType, limit = 10, offset = 0 } = args;
const response = await withRetry(
async () => smartDeliveryClient.post(`/spam-test/report?testType=${testType}`, { limit, offset }),
'list all tests'
);
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 handleGetProviderWiseReport(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isProviderWiseReportParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_provider_wise_report'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.post(`/spam-test/report/${spam_test_id}/providerwise`),
'get provider wise report'
);
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 handleGetGroupWiseReport(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGroupWiseReportParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_group_wise_report'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.post(`/spam-test/report/${spam_test_id}/groupwise`),
'get group wise report'
);
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 handleGetSenderAccountWiseReport(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isSenderAccountWiseReportParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_sender_account_wise_report'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/sender-account-wise`),
'get sender account wise report'
);
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 handleGetSpamFilterDetails(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isSpamFilterDetailsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_spam_filter_details'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/spam-filter-details`),
'get spam filter details'
);
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 handleGetDkimDetails(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isDkimDetailsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_dkim_details'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/dkim-details`),
'get DKIM details'
);
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 handleGetSpfDetails(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isSpfDetailsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_spf_details'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/spf-details`),
'get SPF details'
);
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 handleGetRdnsDetails(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isRdnsDetailsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_rdns_details'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/rdns-details`),
'get rDNS details'
);
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 handleGetSenderAccounts(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isSenderAccountsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_sender_accounts'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/sender-accounts`),
'get sender accounts'
);
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 handleGetBlacklist(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isBlacklistParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_blacklist'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/blacklist`),
'get blacklist'
);
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 handleGetEmailContent(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isEmailContentParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_email_content'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/email-content`),
'get email content'
);
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 handleGetIpAnalytics(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isIpAnalyticsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_ip_analytics'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/ip-analytics`),
'get IP 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 handleGetEmailHeaders(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isEmailHeadersParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_email_headers'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id, reply_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/sender-account-wise/${reply_id}/email-headers`),
'get email headers'
);
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 handleGetScheduleHistory(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isScheduleHistoryParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_schedule_history'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/schedule-history`),
'get schedule history'
);
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 handleGetIpDetails(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isIpDetailsParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_ip_details'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { spam_test_id, reply_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/${spam_test_id}/sender-account-wise/${reply_id}/ip-details`),
'get IP details'
);
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 handleGetMailboxSummary(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isMailboxSummaryParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_mailbox_summary'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { limit = 10, offset = 0 } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/report/mailboxes-summary?limit=${limit}&offset=${offset}`),
'get mailbox summary'
);
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 handleGetMailboxCount(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isMailboxCountParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_mailbox_count'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const response = await withRetry(
async () => smartDeliveryClient.get('/spam-test/report/mailboxes-count'),
'get mailbox count'
);
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 handleGetAllFolders(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGetAllFoldersParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_all_folders'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { limit = 10, offset = 0, name = '' } = args;
const queryParams = new URLSearchParams();
queryParams.append('limit', limit.toString());
queryParams.append('offset', offset.toString());
if (name) {
queryParams.append('name', name);
}
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/folder?${queryParams.toString()}`),
'get all folders'
);
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 handleCreateFolder(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isCreateFolderParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_create_folder'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { name } = args;
const response = await withRetry(
async () => smartDeliveryClient.post('/spam-test/folder', { name }),
'create folder'
);
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 handleGetFolderById(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isGetFolderByIdParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_get_folder_by_id'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { folder_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.get(`/spam-test/folder/${folder_id}`),
'get folder by ID'
);
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 handleDeleteFolder(
args: unknown,
apiClient: AxiosInstance,
withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
if (!isDeleteFolderParams(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Invalid arguments for smartlead_delete_folder'
);
}
try {
const smartDeliveryClient = createSmartDeliveryClient(apiClient);
const { folder_id } = args;
const response = await withRetry(
async () => smartDeliveryClient.delete(`/spam-test/folder/${folder_id}`),
'delete folder'
);
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,
};
}
}
```