#
tokens: 48986/50000 48/54 files (page 1/2)
lines: off (toggle) GitHub
raw markdown copy
This is page 1 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

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
# Dependency directories
node_modules/

# Build output
dist/

# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Coverage directory used by tools like istanbul
coverage/

# IDE files
.idea/
.vscode/
*.swp
*.swo

# OS files
.DS_Store
Thumbs.db

```

--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------

```
# Smartlead API Key (required)
SMARTLEAD_API_KEY=your_api_key_here

# Optional: Custom API URL (defaults to https://server.smartlead.ai/api/v1)
# SMARTLEAD_API_URL=https://custom-server.smartlead.ai/api/v1

# Retry configuration
SMARTLEAD_RETRY_MAX_ATTEMPTS=3
SMARTLEAD_RETRY_INITIAL_DELAY=1000
SMARTLEAD_RETRY_MAX_DELAY=10000
SMARTLEAD_RETRY_BACKOFF_FACTOR=2

# Supergateway Integration
# Set to 'true' to enable Supergateway integration
USE_SUPERGATEWAY=false
# Required if USE_SUPERGATEWAY is true

# Download Tracking Configuration (optional)
# DOWNLOAD_LOG_PATH=/custom/path/to/downloads.json

# Enable Features
# All features are enabled by default. No license key required.

```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
[![MseeP.ai Security Assessment Badge](https://mseep.net/pr/jean-technologies-smartlead-mcp-server-local-badge.png)](https://mseep.ai/app/jean-technologies-smartlead-mcp-server-local)

# Smartlead Simplified MCP Server

[![smithery badge](https://smithery.ai/badge/@jean-technologies/smartlead-mcp-server-local)](https://smithery.ai/server/@jean-technologies/smartlead-mcp-server-local)

This application provides a simplified interface to the Smartlead API, allowing AI assistants and automation tools to interact with Smartlead's email marketing features. We welcome contribution from the community.

**Licensing:** All features are now enabled by default with maximum permissiveness! No license key required.

> **For developer details:** See [DEVELOPER_ONBOARDING.md](./DEVELOPER_ONBOARDING.md)

## Quick Start

### Installation
```bash
npm install [email protected]
```

or use directly with npx (no installation needed):


### Installing via Smithery

To install Smartlead Campaign Management Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@jean-technologies/smartlead-mcp-server-local):

```bash
npx -y @smithery/cli install @jean-technologies/smartlead-mcp-server-local --client claude
```

### With Claude:
```bash
npx smartlead-mcp-server start
```

### With n8n:
```bash
npx smartlead-mcp-server sse
```

First run will prompt for your Smartlead API Key. No license key is required.

## Integration Examples

### Claude Extension:
```json
{
  "mcpServers": {
    "smartlead": {
      "command": "npx",
      "args": ["smartlead-mcp-server", "start"],
      "env": {
        "SMARTLEAD_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

### n8n Setup:
1. Start the server: `npx smartlead-mcp-server sse`
2. Configure n8n MCP Client node with:
   - SSE URL: `http://localhost:3000/sse`
   - Message URL: `http://localhost:3000/message`

## Available Features

**All features are now enabled by default, including:**
- Campaign & Lead Management
- Statistics and Analytics
- Smart Delivery & Webhooks
- n8n Integration
- Client Management
- Smart Senders
- Download Tracking and Analytics

## New Download Tracking Features

This release adds new download tracking capabilities:

### Download Campaign Data
Download campaign data with tracking using the `smartlead_download_campaign_data` tool:
```json
{
  "campaign_id": 12345,
  "download_type": "analytics", // "analytics", "leads", "sequence", "full_export"
  "format": "json", // "json" or "csv"
  "user_id": "optional-user-identifier"
}
```

### View Download Statistics
View download statistics using the `smartlead_view_download_statistics` tool:
```json
{
  "time_period": "all", // "all", "today", "week", "month"
  "group_by": "type" // "type", "format", "campaign", "date"
}
```

All downloads are tracked in `~/.smartlead-mcp/downloads.json` for analytics.

## Need Help?

- Run `npx smartlead-mcp-server config` to set up credentials
- Use `--api-key` option for non-interactive setup
- Contact: [email protected]
- Website: [jeantechnologies.com](https://jeantechnologies.com)

## License

This software is proprietary and confidential. Unauthorized copying, redistribution, or use of this software, in whole or in part, via any medium, is strictly prohibited without the express permission of Jean Technologies.

Copyright © 2025 Jean Technologies. All rights reserved.

```

--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------

```javascript
export default {
  transform: {},
  extensionsToTreatAsEsm: ['.ts'],
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',
  },
  testEnvironment: 'node',
  verbose: true,
  testTimeout: 10000
}; 
```

--------------------------------------------------------------------------------
/mcp_settings_example.json:
--------------------------------------------------------------------------------

```json
{
  "mcpServers": {
    "smartlead": {
      "command": "node",
      "args": ["E:/mcp-servers/smartlead/dist/index.js"],
      "env": {
        "SMARTLEAD_API_KEY": "your_api_key_here"
      },
      "disabled": false,
      "autoApprove": [],
      "name": "@jean-technologies/smartlead-mcp"
    }
  }
}




```

--------------------------------------------------------------------------------
/src/types/statistics.d.ts:
--------------------------------------------------------------------------------

```typescript
export interface CampaignMailboxStatisticsParams {
  campaign_id: number;
}

export interface DownloadCampaignDataParams {
  campaign_id: number;
  download_type: 'analytics' | 'leads' | 'sequence' | 'full_export';
  format: 'json' | 'csv';
  user_id?: string;
}

export interface ViewDownloadStatisticsParams {
  time_period?: 'all' | 'today' | 'week' | 'month';
  group_by?: 'type' | 'format' | 'campaign' | 'date';
} 
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "strict": true,
    "outDir": "dist",
    "declaration": true,
    "sourceMap": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "typeRoots": ["./node_modules/@types", "./src/types"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "**/*.test.ts"]
}

```

--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
# Generated by https://smithery.ai. See: https://smithery.ai/docs/build/project-config
FROM node:lts-alpine
WORKDIR /app

# Install build tools and dependencies
COPY package.json package-lock.json tsconfig.json ./
COPY src ./src

RUN apk add --no-cache python3 make g++ \
    && npm ci --ignore-scripts \
    && npm run build \
    && npm prune --production \
    && apk del python3 make g++

# Default command for stdio usage
CMD ["node", "dist/index.js"]

```

--------------------------------------------------------------------------------
/src/tools/lead.d.ts:
--------------------------------------------------------------------------------

```typescript
// Type declarations for Lead tools
declare module './tools/lead.js' {
  import { CategoryTool } from '../types/common.js';
  
  export const LIST_LEADS_TOOL: CategoryTool;
  export const GET_LEAD_TOOL: CategoryTool;
  export const ADD_LEAD_TO_CAMPAIGN_TOOL: CategoryTool;
  export const UPDATE_LEAD_TOOL: CategoryTool;
  export const UPDATE_LEAD_STATUS_TOOL: CategoryTool;
  export const BULK_IMPORT_LEADS_TOOL: CategoryTool;
  export const DELETE_LEAD_TOOL: CategoryTool;
  
  export const leadTools: CategoryTool[];
} 
```

--------------------------------------------------------------------------------
/src/types/common.ts:
--------------------------------------------------------------------------------

```typescript
import { Tool } from '@modelcontextprotocol/sdk/types.js';

// Extended Tool type with category information
export interface CategoryTool extends Tool {
  category: string;
}

// Categories enum
export enum ToolCategory {
  CAMPAIGN_MANAGEMENT = 'campaignManagement',
  EMAIL_ACCOUNT_MANAGEMENT = 'emailAccountManagement',
  LEAD_MANAGEMENT = 'leadManagement',
  CAMPAIGN_STATISTICS = 'campaignStatistics',
  SMART_DELIVERY = 'smartDelivery',
  WEBHOOKS = 'webhooks',
  CLIENT_MANAGEMENT = 'clientManagement',
  SMART_SENDERS = 'smartSenders'
} 
```

--------------------------------------------------------------------------------
/src/tools/statistics.d.ts:
--------------------------------------------------------------------------------

```typescript
// Type declarations for Statistics tools
declare module './tools/statistics.js' {
  import { CategoryTool } from '../types/common.js';
  
  export const CAMPAIGN_STATISTICS_TOOL: CategoryTool;
  export const CAMPAIGN_STATISTICS_BY_DATE_TOOL: CategoryTool;
  export const WARMUP_STATS_BY_EMAIL_TOOL: CategoryTool;
  export const CAMPAIGN_TOP_LEVEL_ANALYTICS_TOOL: CategoryTool;
  export const CAMPAIGN_TOP_LEVEL_ANALYTICS_BY_DATE_TOOL: CategoryTool;
  export const CAMPAIGN_LEAD_STATISTICS_TOOL: CategoryTool;
  export const CAMPAIGN_MAILBOX_STATISTICS_TOOL: CategoryTool;
  
  export const statisticsTools: CategoryTool[];
} 
```

--------------------------------------------------------------------------------
/src/tools/email.d.ts:
--------------------------------------------------------------------------------

```typescript
// Type declarations for Email tools
declare module './tools/email.js' {
  import { CategoryTool } from '../types/common.js';
  
  export const LIST_EMAIL_ACCOUNTS_CAMPAIGN_TOOL: CategoryTool;
  export const ADD_EMAIL_TO_CAMPAIGN_TOOL: CategoryTool;
  export const REMOVE_EMAIL_FROM_CAMPAIGN_TOOL: CategoryTool;
  export const FETCH_EMAIL_ACCOUNTS_TOOL: CategoryTool;
  export const CREATE_EMAIL_ACCOUNT_TOOL: CategoryTool;
  export const UPDATE_EMAIL_ACCOUNT_TOOL: CategoryTool;
  export const FETCH_EMAIL_ACCOUNT_BY_ID_TOOL: CategoryTool;
  export const UPDATE_EMAIL_WARMUP_TOOL: CategoryTool;
  export const RECONNECT_EMAIL_ACCOUNT_TOOL: CategoryTool;
  export const UPDATE_EMAIL_ACCOUNT_TAG_TOOL: CategoryTool;
  
  export const emailTools: CategoryTool[];
} 
```

--------------------------------------------------------------------------------
/src/types/supergateway.d.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * Type definitions for Supergateway
 */

declare module 'supergateway' {
  export class SuperGateway {
    /**
     * Create a new SuperGateway instance
     * @param options Configuration options including API key
     */
    constructor(options?: { apiKey?: string, [key: string]: any });
  
    /**
     * Process a request
     * @param input Input text to process
     * @param options Processing options
     * @returns Processed text
     */
    process(input: string, options?: Record<string, any>): Promise<string>;
  
    /**
     * Stream a request response
     * @param input Input text to process
     * @param options Processing options
     * @returns Readable stream with response chunks
     */
    stream(input: string, options?: Record<string, any>): Promise<ReadableStream>;
  
    /**
     * Close the client connection
     */
    close(): Promise<void>;
  }
}
```

--------------------------------------------------------------------------------
/smithery.yaml:
--------------------------------------------------------------------------------

```yaml
# Smithery configuration file: https://smithery.ai/docs/build/project-config

startCommand:
  type: stdio
  commandFunction:
    # A JS function that produces the CLI command based on the given config to start the MCP on stdio.
    |-
    (config) => ({ command: 'node', args: ['dist/index.js'], env: { SMARTLEAD_API_KEY: config.smartleadApiKey, JEAN_LICENSE_KEY: config.jeanLicenseKey || 'JEANPARTNER', ...(config.smartleadApiUrl ? { SMARTLEAD_API_URL: config.smartleadApiUrl } : {}) } })
  configSchema:
    # JSON Schema defining the configuration options for the MCP.
    type: object
    required:
      - smartleadApiKey
    properties:
      smartleadApiKey:
        type: string
        description: Smartlead API Key
      jeanLicenseKey:
        type: string
        default: JEANPARTNER
        description: Jean License Key
      smartleadApiUrl:
        type: string
        default: https://server.smartlead.ai/api/v1
        description: Optional Smartlead API URL
  exampleConfig:
    smartleadApiKey: YOUR_SMARTLEAD_API_KEY
    jeanLicenseKey: JEANPARTNER
    smartleadApiUrl: https://server.smartlead.ai/api/v1

```

--------------------------------------------------------------------------------
/src/types/clientManagement.ts:
--------------------------------------------------------------------------------

```typescript
// Type definitions for Client Management functionality

// Client permission types
export type ClientPermission = 'reply_master_inbox' | 'full_access' | string;

// Add Client To System
export interface AddClientParams {
  name: string;
  email: string;
  permission: ClientPermission[];
  logo?: string;
  logo_url?: string | null;
  password: string;
}

// Fetch all clients
export interface FetchAllClientsParams {
  // This endpoint doesn't require specific parameters beyond the API key
  // which is handled at the API client level
}

// Type guards
export function isAddClientParams(args: unknown): args is AddClientParams {
  if (typeof args !== 'object' || args === null) return false;
  
  const params = args as Partial<AddClientParams>;
  
  return (
    typeof params.name === 'string' &&
    typeof params.email === 'string' &&
    Array.isArray(params.permission) &&
    params.permission.every(perm => typeof perm === 'string') &&
    typeof params.password === 'string' &&
    (params.logo === undefined || typeof params.logo === 'string') &&
    (params.logo_url === undefined || params.logo_url === null || typeof params.logo_url === 'string')
  );
}

export function isFetchAllClientsParams(args: unknown): args is FetchAllClientsParams {
  // Since this endpoint doesn't require specific parameters beyond the API key
  // Any object is valid
  return typeof args === 'object' && args !== null;
} 
```

--------------------------------------------------------------------------------
/src/tools/clientManagement.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool, ToolCategory } from '../types/common.js';

// Client Management Tools

export const ADD_CLIENT_TOOL: CategoryTool = {
  name: 'smartlead_add_client',
  description: 'Add a new client to the system, optionally with white-label settings.',
  category: ToolCategory.CLIENT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      name: {
        type: 'string',
        description: 'Name of the client',
      },
      email: {
        type: 'string',
        description: 'Email address of the client',
      },
      permission: {
        type: 'array',
        items: { type: 'string' },
        description: 'Array of permissions to grant to the client. Use ["full_access"] for full permissions.',
      },
      logo: {
        type: 'string',
        description: 'Logo text or identifier',
      },
      logo_url: {
        type: ['string', 'null'],
        description: 'URL to the client\'s logo image',
      },
      password: {
        type: 'string',
        description: 'Password for the client\'s account',
      },
    },
    required: ['name', 'email', 'permission', 'password'],
  },
};

export const FETCH_ALL_CLIENTS_TOOL: CategoryTool = {
  name: 'smartlead_fetch_all_clients',
  description: 'Retrieve a list of all clients in the system.',
  category: ToolCategory.CLIENT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      // This endpoint doesn't require specific parameters beyond the API key
      // which is handled at the API client level
    },
    required: [],
  },
};

// Export all tools as an array for easy registration
export const clientManagementTools = [
  ADD_CLIENT_TOOL,
  FETCH_ALL_CLIENTS_TOOL,
]; 
```

--------------------------------------------------------------------------------
/src/config/feature-config.ts:
--------------------------------------------------------------------------------

```typescript
import { isCategoryEnabled } from '../licensing/index.js';

// Configuration for enabling/disabling feature categories
// These are the default values when license validation is unavailable
export const enabledCategories = {
  campaignManagement: true,
  emailAccountManagement: true,
  leadManagement: true,
  campaignStatistics: true,
  smartDelivery: true,
  webhooks: true,
  clientManagement: true,
  smartSenders: true
};

// Configuration for enabling/disabling individual tools
// This overrides category settings for specific tools
export const enabledTools: Record<string, boolean> = {
  // Override specific tools if needed
  // Example: To enable a specific tool in a disabled category:
  // smartlead_fetch_campaign_sequence: true,
};

// Feature flags for experimental features
export const featureFlags = {
  betaFeatures: process.env.ENABLE_BETA_FEATURES === 'true',
  extendedLogging: process.env.EXTENDED_LOGGING === 'true',
  n8nIntegration: false // Will be set by license validation
};

// Helper function to check if a tool should be enabled
export async function isToolEnabled(toolName: string, category: string): Promise<boolean> {
  // Always enable all tools
  return true;
  
  // The following code is kept for reference but will never execute
  // // Check if the tool has a specific override
  // if (enabledTools[toolName] !== undefined) {
  //   return enabledTools[toolName];
  // }
  // 
  // // Otherwise, check if the category is enabled by the license
  // try {
  //   return await isCategoryEnabled(category);
  // } catch (error) {
  //   // Fallback to default configuration if license check fails
  //   console.error(`License validation failed, using default configuration: ${error}`);
  //   const categoryKey = category as keyof typeof enabledCategories;
  //   return enabledCategories[categoryKey] || false;
  // }
} 
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "smartlead-mcp-server",
  "version": "1.2.1",
  "description": "MCP server for Smartlead campaign management integration. Features include creating campaigns, updating campaign settings, and managing campaign sequences.",
  "author": "Jonathan Politzki",
  "type": "module",
  "bin": {
    "smartlead-mcp": "dist/cli.js"
  },
  "files": [
    "dist"
  ],
  "scripts": {
    "build": "tsc",
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
    "test:supergateway": "node test_supergateway.js",
    "start": "node dist/index.js",
    "start:supergateway": "USE_SUPERGATEWAY=true SUPERGATEWAY_API_KEY=test_key node dist/index.js",
    "start:sse": "npx -y supergateway --stdio \"node dist/index.js\" --port 3000",
    "start:sse-supergateway": "npx -y supergateway --stdio \"USE_SUPERGATEWAY=true SUPERGATEWAY_API_KEY=test_key node dist/index.js\" --port 3000",
    "dev": "npm run build && npm start",
    "dev:supergateway": "npm run build && npm run start:supergateway",
    "dev:sse": "npm run build && npm run start:sse",
    "dev:sse-supergateway": "npm run build && npm run start:sse-supergateway",
    "lint": "eslint src/**/*.ts",
    "lint:fix": "eslint src/**/*.ts --fix",
    "format": "prettier --write .",
    "prepare": "npm run build"
  },
  "license": "MIT",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.4.1",
    "axios": "^1.6.2",
    "commander": "^13.1.0",
    "dotenv": "^16.4.7",
    "mcp-proxy-auth": "^1.0.2",
    "p-queue": "^8.0.1",
    "uuid": "^11.1.0"
  },
  "devDependencies": {
    "@jest/globals": "^29.7.0",
    "@types/jest": "^29.5.14",
    "@types/node": "^20.10.5",
    "@types/uuid": "^10.0.0",
    "@typescript-eslint/eslint-plugin": "^7.0.0",
    "@typescript-eslint/parser": "^7.0.0",
    "eslint": "^8.56.0",
    "eslint-config-prettier": "^9.1.0",
    "jest": "^29.7.0",
    "jest-mock-extended": "^4.0.0-beta1",
    "prettier": "^3.1.1",
    "ts-jest": "^29.1.1",
    "typescript": "^5.3.3"
  },
  "engines": {
    "node": ">=18.0.0"
  },
  "keywords": [
    "mcp",
    "smartlead",
    "campaign-management",
    "email-marketing"
  ]
}

```

--------------------------------------------------------------------------------
/src/supergateway-mock.ts:
--------------------------------------------------------------------------------

```typescript
 /**
 * Mock implementation of the SuperGateway client
 * This is used as a fallback when the real SuperGateway package is not available
 */

/**
 * SuperGateway client mock implementation
 */
export class SuperGateway {
  private apiKey: string | undefined;
  private options: Record<string, any>;

  /**
   * Create a new SuperGateway instance
   * @param options Configuration options
   */
  constructor(options: { apiKey?: string, [key: string]: any } = {}) {
    console.error('[Supergateway] Initialized with API key:', options.apiKey ? '[REDACTED]' : 'undefined');
    this.apiKey = options.apiKey;
    this.options = { ...options };
    
    // Remove apiKey from options to avoid logging it
    delete this.options.apiKey;
  }

  /**
   * Process a request
   * @param input Input text to process
   * @param options Processing options
   * @returns Processed text
   */
  async process(input: string, options?: Record<string, any>): Promise<string> {
    console.error('[Supergateway] Processing request');
    console.error('[Supergateway] Input:', input);
    console.error('[Supergateway] Options:', options);
    
    // Simulate processing delay
    await new Promise(resolve => setTimeout(resolve, 500));
    
    // Return a processed response
    return `[Supergateway Mock] Processed: ${input.substring(0, 30)}...`;
  }

  /**
   * Stream a request response
   * @param input Input text to process
   * @param options Processing options
   * @returns Readable stream with response chunks
   */
  async stream(input: string, options?: Record<string, any>): Promise<ReadableStream> {
    console.error('[Supergateway] Streaming request');
    console.error('[Supergateway] Input:', input);
    console.error('[Supergateway] Options:', options);
    
    // Create a readable stream for the response
    return new ReadableStream({
      start(controller) {
        // Simulate streaming with delays
        const encoder = new TextEncoder();
        
        // Send chunks with delays
        setTimeout(() => {
          controller.enqueue(encoder.encode('[Supergateway] Stream started\n\n'));
        }, 100);
        
        setTimeout(() => {
          controller.enqueue(encoder.encode('Processing input...\n\n'));
        }, 500);
        
        setTimeout(() => {
          controller.enqueue(encoder.encode('Generating response...\n\n'));
        }, 1000);
        
        setTimeout(() => {
          controller.enqueue(encoder.encode('Completed processing\n\n'));
          controller.close();
        }, 1500);
      }
    });
  }

  /**
   * Close the client connection
   */
  async close(): Promise<void> {
    console.error('[Supergateway] Connection closed');
  }
}
```

--------------------------------------------------------------------------------
/llms-install.md:
--------------------------------------------------------------------------------

```markdown
# Smartlead MCP Server - Installation Guide for AI Assistants

This guide helps AI assistants like Cline set up the Smartlead MCP Server. This server allows you to interact with Smartlead's email marketing API through the Model Context Protocol (MCP).

## Prerequisites

- Node.js (v18 or higher)
- npm (comes with Node.js)
- A Smartlead API Key (user will need to provide this)
- Optional: A License Key (free tier is available, paid tiers have more features)

## One-Click Installation Method

The easiest way to install this MCP server is using the npx command:

```bash
# Create a directory for configurations if desired (recommended)
mkdir -p ~/.config/smartlead-mcp
cd ~/.config/smartlead-mcp

# Run the configuration helper
npx smartlead-mcp-server config
```

This will guide you through an interactive setup process to configure the Smartlead API key and license key. The user will need to provide their Smartlead API key when prompted.

## Start the Server

After installation and configuration, you can start the server in different modes depending on the intended use:

### For Claude and other AI assistants (STDIO mode):

```bash
npx smartlead-mcp-server start
```

### For n8n automation (SSE mode):

```bash
npx smartlead-mcp-server sse
```

## Integration with Cline

To set up Cline to use this MCP server:

1. You'll need to add it to Cline's MCP settings:

```json
{
  "mcpServers": {
    "smartlead": {
      "command": "npx",
      "args": ["smartlead-mcp-server", "start"],
      "env": {
        "SMARTLEAD_API_KEY": "user_provides_api_key_here",
        "JEAN_LICENSE_KEY": "optional_license_key_here"
      }
    }
  }
}
```

2. Ask the user for their Smartlead API key and update the configuration accordingly.

3. For the license key, you can use "JEANPARTNER" for the free tier or ask the user if they have a paid license key.

## Features and Capabilities

This MCP server provides tools for:

- **FREE Tier (20+ tools):**
  - Campaign Management
  - Lead Management

- **BASIC Tier (50+ tools):**
  - All FREE tier features
  - Campaign Statistics
  - Smart Delivery (Spam Tests, DNS Checks)
  - Webhooks
  - n8n Integration

- **PREMIUM Tier (All tools):**
  - All BASIC tier features
  - Client Management
  - Smart Senders (Domain/Mailbox Purchase)
  - Advanced Features

## Troubleshooting

- If you encounter issues with configuration, run: `npx smartlead-mcp-server config`
- For license-related issues, use "JEANPARTNER" as the license key for free tier access
- If you need more tools, direct the user to [https://sea-turtle-app-64etr.ondigitalocean.app/](https://sea-turtle-app-64etr.ondigitalocean.app/) to purchase a license

## License Information

This MCP server is available under the MIT license. The number of machines allowed varies by license tier:
- FREE tier: 1 machine
- BASIC tier: 2 machines
- PREMIUM tier: 5 machines 
```

--------------------------------------------------------------------------------
/src/supergateway.ts:
--------------------------------------------------------------------------------

```typescript
import { SuperGateway as MockSuperGateway } from './supergateway-mock.js';
import { isFeatureEnabled, LicenseLevel } from './licensing/index.js';

/**
 * Interface for SupergateWay options
 */
export interface SuperGatewayOptions {
  apiKey?: string;
  [key: string]: any;
}

/**
 * Interface for SuperGateway API
 */
export interface SuperGateway {
  process(input: string, options?: Record<string, any>): Promise<string>;
  stream(input: string, options?: Record<string, any>): Promise<ReadableStream>;
  close(): Promise<void>;
}

/**
 * Try to dynamically import Supergateway package
 */
export async function tryImportSupergateway(): Promise<any> {
  try {
    // First try to import the real package
    return await import('supergateway');
  } catch (error) {
    console.error(`Failed to import Supergateway: ${error instanceof Error ? error.message : String(error)}`);
    console.error('Falling back to mock Supergateway implementation');
    
    // Return our mock implementation as a fallback
    return {
      SuperGateway: MockSuperGateway
    };
  }
}

/**
 * Create a Supergateway instance
 */
export async function createSupergateway(apiKey?: string): Promise<SuperGateway | null> {
  try {
    // Check if the current license allows n8n integration
    const n8nIntegrationEnabled = await isFeatureEnabled('n8nIntegration');
    
    if (!n8nIntegrationEnabled) {
      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('');
      console.error('For testing purposes, you can obtain a Basic license from');
      console.error('https://yourservice.com/pricing');
      console.error('=============================================================');
      return null;
    }
    
    // Try to dynamically import the Supergateway module
    const supergateModule = await tryImportSupergateway();
    
    if (!supergateModule) {
      console.error('Supergateway module not found.');
      return null;
    }
    
    // Check if API key is provided
    if (!apiKey) {
      console.error('SUPERGATEWAY_API_KEY not provided');
      console.error('Please set the SUPERGATEWAY_API_KEY environment variable in your .env file.');
      return null;
    }
    
    // Create Supergateway instance
    const { SuperGateway } = supergateModule;
    const gateway = new SuperGateway({
      apiKey,
      // Additional configuration options can be added here
    });
    
    console.error('Supergateway initialized successfully');
    return gateway;
  } catch (error) {
    console.error(`Error initializing Supergateway: ${error instanceof Error ? error.message : String(error)}`);
    return null;
  }
}
```

--------------------------------------------------------------------------------
/DEVELOPER_ONBOARDING.md:
--------------------------------------------------------------------------------

```markdown
# Smartlead MCP Server - Developer Guide

## Overview

Smartlead MCP Server provides an organized interface to the Smartlead API using the Model Context Protocol (MCP), enabling AI assistants and automation tools to manage email marketing campaigns.

## Prerequisites

- Node.js (v18+)
- A Smartlead API Key

## Quick Start Options

### Option 1: Use npx (Recommended)

```bash
# For Claude
npx smartlead-mcp-server start

# For n8n
npx smartlead-mcp-server sse
```

### Option 2: Development Setup

```bash
# Clone and install
git clone https://github.com/jean-technologies/smartlead-mcp-server-local.git
cd smartlead-mcp-server-local
npm install

# Configure and build
cp .env.example .env  # Then edit with your API key
npm run build

# Run
npm start  # For Claude
# OR
npm run start:sse  # For n8n
```

## Two Integration Pathways

### 1. Claude Integration

Add to Claude settings JSON:
```json
{
  "mcp": {
    "name": "smartlead",
    "command": "npx",
    "args": ["smartlead-mcp-server", "start"],
    "env": {
      "SMARTLEAD_API_KEY": "your_api_key_here"
    }
  }
}
```

### 2. n8n Integration

#### Local n8n:
1. Run server: `npx smartlead-mcp-server sse`
2. Configure n8n MCP node with:
   - SSE URL: `http://localhost:3000/sse`
   - Message URL: `http://localhost:3000/message`

#### n8n Cloud:
1. Run server: `npx smartlead-mcp-server sse`
2. Create tunnel: `npx ngrok http 3000`
3. Use ngrok URL in n8n MCP node

## Available Features

All features are now enabled by default, including:
- Campaign & Lead Management
- Statistics and Analytics
- Smart Delivery & Webhooks
- n8n Integration
- Client Management
- Smart Senders
- Download Tracking and Analytics

## Download Tracking System

### Implementation Details

The download tracking system stores records in `~/.smartlead-mcp/downloads.json` with the following structure:

```json
{
  "downloads": [
    {
      "id": "unique-download-id",
      "timestamp": "2023-06-15T12:34:56.789Z",
      "campaignId": 12345,
      "downloadType": "analytics",
      "format": "json",
      "userId": "optional-user-id",
      "machineId": "machine-identifier"
    }
  ]
}
```

### Available Tools

1. **Download Campaign Data**: `smartlead_download_campaign_data`
   - Fetches data from Smartlead API
   - Converts to CSV if requested
   - Automatically tracks download details

2. **View Download Statistics**: `smartlead_view_download_statistics`
   - Filter by time period (all, today, week, month)
   - Group by various dimensions (type, format, campaign, date)
   - Get usage insights and recent downloads

## Troubleshooting

### Common Solutions
- Configure settings: `npx smartlead-mcp-server config`
- Set API key directly: `npx smartlead-mcp-server sse --api-key=YOUR_API_KEY`
- Debug mode: `DEBUG=smartlead:* npx smartlead-mcp-server start`

## Resources

- [Smartlead API Docs](https://docs.smartlead.ai)
- [MCP Specification](https://github.com/modelcontextprotocol/spec)
- [n8n Integration Guide](https://docs.n8n.io) 
```

--------------------------------------------------------------------------------
/src/handlers/clientManagement.ts:
--------------------------------------------------------------------------------

```typescript
import { AxiosInstance } from 'axios';
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import {
  isAddClientParams,
  isFetchAllClientsParams
} from '../types/clientManagement.js';

// SmartLead API base URL
const SMARTLEAD_API_URL = 'https://server.smartlead.ai/api/v1';

// Handler for Client Management-related tools
export async function handleClientManagementTool(
  toolName: string,
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  switch (toolName) {
    case 'smartlead_add_client': {
      return handleAddClient(args, apiClient, withRetry);
    }
    case 'smartlead_fetch_all_clients': {
      return handleFetchAllClients(args, apiClient, withRetry);
    }
    default:
      throw new Error(`Unknown Client Management tool: ${toolName}`);
  }
}

// Create a modified client for SmartLead API with the correct base URL
function createSmartLeadClient(apiClient: AxiosInstance) {
  return {
    get: (url: string, config?: any) => 
      apiClient.get(`${SMARTLEAD_API_URL}${url}`, config),
    post: (url: string, data?: any, config?: any) => 
      apiClient.post(`${SMARTLEAD_API_URL}${url}`, data, config),
    put: (url: string, data?: any, config?: any) => 
      apiClient.put(`${SMARTLEAD_API_URL}${url}`, data, config),
    delete: (url: string, config?: any) => 
      apiClient.delete(`${SMARTLEAD_API_URL}${url}`, config)
  };
}

// Individual handlers for each tool
async function handleAddClient(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isAddClientParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_add_client'
    );
  }

  try {
    const smartLeadClient = createSmartLeadClient(apiClient);
    
    const response = await withRetry(
      async () => smartLeadClient.post('/client/save', args),
      'add client'
    );

    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 handleFetchAllClients(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isFetchAllClientsParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_fetch_all_clients'
    );
  }

  try {
    const smartLeadClient = createSmartLeadClient(apiClient);
    
    const response = await withRetry(
      async () => smartLeadClient.get('/client/'),
      'fetch all clients'
    );

    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/registry/tool-registry.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool } from '../types/common.js';
import { isToolEnabled } from '../config/feature-config.js';
import { validateLicense, LicenseLevel } from '../licensing/index.js';

/**
 * Tool Registry manages the registration and querying of all available tools.
 * It provides a central place to register, filter, and retrieve tools by various criteria.
 */
export class ToolRegistry {
  private tools: Map<string, CategoryTool> = new Map();
  private cachedEnabledTools: CategoryTool[] | null = null;
  private lastCacheTime = 0;
  private readonly CACHE_TTL = 60000; // 1 minute
  
  /**
   * Register a single tool in the registry
   */
  register(tool: CategoryTool): void {
    this.tools.set(tool.name, tool);
    // Invalidate cache when tools change
    this.cachedEnabledTools = null;
  }
  
  /**
   * Register multiple tools at once
   */
  registerMany(tools: CategoryTool[]): void {
    tools.forEach(tool => this.register(tool));
  }
  
  /**
   * Get a tool by its name
   */
  getByName(name: string): CategoryTool | undefined {
    return this.tools.get(name);
  }
  
  /**
   * Get all tools that belong to a specific category
   */
  getByCategory(category: string): CategoryTool[] {
    return Array.from(this.tools.values())
      .filter(tool => tool.category === category);
  }
  
  /**
   * Get all registered tools
   */
  getAllTools(): CategoryTool[] {
    return Array.from(this.tools.values());
  }
  
  /**
   * Get all tools that are enabled based on the license and configuration
   * This method now returns a subset based on the current license
   */
  async getEnabledToolsAsync(): Promise<CategoryTool[]> {
    const now = Date.now();
    
    // Use cache if available and not expired
    if (this.cachedEnabledTools && (now - this.lastCacheTime < this.CACHE_TTL)) {
      return this.cachedEnabledTools;
    }
    
    // Get license to check allowed categories
    const license = await validateLicense();
    
    // Filter tools based on license-allowed categories
    const enabledTools = this.getAllTools().filter(tool => 
      license.features.allowedCategories.includes(tool.category)
    );
    
    // Cache results
    this.cachedEnabledTools = enabledTools;
    this.lastCacheTime = now;
    
    return enabledTools;
  }
  
  /**
   * Get enabled tools (synchronous version, falls back to configuration)
   * This is used for backward compatibility
   */
  getEnabledTools(): CategoryTool[] {
    // If we have a cache, use it
    if (this.cachedEnabledTools) {
      return this.cachedEnabledTools;
    }
    
    // Otherwise fall back to config-based filtering
    // This uses the local configuration as a fallback
    return this.getAllTools().filter(tool => {
      try {
        return isToolEnabled(tool.name, tool.category);
      } catch (e) {
        // If async check fails, use default behavior
        return false;
      }
    });
  }
  
  /**
   * Check if a tool with the given name exists in the registry
   */
  hasToolWithName(name: string): boolean {
    return this.tools.has(name);
  }
  
  /**
   * Check if a tool belongs to the specified category
   */
  isToolInCategory(name: string, category: string): boolean {
    const tool = this.getByName(name);
    return !!tool && tool.category === category;
  }
}

// Create a singleton instance
export const toolRegistry = new ToolRegistry(); 
```

--------------------------------------------------------------------------------
/src/n8n/index.ts:
--------------------------------------------------------------------------------

```typescript
import axios from 'axios';
import { LicenseLevel, validateLicense, getFeatureToken } from '../licensing/index.js';

const N8N_CONFIG = {
  apiUrl: process.env.N8N_API_URL || 'https://n8n.yourservice.com/api/v1',
};

/**
 * Get workflows from n8n
 * This is a premium feature that requires server-side validation
 */
export async function getWorkflows() {
  // First check if n8n integration is available based on license
  const licenseInfo = await validateLicense();
  if (licenseInfo.level !== LicenseLevel.PREMIUM) {
    throw new Error(
      `N8n integration requires a Premium license. Your current license level is ${licenseInfo.level}. ` +
      'Please upgrade to access this feature.'
    );
  }
  
  // Get a feature token for server-side validation
  const featureToken = await getFeatureToken();
  if (!featureToken) {
    throw new Error('Unable to validate premium feature access. Please try again later.');
  }
  
  try {
    // Make the API call with the feature token
    const response = await axios.get(`${N8N_CONFIG.apiUrl}/workflows`, {
      headers: {
        'Authorization': `Bearer ${process.env.JEAN_LICENSE_KEY}`,
        'X-Feature-Token': featureToken.token
      }
    });
    
    return response.data;
  } catch (error) {
    // Handle API errors
    if (axios.isAxiosError(error) && error.response) {
      // If server rejected the feature token
      if (error.response.status === 403) {
        throw new Error('Premium feature access denied. Please check your license status.');
      }
      
      // Other API errors
      throw new Error(`Failed to fetch n8n workflows: ${error.response.data?.message || error.message}`);
    }
    
    // Generic error
    throw new Error(`Error accessing n8n integration: ${error instanceof Error ? error.message : String(error)}`);
  }
}

/**
 * Execute a workflow in n8n
 * This is a premium feature that requires server-side validation
 */
export async function executeWorkflow(workflowId: string, data: any) {
  // First check if n8n integration is available based on license
  const licenseInfo = await validateLicense();
  if (licenseInfo.level !== LicenseLevel.PREMIUM) {
    throw new Error(
      `N8n integration requires a Premium license. Your current license level is ${licenseInfo.level}. ` +
      'Please upgrade to access this feature.'
    );
  }
  
  // Get a feature token for server-side validation
  const featureToken = await getFeatureToken();
  if (!featureToken) {
    throw new Error('Unable to validate premium feature access. Please try again later.');
  }
  
  try {
    // Make the API call with the feature token
    const response = await axios.post(
      `${N8N_CONFIG.apiUrl}/workflows/${workflowId}/execute`, 
      data,
      {
        headers: {
          'Authorization': `Bearer ${process.env.JEAN_LICENSE_KEY}`,
          'X-Feature-Token': featureToken.token,
          'Content-Type': 'application/json'
        }
      }
    );
    
    return response.data;
  } catch (error) {
    // Handle API errors
    if (axios.isAxiosError(error) && error.response) {
      // If server rejected the feature token
      if (error.response.status === 403) {
        throw new Error('Premium feature access denied. Please check your license status.');
      }
      
      // Other API errors
      throw new Error(`Failed to execute n8n workflow: ${error.response.data?.message || error.message}`);
    }
    
    // Generic error
    throw new Error(`Error accessing n8n integration: ${error instanceof Error ? error.message : String(error)}`);
  }
} 
```

--------------------------------------------------------------------------------
/src/types/webhooks.ts:
--------------------------------------------------------------------------------

```typescript
// Type definitions for Webhooks functionality

// Webhook event types
export enum WebhookEventType {
  EMAIL_SENT = 'EMAIL_SENT',
  EMAIL_OPEN = 'EMAIL_OPEN',
  EMAIL_LINK_CLICK = 'EMAIL_LINK_CLICK',
  EMAIL_REPLY = 'EMAIL_REPLY',
  LEAD_UNSUBSCRIBED = 'LEAD_UNSUBSCRIBED',
  LEAD_CATEGORY_UPDATED = 'LEAD_CATEGORY_UPDATED'
}

// Fetch Webhooks By Campaign ID
export interface FetchWebhooksByCampaignParams {
  campaign_id: string;
}

// Add / Update Campaign Webhook
export interface UpsertCampaignWebhookParams {
  campaign_id: string;
  id?: number | null; // Set to null to create a new webhook
  name: string;
  webhook_url: string;
  event_types: WebhookEventType[];
  categories?: string[];
}

// Delete Campaign Webhook
export interface DeleteCampaignWebhookParams {
  campaign_id: string;
  id: number; // Webhook ID to delete
}

// Get Webhooks Publish Summary [Private Beta]
export interface GetWebhooksPublishSummaryParams {
  campaign_id: string;
  fromTime?: string; // ISO 8601 date-time string
  toTime?: string; // ISO 8601 date-time string
}

// Retrigger Failed Events [Private Beta]
export interface RetriggerFailedEventsParams {
  campaign_id: string;
  fromTime: string; // ISO 8601 date-time string
  toTime: string; // ISO 8601 date-time string
}

// Type guards
export function isFetchWebhooksByCampaignParams(args: unknown): args is FetchWebhooksByCampaignParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as FetchWebhooksByCampaignParams).campaign_id === 'string'
  );
}

export function isUpsertCampaignWebhookParams(args: unknown): args is UpsertCampaignWebhookParams {
  if (typeof args !== 'object' || args === null) return false;
  
  const params = args as Partial<UpsertCampaignWebhookParams>;
  
  return (
    typeof params.campaign_id === 'string' &&
    typeof params.name === 'string' &&
    typeof params.webhook_url === 'string' &&
    Array.isArray(params.event_types) &&
    params.event_types.every(type => 
      Object.values(WebhookEventType).includes(type as WebhookEventType)
    ) &&
    (params.categories === undefined || 
      (Array.isArray(params.categories) && 
       params.categories.every(category => typeof category === 'string')
      )
    ) &&
    (params.id === undefined || params.id === null || typeof params.id === 'number')
  );
}

export function isDeleteCampaignWebhookParams(args: unknown): args is DeleteCampaignWebhookParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as DeleteCampaignWebhookParams).campaign_id === 'string' &&
    'id' in args &&
    typeof (args as DeleteCampaignWebhookParams).id === 'number'
  );
}

export function isGetWebhooksPublishSummaryParams(args: unknown): args is GetWebhooksPublishSummaryParams {
  if (typeof args !== 'object' || args === null) return false;
  
  const params = args as Partial<GetWebhooksPublishSummaryParams>;
  
  return (
    typeof params.campaign_id === 'string' &&
    (params.fromTime === undefined || typeof params.fromTime === 'string') &&
    (params.toTime === undefined || typeof params.toTime === 'string')
  );
}

export function isRetriggerFailedEventsParams(args: unknown): args is RetriggerFailedEventsParams {
  if (typeof args !== 'object' || args === null) return false;
  
  const params = args as Partial<RetriggerFailedEventsParams>;
  
  return (
    typeof params.campaign_id === 'string' &&
    typeof params.fromTime === 'string' &&
    typeof params.toTime === 'string'
  );
} 
```

--------------------------------------------------------------------------------
/src/types/email.d.ts:
--------------------------------------------------------------------------------

```typescript
// Type declarations for Email Account parameters
declare module '../types/email.js' {
  export function isListEmailAccountsParams(args: unknown): args is ListEmailAccountsParams;
  export function isAddEmailToCampaignParams(args: unknown): args is AddEmailToCampaignParams;
  export function isRemoveEmailFromCampaignParams(args: unknown): args is RemoveEmailFromCampaignParams;
  export function isFetchEmailAccountsParams(args: unknown): args is FetchEmailAccountsParams;
  export function isCreateEmailAccountParams(args: unknown): args is CreateEmailAccountParams;
  export function isUpdateEmailAccountParams(args: unknown): args is UpdateEmailAccountParams;
  export function isFetchEmailAccountByIdParams(args: unknown): args is FetchEmailAccountByIdParams;
  export function isUpdateEmailWarmupParams(args: unknown): args is UpdateEmailWarmupParams;
  export function isReconnectEmailAccountParams(args: unknown): args is ReconnectEmailAccountParams;
  export function isUpdateEmailAccountTagParams(args: unknown): args is UpdateEmailAccountTagParams;

  export interface ListEmailAccountsParams {
    campaign_id?: number;
    status?: string;
    limit?: number;
    offset?: number;
  }

  export interface AddEmailToCampaignParams {
    campaign_id: number;
    email_account_id: number;
  }

  export interface RemoveEmailFromCampaignParams {
    campaign_id: number;
    email_account_id: number;
  }

  export interface FetchEmailAccountsParams {
    status?: string;
    limit?: number;
    offset?: number;
    username?: string;
    client_id?: number;
  }

  export interface CreateEmailAccountParams {
    from_name: string;
    from_email: string;
    user_name: string;
    password: string;
    smtp_host: string;
    smtp_port: number;
    imap_host: string;
    imap_port: number;
    max_email_per_day?: number;
    custom_tracking_url?: string;
    bcc?: string;
    signature?: string;
    warmup_enabled?: boolean;
    total_warmup_per_day?: number;
    daily_rampup?: number;
    reply_rate_percentage?: number;
    client_id?: number;
  }

  export interface UpdateEmailAccountParams {
    email_account_id: number;
    max_email_per_day?: number;
    custom_tracking_url?: string;
    bcc?: string;
    signature?: string;
    client_id?: number | null;
    time_to_wait_in_mins?: number;
  }

  export interface FetchEmailAccountByIdParams {
    email_account_id: number;
  }

  export interface UpdateEmailWarmupParams {
    email_account_id: number;
    warmup_enabled: string;
    total_warmup_per_day?: number;
    daily_rampup?: number;
    reply_rate_percentage?: string;
    warmup_key_id?: string;
  }

  export interface ReconnectEmailAccountParams {
    email_account_id: number;
    connection_details?: {
      smtp_host?: string;
      smtp_port?: number;
      smtp_username?: string;
      smtp_password?: string;
      imap_host?: string;
      imap_port?: number;
      imap_username?: string;
      imap_password?: string;
      oauth_token?: string;
    };
  }

  export interface UpdateEmailAccountTagParams {
    id: number;
    name: string;
    color: string;
  }

  export interface EmailAccount {
    id: number;
    email: string;
    name?: string;
    provider: string;
    status: string;
    created_at: string;
    updated_at: string;
    last_checked_at?: string;
    warmup_enabled: boolean;
    daily_limit?: number;
    tags?: string[];
  }

  export interface EmailAccountResponse {
    success: boolean;
    data: EmailAccount;
    message?: string;
  }

  export interface EmailAccountListResponse {
    success: boolean;
    data: {
      accounts: EmailAccount[];
      total: number;
    };
    message?: string;
  }

  export interface EmailAccountActionResponse {
    success: boolean;
    message: string;
  }
} 
```

--------------------------------------------------------------------------------
/src/types/smartSenders.ts:
--------------------------------------------------------------------------------

```typescript
// Type definitions for Smart Senders functionality

// Get Vendors
export interface GetVendorsParams {
  // This endpoint doesn't require specific parameters beyond the API key
  // which is handled at the API client level
}

// Search Domain
export interface SearchDomainParams {
  domain_name: string;
  vendor_id: number;
}

// Mailbox details for auto-generate and order placement
export interface MailboxDetail {
  first_name: string;
  last_name: string;
  profile_pic?: string;
  mailbox?: string; // Required only for place-order
}

// Domain with mailbox details for auto-generate
export interface DomainWithMailboxes {
  domain_name: string;
  mailbox_details: MailboxDetail[];
}

// Auto-generate Mailboxes
export interface AutoGenerateMailboxesParams {
  vendor_id: number;
  domains: DomainWithMailboxes[];
}

// Place order for mailboxes
export interface PlaceOrderParams {
  vendor_id: number;
  forwarding_domain: string;
  domains: DomainWithMailboxes[];
}

// Get Domain List
export interface GetDomainListParams {
  // This endpoint doesn't require specific parameters beyond the API key
  // which is handled at the API client level
}

// Type guards
export function isGetVendorsParams(args: unknown): args is GetVendorsParams {
  // Since this endpoint doesn't require specific parameters beyond the API key
  // Any object is valid
  return typeof args === 'object' && args !== null;
}

export function isSearchDomainParams(args: unknown): args is SearchDomainParams {
  if (typeof args !== 'object' || args === null) return false;
  
  const params = args as Partial<SearchDomainParams>;
  
  return (
    typeof params.domain_name === 'string' &&
    typeof params.vendor_id === 'number'
  );
}

export function isMailboxDetail(obj: unknown): obj is MailboxDetail {
  if (typeof obj !== 'object' || obj === null) return false;
  
  const detail = obj as Partial<MailboxDetail>;
  
  return (
    typeof detail.first_name === 'string' &&
    typeof detail.last_name === 'string' &&
    (detail.profile_pic === undefined || typeof detail.profile_pic === 'string') &&
    (detail.mailbox === undefined || typeof detail.mailbox === 'string')
  );
}

export function isDomainWithMailboxes(obj: unknown): obj is DomainWithMailboxes {
  if (typeof obj !== 'object' || obj === null) return false;
  
  const domain = obj as Partial<DomainWithMailboxes>;
  
  return (
    typeof domain.domain_name === 'string' &&
    Array.isArray(domain.mailbox_details) &&
    domain.mailbox_details.every(detail => isMailboxDetail(detail))
  );
}

export function isAutoGenerateMailboxesParams(args: unknown): args is AutoGenerateMailboxesParams {
  if (typeof args !== 'object' || args === null) return false;
  
  const params = args as Partial<AutoGenerateMailboxesParams>;
  
  return (
    typeof params.vendor_id === 'number' &&
    Array.isArray(params.domains) &&
    params.domains.every(domain => isDomainWithMailboxes(domain))
  );
}

export function isPlaceOrderParams(args: unknown): args is PlaceOrderParams {
  if (typeof args !== 'object' || args === null) return false;
  
  const params = args as Partial<PlaceOrderParams>;
  
  // Check if domains have mailbox property in mailbox_details
  const domainsHaveMailboxes = Array.isArray(params.domains) && 
    params.domains.every(domain => 
      isDomainWithMailboxes(domain) && 
      domain.mailbox_details.every(detail => typeof detail.mailbox === 'string')
    );
  
  return (
    typeof params.vendor_id === 'number' &&
    typeof params.forwarding_domain === 'string' &&
    domainsHaveMailboxes
  );
}

export function isGetDomainListParams(args: unknown): args is GetDomainListParams {
  // Since this endpoint doesn't require specific parameters beyond the API key
  // Any object is valid
  return typeof args === 'object' && args !== null;
} 
```

--------------------------------------------------------------------------------
/src/tools/webhooks.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool, ToolCategory } from '../types/common.js';
import { WebhookEventType } from '../types/webhooks.js';

// Webhook Tools

export const FETCH_WEBHOOKS_BY_CAMPAIGN_TOOL: CategoryTool = {
  name: 'smartlead_fetch_webhooks_by_campaign',
  description: 'Fetch all the webhooks associated with a campaign using the campaign ID.',
  category: ToolCategory.WEBHOOKS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'string',
        description: 'ID of the campaign to fetch webhooks for',
      },
    },
    required: ['campaign_id'],
  },
};

export const UPSERT_CAMPAIGN_WEBHOOK_TOOL: CategoryTool = {
  name: 'smartlead_upsert_campaign_webhook',
  description: 'Add or update a webhook for a specific campaign.',
  category: ToolCategory.WEBHOOKS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'string',
        description: 'ID of the campaign to add/update webhook for',
      },
      id: {
        type: ['integer', 'null'],
        description: 'ID of the webhook to update. Set to null to create a new webhook.',
      },
      name: {
        type: 'string',
        description: 'Name for the webhook',
      },
      webhook_url: {
        type: 'string',
        description: 'URL to call when the webhook event occurs',
      },
      event_types: {
        type: 'array',
        items: {
          type: 'string',
          enum: Object.values(WebhookEventType),
        },
        description: `Types of events to trigger the webhook. Options: ${Object.values(WebhookEventType).join(', ')}`,
      },
      categories: {
        type: 'array',
        items: { type: 'string' },
        description: 'Categories for filtering webhook events (e.g. ["Interested", "NotInterested"])',
      },
    },
    required: ['campaign_id', 'name', 'webhook_url', 'event_types'],
  },
};

export const DELETE_CAMPAIGN_WEBHOOK_TOOL: CategoryTool = {
  name: 'smartlead_delete_campaign_webhook',
  description: 'Delete a specific webhook from a campaign.',
  category: ToolCategory.WEBHOOKS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'string',
        description: 'ID of the campaign containing the webhook',
      },
      id: {
        type: 'integer',
        description: 'ID of the webhook to delete',
      },
    },
    required: ['campaign_id', 'id'],
  },
};

export const GET_WEBHOOKS_PUBLISH_SUMMARY_TOOL: CategoryTool = {
  name: 'smartlead_get_webhooks_publish_summary',
  description: 'Get a summary of webhook publish events (Private Beta feature).',
  category: ToolCategory.WEBHOOKS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'string',
        description: 'ID of the campaign to get webhook publish summary for',
      },
      fromTime: {
        type: 'string',
        description: 'Start date/time in ISO 8601 format (e.g. 2025-03-21T00:00:00Z)',
      },
      toTime: {
        type: 'string',
        description: 'End date/time in ISO 8601 format (e.g. 2025-04-04T23:59:59Z)',
      },
    },
    required: ['campaign_id'],
  },
};

export const RETRIGGER_FAILED_EVENTS_TOOL: CategoryTool = {
  name: 'smartlead_retrigger_failed_events',
  description: 'Retrigger failed webhook events (Private Beta feature).',
  category: ToolCategory.WEBHOOKS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'string',
        description: 'ID of the campaign to retrigger failed webhook events for',
      },
      fromTime: {
        type: 'string',
        description: 'Start date/time in ISO 8601 format (e.g. 2025-03-21T00:00:00Z)',
      },
      toTime: {
        type: 'string',
        description: 'End date/time in ISO 8601 format (e.g. 2025-04-04T23:59:59Z)',
      },
    },
    required: ['campaign_id', 'fromTime', 'toTime'],
  },
};

// Export all tools as an array for easy registration
export const webhookTools = [
  FETCH_WEBHOOKS_BY_CAMPAIGN_TOOL,
  UPSERT_CAMPAIGN_WEBHOOK_TOOL,
  DELETE_CAMPAIGN_WEBHOOK_TOOL,
  GET_WEBHOOKS_PUBLISH_SUMMARY_TOOL,
  RETRIGGER_FAILED_EVENTS_TOOL,
]; 
```

--------------------------------------------------------------------------------
/src/utils/download-tracker.ts:
--------------------------------------------------------------------------------

```typescript
import fs from 'fs';
import path from 'path';
import os from 'os';
import { v4 as uuidv4 } from 'uuid';

// Interface for download tracking data
export interface DownloadRecord {
  id: string;
  timestamp: string;
  campaignId: number;
  downloadType: string;
  format: string;
  userId?: string;
  machineId: string;
  ipAddress?: string;
}

// Path to store download records
const DOWNLOAD_LOG_PATH = process.env.DOWNLOAD_LOG_PATH || path.join(os.homedir(), '.smartlead-mcp', 'downloads.json');

// Ensure directory exists
const ensureDirectoryExists = (filePath: string) => {
  const dirname = path.dirname(filePath);
  if (!fs.existsSync(dirname)) {
    fs.mkdirSync(dirname, { recursive: true });
  }
};

// Initialize the download log file if it doesn't exist
const initializeLogFile = () => {
  ensureDirectoryExists(DOWNLOAD_LOG_PATH);
  if (!fs.existsSync(DOWNLOAD_LOG_PATH)) {
    fs.writeFileSync(DOWNLOAD_LOG_PATH, JSON.stringify({ downloads: [] }, null, 2));
    console.log(`Created download tracking file at: ${DOWNLOAD_LOG_PATH}`);
  }
};

// Get a unique machine identifier
const getMachineId = (): string => {
  try {
    const os = process.platform;
    const cpus = process.env.NUMBER_OF_PROCESSORS || '';
    const username = process.env.USER || process.env.USERNAME || '';
    const hostname = process.env.HOSTNAME || '';
    
    // Create a simple hash of these values
    const combinedString = `${os}-${cpus}-${username}-${hostname}`;
    let hash = 0;
    for (let i = 0; i < combinedString.length; i++) {
      hash = ((hash << 5) - hash) + combinedString.charCodeAt(i);
      hash |= 0; // Convert to 32bit integer
    }
    
    return Math.abs(hash).toString(16);
  } catch (e) {
    // Fallback to a random ID if we can't get system info
    return Math.random().toString(36).substring(2, 15);
  }
};

/**
 * Track a download event
 * @param campaignId The ID of the campaign being downloaded
 * @param downloadType The type of download (analytics, leads, etc.)
 * @param format The format of the download (json, csv)
 * @param userId Optional user identifier
 * @param ipAddress Optional IP address of the requester
 * @returns The unique ID of the download record
 */
export const trackDownload = (
  campaignId: number,
  downloadType: string,
  format: string,
  userId?: string,
  ipAddress?: string
): string => {
  try {
    // Initialize log file if it doesn't exist
    initializeLogFile();
    
    // Read existing records
    const data = JSON.parse(fs.readFileSync(DOWNLOAD_LOG_PATH, 'utf8'));
    
    // Create new download record
    const downloadId = uuidv4();
    const downloadRecord: DownloadRecord = {
      id: downloadId,
      timestamp: new Date().toISOString(),
      campaignId,
      downloadType,
      format,
      userId,
      machineId: getMachineId(),
      ipAddress
    };
    
    // Add to records and save
    data.downloads.push(downloadRecord);
    fs.writeFileSync(DOWNLOAD_LOG_PATH, JSON.stringify(data, null, 2));
    
    console.log(`Tracked download: ${downloadId} for campaign ${campaignId}`);
    return downloadId;
  } catch (error) {
    console.error('Failed to track download:', error);
    return '';
  }
};

/**
 * Get all download records
 * @returns Array of download records
 */
export const getDownloadRecords = (): DownloadRecord[] => {
  try {
    initializeLogFile();
    const data = JSON.parse(fs.readFileSync(DOWNLOAD_LOG_PATH, 'utf8'));
    return data.downloads || [];
  } catch (error) {
    console.error('Failed to get download records:', error);
    return [];
  }
};

/**
 * Get download statistics
 * @returns Statistics about downloads
 */
export const getDownloadStats = () => {
  const records = getDownloadRecords();
  
  // Count downloads by type
  const byType: Record<string, number> = {};
  
  // Count downloads by format
  const byFormat: Record<string, number> = {};
  
  // Count downloads by campaign
  const byCampaign: Record<number, number> = {};
  
  // Count unique users
  const uniqueUsers = new Set<string>();
  
  // Count by date (YYYY-MM-DD)
  const byDate: Record<string, number> = {};
  
  records.forEach(record => {
    // Count by type
    byType[record.downloadType] = (byType[record.downloadType] || 0) + 1;
    
    // Count by format
    byFormat[record.format] = (byFormat[record.format] || 0) + 1;
    
    // Count by campaign
    byCampaign[record.campaignId] = (byCampaign[record.campaignId] || 0) + 1;
    
    // Track unique users (either by userId or machineId)
    if (record.userId) {
      uniqueUsers.add(record.userId);
    } else {
      uniqueUsers.add(record.machineId);
    }
    
    // Count by date
    const date = record.timestamp.split('T')[0];
    byDate[date] = (byDate[date] || 0) + 1;
  });
  
  return {
    totalDownloads: records.length,
    uniqueUsers: uniqueUsers.size,
    byType,
    byFormat,
    byCampaign,
    byDate
  };
}; 
```

--------------------------------------------------------------------------------
/src/licensing/stripe-integration.js:
--------------------------------------------------------------------------------

```javascript
import Stripe from 'stripe';
import axios from 'axios';
import { LicenseLevel } from './index.js';

// Initialize Stripe with your secret key
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '');

// Your license server URL
const LICENSE_SERVER_URL = process.env.LICENSE_SERVER_URL || 'https://api.yourservice.com/licensing';

/**
 * Check subscription status with Stripe
 * @param {string} customerId The Stripe customer ID
 * @returns {Promise<Object>} Subscription information
 */
export async function getSubscriptionStatus(customerId) {
  try {
    // Get all active subscriptions for this customer
    const subscriptions = await stripe.subscriptions.list({
      customer: customerId,
      status: 'active',
      expand: ['data.plan.product']
    });
    
    if (subscriptions.data.length === 0) {
      return {
        active: false,
        level: LicenseLevel.FREE,
        message: 'No active subscription found'
      };
    }
    
    // Get the highest tier subscription if there are multiple
    const subscription = subscriptions.data[0];
    const product = subscription.items.data[0].plan.product;
    
    // Determine license level based on product ID or metadata
    let level = LicenseLevel.FREE;
    if (product.metadata.license_level) {
      level = product.metadata.license_level;
    } else {
      // Map product IDs to license levels if metadata not available
      const productMapping = {
        'prod_basic123': LicenseLevel.BASIC,
        'prod_premium456': LicenseLevel.PREMIUM
      };
      level = productMapping[product.id] || LicenseLevel.FREE;
    }
    
    return {
      active: true,
      level,
      subscriptionId: subscription.id,
      currentPeriodEnd: new Date(subscription.current_period_end * 1000),
      cancelAtPeriodEnd: subscription.cancel_at_period_end,
      message: 'Subscription active'
    };
  } catch (error) {
    console.error('Error checking subscription status:', error);
    return {
      active: false,
      level: LicenseLevel.FREE,
      message: 'Error checking subscription status'
    };
  }
}

/**
 * Generate a new license key for a customer
 * @param {string} customerId The Stripe customer ID
 * @param {string} level The license level
 * @returns {Promise<Object>} The generated license information
 */
export async function generateLicense(customerId, level) {
  try {
    // Call your license server to generate a new license
    const response = await axios.post(`${LICENSE_SERVER_URL}/generate`, {
      customerId,
      level
    }, {
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': process.env.LICENSE_API_KEY
      }
    });
    
    return response.data;
  } catch (error) {
    console.error('Error generating license:', error);
    throw new Error('Failed to generate license');
  }
}

/**
 * Handle Stripe webhook events
 * @param {Object} event The Stripe webhook event
 * @returns {Promise<Object>} Result of webhook handling
 */
export async function handleStripeWebhook(event) {
  try {
    switch (event.type) {
      case 'customer.subscription.created':
      case 'customer.subscription.updated': {
        const subscription = event.data.object;
        const customerId = subscription.customer;
        
        // Get product information to determine license level
        const product = await stripe.products.retrieve(
          subscription.items.data[0].plan.product
        );
        
        const level = product.metadata.license_level || LicenseLevel.BASIC;
        
        // Generate or update license
        const licenseInfo = await generateLicense(customerId, level);
        
        // Update customer metadata with license key
        await stripe.customers.update(customerId, {
          metadata: { 
            license_key: licenseInfo.key,
            license_level: level
          }
        });
        
        return { success: true, message: 'License updated', licenseInfo };
      }
      
      case 'customer.subscription.deleted': {
        const subscription = event.data.object;
        const customerId = subscription.customer;
        
        // Downgrade to free tier or deactivate license
        const response = await axios.post(`${LICENSE_SERVER_URL}/downgrade`, {
          customerId
        }, {
          headers: {
            'Content-Type': 'application/json',
            'X-API-Key': process.env.LICENSE_API_KEY
          }
        });
        
        // Update customer metadata
        await stripe.customers.update(customerId, {
          metadata: { 
            license_level: LicenseLevel.FREE 
          }
        });
        
        return { success: true, message: 'License downgraded', response: response.data };
      }
      
      default:
        return { success: true, message: 'Event ignored' };
    }
  } catch (error) {
    console.error('Error handling webhook:', error);
    return { success: false, message: error.message };
  }
} 
```

--------------------------------------------------------------------------------
/src/tools/smartSenders.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool, ToolCategory } from '../types/common.js';

// Smart Senders Tools

export const GET_VENDORS_TOOL: CategoryTool = {
  name: 'smartlead_get_vendors',
  description: 'Retrieve all active domain vendors with their corresponding IDs.',
  category: ToolCategory.SMART_SENDERS,
  inputSchema: {
    type: 'object',
    properties: {
      // This endpoint doesn't require specific parameters beyond the API key
      // which is handled at the API client level
    },
    required: [],
  },
};

export const SEARCH_DOMAIN_TOOL: CategoryTool = {
  name: 'smartlead_search_domain',
  description: 'Search for available domains under $15 that match a given domain name pattern.',
  category: ToolCategory.SMART_SENDERS,
  inputSchema: {
    type: 'object',
    properties: {
      domain_name: {
        type: 'string',
        description: 'The domain name pattern you want to search for',
      },
      vendor_id: {
        type: 'integer',
        description: 'ID of the vendor from whom you want to purchase the domain (use Get Vendors API to retrieve this ID)',
      },
    },
    required: ['domain_name', 'vendor_id'],
  },
};

export const AUTO_GENERATE_MAILBOXES_TOOL: CategoryTool = {
  name: 'smartlead_auto_generate_mailboxes',
  description: 'Auto-generate mailboxes based on the domain name and personal details provided.',
  category: ToolCategory.SMART_SENDERS,
  inputSchema: {
    type: 'object',
    properties: {
      vendor_id: {
        type: 'integer',
        description: 'ID of the vendor from whom you want to purchase the domains and mailboxes',
      },
      domains: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            domain_name: {
              type: 'string',
              description: 'The domain name for which you want to generate mailboxes (e.g., example.com)',
            },
            mailbox_details: {
              type: 'array',
              items: {
                type: 'object',
                properties: {
                  first_name: {
                    type: 'string',
                    description: 'First name for the mailbox owner (should be more than 2 characters and without spaces)',
                  },
                  last_name: {
                    type: 'string',
                    description: 'Last name for the mailbox owner (should be more than 2 characters and without spaces)',
                  },
                  profile_pic: {
                    type: 'string',
                    description: 'URL or identifier for profile picture (optional)',
                  },
                },
                required: ['first_name', 'last_name'],
              },
              description: 'Details for each mailbox you want to generate',
            },
          },
          required: ['domain_name', 'mailbox_details'],
        },
        description: 'List of domains and associated mailbox details',
      },
    },
    required: ['vendor_id', 'domains'],
  },
};

export const PLACE_ORDER_MAILBOXES_TOOL: CategoryTool = {
  name: 'smartlead_place_order_mailboxes',
  description: 'Confirm and place order for domains and mailboxes to be purchased.',
  category: ToolCategory.SMART_SENDERS,
  inputSchema: {
    type: 'object',
    properties: {
      vendor_id: {
        type: 'integer',
        description: 'ID of the vendor from whom you want to purchase the domains and mailboxes',
      },
      forwarding_domain: {
        type: 'string',
        description: 'The domain to forward to when users access purchased domains',
      },
      domains: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            domain_name: {
              type: 'string',
              description: 'The domain name you want to purchase',
            },
            mailbox_details: {
              type: 'array',
              items: {
                type: 'object',
                properties: {
                  mailbox: {
                    type: 'string',
                    description: 'The complete mailbox address (e.g., [email protected])',
                  },
                  first_name: {
                    type: 'string',
                    description: 'First name for the mailbox owner',
                  },
                  last_name: {
                    type: 'string',
                    description: 'Last name for the mailbox owner',
                  },
                  profile_pic: {
                    type: 'string',
                    description: 'URL or identifier for profile picture (optional)',
                  },
                },
                required: ['mailbox', 'first_name', 'last_name'],
              },
              description: 'Details for each mailbox you want to purchase',
            },
          },
          required: ['domain_name', 'mailbox_details'],
        },
        description: 'List of domains and associated mailbox details for purchase',
      },
    },
    required: ['vendor_id', 'forwarding_domain', 'domains'],
  },
};

export const GET_DOMAIN_LIST_TOOL: CategoryTool = {
  name: 'smartlead_get_domain_list',
  description: 'Retrieve a list of all domains purchased through SmartSenders.',
  category: ToolCategory.SMART_SENDERS,
  inputSchema: {
    type: 'object',
    properties: {
      // This endpoint doesn't require specific parameters beyond the API key
      // which is handled at the API client level
    },
    required: [],
  },
};

// Export all tools as an array for easy registration
export const smartSendersTools = [
  GET_VENDORS_TOOL,
  SEARCH_DOMAIN_TOOL,
  AUTO_GENERATE_MAILBOXES_TOOL,
  PLACE_ORDER_MAILBOXES_TOOL,
  GET_DOMAIN_LIST_TOOL,
]; 
```

--------------------------------------------------------------------------------
/src/tools/smartDelivery.d.ts:
--------------------------------------------------------------------------------

```typescript
import { z } from 'zod';

// Tool schemas for Smart Delivery category
export const regionWiseProviderIdsSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const createManualPlacementTestSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const createAutomatedPlacementTestSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const getSpamTestDetailsSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const deleteSmartDeliveryTestsInBulkSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const stopAutomatedSmartDeliveryTestSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const listAllTestsSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const providerWiseReportSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const geoWiseReportSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const senderAccountWiseReportSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const spamFilterReportSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const dkimDetailsSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const spfDetailsSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const rdnsReportSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const senderAccountListSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const blacklistsSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const spamTestEmailContentSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const spamTestIpBlacklistCountSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const emailReplyHeadersSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const scheduleHistoryForAutomatedTestsSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const ipDetailsSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const mailboxSummarySchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const mailboxCountApiSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const getAllFoldersSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const createFoldersSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const getFolderByIdSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

export const deleteFolderSchema: {
  name: string;
  description: string;
  schema: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
};

// Type declarations for Smart Delivery tools
declare module './tools/smartDelivery.js' {
  import { CategoryTool } from '../types/common.js';
  
  export const REGION_WISE_PROVIDER_IDS_TOOL: string;
  export const CREATE_MANUAL_PLACEMENT_TEST_TOOL: string;
  export const CREATE_AUTOMATED_PLACEMENT_TEST_TOOL: string;
  export const GET_SPAM_TEST_DETAILS_TOOL: string;
  export const DELETE_SMART_DELIVERY_TESTS_IN_BULK_TOOL: string;
  export const STOP_AUTOMATED_SMART_DELIVERY_TEST_TOOL: string;
  export const LIST_ALL_TESTS_TOOL: string;
  export const PROVIDER_WISE_REPORT_TOOL: string;
  export const GEO_WISE_REPORT_TOOL: string;
  export const SENDER_ACCOUNT_WISE_REPORT_TOOL: string;
  export const SPAM_FILTER_REPORT_TOOL: string;
  export const DKIM_DETAILS_TOOL: string;
  export const SPF_DETAILS_TOOL: string;
  export const RDNS_REPORT_TOOL: string;
  export const SENDER_ACCOUNT_LIST_TOOL: string;
  export const BLACKLISTS_TOOL: string;
  export const SPAM_TEST_EMAIL_CONTENT_TOOL: string;
  export const SPAM_TEST_IP_BLACKLIST_COUNT_TOOL: string;
  export const EMAIL_REPLY_HEADERS_TOOL: string;
  export const SCHEDULE_HISTORY_FOR_AUTOMATED_TESTS_TOOL: string;
  export const IP_DETAILS_TOOL: string;
  export const MAILBOX_SUMMARY_TOOL: string;
  export const MAILBOX_COUNT_API_TOOL: string;
  export const GET_ALL_FOLDERS_TOOL: string;
  export const CREATE_FOLDERS_TOOL: string;
  export const GET_FOLDER_BY_ID_TOOL: string;
  export const DELETE_FOLDER_TOOL: string;
  
  export const smartDeliveryTools: CategoryTool[];
} 
```

--------------------------------------------------------------------------------
/src/tools/lead.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool, ToolCategory } from '../types/common.js';

// Lead Management Tools
export const LIST_LEADS_TOOL: CategoryTool = {
  name: 'smartlead_list_leads',
  description: 'List leads with optional filtering by campaign or status.',
  category: ToolCategory.LEAD_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'Filter leads by campaign ID',
      },
      status: {
        type: 'string',
        description: 'Filter leads by status (e.g., "active", "unsubscribed", "bounced")',
      },
      limit: {
        type: 'number',
        description: 'Maximum number of leads to return',
      },
      offset: {
        type: 'number',
        description: 'Offset for pagination',
      },
      search: {
        type: 'string',
        description: 'Search term to filter leads',
      },
      start_date: {
        type: 'string',
        description: 'Filter leads created after this date (YYYY-MM-DD format)',
      },
      end_date: {
        type: 'string',
        description: 'Filter leads created before this date (YYYY-MM-DD format)',
      },
    },
  },
};

export const GET_LEAD_TOOL: CategoryTool = {
  name: 'smartlead_get_lead',
  description: 'Get details of a specific lead by ID.',
  category: ToolCategory.LEAD_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      lead_id: {
        type: 'number',
        description: 'ID of the lead to retrieve',
      },
    },
    required: ['lead_id'],
  },
};

export const ADD_LEAD_TO_CAMPAIGN_TOOL: CategoryTool = {
  name: 'smartlead_add_lead_to_campaign',
  description: 'Add a new lead to a campaign.',
  category: ToolCategory.LEAD_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to add the lead to',
      },
      email: {
        type: 'string',
        description: 'Email address of the lead',
      },
      first_name: {
        type: 'string',
        description: 'First name of the lead',
      },
      last_name: {
        type: 'string',
        description: 'Last name of the lead',
      },
      company: {
        type: 'string',
        description: 'Company of the lead',
      },
      title: {
        type: 'string',
        description: 'Job title of the lead',
      },
      phone: {
        type: 'string',
        description: 'Phone number of the lead',
      },
      custom_fields: {
        type: 'object',
        description: 'Custom fields for the lead',
      },
    },
    required: ['campaign_id', 'email'],
  },
};

export const UPDATE_LEAD_TOOL: CategoryTool = {
  name: 'smartlead_update_lead',
  description: 'Update an existing lead\'s information.',
  category: ToolCategory.LEAD_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      lead_id: {
        type: 'number',
        description: 'ID of the lead to update',
      },
      email: {
        type: 'string',
        description: 'New email address for the lead',
      },
      first_name: {
        type: 'string',
        description: 'New first name for the lead',
      },
      last_name: {
        type: 'string',
        description: 'New last name for the lead',
      },
      company: {
        type: 'string',
        description: 'New company for the lead',
      },
      title: {
        type: 'string',
        description: 'New job title for the lead',
      },
      phone: {
        type: 'string',
        description: 'New phone number for the lead',
      },
      custom_fields: {
        type: 'object',
        description: 'Updated custom fields for the lead',
      },
    },
    required: ['lead_id'],
  },
};

export const UPDATE_LEAD_STATUS_TOOL: CategoryTool = {
  name: 'smartlead_update_lead_status',
  description: 'Update a lead\'s status.',
  category: ToolCategory.LEAD_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      lead_id: {
        type: 'number',
        description: 'ID of the lead to update',
      },
      status: {
        type: 'string',
        description: 'New status for the lead',
      },
    },
    required: ['lead_id', 'status'],
  },
};

export const BULK_IMPORT_LEADS_TOOL: CategoryTool = {
  name: 'smartlead_bulk_import_leads',
  description: 'Import multiple leads into a campaign at once.',
  category: ToolCategory.LEAD_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to add the leads to',
      },
      leads: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            email: {
              type: 'string',
              description: 'Email address of the lead',
            },
            first_name: {
              type: 'string',
              description: 'First name of the lead',
            },
            last_name: {
              type: 'string',
              description: 'Last name of the lead',
            },
            company: {
              type: 'string',
              description: 'Company of the lead',
            },
            title: {
              type: 'string',
              description: 'Job title of the lead',
            },
            phone: {
              type: 'string',
              description: 'Phone number of the lead',
            },
            custom_fields: {
              type: 'object',
              description: 'Custom fields for the lead',
            },
          },
          required: ['email'],
        },
        description: 'Array of leads to import',
      },
    },
    required: ['campaign_id', 'leads'],
  },
};

export const DELETE_LEAD_TOOL: CategoryTool = {
  name: 'smartlead_delete_lead',
  description: 'Delete a lead permanently.',
  category: ToolCategory.LEAD_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      lead_id: {
        type: 'number',
        description: 'ID of the lead to delete',
      },
    },
    required: ['lead_id'],
  },
};

// Export an array of all lead management tools for registration
export const leadTools = [
  LIST_LEADS_TOOL,
  GET_LEAD_TOOL,
  ADD_LEAD_TO_CAMPAIGN_TOOL,
  UPDATE_LEAD_TOOL,
  UPDATE_LEAD_STATUS_TOOL,
  BULK_IMPORT_LEADS_TOOL,
  DELETE_LEAD_TOOL,
]; 
```

--------------------------------------------------------------------------------
/src/handlers/smartSenders.ts:
--------------------------------------------------------------------------------

```typescript
import { AxiosInstance } from 'axios';
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import {
  isGetVendorsParams,
  isSearchDomainParams,
  isAutoGenerateMailboxesParams,
  isPlaceOrderParams,
  isGetDomainListParams
} from '../types/smartSenders.js';

// Smart Senders API base URL - different from the main SmartLead API
const SMART_SENDERS_API_URL = 'https://smart-senders.smartlead.ai/api/v1';

// Handler for Smart Senders-related tools
export async function handleSmartSendersTool(
  toolName: string,
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  switch (toolName) {
    case 'smartlead_get_vendors': {
      return handleGetVendors(args, apiClient, withRetry);
    }
    case 'smartlead_search_domain': {
      return handleSearchDomain(args, apiClient, withRetry);
    }
    case 'smartlead_auto_generate_mailboxes': {
      return handleAutoGenerateMailboxes(args, apiClient, withRetry);
    }
    case 'smartlead_place_order_mailboxes': {
      return handlePlaceOrderMailboxes(args, apiClient, withRetry);
    }
    case 'smartlead_get_domain_list': {
      return handleGetDomainList(args, apiClient, withRetry);
    }
    default:
      throw new Error(`Unknown Smart Senders tool: ${toolName}`);
  }
}

// Create a modified client for Smart Senders API with the correct base URL
function createSmartSendersClient(apiClient: AxiosInstance) {
  return {
    get: (url: string, config?: any) => 
      apiClient.get(`${SMART_SENDERS_API_URL}${url}`, config),
    post: (url: string, data?: any, config?: any) => 
      apiClient.post(`${SMART_SENDERS_API_URL}${url}`, data, config),
    put: (url: string, data?: any, config?: any) => 
      apiClient.put(`${SMART_SENDERS_API_URL}${url}`, data, config),
    delete: (url: string, config?: any) => 
      apiClient.delete(`${SMART_SENDERS_API_URL}${url}`, config)
  };
}

// Individual handlers for each tool
async function handleGetVendors(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isGetVendorsParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_get_vendors'
    );
  }

  try {
    const smartSendersClient = createSmartSendersClient(apiClient);
    
    const response = await withRetry(
      async () => smartSendersClient.get('/smart-senders/get-vendors'),
      'get vendors'
    );

    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 handleSearchDomain(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isSearchDomainParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_search_domain'
    );
  }

  try {
    const smartSendersClient = createSmartSendersClient(apiClient);
    const { domain_name, vendor_id } = args;
    
    const response = await withRetry(
      async () => smartSendersClient.get(`/smart-senders/search-domain?domain_name=${domain_name}&vendor_id=${vendor_id}`),
      'search domain'
    );

    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 handleAutoGenerateMailboxes(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isAutoGenerateMailboxesParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_auto_generate_mailboxes'
    );
  }

  try {
    const smartSendersClient = createSmartSendersClient(apiClient);
    
    const response = await withRetry(
      async () => smartSendersClient.post('/smart-senders/auto-generate-mailboxes', args),
      'auto-generate mailboxes'
    );

    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 handlePlaceOrderMailboxes(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isPlaceOrderParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_place_order_mailboxes'
    );
  }

  try {
    const smartSendersClient = createSmartSendersClient(apiClient);
    
    const response = await withRetry(
      async () => smartSendersClient.post('/smart-senders/place-order', args),
      'place order for mailboxes'
    );

    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 handleGetDomainList(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isGetDomainListParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_get_domain_list'
    );
  }

  try {
    const smartSendersClient = createSmartSendersClient(apiClient);
    
    const response = await withRetry(
      async () => smartSendersClient.get('/smart-senders/get-domain-list'),
      'get domain list'
    );

    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/types/email.ts:
--------------------------------------------------------------------------------

```typescript
import { AxiosError } from 'axios';

// Type guards for Email Account parameters
export function isListEmailAccountsParams(args: unknown): args is ListEmailAccountsParams {
  if (!args || typeof args !== 'object') return false;
  return true;
}

export function isAddEmailToCampaignParams(args: unknown): args is AddEmailToCampaignParams {
  if (!args || typeof args !== 'object') return false;
  const { campaign_id, email_account_id } = args as Partial<AddEmailToCampaignParams>;
  return (
    typeof campaign_id === 'number' &&
    typeof email_account_id === 'number'
  );
}

export function isRemoveEmailFromCampaignParams(args: unknown): args is RemoveEmailFromCampaignParams {
  if (!args || typeof args !== 'object') return false;
  const { campaign_id, email_account_id } = args as Partial<RemoveEmailFromCampaignParams>;
  return (
    typeof campaign_id === 'number' &&
    typeof email_account_id === 'number'
  );
}

export function isFetchEmailAccountsParams(args: unknown): args is FetchEmailAccountsParams {
  if (!args || typeof args !== 'object') return false;
  return true;
}

export function isCreateEmailAccountParams(args: unknown): args is CreateEmailAccountParams {
  if (!args || typeof args !== 'object') return false;
  const { from_name, from_email, user_name, password, smtp_host, smtp_port, imap_host, imap_port } = args as Partial<CreateEmailAccountParams>;
  return (
    typeof from_name === 'string' &&
    typeof from_email === 'string' &&
    typeof user_name === 'string' &&
    typeof password === 'string' &&
    typeof smtp_host === 'string' &&
    typeof smtp_port === 'number' &&
    typeof imap_host === 'string' &&
    typeof imap_port === 'number'
  );
}

export function isUpdateEmailAccountParams(args: unknown): args is UpdateEmailAccountParams {
  if (!args || typeof args !== 'object') return false;
  const { email_account_id } = args as Partial<UpdateEmailAccountParams>;
  return typeof email_account_id === 'number';
}

export function isFetchEmailAccountByIdParams(args: unknown): args is FetchEmailAccountByIdParams {
  if (!args || typeof args !== 'object') return false;
  const { email_account_id } = args as Partial<FetchEmailAccountByIdParams>;
  return typeof email_account_id === 'number';
}

export function isUpdateEmailWarmupParams(args: unknown): args is UpdateEmailWarmupParams {
  if (!args || typeof args !== 'object') return false;
  const { email_account_id, warmup_enabled } = args as Partial<UpdateEmailWarmupParams>;
  return (
    typeof email_account_id === 'number' &&
    typeof warmup_enabled === 'string'
  );
}

export function isReconnectEmailAccountParams(args: unknown): args is ReconnectEmailAccountParams {
  if (!args || typeof args !== 'object') return false;
  const { email_account_id } = args as Partial<ReconnectEmailAccountParams>;
  return typeof email_account_id === 'number';
}

export function isUpdateEmailAccountTagParams(args: unknown): args is UpdateEmailAccountTagParams {
  if (!args || typeof args !== 'object') return false;
  const { id, name, color } = args as Partial<UpdateEmailAccountTagParams>;
  return (
    typeof id === 'number' &&
    typeof name === 'string' &&
    typeof color === 'string'
  );
}

// Interface definitions for Email Account parameters
export interface ListEmailAccountsParams {
  campaign_id?: number;
  status?: string;
  limit?: number;
  offset?: number;
}

export interface AddEmailToCampaignParams {
  campaign_id: number;
  email_account_id: number;
}

export interface RemoveEmailFromCampaignParams {
  campaign_id: number;
  email_account_id: number;
}

export interface FetchEmailAccountsParams {
  status?: string;
  limit?: number;
  offset?: number;
  username?: string;
  client_id?: number; // Required Client ID according to the docs
}

export interface CreateEmailAccountParams {
  from_name: string;         // User's name
  from_email: string;        // User email
  user_name: string;         // Username
  password: string;          // User's password
  smtp_host: string;         // Mail SMTP host
  smtp_port: number;         // Mail SMTP port
  imap_host: string;         // Imap host URL
  imap_port: number;         // Imap port
  max_email_per_day?: number; // Max number of emails per day
  custom_tracking_url?: string; // Custom email tracking url
  bcc?: string;              // Email BCC
  signature?: string;        // Email signature
  warmup_enabled?: boolean;  // Set true to enable warmup
  total_warmup_per_day?: number; // Total number of warmups per day
  daily_rampup?: number;     // Daily rampup number
  reply_rate_percentage?: number; // Reply rate in percentage
  client_id?: number;        // Client ID
}

export interface UpdateEmailAccountParams {
  email_account_id: number;          // ID of the email to update
  max_email_per_day?: number;        // Max number of emails per day
  custom_tracking_url?: string;      // Custom email tracking URL
  bcc?: string;                      // Email BCC
  signature?: string;                // Email signature
  client_id?: number | null;         // Client ID. Set to null if not needed
  time_to_wait_in_mins?: number;     // Minimum integer time (in minutes) to wait before sending next email
}

export interface FetchEmailAccountByIdParams {
  email_account_id: number;
}

export interface UpdateEmailWarmupParams {
  email_account_id: number;          // Email account ID
  warmup_enabled: string;            // Set false to disable warmup
  total_warmup_per_day?: number;     // Total number of warmups in a day
  daily_rampup?: number;             // Set this value to increase or decrease daily ramup in warmup emails
  reply_rate_percentage?: string;    // Reply rate in percentage
  warmup_key_id?: string;            // If passed will update the custom warmup-key identifier
}

export interface ReconnectEmailAccountParams {
  email_account_id: number;
  connection_details?: {
    smtp_host?: string;
    smtp_port?: number;
    smtp_username?: string;
    smtp_password?: string;
    imap_host?: string;
    imap_port?: number;
    imap_username?: string;
    imap_password?: string;
    oauth_token?: string;
  };
}

export interface UpdateEmailAccountTagParams {
  id: number;              // ID of the tag
  name: string;            // Name of the tag
  color: string;           // The color of the tag in HEX format
}

// Email Account response interfaces
export interface EmailAccount {
  id: number;
  email: string;
  name?: string;
  provider: string;
  status: string;
  created_at: string;
  updated_at: string;
  last_checked_at?: string;
  warmup_enabled: boolean;
  daily_limit?: number;
  tags?: string[];
}

export interface EmailAccountResponse {
  success: boolean;
  data: EmailAccount;
  message?: string;
}

export interface EmailAccountListResponse {
  success: boolean;
  data: {
    accounts: EmailAccount[];
    total: number;
  };
  message?: string;
}

export interface EmailAccountActionResponse {
  success: boolean;
  message: string;
} 
```

--------------------------------------------------------------------------------
/src/types/statistics.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool, ToolCategory } from './common.js';

// Interface for fetching campaign statistics
export interface CampaignStatisticsParams {
  campaign_id: number;
  offset?: number;
  limit?: number;
  email_sequence_number?: string;
  email_status?: string;
  sent_time_start_date?: string;
  sent_time_end_date?: string;
}

// Interface for fetching campaign statistics by date range
export interface CampaignStatisticsByDateParams {
  campaign_id: number;
  start_date: string;
  end_date: string;
}

// Interface for fetching warmup stats by email account
export interface WarmupStatsByEmailParams {
  email_account_id: number;
}

// Interface for fetching campaign top level analytics
export interface CampaignTopLevelAnalyticsParams {
  campaign_id: number;
}

// Interface for fetching campaign top level analytics by date range
export interface CampaignTopLevelAnalyticsByDateParams {
  campaign_id: number;
  start_date: string;
  end_date: string;
}

// Interface for fetching campaign lead statistics
export interface CampaignLeadStatisticsParams {
  campaign_id: number;
  limit?: number;
  created_at_gt?: string;
  event_time_gt?: string;
  offset?: number;
}

// Interface for fetching campaign mailbox statistics
export interface CampaignMailboxStatisticsParams {
  campaign_id: number;
  client_id?: string;
  offset?: number;
  limit?: number;
  start_date?: string;
  end_date?: string;
  timezone?: string;
}

// Interface for downloading campaign data
export interface DownloadCampaignDataParams {
  campaign_id: number;
  download_type: string;
  format: string;
  user_id?: string;
}

// Interface for viewing download statistics
export interface ViewDownloadStatisticsParams {
  time_period?: 'all' | 'today' | 'week' | 'month';
  group_by?: 'type' | 'format' | 'campaign' | 'date';
}

// Type guards for params validation

export function isCampaignStatisticsParams(args: unknown): args is CampaignStatisticsParams {
  if (typeof args !== 'object' || args === null) {
    return false;
  }

  const params = args as CampaignStatisticsParams;
  
  if (typeof params.campaign_id !== 'number') {
    return false;
  }
  
  // Optional offset must be a number if present
  if (params.offset !== undefined && typeof params.offset !== 'number') {
    return false;
  }
  
  // Optional limit must be a number if present
  if (params.limit !== undefined && typeof params.limit !== 'number') {
    return false;
  }
  
  // Optional email_sequence_number must be a string if present
  if (params.email_sequence_number !== undefined && typeof params.email_sequence_number !== 'string') {
    return false;
  }
  
  // Optional email_status must be a string if present
  if (params.email_status !== undefined && typeof params.email_status !== 'string') {
    return false;
  }
  
  // Optional sent_time_start_date must be a string if present
  if (params.sent_time_start_date !== undefined && typeof params.sent_time_start_date !== 'string') {
    return false;
  }
  
  // Optional sent_time_end_date must be a string if present
  if (params.sent_time_end_date !== undefined && typeof params.sent_time_end_date !== 'string') {
    return false;
  }
  
  return true;
}

export function isCampaignStatisticsByDateParams(args: unknown): args is CampaignStatisticsByDateParams {
  if (typeof args !== 'object' || args === null) {
    return false;
  }

  const params = args as CampaignStatisticsByDateParams;
  
  return (
    typeof params.campaign_id === 'number' &&
    typeof params.start_date === 'string' &&
    typeof params.end_date === 'string'
  );
}

export function isWarmupStatsByEmailParams(args: unknown): args is WarmupStatsByEmailParams {
  if (typeof args !== 'object' || args === null) {
    return false;
  }

  const params = args as WarmupStatsByEmailParams;
  
  return typeof params.email_account_id === 'number';
}

export function isCampaignTopLevelAnalyticsParams(args: unknown): args is CampaignTopLevelAnalyticsParams {
  if (typeof args !== 'object' || args === null) {
    return false;
  }

  const params = args as CampaignTopLevelAnalyticsParams;
  
  return typeof params.campaign_id === 'number';
}

export function isCampaignTopLevelAnalyticsByDateParams(args: unknown): args is CampaignTopLevelAnalyticsByDateParams {
  if (typeof args !== 'object' || args === null) {
    return false;
  }

  const params = args as CampaignTopLevelAnalyticsByDateParams;
  
  return (
    typeof params.campaign_id === 'number' &&
    typeof params.start_date === 'string' &&
    typeof params.end_date === 'string'
  );
}

export function isCampaignLeadStatisticsParams(args: unknown): args is CampaignLeadStatisticsParams {
  if (typeof args !== 'object' || args === null) {
    return false;
  }

  const params = args as CampaignLeadStatisticsParams;
  
  if (typeof params.campaign_id !== 'number') {
    return false;
  }
  
  // Optional limit must be a string if present (it will be converted to number)
  if (params.limit !== undefined && typeof params.limit !== 'number') {
    return false;
  }
  
  // Optional created_at_gt must be a string if present
  if (params.created_at_gt !== undefined && typeof params.created_at_gt !== 'string') {
    return false;
  }
  
  // Optional event_time_gt must be a string if present
  if (params.event_time_gt !== undefined && typeof params.event_time_gt !== 'string') {
    return false;
  }
  
  // Optional offset must be a string if present (it will be converted to number)
  if (params.offset !== undefined && typeof params.offset !== 'number') {
    return false;
  }
  
  return true;
}

export function isCampaignMailboxStatisticsParams(obj: unknown): obj is CampaignMailboxStatisticsParams {
  return (
    !!obj &&
    typeof obj === 'object' &&
    'campaign_id' in obj &&
    typeof (obj as CampaignMailboxStatisticsParams).campaign_id === 'number'
  );
}

export function isDownloadCampaignDataParams(obj: unknown): obj is DownloadCampaignDataParams {
  if (!obj || typeof obj !== 'object') return false;
  
  const params = obj as Partial<DownloadCampaignDataParams>;
  
  // Check required fields
  if (typeof params.campaign_id !== 'number') return false;
  
  if (!params.download_type || 
      !['analytics', 'leads', 'sequence', 'full_export'].includes(params.download_type)) {
    return false;
  }
  
  if (!params.format || !['json', 'csv'].includes(params.format)) {
    return false;
  }
  
  // Check optional fields
  if (params.user_id !== undefined && typeof params.user_id !== 'string') {
    return false;
  }
  
  return true;
}

export function isViewDownloadStatisticsParams(obj: unknown): obj is ViewDownloadStatisticsParams {
  if (!obj || typeof obj !== 'object') return false;
  
  const params = obj as Partial<ViewDownloadStatisticsParams>;
  
  // Both fields are optional, but need to be validated if present
  if (params.time_period !== undefined && 
      !['all', 'today', 'week', 'month'].includes(params.time_period)) {
    return false;
  }
  
  if (params.group_by !== undefined &&
      !['type', 'format', 'campaign', 'date'].includes(params.group_by)) {
    return false;
  }
  
  return true;
} 
```

--------------------------------------------------------------------------------
/src/types/lead.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool, ToolCategory } from './common.js';

// Interface for listing leads
export interface ListLeadsParams {
  campaign_id?: number;
  status?: string;
  limit?: number;
  offset?: number;
  search?: string;
  start_date?: string;
  end_date?: string;
}

// Interface for getting a single lead
export interface GetLeadParams {
  lead_id: number;
}

// Interface for adding a lead to a campaign
export interface AddLeadToCampaignParams {
  campaign_id: number;
  email: string;
  first_name?: string;
  last_name?: string;
  company?: string;
  title?: string;
  phone?: string;
  custom_fields?: Record<string, string>;
}

// Interface for updating a lead
export interface UpdateLeadParams {
  lead_id: number;
  email?: string;
  first_name?: string;
  last_name?: string;
  company?: string;
  title?: string;
  phone?: string;
  custom_fields?: Record<string, string>;
}

// Interface for updating lead status
export interface UpdateLeadStatusParams {
  lead_id: number;
  status: string;
}

// Interface for bulk importing leads
export interface BulkImportLeadsParams {
  campaign_id: number;
  leads: Array<{
    email: string;
    first_name?: string;
    last_name?: string;
    company?: string;
    title?: string;
    phone?: string;
    custom_fields?: Record<string, string>;
  }>;
}

// Interface for deleting a lead
export interface DeleteLeadParams {
  lead_id: number;
}

// Type guards for params validation

export function isListLeadsParams(args: unknown): args is ListLeadsParams {
  if (typeof args !== 'object' || args === null) {
    return false;
  }

  const params = args as ListLeadsParams;
  
  // Optional campaign_id must be a number if present
  if (params.campaign_id !== undefined && typeof params.campaign_id !== 'number') {
    return false;
  }
  
  // Optional status must be a string if present
  if (params.status !== undefined && typeof params.status !== 'string') {
    return false;
  }
  
  // Optional limit must be a number if present
  if (params.limit !== undefined && typeof params.limit !== 'number') {
    return false;
  }
  
  // Optional offset must be a number if present
  if (params.offset !== undefined && typeof params.offset !== 'number') {
    return false;
  }
  
  // Optional search must be a string if present
  if (params.search !== undefined && typeof params.search !== 'string') {
    return false;
  }
  
  // Optional start_date must be a string if present
  if (params.start_date !== undefined && typeof params.start_date !== 'string') {
    return false;
  }
  
  // Optional end_date must be a string if present
  if (params.end_date !== undefined && typeof params.end_date !== 'string') {
    return false;
  }
  
  return true;
}

export function isGetLeadParams(args: unknown): args is GetLeadParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'lead_id' in args &&
    typeof (args as { lead_id: unknown }).lead_id === 'number'
  );
}

export function isAddLeadToCampaignParams(args: unknown): args is AddLeadToCampaignParams {
  if (
    typeof args !== 'object' ||
    args === null ||
    !('campaign_id' in args) ||
    !('email' in args) ||
    typeof (args as { campaign_id: unknown }).campaign_id !== 'number' ||
    typeof (args as { email: unknown }).email !== 'string'
  ) {
    return false;
  }
  
  const params = args as AddLeadToCampaignParams;
  
  // Optional fields validation
  if (params.first_name !== undefined && typeof params.first_name !== 'string') {
    return false;
  }
  if (params.last_name !== undefined && typeof params.last_name !== 'string') {
    return false;
  }
  if (params.company !== undefined && typeof params.company !== 'string') {
    return false;
  }
  if (params.title !== undefined && typeof params.title !== 'string') {
    return false;
  }
  if (params.phone !== undefined && typeof params.phone !== 'string') {
    return false;
  }
  if (
    params.custom_fields !== undefined && 
    (typeof params.custom_fields !== 'object' || params.custom_fields === null)
  ) {
    return false;
  }
  
  return true;
}

export function isUpdateLeadParams(args: unknown): args is UpdateLeadParams {
  if (
    typeof args !== 'object' ||
    args === null ||
    !('lead_id' in args) ||
    typeof (args as { lead_id: unknown }).lead_id !== 'number'
  ) {
    return false;
  }
  
  const params = args as UpdateLeadParams;
  
  // Optional fields validation
  if (params.email !== undefined && typeof params.email !== 'string') {
    return false;
  }
  if (params.first_name !== undefined && typeof params.first_name !== 'string') {
    return false;
  }
  if (params.last_name !== undefined && typeof params.last_name !== 'string') {
    return false;
  }
  if (params.company !== undefined && typeof params.company !== 'string') {
    return false;
  }
  if (params.title !== undefined && typeof params.title !== 'string') {
    return false;
  }
  if (params.phone !== undefined && typeof params.phone !== 'string') {
    return false;
  }
  if (
    params.custom_fields !== undefined && 
    (typeof params.custom_fields !== 'object' || params.custom_fields === null)
  ) {
    return false;
  }
  
  return true;
}

export function isUpdateLeadStatusParams(args: unknown): args is UpdateLeadStatusParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'lead_id' in args &&
    'status' in args &&
    typeof (args as { lead_id: unknown }).lead_id === 'number' &&
    typeof (args as { status: unknown }).status === 'string'
  );
}

export function isBulkImportLeadsParams(args: unknown): args is BulkImportLeadsParams {
  if (
    typeof args !== 'object' ||
    args === null ||
    !('campaign_id' in args) ||
    !('leads' in args) ||
    typeof (args as { campaign_id: unknown }).campaign_id !== 'number' ||
    !Array.isArray((args as { leads: unknown }).leads)
  ) {
    return false;
  }
  
  const params = args as BulkImportLeadsParams;
  
  // Validate each lead in the leads array
  for (const lead of params.leads) {
    if (
      typeof lead !== 'object' ||
      lead === null ||
      !('email' in lead) ||
      typeof lead.email !== 'string'
    ) {
      return false;
    }
    
    // Optional fields validation
    if (lead.first_name !== undefined && typeof lead.first_name !== 'string') {
      return false;
    }
    if (lead.last_name !== undefined && typeof lead.last_name !== 'string') {
      return false;
    }
    if (lead.company !== undefined && typeof lead.company !== 'string') {
      return false;
    }
    if (lead.title !== undefined && typeof lead.title !== 'string') {
      return false;
    }
    if (lead.phone !== undefined && typeof lead.phone !== 'string') {
      return false;
    }
    if (
      lead.custom_fields !== undefined && 
      (typeof lead.custom_fields !== 'object' || lead.custom_fields === null)
    ) {
      return false;
    }
  }
  
  return true;
}

export function isDeleteLeadParams(args: unknown): args is DeleteLeadParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'lead_id' in args &&
    typeof (args as { lead_id: unknown }).lead_id === 'number'
  );
} 
```

--------------------------------------------------------------------------------
/src/cli.ts:
--------------------------------------------------------------------------------

```typescript
#!/usr/bin/env node

import { program } from 'commander';
import dotenv from 'dotenv';
import { spawn } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
import readline from 'readline';
import { createInterface } from 'readline';

// Load environment variables from .env file
dotenv.config();

// Get the directory name of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Get version from package.json
const version = '1.0.0'; // This should ideally be imported from package.json

// License server URL
const LICENSE_SERVER_URL = 'https://sea-turtle-app-64etr.ondigitalocean.app/';

// Function to prompt for value interactively
async function promptForValue(question: string, hidden = false): Promise<string> {
  const rl = createInterface({
    input: process.stdin,
    output: process.stdout,
  });
  
  return new Promise((resolve) => {
    if (hidden) {
      process.stdout.write(question);
      process.stdin.setRawMode(true);
      let password = '';
      
      process.stdin.on('data', (chunk) => {
        const str = chunk.toString();
        if (str === '\n' || str === '\r' || str === '\u0004') {
          process.stdin.setRawMode(false);
          process.stdout.write('\n');
          rl.close();
          resolve(password);
        } else if (str === '\u0003') { // Ctrl+C
          process.exit(0);
        } else if (str === '\u007F') { // Backspace
          if (password.length > 0) {
            password = password.substring(0, password.length - 1);
            process.stdout.write('\b \b');
          }
        } else {
          password += str;
          process.stdout.write('*');
        }
      });
    } else {
      rl.question(question, (answer) => {
        rl.close();
        resolve(answer);
      });
    }
  });
}

// Function to ensure required environment variables are set
async function ensureEnvVars(): Promise<void> {
  // Check for API key
  if (!process.env.SMARTLEAD_API_KEY) {
    console.log('\nSmartlead API Key not found.');
    const apiKey = await promptForValue('Enter your Smartlead API Key: ', true);
    if (apiKey) {
      process.env.SMARTLEAD_API_KEY = apiKey;
    } else {
      console.log('Smartlead API Key is required to continue.');
      process.exit(1);
    }
  }

  // Check for license key
  if (!process.env.JEAN_LICENSE_KEY) {
    console.log('\nJean License Key not found. Defaulting to free tier access.');
    process.env.JEAN_LICENSE_KEY = 'JEANPARTNER';
  }

  // Set license server URL if not set
  if (!process.env.LICENSE_SERVER_URL) {
    process.env.LICENSE_SERVER_URL = LICENSE_SERVER_URL;
  }
  
  console.log('\nConfiguration complete!\n');
}

// Function to save environment variables to .env file
async function saveEnvToFile(): Promise<void> {
  if (process.env.SMARTLEAD_API_KEY || process.env.JEAN_LICENSE_KEY) {
    const saveEnv = await promptForValue('Do you want to save these settings to a .env file for future use? (y/n): ');
    if (saveEnv.toLowerCase() === 'y') {
      try {
        let envContent = '';
        if (process.env.SMARTLEAD_API_KEY) {
          envContent += `SMARTLEAD_API_KEY=${process.env.SMARTLEAD_API_KEY}\n`;
        }
        if (process.env.JEAN_LICENSE_KEY) {
          envContent += `JEAN_LICENSE_KEY=${process.env.JEAN_LICENSE_KEY}\n`;
        }
        if (process.env.LICENSE_SERVER_URL) {
          envContent += `LICENSE_SERVER_URL=${process.env.LICENSE_SERVER_URL}\n`;
        }
        
        fs.writeFileSync('.env', envContent);
        console.log('Settings saved to .env file in the current directory.');
      } catch (error) {
        console.error('Error saving .env file:', error);
      }
    }
  }
}

program
  .version(version)
  .description('Smartlead MCP Server CLI');

program
  .command('start')
  .description('Start the MCP server in standard STDIO mode')
  .option('--api-key <key>', 'Your Smartlead API Key')
  .option('--license-key <key>', 'Your Jean License Key')
  .action(async (options: { apiKey?: string; licenseKey?: string }) => {
    // Set env vars from command line options if provided
    if (options.apiKey) process.env.SMARTLEAD_API_KEY = options.apiKey;
    if (options.licenseKey) process.env.JEAN_LICENSE_KEY = options.licenseKey;
    
    // Ensure required env vars are set (will prompt if missing)
    await ensureEnvVars();
    await saveEnvToFile();
    
    console.log('Starting Smartlead MCP Server in STDIO mode...');
    // Run as a separate process instead of trying to import
    const indexPath = path.join(__dirname, 'index.js');
    const child = spawn('node', [indexPath], {
      stdio: 'inherit',
      env: process.env
    });
    
    process.on('SIGINT', () => {
      child.kill();
      process.exit();
    });
  });

program
  .command('sse')
  .description('Start the MCP server in SSE mode for n8n integration')
  .option('-p, --port <port>', 'Port to run the server on', '3000')
  .option('--api-key <key>', 'Your Smartlead API Key')
  .option('--license-key <key>', 'Your Jean License Key')
  .action(async (options: { port: string; apiKey?: string; licenseKey?: string }) => {
    // Set env vars from command line options if provided
    if (options.apiKey) process.env.SMARTLEAD_API_KEY = options.apiKey;
    if (options.licenseKey) process.env.JEAN_LICENSE_KEY = options.licenseKey;
    
    // Ensure required env vars are set (will prompt if missing)
    await ensureEnvVars();
    await saveEnvToFile();
    
    console.log(`Starting Smartlead MCP Server in SSE mode on port ${options.port}...`);
    console.log(`Connect from n8n to http://localhost:${options.port}/sse`);
    
    // Use supergateway to run in SSE mode
    const indexPath = path.join(__dirname, 'index.js');
    const supergateway = spawn('npx', [
      '-y', 
      'supergateway', 
      '--stdio', 
      `node ${indexPath}`, 
      '--port', 
      options.port
    ], { 
      shell: true,
      stdio: 'inherit',
      env: process.env
    });
    
    process.on('SIGINT', () => {
      supergateway.kill();
      process.exit();
    });
  });

program
  .command('config')
  .description('Show current configuration and set up environment variables')
  .option('--api-key <key>', 'Set your Smartlead API Key')
  .option('--license-key <key>', 'Set your Jean License Key')
  .action(async (options: { apiKey?: string; licenseKey?: string }) => {
    if (options.apiKey) process.env.SMARTLEAD_API_KEY = options.apiKey;
    if (options.licenseKey) process.env.JEAN_LICENSE_KEY = options.licenseKey;
    
    await ensureEnvVars();
    await saveEnvToFile();
    
    console.log('\nSmartlead MCP Server Configuration:');
    console.log(`API URL: ${process.env.SMARTLEAD_API_URL || 'https://server.smartlead.ai/api/v1'}`);
    console.log(`License Server: ${process.env.LICENSE_SERVER_URL || LICENSE_SERVER_URL}`);
    console.log(`License Status: ${process.env.JEAN_LICENSE_KEY ? 'Configured' : 'Not Configured'}`);
    console.log('\nConfiguration saved and ready to use.');
  });

program.parse(process.argv);

// Default to help if no command is provided
if (!process.argv.slice(2).length) {
  program.outputHelp();
} 
```

--------------------------------------------------------------------------------
/src/handlers/webhooks.ts:
--------------------------------------------------------------------------------

```typescript
import { AxiosInstance } from 'axios';
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import {
  isFetchWebhooksByCampaignParams,
  isUpsertCampaignWebhookParams,
  isDeleteCampaignWebhookParams,
  isGetWebhooksPublishSummaryParams,
  isRetriggerFailedEventsParams
} from '../types/webhooks.js';

// SmartLead API base URL
const SMARTLEAD_API_URL = 'https://server.smartlead.ai/api/v1';

// Handler for Webhook-related tools
export async function handleWebhookTool(
  toolName: string,
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  switch (toolName) {
    case 'smartlead_fetch_webhooks_by_campaign': {
      return handleFetchWebhooksByCampaign(args, apiClient, withRetry);
    }
    case 'smartlead_upsert_campaign_webhook': {
      return handleUpsertCampaignWebhook(args, apiClient, withRetry);
    }
    case 'smartlead_delete_campaign_webhook': {
      return handleDeleteCampaignWebhook(args, apiClient, withRetry);
    }
    case 'smartlead_get_webhooks_publish_summary': {
      return handleGetWebhooksPublishSummary(args, apiClient, withRetry);
    }
    case 'smartlead_retrigger_failed_events': {
      return handleRetriggerFailedEvents(args, apiClient, withRetry);
    }
    default:
      throw new Error(`Unknown Webhook tool: ${toolName}`);
  }
}

// Create a modified client for SmartLead API with the correct base URL
function createSmartLeadClient(apiClient: AxiosInstance) {
  return {
    get: (url: string, config?: any) => 
      apiClient.get(`${SMARTLEAD_API_URL}${url}`, config),
    post: (url: string, data?: any, config?: any) => 
      apiClient.post(`${SMARTLEAD_API_URL}${url}`, data, config),
    put: (url: string, data?: any, config?: any) => 
      apiClient.put(`${SMARTLEAD_API_URL}${url}`, data, config),
    delete: (url: string, config?: any) => 
      apiClient.delete(`${SMARTLEAD_API_URL}${url}`, config)
  };
}

// Individual handlers for each tool
async function handleFetchWebhooksByCampaign(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isFetchWebhooksByCampaignParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_fetch_webhooks_by_campaign'
    );
  }

  try {
    const smartLeadClient = createSmartLeadClient(apiClient);
    const { campaign_id } = args;
    
    const response = await withRetry(
      async () => smartLeadClient.get(`/campaigns/${campaign_id}/webhooks`),
      'fetch webhooks by 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 handleUpsertCampaignWebhook(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isUpsertCampaignWebhookParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_upsert_campaign_webhook'
    );
  }

  try {
    const smartLeadClient = createSmartLeadClient(apiClient);
    const { campaign_id, ...webhookData } = args;
    
    const response = await withRetry(
      async () => smartLeadClient.post(`/campaigns/${campaign_id}/webhooks`, webhookData),
      'upsert campaign webhook'
    );

    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 handleDeleteCampaignWebhook(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isDeleteCampaignWebhookParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_delete_campaign_webhook'
    );
  }

  try {
    const smartLeadClient = createSmartLeadClient(apiClient);
    const { campaign_id, id } = args;
    
    // The API documentation suggests a DELETE with a body payload
    // Different from typical REST practices but following the API spec
    const response = await withRetry(
      async () => smartLeadClient.delete(`/campaigns/${campaign_id}/webhooks`, { 
        data: { id }
      }),
      'delete campaign webhook'
    );

    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 handleGetWebhooksPublishSummary(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isGetWebhooksPublishSummaryParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_get_webhooks_publish_summary'
    );
  }

  try {
    const smartLeadClient = createSmartLeadClient(apiClient);
    const { campaign_id, fromTime, toTime } = args;
    
    let url = `/campaigns/${campaign_id}/webhooks/summary`;
    const queryParams = new URLSearchParams();
    
    if (fromTime) {
      queryParams.append('fromTime', fromTime);
    }
    
    if (toTime) {
      queryParams.append('toTime', toTime);
    }
    
    if (queryParams.toString()) {
      url += `?${queryParams.toString()}`;
    }
    
    const response = await withRetry(
      async () => smartLeadClient.get(url),
      'get webhooks publish 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 handleRetriggerFailedEvents(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isRetriggerFailedEventsParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_retrigger_failed_events'
    );
  }

  try {
    const smartLeadClient = createSmartLeadClient(apiClient);
    const { campaign_id, fromTime, toTime } = args;
    
    const response = await withRetry(
      async () => smartLeadClient.post(`/campaigns/${campaign_id}/webhooks/retrigger-failed-events`, {
        fromTime,
        toTime
      }),
      'retrigger failed events'
    );

    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/types/campaign.ts:
--------------------------------------------------------------------------------

```typescript
// Type definitions for campaign management

export interface CreateCampaignParams {
  name: string;
  client_id?: number;
}

export interface UpdateCampaignScheduleParams {
  campaign_id: number;
  timezone?: string;
  days_of_the_week?: number[];
  start_hour?: string;
  end_hour?: string;
  min_time_btw_emails?: number;
  max_new_leads_per_day?: number;
  schedule_start_time?: string;
}

export interface UpdateCampaignSettingsParams {
  campaign_id: number;
  name?: string;
  status?: 'active' | 'paused' | 'completed';
  settings?: Record<string, any>;
}

export interface UpdateCampaignStatusParams {
  campaign_id: number;
  status: 'PAUSED' | 'STOPPED' | 'START';
}

export interface GetCampaignParams {
  campaign_id: number;
}

export interface GetCampaignSequenceParams {
  campaign_id: number;
}

export interface ListCampaignsParams {
  status?: 'active' | 'paused' | 'completed';
  limit?: number;
  offset?: number;
}

export interface SaveCampaignSequenceParams {
  campaign_id: number;
  sequence: Array<{
    seq_number: number;
    seq_delay_details: {
      delay_in_days: number;
    };
    variant_distribution_type: 'MANUAL_EQUAL' | 'MANUAL_PERCENTAGE' | 'AI_EQUAL';
    lead_distribution_percentage?: number;
    winning_metric_property?: 'OPEN_RATE' | 'CLICK_RATE' | 'REPLY_RATE' | 'POSITIVE_REPLY_RATE';
    seq_variants: Array<{
      subject: string;
      email_body: string;
      variant_label: string;
      id?: number;
      variant_distribution_percentage?: number;
    }>;
  }>;
}

// New interface definitions for remaining campaign management endpoints
export interface GetCampaignsByLeadParams {
  lead_id: number;
}

export interface ExportCampaignLeadsParams {
  campaign_id: number;
}

export interface DeleteCampaignParams {
  campaign_id: number;
}

export interface GetCampaignAnalyticsByDateParams {
  campaign_id: number;
  start_date: string;
  end_date: string;
}

export interface GetCampaignSequenceAnalyticsParams {
  campaign_id: number;
  start_date: string;
  end_date: string;
  time_zone?: string;
}

// Type guards
export function isCreateCampaignParams(args: unknown): args is CreateCampaignParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'name' in args &&
    typeof (args as { name: unknown }).name === 'string'
  );
}

export function isUpdateCampaignScheduleParams(args: unknown): args is UpdateCampaignScheduleParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as { campaign_id: unknown }).campaign_id === 'number'
  );
}

export function isUpdateCampaignSettingsParams(args: unknown): args is UpdateCampaignSettingsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as { campaign_id: unknown }).campaign_id === 'number'
  );
}

export function isUpdateCampaignStatusParams(args: unknown): args is UpdateCampaignStatusParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as { campaign_id: unknown }).campaign_id === 'number' &&
    'status' in args &&
    typeof (args as { status: unknown }).status === 'string' &&
    ['PAUSED', 'STOPPED', 'START'].includes((args as { status: string }).status)
  );
}

export function isGetCampaignParams(args: unknown): args is GetCampaignParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as { campaign_id: unknown }).campaign_id === 'number'
  );
}

export function isGetCampaignSequenceParams(args: unknown): args is GetCampaignSequenceParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as { campaign_id: unknown }).campaign_id === 'number'
  );
}

export function isListCampaignsParams(args: unknown): args is ListCampaignsParams {
  return typeof args === 'object' && args !== null;
}

export function isSaveCampaignSequenceParams(args: unknown): args is SaveCampaignSequenceParams {
  if (
    typeof args !== 'object' ||
    args === null ||
    !('campaign_id' in args) ||
    typeof (args as { campaign_id: unknown }).campaign_id !== 'number' ||
    !('sequence' in args) ||
    !Array.isArray((args as { sequence: unknown }).sequence)
  ) {
    return false;
  }

  const sequence = (args as { sequence: unknown[] }).sequence;
  return sequence.every(isValidSequenceItem);
}

// New type guards for the remaining campaign management endpoints
export function isGetCampaignsByLeadParams(args: unknown): args is GetCampaignsByLeadParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'lead_id' in args &&
    typeof (args as { lead_id: unknown }).lead_id === 'number'
  );
}

export function isExportCampaignLeadsParams(args: unknown): args is ExportCampaignLeadsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as { campaign_id: unknown }).campaign_id === 'number'
  );
}

export function isDeleteCampaignParams(args: unknown): args is DeleteCampaignParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as { campaign_id: unknown }).campaign_id === 'number'
  );
}

export function isGetCampaignAnalyticsByDateParams(args: unknown): args is GetCampaignAnalyticsByDateParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as { campaign_id: unknown }).campaign_id === 'number' &&
    'start_date' in args &&
    typeof (args as { start_date: unknown }).start_date === 'string' &&
    'end_date' in args &&
    typeof (args as { end_date: unknown }).end_date === 'string'
  );
}

export function isGetCampaignSequenceAnalyticsParams(args: unknown): args is GetCampaignSequenceAnalyticsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'campaign_id' in args &&
    typeof (args as { campaign_id: unknown }).campaign_id === 'number' &&
    'start_date' in args &&
    typeof (args as { start_date: unknown }).start_date === 'string' &&
    'end_date' in args &&
    typeof (args as { end_date: unknown }).end_date === 'string'
  );
}

function isValidSequenceItem(item: unknown): boolean {
  return (
    typeof item === 'object' &&
    item !== null &&
    'seq_number' in item &&
    typeof (item as { seq_number: unknown }).seq_number === 'number' &&
    'seq_delay_details' in item &&
    typeof (item as { seq_delay_details: unknown }).seq_delay_details === 'object' &&
    (item as { seq_delay_details: unknown }).seq_delay_details !== null &&
    'delay_in_days' in (item as { seq_delay_details: { delay_in_days: unknown } }).seq_delay_details &&
    typeof (item as { seq_delay_details: { delay_in_days: unknown } }).seq_delay_details.delay_in_days === 'number' &&
    'variant_distribution_type' in item &&
    typeof (item as { variant_distribution_type: unknown }).variant_distribution_type === 'string' &&
    'seq_variants' in item &&
    Array.isArray((item as { seq_variants: unknown[] }).seq_variants) &&
    (item as { seq_variants: unknown[] }).seq_variants.every(
      (variant) =>
        typeof variant === 'object' &&
        variant !== null &&
        'subject' in variant &&
        typeof (variant as { subject: unknown }).subject === 'string' &&
        'email_body' in variant &&
        typeof (variant as { email_body: unknown }).email_body === 'string' &&
        'variant_label' in variant &&
        typeof (variant as { variant_label: unknown }).variant_label === 'string'
    )
  );
} 
```

--------------------------------------------------------------------------------
/src/tools/statistics.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool, ToolCategory } from '../types/common.js';

// Campaign Statistics Tools
export const CAMPAIGN_STATISTICS_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign_statistics',
  description: 'Fetch campaign statistics using the campaign\'s ID.',
  category: ToolCategory.CAMPAIGN_STATISTICS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to fetch statistics for',
      },
      offset: {
        type: 'number',
        description: 'Offset for pagination',
      },
      limit: {
        type: 'number',
        description: 'Maximum number of statistics to return',
      },
      email_sequence_number: {
        type: 'string',
        description: 'Email sequence number to filter by (e.g., "1,2,3,4")',
      },
      email_status: {
        type: 'string',
        description: 'Email status to filter by (e.g., "opened", "clicked", "replied", "unsubscribed", "bounced")',
      },
      sent_time_start_date: {
        type: 'string',
        description: 'Filter by sent time greater than this date (e.g., "2023-10-16 10:33:02.000Z")',
      },
      sent_time_end_date: {
        type: 'string',
        description: 'Filter by sent time less than this date (e.g., "2023-10-16 10:33:02.000Z")',
      },
    },
    required: ['campaign_id'],
  },
};

export const CAMPAIGN_STATISTICS_BY_DATE_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign_statistics_by_date',
  description: 'Fetch campaign statistics for a specific date range.',
  category: ToolCategory.CAMPAIGN_STATISTICS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to fetch statistics for',
      },
      start_date: {
        type: 'string',
        description: 'Start date in YYYY-MM-DD format',
      },
      end_date: {
        type: 'string',
        description: 'End date in YYYY-MM-DD format',
      },
    },
    required: ['campaign_id', 'start_date', 'end_date'],
  },
};

export const WARMUP_STATS_BY_EMAIL_TOOL: CategoryTool = {
  name: 'smartlead_get_warmup_stats_by_email',
  description: 'Fetch warmup stats for the last 7 days for a specific email account.',
  category: ToolCategory.CAMPAIGN_STATISTICS,
  inputSchema: {
    type: 'object',
    properties: {
      email_account_id: {
        type: 'number',
        description: 'ID of the email account to fetch warmup stats for',
      },
    },
    required: ['email_account_id'],
  },
};

export const CAMPAIGN_TOP_LEVEL_ANALYTICS_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign_top_level_analytics',
  description: 'Fetch top level analytics for a campaign.',
  category: ToolCategory.CAMPAIGN_STATISTICS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to fetch analytics for',
      },
    },
    required: ['campaign_id'],
  },
};

export const CAMPAIGN_TOP_LEVEL_ANALYTICS_BY_DATE_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign_top_level_analytics_by_date',
  description: 'Fetch campaign top level analytics for a specific date range.',
  category: ToolCategory.CAMPAIGN_STATISTICS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to fetch analytics for',
      },
      start_date: {
        type: 'string',
        description: 'Start date in YYYY-MM-DD format',
      },
      end_date: {
        type: 'string',
        description: 'End date in YYYY-MM-DD format',
      },
    },
    required: ['campaign_id', 'start_date', 'end_date'],
  },
};

export const CAMPAIGN_LEAD_STATISTICS_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign_lead_statistics',
  description: 'Fetch lead statistics for a campaign.',
  category: ToolCategory.CAMPAIGN_STATISTICS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to fetch lead statistics for',
      },
      limit: {
        type: 'number',
        description: 'Maximum number of leads to return (max 100)',
      },
      created_at_gt: {
        type: 'string',
        description: 'Filter by leads created after this date (YYYY-MM-DD format)',
      },
      event_time_gt: {
        type: 'string',
        description: 'Filter by events after this date (YYYY-MM-DD format)',
      },
      offset: {
        type: 'number',
        description: 'Offset for pagination',
      },
    },
    required: ['campaign_id'],
  },
};

export const CAMPAIGN_MAILBOX_STATISTICS_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign_mailbox_statistics',
  description: 'Fetch mailbox statistics for a campaign.',
  category: ToolCategory.CAMPAIGN_STATISTICS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to fetch mailbox statistics for',
      },
      client_id: {
        type: 'string',
        description: 'Client ID if the campaign is client-specific',
      },
      offset: {
        type: 'number',
        description: 'Offset for pagination',
      },
      limit: {
        type: 'number',
        description: 'Maximum number of results to return (min 1, max 20)',
      },
      start_date: {
        type: 'string',
        description: 'Start date (must be used with end_date)',
      },
      end_date: {
        type: 'string',
        description: 'End date (must be used with start_date)',
      },
      timezone: {
        type: 'string',
        description: 'Timezone for the data (e.g., "America/Los_Angeles")',
      },
    },
    required: ['campaign_id'],
  },
};

// Add this new tool for downloading campaign data with tracking
export const DOWNLOAD_CAMPAIGN_DATA_TOOL: CategoryTool = {
  name: 'smartlead_download_campaign_data',
  description: 'Download campaign data and track the download for analytics.',
  category: ToolCategory.CAMPAIGN_STATISTICS,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to download data for',
      },
      download_type: {
        type: 'string',
        enum: ['analytics', 'leads', 'sequence', 'full_export'],
        description: 'Type of data to download',
      },
      format: {
        type: 'string',
        enum: ['json', 'csv'],
        description: 'Format of the downloaded data',
      },
      user_id: {
        type: 'string',
        description: 'Optional user identifier for tracking downloads',
      },
    },
    required: ['campaign_id', 'download_type', 'format'],
  },
};

// Add this new tool for viewing download statistics
export const VIEW_DOWNLOAD_STATISTICS_TOOL: CategoryTool = {
  name: 'smartlead_view_download_statistics',
  description: 'View statistics about downloaded campaign data.',
  category: ToolCategory.CAMPAIGN_STATISTICS,
  inputSchema: {
    type: 'object',
    properties: {
      time_period: {
        type: 'string',
        enum: ['all', 'today', 'week', 'month'],
        description: 'Time period to filter statistics by',
      },
      group_by: {
        type: 'string',
        enum: ['type', 'format', 'campaign', 'date'],
        description: 'How to group the statistics',
      },
    },
  },
};

// Export an array of all campaign statistics tools for registration
export const statisticsTools: CategoryTool[] = [
  CAMPAIGN_STATISTICS_TOOL,
  CAMPAIGN_STATISTICS_BY_DATE_TOOL,
  WARMUP_STATS_BY_EMAIL_TOOL,
  CAMPAIGN_TOP_LEVEL_ANALYTICS_TOOL,
  CAMPAIGN_TOP_LEVEL_ANALYTICS_BY_DATE_TOOL,
  CAMPAIGN_LEAD_STATISTICS_TOOL,
  CAMPAIGN_MAILBOX_STATISTICS_TOOL,
  DOWNLOAD_CAMPAIGN_DATA_TOOL,
  VIEW_DOWNLOAD_STATISTICS_TOOL,
]; 
```

--------------------------------------------------------------------------------
/src/handlers/lead.ts:
--------------------------------------------------------------------------------

```typescript
import { AxiosInstance } from 'axios';
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import {
  isListLeadsParams,
  isGetLeadParams,
  isAddLeadToCampaignParams,
  isUpdateLeadParams,
  isUpdateLeadStatusParams,
  isBulkImportLeadsParams,
  isDeleteLeadParams
} from '../types/lead.js';

// Handler for lead-related tools
export async function handleLeadTool(
  toolName: string,
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  switch (toolName) {
    case 'smartlead_list_leads': {
      return handleListLeads(args, apiClient, withRetry);
    }
    case 'smartlead_get_lead': {
      return handleGetLead(args, apiClient, withRetry);
    }
    case 'smartlead_add_lead_to_campaign': {
      return handleAddLeadToCampaign(args, apiClient, withRetry);
    }
    case 'smartlead_update_lead': {
      return handleUpdateLead(args, apiClient, withRetry);
    }
    case 'smartlead_update_lead_status': {
      return handleUpdateLeadStatus(args, apiClient, withRetry);
    }
    case 'smartlead_bulk_import_leads': {
      return handleBulkImportLeads(args, apiClient, withRetry);
    }
    case 'smartlead_delete_lead': {
      return handleDeleteLead(args, apiClient, withRetry);
    }
    default:
      throw new Error(`Unknown lead tool: ${toolName}`);
  }
}

// Individual handlers for each tool
async function handleListLeads(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isListLeadsParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_list_leads'
    );
  }

  try {
    // Build query parameters from args
    const params = new URLSearchParams();
    if (args.campaign_id !== undefined) {
      params.append('campaign_id', args.campaign_id.toString());
    }
    if (args.status !== undefined) {
      params.append('status', args.status);
    }
    if (args.limit !== undefined) {
      params.append('limit', args.limit.toString());
    }
    if (args.offset !== undefined) {
      params.append('offset', args.offset.toString());
    }
    if (args.search !== undefined) {
      params.append('search', args.search);
    }
    if (args.start_date !== undefined) {
      params.append('start_date', args.start_date);
    }
    if (args.end_date !== undefined) {
      params.append('end_date', args.end_date);
    }

    const response = await withRetry(
      async () => apiClient.get('/leads', { params }),
      'list leads'
    );

    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 handleGetLead(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isGetLeadParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_get_lead'
    );
  }

  try {
    const response = await withRetry(
      async () => apiClient.get(`/leads/${args.lead_id}`),
      'get 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 handleAddLeadToCampaign(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isAddLeadToCampaignParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_add_lead_to_campaign'
    );
  }

  try {
    const response = await withRetry(
      async () => apiClient.post(`/campaigns/${args.campaign_id}/leads`, args),
      'add lead 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 handleUpdateLead(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isUpdateLeadParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_update_lead'
    );
  }

  const { lead_id, ...leadData } = args;

  try {
    const response = await withRetry(
      async () => apiClient.put(`/leads/${lead_id}`, leadData),
      'update 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 handleUpdateLeadStatus(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isUpdateLeadStatusParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_update_lead_status'
    );
  }

  const { lead_id, status } = args;

  try {
    const response = await withRetry(
      async () => apiClient.put(`/leads/${lead_id}/status`, { status }),
      'update lead 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 handleBulkImportLeads(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isBulkImportLeadsParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_bulk_import_leads'
    );
  }

  try {
    const response = await withRetry(
      async () => apiClient.post(`/campaigns/${args.campaign_id}/leads/bulk`, {
        leads: args.leads
      }),
      'bulk import leads'
    );

    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 handleDeleteLead(
  args: unknown,
  apiClient: AxiosInstance,
  withRetry: <T>(operation: () => Promise<T>, context: string) => Promise<T>
) {
  if (!isDeleteLeadParams(args)) {
    throw new McpError(
      ErrorCode.InvalidParams,
      'Invalid arguments for smartlead_delete_lead'
    );
  }

  try {
    const response = await withRetry(
      async () => apiClient.delete(`/leads/${args.lead_id}`),
      'delete 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,
    };
  }
} 
```

--------------------------------------------------------------------------------
/src/licensing/index.ts:
--------------------------------------------------------------------------------

```typescript
import axios from 'axios';
import * as dotenv from 'dotenv';

// Ensure .env file is loaded
dotenv.config();

// License levels
export enum LicenseLevel {
  FREE = 'free',
  BASIC = 'basic',
  PREMIUM = 'premium'
}

// Feature definitions
export interface LicenseFeatures {
  allowedCategories: string[];
  maxRequests: number;
  n8nIntegration: boolean;
  smartleadApiAccess: boolean;
}

// Licensing configuration - This is just a fallback when offline
const LICENSE_CONFIG: Record<LicenseLevel, LicenseFeatures> = {
  [LicenseLevel.FREE]: {
    allowedCategories: ['campaignManagement', 'leadManagement'],
    maxRequests: 100,
    n8nIntegration: false,
    smartleadApiAccess: true
  },
  [LicenseLevel.BASIC]: {
    allowedCategories: ['campaignManagement', 'leadManagement', 'campaignStatistics', 'smartDelivery', 'webhooks', 'clientManagement', 'smartSenders'],
    maxRequests: 1000,
    n8nIntegration: true,
    smartleadApiAccess: true
  },
  [LicenseLevel.PREMIUM]: {
    allowedCategories: ['campaignManagement', 'leadManagement', 'campaignStatistics', 'smartDelivery', 'webhooks', 'clientManagement', 'smartSenders'],
    maxRequests: 10000,
    n8nIntegration: true,
    smartleadApiAccess: true
  }
};

// License validation result
export interface LicenseValidationResult {
  valid: boolean;
  level: LicenseLevel;
  features: LicenseFeatures;
  message: string;
  usageCount: number;
}

// Generation info for server-side validation
export interface FeatureRequestToken {
  token: string;
  expires: number;
}

// Validation status cache
let cachedValidation: LicenseValidationResult | null = null;
let cachedFeatureToken: FeatureRequestToken | null = null;
const requestCounts: Record<string, number> = {};

// API configuration
// Use the environment variable for the license server URL
const LICENSE_SERVER_URL = process.env.LICENSE_SERVER_URL; 
const LICENSING_CACHE_TTL = 3600000; // 1 hour
let lastValidationTime = 0;

/**
 * Validate a license key
 * @param licenseKey Optional: license key to validate (primarily uses env var)
 * @returns License validation result
 */
export async function validateLicense(): Promise<LicenseValidationResult> {
  // Always return PREMIUM license regardless of key
  console.log('✅ License override: All features enabled in PREMIUM mode');
  return createValidationResult(
    LicenseLevel.PREMIUM,
    true,
    'License override enabled: All features available',
    0
  );
  
  // The following code will never be reached due to the early return above
  
  // Original code remains for reference but won't be executed:
  // Use the license key from the specific env var first
  // const apiKey = process.env.JEAN_LICENSE_KEY;
  // ... existing code ...
}

/**
 * Get a token for server-side feature validation
 * This adds security since critical operations will need server validation
 */
export async function getFeatureToken(): Promise<FeatureRequestToken | null> {
  // Ensure we have a valid license first
  const licenseResult = await validateLicense();
  
  // Check if we have a valid cached token
  if (cachedFeatureToken && Date.now() < cachedFeatureToken.expires) {
    return cachedFeatureToken;
  }
  
  // If no license server URL or not in BASIC or PREMIUM tier, don't try to get a token
  if (!LICENSE_SERVER_URL || 
      (licenseResult.level !== LicenseLevel.BASIC && 
       licenseResult.level !== LicenseLevel.PREMIUM)) {
    return null;
  }
  
  // Try to get a fresh token from the server
  try {
    const apiKey = process.env.JEAN_LICENSE_KEY;
    if (!apiKey) return null;
    
    console.log(`Requesting feature token from ${LICENSE_SERVER_URL}/token`);
    const response = await axios.post(`${LICENSE_SERVER_URL}/token`, {}, {
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      timeout: 5000
    });
    
    if (response.data && response.data.token) {
      cachedFeatureToken = {
        token: response.data.token,
        expires: response.data.expires || (Date.now() + 3600000) // Default to 1 hour if not specified
      };
      
      console.log(`✅ Feature token acquired, valid until ${new Date(cachedFeatureToken.expires).toISOString()}`);
      return cachedFeatureToken;
    }
    
    return null;
  } catch (error: any) {
    console.error(`Failed to get feature token: ${error.message}`);
    // Silent failure - just return null
    return null;
  }
}

/**
 * Track usage for a license
 * @param licenseKey The license key
 * @param toolName The tool being used
 */
export async function trackUsage(licenseKey?: string, toolName = 'unknown'): Promise<void> {
  const apiKey = licenseKey || process.env.JEAN_LICENSE_KEY;
  if (!apiKey || !LICENSE_SERVER_URL) return;
  
  // Get a unique identifier for tracking
  const machineId = getMachineId();
  
  // Increment local counter
  const key = apiKey.substring(0, 8); // Use part of the key as an identifier
  requestCounts[key] = (requestCounts[key] || 0) + 1;
  
  // Only report every 10 requests to reduce API load
  if (requestCounts[key] % 10 !== 0) return;
  
  try {
    // Report usage asynchronously (don't await)
    axios.post(`${LICENSE_SERVER_URL}/track`, {
      key: apiKey,
      tool: toolName,
      count: 10, // Batch reporting
      machineId
    }, {
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      }
    }).catch((error) => {
      // Silently fail with more context - we don't want to impact performance
      console.debug(`Usage tracking failed: ${error.message}`);
    });
  } catch (error) {
    // Ignore errors - usage tracking is non-critical
  }
}

/**
 * Create a validation result object
 */
function createValidationResult(
  level: LicenseLevel, 
  valid: boolean, 
  message: string,
  usageCount = 0
): LicenseValidationResult {
  return {
    valid,
    level,
    features: LICENSE_CONFIG[level],
    message,
    usageCount
  };
}

/**
 * Check if a feature is available in the current license
 * @param feature The feature to check
 * @returns Whether the feature is available
 */
export async function isFeatureEnabled(feature: keyof LicenseFeatures): Promise<boolean> {
  // Always return true for all features
  return true;
}

/**
 * Check if a category is available in the current license
 * @param category The category to check
 * @returns Whether the category is available
 */
export async function isCategoryEnabled(category: string): Promise<boolean> {
  // Always return true for all categories
  return true;
}

/**
 * Get the current license information
 * @returns Current license information
 */
export async function getLicenseInfo(): Promise<LicenseValidationResult> {
  return validateLicense();
}

/**
 * Get a unique identifier for the machine
 * This helps prevent sharing of license keys
 */
function getMachineId(): string {
  try {
    // Use environment variables to create a semi-unique ID
    // This is not perfect but provides basic machine identification
    const os = process.platform;
    const cpus = process.env.NUMBER_OF_PROCESSORS || '';
    const username = process.env.USER || process.env.USERNAME || '';
    const hostname = process.env.HOSTNAME || '';
    
    // Create a simple hash of these values
    const combinedString = `${os}-${cpus}-${username}-${hostname}`;
    let hash = 0;
    for (let i = 0; i < combinedString.length; i++) {
      hash = ((hash << 5) - hash) + combinedString.charCodeAt(i);
      hash |= 0; // Convert to 32bit integer
    }
    
    return Math.abs(hash).toString(16);
  } catch (e) {
    // Fallback to a random ID if we can't get system info
    return Math.random().toString(36).substring(2, 15);
  }
}

/**
 * Print a summary of the current license status to the console
 * This is useful for displaying on server startup
 */
export async function printLicenseStatus(): Promise<void> {
  try {
    const validation = await validateLicense();
    
    console.log('\n========== LICENSE STATUS ==========');
    console.log(`License Tier: ${validation.level.toUpperCase()}`);
    console.log(`Valid: ${validation.valid ? 'Yes' : 'No'}`);
    console.log(`Message: ${validation.message}`);
    console.log('Available Features:');
    console.log(`- Categories: ${validation.features.allowedCategories.join(', ')}`);
    console.log(`- Max Requests: ${validation.features.maxRequests}`);
    console.log(`- n8n Integration: ${validation.features.n8nIntegration ? 'Enabled' : 'Disabled'}`);
    console.log(`- Smartlead API Access: ${validation.features.smartleadApiAccess ? 'Enabled' : 'Disabled'}`);
    
    if (!validation.valid) {
      console.log('\n⚠️  ATTENTION ⚠️');
      console.log('Your license is not valid or is running in limited mode.');
      if (!process.env.JEAN_LICENSE_KEY) {
        console.log('You have not set a license key (JEAN_LICENSE_KEY) in your .env file.');
      }
      if (!process.env.LICENSE_SERVER_URL) {
        console.log('The LICENSE_SERVER_URL is not configured in your .env file.');
      }
      console.log('To enable all features, please check your configuration.');
    }
    
    if (process.env.LICENSE_LEVEL_OVERRIDE) {
      console.log('\n⚠️  DEVELOPMENT MODE ⚠️');
      console.log(`License level is overridden to: ${process.env.LICENSE_LEVEL_OVERRIDE.toUpperCase()}`);
      console.log('This override should not be used in production environments.');
    }
    
    console.log('=====================================\n');
  } catch (error) {
    console.error('Failed to print license status:', error);
  }
} 
```

--------------------------------------------------------------------------------
/server/license-server.js:
--------------------------------------------------------------------------------

```javascript
import express from 'express';
import crypto from 'crypto';
import { createClient } from '@supabase/supabase-js';
import Stripe from 'stripe';
import dotenv from 'dotenv';

dotenv.config();

// Initialize Express app
const app = express();
app.use(express.json());

// Initialize Stripe
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

// Initialize Supabase client
const supabase = createClient(
  process.env.SUPABASE_URL,
  process.env.SUPABASE_SERVICE_KEY
);

// License levels
const LicenseLevel = {
  FREE: 'free',
  BASIC: 'basic',
  PREMIUM: 'premium'
};

// Feature mappings
const LicenseFeatures = {
  [LicenseLevel.FREE]: {
    allowedCategories: ['campaignManagement', 'leadManagement'],
    maxRequests: 100,
    n8nIntegration: false,
    smartleadApiAccess: true
  },
  [LicenseLevel.BASIC]: {
    allowedCategories: ['campaignManagement', 'leadManagement', 'campaignStatistics', 'smartDelivery'],
    maxRequests: 1000,
    n8nIntegration: false,
    smartleadApiAccess: true
  },
  [LicenseLevel.PREMIUM]: {
    allowedCategories: ['campaignManagement', 'leadManagement', 'campaignStatistics', 'smartDelivery', 'webhooks', 'clientManagement', 'smartSenders'],
    maxRequests: 10000,
    n8nIntegration: true,
    smartleadApiAccess: true
  }
};

// Generate a secure license key
function generateLicenseKey() {
  return crypto.randomBytes(24).toString('hex');
}

// Generate a temporary feature token
function generateFeatureToken() {
  return {
    token: crypto.randomBytes(32).toString('hex'),
    expires: Date.now() + 3600000 // 1 hour
  };
}

// API Routes

// Validate a license key
app.post('/validate', async (req, res) => {
  try {
    const { Authorization } = req.headers;
    const apiKey = Authorization ? Authorization.replace('Bearer ', '') : null;
    const machineId = req.headers['x-client-id'];
    
    if (!apiKey) {
      return res.json({
        valid: false,
        level: LicenseLevel.FREE,
        message: 'No API key provided'
      });
    }
    
    // Query license in Supabase
    const { data, error } = await supabase
      .from('licenses')
      .select('*')
      .eq('key', apiKey)
      .single();
    
    if (error || !data) {
      return res.json({
        valid: false,
        level: LicenseLevel.FREE,
        message: 'Invalid license key'
      });
    }
    
    // Check if license is expired
    if (data.expires && new Date(data.expires) < new Date()) {
      return res.json({
        valid: false,
        level: LicenseLevel.FREE,
        message: 'License expired'
      });
    }
    
    // Check if this machine is authorized
    if (data.machine_ids && data.machine_ids.length > 0) {
      if (!machineId || !data.machine_ids.includes(machineId)) {
        // If this is a new machine, check if we've reached the limit
        if (data.machine_ids.length >= data.max_machines) {
          return res.json({
            valid: false,
            level: LicenseLevel.FREE,
            message: 'Maximum number of machines reached'
          });
        }
        
        // Otherwise add this machine to the authorized list
        const updatedMachines = [...data.machine_ids, machineId];
        await supabase
          .from('licenses')
          .update({ machine_ids: updatedMachines })
          .eq('id', data.id);
      }
    } else {
      // Initialize the machine_ids array with this machine
      await supabase
        .from('licenses')
        .update({ machine_ids: [machineId] })
        .eq('id', data.id);
    }
    
    // Generate a feature token for server-side validation
    const featureToken = generateFeatureToken();
    
    // Track usage
    await supabase
      .from('license_usage')
      .insert({
        license_id: data.id,
        machine_id: machineId,
        timestamp: new Date().toISOString()
      });
    
    // Increment usage count
    const { count } = await supabase
      .from('license_usage')
      .select('count', { count: 'exact' })
      .eq('license_id', data.id);
    
    return res.json({
      valid: true,
      level: data.level,
      usage: count || 0,
      featureToken: featureToken.token,
      tokenExpires: 3600, // 1 hour in seconds
      message: 'License validated successfully'
    });
  } catch (error) {
    console.error('License validation error:', error);
    return res.status(500).json({
      valid: false,
      level: LicenseLevel.FREE,
      message: 'Server error during validation'
    });
  }
});

// Validate an installation
app.post('/validate-install', async (req, res) => {
  try {
    const { apiKey, machineId, version, installPath } = req.body;
    
    if (!apiKey) {
      return res.json({
        success: false,
        message: 'No API key provided'
      });
    }
    
    // Query license in Supabase
    const { data, error } = await supabase
      .from('licenses')
      .select('*')
      .eq('key', apiKey)
      .single();
    
    if (error || !data) {
      return res.json({
        success: false,
        message: 'Invalid license key'
      });
    }
    
    // Check if license is expired
    if (data.expires && new Date(data.expires) < new Date()) {
      return res.json({
        success: false,
        message: 'License expired'
      });
    }
    
    // Record installation info
    await supabase
      .from('installations')
      .insert({
        license_id: data.id,
        machine_id: machineId,
        version,
        install_path: installPath,
        installed_at: new Date().toISOString()
      });
    
    // Return license details
    return res.json({
      success: true,
      level: data.level,
      features: LicenseFeatures[data.level].allowedCategories,
      expires: data.expires,
      message: 'Installation validated successfully'
    });
  } catch (error) {
    console.error('Installation validation error:', error);
    return res.status(500).json({
      success: false,
      message: 'Server error during installation validation'
    });
  }
});

// Generate a feature token (used for server-side validation)
app.post('/token', async (req, res) => {
  try {
    const { Authorization } = req.headers;
    const apiKey = Authorization ? Authorization.replace('Bearer ', '') : null;
    
    if (!apiKey) {
      return res.status(401).json({ error: 'Unauthorized' });
    }
    
    // Verify the license is valid
    const { data, error } = await supabase
      .from('licenses')
      .select('level')
      .eq('key', apiKey)
      .single();
    
    if (error || !data) {
      return res.status(401).json({ error: 'Invalid license' });
    }
    
    // Generate a new token
    const featureToken = generateFeatureToken();
    
    // Store the token in Supabase with expiration
    await supabase
      .from('feature_tokens')
      .insert({
        token: featureToken.token,
        license_key: apiKey,
        expires_at: new Date(featureToken.expires).toISOString()
      });
    
    return res.json({
      token: featureToken.token,
      expires: featureToken.expires
    });
  } catch (error) {
    console.error('Token generation error:', error);
    return res.status(500).json({ error: 'Server error' });
  }
});

// Handle Stripe webhook
app.post('/webhook', async (req, res) => {
  const sig = req.headers['stripe-signature'];
  
  try {
    const event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET
    );
    
    switch (event.type) {
      case 'customer.subscription.created':
      case 'customer.subscription.updated': {
        const subscription = event.data.object;
        const customerId = subscription.customer;
        
        // Get the product details to determine license level
        const product = await stripe.products.retrieve(
          subscription.items.data[0].plan.product
        );
        
        // Get license level from product metadata
        const level = product.metadata.license_level || LicenseLevel.BASIC;
        
        // Generate a license key
        const licenseKey = generateLicenseKey();
        
        // Get the customer email
        const customer = await stripe.customers.retrieve(customerId);
        
        // Store the license in Supabase
        await supabase
          .from('licenses')
          .upsert({
            key: licenseKey,
            customer_id: customerId,
            customer_email: customer.email,
            level,
            created_at: new Date().toISOString(),
            expires: subscription.current_period_end 
              ? new Date(subscription.current_period_end * 1000).toISOString() 
              : null,
            max_machines: level === LicenseLevel.PREMIUM ? 5 : 2, // Limit based on tier
            machine_ids: [],
            active: true
          }, { onConflict: 'customer_id' });
        
        // Update customer metadata with license key
        await stripe.customers.update(customerId, {
          metadata: { 
            license_key: licenseKey,
            license_level: level
          }
        });
        
        break;
      }
      
      case 'customer.subscription.deleted': {
        const subscription = event.data.object;
        const customerId = subscription.customer;
        
        // Find the license by customer ID
        const { data } = await supabase
          .from('licenses')
          .select('id')
          .eq('customer_id', customerId)
          .single();
        
        if (data) {
          // Downgrade the license to free tier
          await supabase
            .from('licenses')
            .update({ 
              level: LicenseLevel.FREE,
              expires: new Date().toISOString() // Expire now
            })
            .eq('id', data.id);
        }
        
        break;
      }
    }
    
    res.json({ received: true });
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(400).json({ error: error.message });
  }
});

// Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`License server running on port ${PORT}`);
}); 
```

--------------------------------------------------------------------------------
/src/tools/email.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool, ToolCategory } from '../types/common.js';

// Email Account Management Tools
export const LIST_EMAIL_ACCOUNTS_CAMPAIGN_TOOL: CategoryTool = {
  name: 'smartlead_list_email_accounts_campaign',
  description: 'List all email accounts associated with a specific campaign.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to get email accounts for',
      },
      status: {
        type: 'string',
        enum: ['active', 'disconnected', 'pending'],
        description: 'Filter email accounts by status',
      },
      limit: {
        type: 'number',
        description: 'Maximum number of email accounts to return',
      },
      offset: {
        type: 'number',
        description: 'Offset for pagination',
      },
    },
    required: ['campaign_id'],
  },
};

export const ADD_EMAIL_TO_CAMPAIGN_TOOL: CategoryTool = {
  name: 'smartlead_add_email_to_campaign',
  description: 'Add an email account to a campaign.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to add the email account to',
      },
      email_account_id: {
        type: 'number',
        description: 'ID of the email account to add to the campaign',
      },
    },
    required: ['campaign_id', 'email_account_id'],
  },
};

export const REMOVE_EMAIL_FROM_CAMPAIGN_TOOL: CategoryTool = {
  name: 'smartlead_remove_email_from_campaign',
  description: 'Remove an email account from a campaign.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to remove the email account from',
      },
      email_account_id: {
        type: 'number',
        description: 'ID of the email account to remove from the campaign',
      },
    },
    required: ['campaign_id', 'email_account_id'],
  },
};

export const FETCH_EMAIL_ACCOUNTS_TOOL: CategoryTool = {
  name: 'smartlead_fetch_email_accounts',
  description: 'Fetch all email accounts associated with the user.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      status: {
        type: 'string',
        enum: ['active', 'disconnected', 'pending'],
        description: 'Filter email accounts by status',
      },
      limit: {
        type: 'number',
        description: 'Maximum number of email accounts to return',
      },
      offset: {
        type: 'number',
        description: 'Offset for pagination',
      },
    },
  },
};

export const CREATE_EMAIL_ACCOUNT_TOOL: CategoryTool = {
  name: 'smartlead_create_email_account',
  description: 'Create a new email account.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      email: {
        type: 'string',
        description: 'Email address',
      },
      provider: {
        type: 'string',
        description: 'Email provider (e.g., "gmail", "outlook", "custom")',
      },
      name: {
        type: 'string',
        description: 'Display name for the email account',
      },
      smtp_host: {
        type: 'string',
        description: 'SMTP server hostname (for custom providers)',
      },
      smtp_port: {
        type: 'number',
        description: 'SMTP server port (for custom providers)',
      },
      smtp_username: {
        type: 'string',
        description: 'SMTP username (for custom providers)',
      },
      smtp_password: {
        type: 'string',
        description: 'SMTP password (for custom providers)',
      },
      imap_host: {
        type: 'string',
        description: 'IMAP server hostname (for custom providers)',
      },
      imap_port: {
        type: 'number',
        description: 'IMAP server port (for custom providers)',
      },
      imap_username: {
        type: 'string',
        description: 'IMAP username (for custom providers)',
      },
      imap_password: {
        type: 'string',
        description: 'IMAP password (for custom providers)',
      },
      oauth_token: {
        type: 'string',
        description: 'OAuth token (for OAuth-based providers)',
      },
      tags: {
        type: 'array',
        items: {
          type: 'string',
        },
        description: 'Tags to assign to the email account',
      },
    },
    required: ['email', 'provider'],
  },
};

export const UPDATE_EMAIL_ACCOUNT_TOOL: CategoryTool = {
  name: 'smartlead_update_email_account',
  description: 'Update an existing email account.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      email_account_id: {
        type: 'number',
        description: 'ID of the email account to update',
      },
      name: {
        type: 'string',
        description: 'Display name for the email account',
      },
      smtp_host: {
        type: 'string',
        description: 'SMTP server hostname',
      },
      smtp_port: {
        type: 'number',
        description: 'SMTP server port',
      },
      smtp_username: {
        type: 'string',
        description: 'SMTP username',
      },
      smtp_password: {
        type: 'string',
        description: 'SMTP password',
      },
      imap_host: {
        type: 'string',
        description: 'IMAP server hostname',
      },
      imap_port: {
        type: 'number',
        description: 'IMAP server port',
      },
      imap_username: {
        type: 'string',
        description: 'IMAP username',
      },
      imap_password: {
        type: 'string',
        description: 'IMAP password',
      },
      oauth_token: {
        type: 'string',
        description: 'OAuth token',
      },
      status: {
        type: 'string',
        enum: ['active', 'paused', 'disconnected'],
        description: 'Status of the email account',
      },
    },
    required: ['email_account_id'],
  },
};

export const FETCH_EMAIL_ACCOUNT_BY_ID_TOOL: CategoryTool = {
  name: 'smartlead_fetch_email_account_by_id',
  description: 'Fetch a specific email account by ID.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      email_account_id: {
        type: 'number',
        description: 'ID of the email account to fetch',
      },
    },
    required: ['email_account_id'],
  },
};

export const UPDATE_EMAIL_WARMUP_TOOL: CategoryTool = {
  name: 'smartlead_update_email_warmup',
  description: 'Add or update warmup settings for an email account.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      email_account_id: {
        type: 'number',
        description: 'ID of the email account to update warmup settings for',
      },
      enabled: {
        type: 'boolean',
        description: 'Whether warmup is enabled for this email account',
      },
      daily_limit: {
        type: 'number',
        description: 'Daily limit for warmup emails',
      },
      warmup_settings: {
        type: 'object',
        properties: {
          start_time: {
            type: 'string',
            description: 'Start time for warmup in HH:MM format',
          },
          end_time: {
            type: 'string',
            description: 'End time for warmup in HH:MM format',
          },
          days_of_week: {
            type: 'array',
            items: {
              type: 'number',
            },
            description: 'Days of the week for warmup (1-7, where 1 is Monday)',
          },
        },
        description: 'Additional warmup settings',
      },
    },
    required: ['email_account_id', 'enabled'],
  },
};

export const RECONNECT_EMAIL_ACCOUNT_TOOL: CategoryTool = {
  name: 'smartlead_reconnect_email_account',
  description: 'Reconnect a failed email account.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      email_account_id: {
        type: 'number',
        description: 'ID of the email account to reconnect',
      },
      connection_details: {
        type: 'object',
        properties: {
          smtp_host: {
            type: 'string',
            description: 'SMTP server hostname',
          },
          smtp_port: {
            type: 'number',
            description: 'SMTP server port',
          },
          smtp_username: {
            type: 'string',
            description: 'SMTP username',
          },
          smtp_password: {
            type: 'string',
            description: 'SMTP password',
          },
          imap_host: {
            type: 'string',
            description: 'IMAP server hostname',
          },
          imap_port: {
            type: 'number',
            description: 'IMAP server port',
          },
          imap_username: {
            type: 'string',
            description: 'IMAP username',
          },
          imap_password: {
            type: 'string',
            description: 'IMAP password',
          },
          oauth_token: {
            type: 'string',
            description: 'OAuth token',
          },
        },
        description: 'Connection details for reconnecting the email account',
      },
    },
    required: ['email_account_id'],
  },
};

export const UPDATE_EMAIL_ACCOUNT_TAG_TOOL: CategoryTool = {
  name: 'smartlead_update_email_account_tag',
  description: 'Update tags for an email account.',
  category: ToolCategory.EMAIL_ACCOUNT_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      email_account_id: {
        type: 'number',
        description: 'ID of the email account to update tags for',
      },
      tags: {
        type: 'array',
        items: {
          type: 'string',
        },
        description: 'Tags to assign to the email account',
      },
    },
    required: ['email_account_id', 'tags'],
  },
};

// Export all email tools as an array
export const emailTools = [
  LIST_EMAIL_ACCOUNTS_CAMPAIGN_TOOL,
  ADD_EMAIL_TO_CAMPAIGN_TOOL,
  REMOVE_EMAIL_FROM_CAMPAIGN_TOOL,
  FETCH_EMAIL_ACCOUNTS_TOOL,
  CREATE_EMAIL_ACCOUNT_TOOL,
  UPDATE_EMAIL_ACCOUNT_TOOL,
  FETCH_EMAIL_ACCOUNT_BY_ID_TOOL,
  UPDATE_EMAIL_WARMUP_TOOL,
  RECONNECT_EMAIL_ACCOUNT_TOOL,
  UPDATE_EMAIL_ACCOUNT_TAG_TOOL,
]; 
```

--------------------------------------------------------------------------------
/src/tools/campaign.ts:
--------------------------------------------------------------------------------

```typescript
import { CategoryTool, ToolCategory } from '../types/common.js';

// Campaign Management Tools
export const CREATE_CAMPAIGN_TOOL: CategoryTool = {
  name: 'smartlead_create_campaign',
  description: 'Create a new campaign in Smartlead.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      name: {
        type: 'string',
        description: 'Name of the campaign',
      },
      client_id: {
        type: 'number',
        description: 'Client ID for the campaign',
      },
    },
    required: ['name'],
  },
};

export const UPDATE_CAMPAIGN_SCHEDULE_TOOL: CategoryTool = {
  name: 'smartlead_update_campaign_schedule',
  description: 'Update a campaign\'s schedule settings.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to update',
      },
      timezone: {
        type: 'string',
        description: 'Timezone for the campaign (e.g., "America/Los_Angeles")',
      },
      days_of_the_week: {
        type: 'array',
        items: { type: 'number' },
        description: 'Days of the week to send emails (1-7, where 1 is Monday)',
      },
      start_hour: {
        type: 'string',
        description: 'Start hour in 24-hour format (e.g., "09:00")',
      },
      end_hour: {
        type: 'string',
        description: 'End hour in 24-hour format (e.g., "17:00")',
      },
      min_time_btw_emails: {
        type: 'number',
        description: 'Minimum time between emails in minutes',
      },
      max_new_leads_per_day: {
        type: 'number',
        description: 'Maximum number of new leads per day',
      },
      schedule_start_time: {
        type: 'string',
        description: 'Schedule start time in ISO format',
      },
    },
    required: ['campaign_id'],
  },
};

export const UPDATE_CAMPAIGN_SETTINGS_TOOL: CategoryTool = {
  name: 'smartlead_update_campaign_settings',
  description: 'Update a campaign\'s general settings.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to update',
      },
      name: {
        type: 'string',
        description: 'New name for the campaign',
      },
      status: {
        type: 'string',
        enum: ['active', 'paused', 'completed'],
        description: 'Status of the campaign',
      },
      settings: {
        type: 'object',
        description: 'Additional campaign settings',
      },
    },
    required: ['campaign_id'],
  },
};

export const UPDATE_CAMPAIGN_STATUS_TOOL: CategoryTool = {
  name: 'smartlead_update_campaign_status',
  description: 'Update the status of a campaign. Use this specifically for changing a campaign\'s status.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to update the status for',
      },
      status: {
        type: 'string',
        enum: ['PAUSED', 'STOPPED', 'START'],
        description: 'New status for the campaign (must be in uppercase)',
      },
    },
    required: ['campaign_id', 'status'],
  },
};

export const GET_CAMPAIGN_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign',
  description: 'Get details of a specific campaign by ID.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to retrieve',
      },
    },
    required: ['campaign_id'],
  },
};

export const LIST_CAMPAIGNS_TOOL: CategoryTool = {
  name: 'smartlead_list_campaigns',
  description: 'List all campaigns with optional filtering.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      status: {
        type: 'string',
        enum: ['active', 'paused', 'completed'],
        description: 'Filter campaigns by status',
      },
      limit: {
        type: 'number',
        description: 'Maximum number of campaigns to return',
      },
      offset: {
        type: 'number',
        description: 'Offset for pagination',
      },
    },
  },
};

export const SAVE_CAMPAIGN_SEQUENCE_TOOL: CategoryTool = {
  name: 'smartlead_save_campaign_sequence',
  description: 'Save a sequence of emails for a campaign.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign',
      },
      sequence: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            seq_number: {
              type: 'number',
              description: 'The sequence number (order) of this email',
            },
            seq_delay_details: {
              type: 'object',
              properties: {
                delay_in_days: {
                  type: 'number',
                  description: 'Days to wait before sending this email',
                }
              },
              description: 'Delay details for this sequence'
            },
            variant_distribution_type: {
              type: 'string',
              enum: ['MANUAL_EQUAL', 'MANUAL_PERCENTAGE', 'AI_EQUAL'],
              description: 'How to distribute variants'
            },
            lead_distribution_percentage: {
              type: 'number',
              description: 'What sample % size of the lead pool to use to find the winner (for AI_EQUAL)'
            },
            winning_metric_property: {
              type: 'string',
              enum: ['OPEN_RATE', 'CLICK_RATE', 'REPLY_RATE', 'POSITIVE_REPLY_RATE'],
              description: 'Metric to use for determining the winning variant (for AI_EQUAL)'
            },
            seq_variants: {
              type: 'array',
              items: {
                type: 'object',
                properties: {
                  subject: {
                    type: 'string',
                    description: 'Email subject line',
                  },
                  email_body: {
                    type: 'string',
                    description: 'Email body content in HTML',
                  },
                  variant_label: {
                    type: 'string',
                    description: 'Label for this variant (A, B, C, etc.)',
                  },
                  variant_distribution_percentage: {
                    type: 'number',
                    description: 'Percentage of leads to receive this variant (for MANUAL_PERCENTAGE)'
                  }
                },
                required: ['subject', 'email_body', 'variant_label'],
              },
              description: 'Variants of the email in this sequence'
            }
          },
          required: ['seq_number', 'seq_delay_details', 'variant_distribution_type', 'seq_variants'],
        },
        description: 'Sequence of emails to send',
      },
    },
    required: ['campaign_id', 'sequence'],
  },
};

export const GET_CAMPAIGN_SEQUENCE_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign_sequence',
  description: 'Fetch a campaign\'s sequence data.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to fetch sequences for',
      },
    },
    required: ['campaign_id'],
  },
};

// New tool definitions for the remaining campaign management API endpoints

export const GET_CAMPAIGNS_BY_LEAD_TOOL: CategoryTool = {
  name: 'smartlead_get_campaigns_by_lead',
  description: 'Fetch all campaigns that a lead belongs to.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      lead_id: {
        type: 'number',
        description: 'ID of the lead to fetch campaigns for',
      },
    },
    required: ['lead_id'],
  },
};

export const EXPORT_CAMPAIGN_LEADS_TOOL: CategoryTool = {
  name: 'smartlead_export_campaign_leads',
  description: 'Export all leads data from a campaign as CSV.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to export leads from',
      },
    },
    required: ['campaign_id'],
  },
};

export const DELETE_CAMPAIGN_TOOL: CategoryTool = {
  name: 'smartlead_delete_campaign',
  description: 'Delete a campaign permanently.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to delete',
      },
    },
    required: ['campaign_id'],
  },
};

export const GET_CAMPAIGN_ANALYTICS_BY_DATE_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign_analytics_by_date',
  description: 'Fetch campaign analytics for a specific date range.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to fetch analytics for',
      },
      start_date: {
        type: 'string',
        format: 'date',
        description: 'Start date in YYYY-MM-DD format',
      },
      end_date: {
        type: 'string',
        format: 'date',
        description: 'End date in YYYY-MM-DD format',
      },
    },
    required: ['campaign_id', 'start_date', 'end_date'],
  },
};

export const GET_CAMPAIGN_SEQUENCE_ANALYTICS_TOOL: CategoryTool = {
  name: 'smartlead_get_campaign_sequence_analytics',
  description: 'Fetch analytics data for a specific email campaign sequence.',
  category: ToolCategory.CAMPAIGN_MANAGEMENT,
  inputSchema: {
    type: 'object',
    properties: {
      campaign_id: {
        type: 'number',
        description: 'ID of the campaign to fetch sequence analytics for',
      },
      start_date: {
        type: 'string',
        description: 'Start date in YYYY-MM-DD HH:MM:SS format',
      },
      end_date: {
        type: 'string',
        description: 'End date in YYYY-MM-DD HH:MM:SS format',
      },
      time_zone: {
        type: 'string',
        description: 'Timezone for the analytics data (e.g., "Europe/London")',
      },
    },
    required: ['campaign_id', 'start_date', 'end_date'],
  },
};

// Export an array of all campaign tools for registration
export const campaignTools = [
  CREATE_CAMPAIGN_TOOL,
  UPDATE_CAMPAIGN_SCHEDULE_TOOL,
  UPDATE_CAMPAIGN_SETTINGS_TOOL,
  UPDATE_CAMPAIGN_STATUS_TOOL,
  GET_CAMPAIGN_TOOL,
  LIST_CAMPAIGNS_TOOL,
  SAVE_CAMPAIGN_SEQUENCE_TOOL,
  GET_CAMPAIGN_SEQUENCE_TOOL,
  GET_CAMPAIGNS_BY_LEAD_TOOL,
  EXPORT_CAMPAIGN_LEADS_TOOL,
  DELETE_CAMPAIGN_TOOL,
  GET_CAMPAIGN_ANALYTICS_BY_DATE_TOOL,
  GET_CAMPAIGN_SEQUENCE_ANALYTICS_TOOL
]; 
```

--------------------------------------------------------------------------------
/src/types/smartDelivery.ts:
--------------------------------------------------------------------------------

```typescript
// Type definitions for SmartDelivery functionality

// Region wise Provider IDs response types
export interface SpamTestProvider {
  id: number;
  name: string;
  description?: string;
  region?: string;
  country?: string;
  is_active: boolean;
}

export interface RegionWiseProvidersResponse {
  success: boolean;
  data: {
    providers: SpamTestProvider[];
  };
  message?: string;
}

// Manual Placement Test types
export interface CreateManualPlacementTestParams {
  test_name: string;
  description?: string;
  spam_filters: string[];
  link_checker: boolean;
  campaign_id: number;
  sequence_mapping_id: number;
  provider_ids: number[];
  sender_accounts: string[];
  all_email_sent_without_time_gap: boolean;
  min_time_btwn_emails: number;
  min_time_unit: string;
  is_warmup: boolean;
}

// Automated Placement Test additional types
export interface CreateAutomatedPlacementTestParams extends CreateManualPlacementTestParams {
  schedule_start_time: string;
  test_end_date: string;
  every_days: number;
  tz: string;
  days: number[];
  starHour?: string;
  folder_id?: number;
  scheduler_cron_value?: {
    tz: string;
    days: number[];
  };
}

// Spam Test Details types
export interface GetSpamTestDetailsParams {
  spam_test_id: number;
}

// Delete Smart Delivery Tests types
export interface DeleteSmartDeliveryTestsParams {
  spamTestIds: number[];
}

// Stop Automated Test types
export interface StopAutomatedTestParams {
  spam_test_id: number;
}

// List all Tests types
export interface ListAllTestsParams {
  testType: 'manual' | 'auto';
  limit?: number;
  offset?: number;
}

// Provider wise report types
export interface ProviderWiseReportParams {
  spam_test_id: number;
}

// Geo wise report types
export interface GroupWiseReportParams {
  spam_test_id: number;
}

// Sender Account wise report types
export interface SenderAccountWiseReportParams {
  spam_test_id: number;
}

// Spam filter report types
export interface SpamFilterDetailsParams {
  spam_test_id: number;
}

// DKIM details types
export interface DkimDetailsParams {
  spam_test_id: number;
}

// SPF details types
export interface SpfDetailsParams {
  spam_test_id: number;
}

// rDNS report types
export interface RdnsDetailsParams {
  spam_test_id: number;
}

// Sender Account list types
export interface SenderAccountsParams {
  spam_test_id: number;
}

// Blacklists types
export interface BlacklistParams {
  spam_test_id: number;
}

// Spam test email content types
export interface EmailContentParams {
  spam_test_id: number;
}

// Spam test IP blacklist count types
export interface IpAnalyticsParams {
  spam_test_id: number;
}

// Email reply headers types
export interface EmailHeadersParams {
  spam_test_id: number;
  reply_id: number;
}

// Schedule history for automated tests types
export interface ScheduleHistoryParams {
  spam_test_id: number;
}

// IP details types
export interface IpDetailsParams {
  spam_test_id: number;
  reply_id: number;
}

// Mailbox summary types
export interface MailboxSummaryParams {
  limit?: number;
  offset?: number;
}

// Mailbox count API types
export interface MailboxCountParams {
  // This endpoint doesn't require any specific parameters
}

// Get all folders types
export interface GetAllFoldersParams {
  limit?: number;
  offset?: number;
  name?: string;
}

// Create folders types
export interface CreateFolderParams {
  name: string;
}

// Get folder by ID types
export interface GetFolderByIdParams {
  folder_id: number;
}

// Delete folder types
export interface DeleteFolderParams {
  folder_id: number;
}

// Tool parameter interfaces
export interface GetRegionWiseProvidersParams {
  // This endpoint doesn't require any specific parameters beyond the API key
  // which is handled at the API client level
}

// Type guards
export function isGetRegionWiseProvidersParams(args: unknown): args is GetRegionWiseProvidersParams {
  // Since this tool doesn't require specific parameters, any object is valid
  return typeof args === 'object' && args !== null;
}

export function isCreateManualPlacementTestParams(args: unknown): args is CreateManualPlacementTestParams {
  if (typeof args !== 'object' || args === null) return false;
  
  const params = args as Partial<CreateManualPlacementTestParams>;
  
  return (
    typeof params.test_name === 'string' &&
    Array.isArray(params.spam_filters) &&
    typeof params.link_checker === 'boolean' &&
    typeof params.campaign_id === 'number' &&
    typeof params.sequence_mapping_id === 'number' &&
    Array.isArray(params.provider_ids) &&
    Array.isArray(params.sender_accounts) &&
    typeof params.all_email_sent_without_time_gap === 'boolean' &&
    typeof params.min_time_btwn_emails === 'number' &&
    typeof params.min_time_unit === 'string' &&
    typeof params.is_warmup === 'boolean'
  );
}

export function isCreateAutomatedPlacementTestParams(args: unknown): args is CreateAutomatedPlacementTestParams {
  if (!isCreateManualPlacementTestParams(args)) return false;
  
  const params = args as Partial<CreateAutomatedPlacementTestParams>;
  
  return (
    typeof params.schedule_start_time === 'string' &&
    typeof params.test_end_date === 'string' &&
    typeof params.every_days === 'number' &&
    typeof params.tz === 'string' &&
    Array.isArray(params.days)
  );
}

export function isGetSpamTestDetailsParams(args: unknown): args is GetSpamTestDetailsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as GetSpamTestDetailsParams).spam_test_id === 'number'
  );
}

export function isDeleteSmartDeliveryTestsParams(args: unknown): args is DeleteSmartDeliveryTestsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spamTestIds' in args &&
    Array.isArray((args as DeleteSmartDeliveryTestsParams).spamTestIds) &&
    (args as DeleteSmartDeliveryTestsParams).spamTestIds.every(id => typeof id === 'number')
  );
}

export function isStopAutomatedTestParams(args: unknown): args is StopAutomatedTestParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as StopAutomatedTestParams).spam_test_id === 'number'
  );
}

export function isListAllTestsParams(args: unknown): args is ListAllTestsParams {
  if (typeof args !== 'object' || args === null) return false;
  
  const params = args as Partial<ListAllTestsParams>;
  
  return (
    params.testType === 'manual' || params.testType === 'auto'
  );
}

export function isProviderWiseReportParams(args: unknown): args is ProviderWiseReportParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as ProviderWiseReportParams).spam_test_id === 'number'
  );
}

export function isGroupWiseReportParams(args: unknown): args is GroupWiseReportParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as GroupWiseReportParams).spam_test_id === 'number'
  );
}

export function isSenderAccountWiseReportParams(args: unknown): args is SenderAccountWiseReportParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as SenderAccountWiseReportParams).spam_test_id === 'number'
  );
}

export function isSpamFilterDetailsParams(args: unknown): args is SpamFilterDetailsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as SpamFilterDetailsParams).spam_test_id === 'number'
  );
}

export function isDkimDetailsParams(args: unknown): args is DkimDetailsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as DkimDetailsParams).spam_test_id === 'number'
  );
}

export function isSpfDetailsParams(args: unknown): args is SpfDetailsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as SpfDetailsParams).spam_test_id === 'number'
  );
}

export function isRdnsDetailsParams(args: unknown): args is RdnsDetailsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as RdnsDetailsParams).spam_test_id === 'number'
  );
}

export function isSenderAccountsParams(args: unknown): args is SenderAccountsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as SenderAccountsParams).spam_test_id === 'number'
  );
}

export function isBlacklistParams(args: unknown): args is BlacklistParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as BlacklistParams).spam_test_id === 'number'
  );
}

export function isEmailContentParams(args: unknown): args is EmailContentParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as EmailContentParams).spam_test_id === 'number'
  );
}

export function isIpAnalyticsParams(args: unknown): args is IpAnalyticsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as IpAnalyticsParams).spam_test_id === 'number'
  );
}

export function isEmailHeadersParams(args: unknown): args is EmailHeadersParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as EmailHeadersParams).spam_test_id === 'number' &&
    'reply_id' in args &&
    typeof (args as EmailHeadersParams).reply_id === 'number'
  );
}

export function isScheduleHistoryParams(args: unknown): args is ScheduleHistoryParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as ScheduleHistoryParams).spam_test_id === 'number'
  );
}

export function isIpDetailsParams(args: unknown): args is IpDetailsParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'spam_test_id' in args &&
    typeof (args as IpDetailsParams).spam_test_id === 'number' &&
    'reply_id' in args &&
    typeof (args as IpDetailsParams).reply_id === 'number'
  );
}

export function isMailboxSummaryParams(args: unknown): args is MailboxSummaryParams {
  return typeof args === 'object' && args !== null;
}

export function isMailboxCountParams(args: unknown): args is MailboxCountParams {
  return typeof args === 'object' && args !== null;
}

export function isGetAllFoldersParams(args: unknown): args is GetAllFoldersParams {
  return typeof args === 'object' && args !== null;
}

export function isCreateFolderParams(args: unknown): args is CreateFolderParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'name' in args &&
    typeof (args as CreateFolderParams).name === 'string'
  );
}

export function isGetFolderByIdParams(args: unknown): args is GetFolderByIdParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'folder_id' in args &&
    typeof (args as GetFolderByIdParams).folder_id === 'number'
  );
}

export function isDeleteFolderParams(args: unknown): args is DeleteFolderParams {
  return (
    typeof args === 'object' &&
    args !== null &&
    'folder_id' in args &&
    typeof (args as DeleteFolderParams).folder_id === 'number'
  );
}

```
Page 1/2FirstPrevNextLast