Skip to main content
Glama
bedro96

Email Send/Receive MCP Server

by bedro96

Email Send/Receive MCP Server

Python 3.11+ FastMCP License: MIT

A Model Context Protocol (MCP) server for sending and receiving emails via SMTP, POP3, and IMAP. Built with FastMCP 2.0, this server enables AI assistants like Claude to interact with email services, making it easy to automate email workflows, check inboxes, and send messages programmatically.

🎯 What is MCP?

The Model Context Protocol (MCP) is an open standard that enables AI applications to securely connect to external data sources and tools. This server implements MCP to give AI assistants the ability to:

  • Send emails with attachments, CC/BCC support

  • Receive and read emails from IMAP/POP3 servers

  • Search and filter email messages

  • Work with multiple email providers (Gmail, Outlook, Yahoo, etc.)

Perfect for integration with AI assistants like Claude Desktop, this server acts as a bridge between conversational AI and your email infrastructure.

✨ Features

πŸ“€ Email Sending (SMTP)

  • βœ… Send emails with validated recipient addresses

  • βœ… Support for CC (Carbon Copy) and BCC (Blind Carbon Copy)

  • βœ… HTML and plain text email bodies

  • βœ… File attachments support with size validation

  • βœ… Configurable sender information (name and email)

  • βœ… Batch email validation for multiple recipients

  • βœ… Smart TLS/SSL connection handling

πŸ“₯ Email Receiving (IMAP/POP3)

  • βœ… Retrieve emails from IMAP servers with full folder support

  • βœ… POP3 protocol support for simple email retrieval

  • βœ… Filter by mailbox/folder (INBOX, Sent, Drafts, etc.)

  • βœ… Unread emails filtering

  • βœ… Attachment information extraction

  • βœ… Email metadata parsing (sender, subject, date, etc.)

  • βœ… Body preview with length limiting

πŸ”’ Email Validation & Security

  • βœ… RFC-compliant email address validation

  • βœ… Automatic email normalization

  • βœ… Batch validation for multiple recipients

  • βœ… App Password support for major providers

  • βœ… TLS/SSL encryption for all connections

  • βœ… Secure credential management via environment variables

πŸ“‹ Table of Contents

πŸš€ Quick Start

Get started in 5 minutes! Follow these steps:

# 1. Clone and install
git clone https://github.com/bedro96/email-send-mcp.git
cd email-send-mcp
pip install -e .

# 2. Configure email credentials
cp .env.example .env
# Edit .env with your email provider settings

# 3. Run the server
python main.py

For detailed quick start instructions, see QUICKSTART.md.

πŸ“¦ Installation

Prerequisites

  • Python 3.11 or higher - Download Python

  • Email account with SMTP/IMAP access (Gmail, Outlook, Yahoo, etc.)

  • App Password for your email provider (for Gmail, Outlook, Yahoo)

uv is a fast Python package manager that simplifies dependency management.

# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Clone the repository
git clone https://github.com/bedro96/email-send-mcp.git
cd email-send-mcp

# Install dependencies
uv pip install -e .

# For development with testing tools
uv pip install -e ".[dev]"

Method 2: Using pip

# Clone the repository
git clone https://github.com/bedro96/email-send-mcp.git
cd email-send-mcp

# Install dependencies
pip install -e .

# For development (optional)
pip install -e ".[dev]"

Verify Installation

# Check if dependencies are installed
python -c "import fastmcp; print('FastMCP version:', fastmcp.__version__)"

βš™οΈ Configuration

Step 1: Create Environment File

  1. Copy the example environment file:

cp .env.example .env
  1. Edit .env with your email server credentials:

# SMTP Configuration (for sending emails)
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@example.com
SMTP_PASSWORD=your-app-password
SMTP_USE_TLS=true

# IMAP Configuration (for receiving emails)
IMAP_SERVER=imap.gmail.com
IMAP_PORT=993
IMAP_USERNAME=your-email@example.com
IMAP_PASSWORD=your-app-password
IMAP_USE_SSL=true

# POP3 Configuration (alternative for receiving emails)
POP3_SERVER=pop.gmail.com
POP3_PORT=995
POP3_USERNAME=your-email@example.com
POP3_PASSWORD=your-app-password
POP3_USE_SSL=true

# Email Settings
DEFAULT_FROM_EMAIL=your-email@example.com
DEFAULT_FROM_NAME=MCP Email Server
MAX_ATTACHMENT_SIZE_MB=25

# Server Configuration
LOG_LEVEL=INFO
DEBUG=false

Step 2: Email Provider Setup

Gmail Setup (Most Common)

For Gmail, you'll need to:

  1. Enable 2-Factor Authentication

  2. Generate an App Password

    • Visit App Passwords

    • Select "Mail" and your device

    • Copy the generated 16-character password

    • Use this password in your .env file

  3. Enable IMAP Access (for receiving emails)

    • Open Gmail β†’ Settings β†’ See all settings

    • Go to "Forwarding and POP/IMAP" tab

    • Enable IMAP

    • Save Changes

Gmail Configuration:

SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=xxxx xxxx xxxx xxxx  # 16-character app password
SMTP_USE_TLS=true

IMAP_SERVER=imap.gmail.com
IMAP_PORT=993
IMAP_USERNAME=your-email@gmail.com
IMAP_PASSWORD=xxxx xxxx xxxx xxxx  # Same app password
IMAP_USE_SSL=true

DEFAULT_FROM_EMAIL=your-email@gmail.com

Other Email Providers

For configuration details for Outlook, Yahoo, ProtonMail, iCloud, and custom SMTP servers, see EMAIL_PROVIDERS.md.

Configuration Parameters Explained

Parameter

Description

Default

Required

SMTP_SERVER

SMTP server hostname

smtp.gmail.com

Yes (for sending)

SMTP_PORT

SMTP server port (587 for TLS, 465 for SSL)

587

Yes (for sending)

SMTP_USERNAME

SMTP authentication username (usually email)

-

Yes (for sending)

SMTP_PASSWORD

SMTP authentication password (use app password)

-

Yes (for sending)

SMTP_USE_TLS

Use STARTTLS for SMTP (recommended for port 587)

true

No

IMAP_SERVER

IMAP server hostname

imap.gmail.com

Yes (for receiving)

IMAP_PORT

IMAP server port (993 for SSL)

993

Yes (for receiving)

IMAP_USERNAME

IMAP authentication username

-

Yes (for receiving)

IMAP_PASSWORD

IMAP authentication password

-

Yes (for receiving)

IMAP_USE_SSL

Use SSL for IMAP

true

No

POP3_SERVER

POP3 server hostname

pop.gmail.com

No

POP3_PORT

POP3 server port (995 for SSL)

995

No

POP3_USERNAME

POP3 authentication username

-

No

POP3_PASSWORD

POP3 authentication password

-

No

POP3_USE_SSL

Use SSL for POP3

true

No

DEFAULT_FROM_EMAIL

Default sender email address

-

Yes

DEFAULT_FROM_NAME

Default sender display name

MCP Email Server

No

MAX_ATTACHMENT_SIZE_MB

Maximum attachment size in MB

25

No

LOG_LEVEL

Logging level (DEBUG, INFO, WARNING, ERROR)

INFO

No

DEBUG

Enable debug mode

false

No

Security Best Practices

⚠️ Important Security Notes:

  1. Never commit .env files with real credentials to version control

  2. Always use App Passwords instead of your main account password

  3. Enable 2-Factor Authentication on your email account

  4. Use TLS/SSL for all email connections

  5. Store secrets securely in production (Azure Key Vault, AWS Secrets Manager, etc.)

  6. Rotate passwords regularly and revoke unused app passwords

  7. Limit permissions to only what's necessary

πŸ› οΈ MCP Tools (Functions)

This server exposes 3 powerful MCP tools that AI assistants can use to interact with email services. Each tool is thoroughly documented below.

1. send_email - Send Emails via SMTP

Send emails with full support for attachments, CC/BCC, and HTML formatting.

Function Signature:

async def send_email(
    recipient: str,              # Required: Primary recipient email
    subject: str,                # Required: Email subject/title
    body: str,                   # Required: Email body content
    attachments: List[str] = None,  # Optional: File paths to attach
    cc: List[str] = None,        # Optional: CC recipients
    bcc: List[str] = None,       # Optional: BCC recipients
    is_html: bool = False        # Optional: HTML formatting flag
) -> str

Parameters:

Parameter

Type

Required

Description

recipient

str

βœ… Yes

Primary recipient email address (validated against RFC standards)

subject

str

βœ… Yes

Email subject line

body

str

βœ… Yes

Email body content (plain text or HTML)

attachments

List[str]

❌ No

List of absolute file paths to attach (validates size and existence)

cc

List[str]

❌ No

List of carbon copy recipient email addresses

bcc

List[str]

❌ No

List of blind carbon copy recipient email addresses

is_html

bool

❌ No

Set to true for HTML-formatted emails (default: false for plain text)

Returns:

  • Success: Formatted confirmation message with delivery details

  • Error: Error message explaining what went wrong

Example Usage in Claude:

Please send an email to john@example.com with the subject "Project Update" 
and body "The quarterly report is attached." Attach the file /path/to/report.pdf

Example Response:

βœ… Email sent successfully!
Recipient: john@example.com
Subject: Project Update
CC: None
BCC: None
Attachments: 1

Features:

  • βœ… Automatic email address validation and normalization

  • βœ… File attachment with size validation (default max: 25MB)

  • βœ… Support for multiple CC and BCC recipients

  • βœ… HTML email support with proper MIME encoding

  • βœ… Smart SMTP connection handling (TLS/SSL)

  • βœ… Detailed error messages for troubleshooting


2. receive_emails_imap - Retrieve Emails via IMAP

Retrieve and read emails from IMAP servers with advanced filtering options.

Function Signature:

async def receive_emails_imap(
    mailbox: str = "INBOX",      # Mailbox/folder to read from
    limit: int = 10,             # Maximum emails to retrieve
    unread_only: bool = False    # Filter for unread only
) -> str

Parameters:

Parameter

Type

Required

Default

Description

mailbox

str

❌ No

"INBOX"

Mailbox/folder name (INBOX, Sent, Drafts, etc.)

limit

int

❌ No

10

Maximum number of emails to retrieve (1-100)

unread_only

bool

❌ No

false

Only retrieve unread messages

Returns:

  • Formatted list of emails with metadata and body previews

  • Each email includes: ID, From, To, Subject, Date, Body Preview, Attachments

Example Usage in Claude:

Please check my inbox and show me the last 5 unread emails

Example Response:

πŸ“¬ Retrieved 5 email(s):

--- Email 1 ---
ID: 12345
From: alice@company.com
To: you@example.com
Subject: Meeting Tomorrow
Date: Mon, 10 Nov 2025 10:30:00 +0000
Attachments: 1
  - agenda.pdf (application/pdf)
Body Preview: Hi, just a reminder about our meeting tomorrow at 2 PM. 
I've attached the agenda for your review...
Body Length: 450 characters

--- Email 2 ---
[...]

Features:

  • βœ… Support for all IMAP folders (INBOX, Sent, Drafts, custom folders)

  • βœ… Unread-only filtering

  • βœ… Attachment detection and metadata extraction

  • βœ… Email body preview (first 200 characters)

  • βœ… Full metadata parsing (sender, recipient, date, subject)

  • βœ… Handles multiple encodings and international characters

  • βœ… Secure SSL/TLS connection

Supported Mailbox Names:

  • INBOX - Primary inbox

  • Sent - Sent emails

  • Drafts - Draft messages

  • Trash - Deleted items

  • Spam or Junk - Spam folder

  • Custom folders created by the user


3. receive_emails_pop3 - Retrieve Emails via POP3

Retrieve emails using the simpler POP3 protocol (note: POP3 is less feature-rich than IMAP).

Function Signature:

def receive_emails_pop3(
    limit: int = 10              # Maximum emails to retrieve
) -> str

Parameters:

Parameter

Type

Required

Default

Description

limit

int

❌ No

10

Maximum number of emails to retrieve

Returns:

  • Formatted list of emails (similar to IMAP output)

Example Usage in Claude:

Fetch my last 10 emails using POP3

Features:

  • βœ… Simple email retrieval

  • βœ… Attachment detection

  • βœ… Email metadata parsing

  • βœ… SSL/TLS support

Note: POP3 has limitations compared to IMAP:

  • ❌ No folder support (only retrieves from main inbox)

  • ❌ No unread filtering

  • ❌ Less efficient for large mailboxes

  • βœ… Use IMAP when possible for better features


Tool Comparison

Feature

send_email

receive_emails_imap

receive_emails_pop3

Primary Function

Send emails

Receive emails

Receive emails

Protocol

SMTP

IMAP

POP3

Attachments Support

βœ… Send

βœ… Detect

βœ… Detect

HTML Support

βœ… Yes

βœ… Yes

βœ… Yes

Folder Support

N/A

βœ… Yes

❌ No

Unread Filtering

N/A

βœ… Yes

❌ No

CC/BCC Support

βœ… Yes

N/A

N/A

Use Case

Sending automated emails

Full email management

Simple email retrieval

πŸ’‘ Usage Examples

Running the MCP Server

Start the server in HTTP mode (for MCP client connections):

python main.py

The server will:

  1. Load configuration from .env file

  2. Initialize SMTP, IMAP, and POP3 services

  3. Start listening on http://0.0.0.0:8888/mcp

  4. Expose MCP tools for AI assistants to use

  5. Log all activities to console and log files

Server Output:

2025-11-10 15:57:03 - email-send-mcp - INFO - Starting Email Send/Receive MCP Server...
2025-11-10 15:57:03 - email-send-mcp - INFO - Configuration values set from environment variables.
2025-11-10 15:57:03 - email-send-mcp - INFO - EmailSender service initialized.
2025-11-10 15:57:03 - email-send-mcp - INFO - EmailReceiver service initialized.
2025-11-10 15:57:03 - email-send-mcp - INFO - Server running on http://0.0.0.0:8888/mcp

Example 1: Send a Simple Text Email

Natural Language Request (via Claude):

Please send an email to colleague@company.com with the subject "Team Meeting" 
and tell them the meeting is scheduled for tomorrow at 2 PM.

What Happens:

  • Claude uses the send_email tool

  • Email address is validated

  • Email is sent via configured SMTP server

  • Confirmation is returned

MCP Tool Call (Behind the Scenes):

send_email(
    recipient="colleague@company.com",
    subject="Team Meeting",
    body="The meeting is scheduled for tomorrow at 2 PM."
)

Response:

βœ… Email sent successfully!
Recipient: colleague@company.com
Subject: Team Meeting
CC: None
BCC: None
Attachments: 0

Example 2: Send HTML Email with Attachments

Natural Language Request:

Send an email to team@company.com with subject "Quarterly Report" 
and include the report.pdf file. Use HTML formatting with a professional header.

MCP Tool Call:

send_email(
    recipient="team@company.com",
    subject="Quarterly Report",
    body="""
    <html>
        <body>
            <h1>Quarterly Report - Q4 2025</h1>
            <p>Dear Team,</p>
            <p>Please find attached the quarterly report for your review.</p>
            <p>Best regards,<br>Management</p>
        </body>
    </html>
    """,
    attachments=["/path/to/report.pdf"],
    is_html=True
)

Example 3: Send Email with CC and BCC

Natural Language Request:

Email the project update to john@company.com, CC alice@company.com 
and bob@company.com, and BCC the manager@company.com

MCP Tool Call:

send_email(
    recipient="john@company.com",
    subject="Project Update",
    body="The project is on track and will be completed by the deadline.",
    cc=["alice@company.com", "bob@company.com"],
    bcc=["manager@company.com"]
)

Example 4: Check Unread Emails

Natural Language Request:

Show me my unread emails from the last week

MCP Tool Call:

receive_emails_imap(
    mailbox="INBOX",
    limit=20,
    unread_only=True
)

Response:

πŸ“¬ Retrieved 3 email(s):

--- Email 1 ---
ID: 12345
From: client@example.com
To: you@company.com
Subject: Question about Invoice
Date: Mon, 09 Nov 2025 14:30:00 +0000
Body Preview: Hi, I have a question about invoice #12345. Could you please clarify the charges for...
Body Length: 320 characters

[More emails...]

Example 5: Check Specific Email Folder

Natural Language Request:

Check my Sent folder and show me the last 5 emails I sent

MCP Tool Call:

receive_emails_imap(
    mailbox="Sent",
    limit=5,
    unread_only=False
)

Example 6: Retrieve Emails with Attachments

Natural Language Request:

Show me emails with attachments from my inbox

MCP Tool Call:

receive_emails_imap(
    mailbox="INBOX",
    limit=10,
    unread_only=False
)

Response (showing attachment info):

πŸ“¬ Retrieved 2 email(s):

--- Email 1 ---
ID: 98765
From: partner@company.com
To: you@example.com
Subject: Contract Documents
Date: Tue, 08 Nov 2025 16:45:00 +0000
Attachments: 2
  - contract.pdf (application/pdf)
  - terms.docx (application/vnd.openxmlformats-officedocument.wordprocessingml.document)
Body Preview: Please review the attached contract documents...

Example 7: Using POP3 for Simple Retrieval

Natural Language Request:

Get my last 5 emails using POP3

MCP Tool Call:

receive_emails_pop3(limit=5)

Programmatic Usage (Python)

If you want to use the email services directly in Python (without MCP):

import asyncio
from src.services.email_sender import EmailSender
from src.services.email_receiver import EmailReceiver

async def main():
    # Send an email
    sender = EmailSender()
    result = await sender.send_email(
        recipient="user@example.com",
        subject="Test Email",
        body="This is a test message"
    )
    print(result)
    
    # Receive emails
    receiver = EmailReceiver()
    result = await receiver.receive_emails_imap(
        mailbox="INBOX",
        limit=5,
        unread_only=True
    )
    print(result)

if __name__ == "__main__":
    asyncio.run(main())

For more examples, see examples.py in the repository.

πŸ§ͺ Testing

This project includes comprehensive test coverage for validators, configuration, and core functionality.

Running Tests

Run All Tests

# Basic test run
pytest tests/ -v

# Run with detailed output
pytest tests/ -vv

# Run tests with coverage report
pytest tests/ --cov=src --cov-report=html --cov-report=term

# Run tests in parallel (faster)
pytest tests/ -n auto

Run Specific Test Files

# Test email validators only
pytest tests/test_validators.py -v

# Test configuration management
pytest tests/test_config.py -v

# Test specific function
pytest tests/test_validators.py::TestEmailValidation::test_validate_valid_email -v

Test Coverage

The project includes tests for:

βœ… Email Validation (tests/test_validators.py)

  • Valid email address validation

  • Invalid email detection (missing @, invalid domain, etc.)

  • Email normalization

  • Batch email validation

  • Email formatting with names

βœ… Configuration Management (tests/test_config.py)

  • Settings loading from environment

  • Default value validation

  • Port number validation

  • Field type validation

βœ… SMTP Testing (test_smtp.py, test_smtp_variations.py)

  • SMTP connection testing

  • Email sending variations

  • Different provider configurations

βœ… Integration Tests (test_kakao_specific.py)

  • Provider-specific testing

  • Real-world scenarios

Example Test Output

$ pytest tests/ -v

============================= test session starts ==============================
tests/test_validators.py::TestEmailValidation::test_validate_valid_email PASSED
tests/test_validators.py::TestEmailValidation::test_validate_invalid_email_no_at PASSED
tests/test_validators.py::TestEmailValidation::test_validate_email_with_dots PASSED
tests/test_validators.py::TestEmailValidation::test_validate_email_with_plus PASSED
tests/test_validators.py::TestEmailValidation::test_validate_multiple_emails PASSED
tests/test_validators.py::TestEmailValidation::test_format_email_with_name PASSED
tests/test_config.py::TestSettings::test_default_values PASSED
tests/test_config.py::TestSettings::test_port_validation PASSED
============================== 8 passed in 0.45s ===============================

Writing New Tests

When adding new features, include tests following this pattern:

# tests/test_my_feature.py
import pytest
from src.services.my_service import MyService

class TestMyFeature:
    """Test suite for my new feature."""
    
    def test_basic_functionality(self):
        """Test basic feature operation."""
        service = MyService()
        result = service.do_something()
        assert result is not None
    
    @pytest.mark.asyncio
    async def test_async_functionality(self):
        """Test async feature operation."""
        service = MyService()
        result = await service.do_something_async()
        assert result["status"] == "success"

Integration Testing

For testing with real email servers:

  1. Create a test email account (don't use your primary account)

  2. Set up test credentials in .env.test:

    SMTP_SERVER=smtp.gmail.com
    SMTP_PORT=587
    SMTP_USERNAME=test-account@gmail.com
    SMTP_PASSWORD=test-app-password
  3. Run integration tests (not included in default test suite):

    pytest tests/integration/ -v --env-file=.env.test

Manual Testing

You can test the MCP server manually:

  1. Start the server:

    python main.py
  2. Test with curl (health check):

    curl http://localhost:8888/api/health
    # Expected: {"status":"ok"}
  3. Test email sending (using examples.py):

    python examples.py

Testing Checklist

Before submitting code:

  • All existing tests pass (pytest tests/ -v)

  • New tests added for new features

  • Code coverage maintained or improved

  • Tests follow naming conventions (test_*.py, Test* classes)

  • Async tests use @pytest.mark.asyncio decorator

  • Integration tests are marked separately

Continuous Integration

This project is ready for CI/CD integration. Example GitHub Actions workflow:

name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.11'
      - name: Install dependencies
        run: |
          pip install -e ".[dev]"
      - name: Run tests
        run: |
          pytest tests/ -v --cov=src --cov-report=xml
      - name: Upload coverage
        uses: codecov/codecov-action@v3

πŸ”Œ Integration with MCP Clients

This server is compatible with any MCP client. Below are detailed instructions for popular clients.

Claude Desktop Integration

Claude Desktop is Anthropic's official desktop app that supports MCP servers.

Setup Instructions

  1. Locate Claude Desktop Configuration File

    The configuration file location varies by operating system:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

    • Linux: ~/.config/Claude/claude_desktop_config.json

  2. Add Email MCP Server to Configuration

    Option A: Using Environment Variables (Recommended)

    {
      "mcpServers": {
        "email": {
          "command": "python",
          "args": ["/absolute/path/to/email-send-mcp/main.py"],
          "env": {
            "SMTP_SERVER": "smtp.gmail.com",
            "SMTP_PORT": "587",
            "SMTP_USERNAME": "your-email@gmail.com",
            "SMTP_PASSWORD": "your-app-password",
            "IMAP_SERVER": "imap.gmail.com",
            "IMAP_PORT": "993",
            "IMAP_USERNAME": "your-email@gmail.com",
            "IMAP_PASSWORD": "your-app-password",
            "DEFAULT_FROM_EMAIL": "your-email@gmail.com"
          }
        }
      }
    }

    Option B: Using .env File (Simpler)

    {
      "mcpServers": {
        "email": {
          "command": "python",
          "args": ["/absolute/path/to/email-send-mcp/main.py"],
          "cwd": "/absolute/path/to/email-send-mcp"
        }
      }
    }

    This option assumes you have a .env file in the project directory.

  3. Restart Claude Desktop

    After updating the configuration, fully quit and restart Claude Desktop.

  4. Verify Integration

    In Claude Desktop, you should see email tools available. Try asking:

    Can you help me send an email?

    Claude should recognize it has access to the send_email tool.

Using Email Tools in Claude Desktop

Once configured, you can use natural language to interact with emails:

Sending Emails:

  • "Send an email to john@example.com with subject 'Meeting' and tell him about tomorrow's meeting"

  • "Email the team about the project update"

  • "Send an email with the quarterly report attached"

Receiving Emails:

  • "Check my inbox for unread emails"

  • "Show me the last 10 emails I received"

  • "What emails with attachments do I have?"

  • "Check my Sent folder"

Other MCP Clients

This server works with any MCP-compatible client:

Custom MCP Client

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main():
    server_params = StdioServerParameters(
        command="python",
        args=["/path/to/email-send-mcp/main.py"],
        env={
            "SMTP_SERVER": "smtp.gmail.com",
            # ... other env vars
        }
    )
    
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            # Initialize the connection
            await session.initialize()
            
            # List available tools
            tools = await session.list_tools()
            print("Available tools:", tools)
            
            # Call send_email tool
            result = await session.call_tool(
                "send_email",
                arguments={
                    "recipient": "user@example.com",
                    "subject": "Test",
                    "body": "Hello from MCP client!"
                }
            )
            print(result)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

HTTP MCP Client

The server also supports HTTP transport for web-based integrations:

// JavaScript/Node.js example
const response = await fetch('http://localhost:8888/mcp', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    method: 'tools/call',
    params: {
      name: 'send_email',
      arguments: {
        recipient: 'user@example.com',
        subject: 'Test Email',
        body: 'Hello from HTTP client!'
      }
    },
    id: 1
  })
});

const result = await response.json();
console.log(result);

Environment Variable Reference for MCP Clients

When configuring MCP clients, these environment variables are required:

Minimum Required Variables:

{
  "SMTP_SERVER": "smtp.gmail.com",
  "SMTP_PORT": "587",
  "SMTP_USERNAME": "your-email@gmail.com",
  "SMTP_PASSWORD": "your-app-password",
  "DEFAULT_FROM_EMAIL": "your-email@gmail.com"
}

For Email Receiving (Optional):

{
  "IMAP_SERVER": "imap.gmail.com",
  "IMAP_PORT": "993",
  "IMAP_USERNAME": "your-email@gmail.com",
  "IMAP_PASSWORD": "your-app-password"
}

Troubleshooting MCP Integration

Issue: Tools not appearing in Claude Desktop

  • Solution: Verify the config file path is correct

  • Solution: Check that the Python path is absolute

  • Solution: Restart Claude Desktop after configuration changes

Issue: "Module not found" errors

  • Solution: Ensure dependencies are installed (pip install -e .)

  • Solution: Use the full Python path (e.g., /usr/local/bin/python3)

Issue: Authentication errors

  • Solution: Verify environment variables are set correctly

  • Solution: Check that app passwords are used (not regular passwords)

  • Solution: Verify SMTP/IMAP credentials are correct

Issue: Server not starting

  • Solution: Check logs in the logs/ directory

  • Solution: Verify .env file exists and is readable

  • Solution: Test server manually: python main.py

🐳 Docker Deployment

Docker provides a containerized way to run the Email MCP Server, ensuring consistency across different environments.

Prerequisites

  • Docker installed (Get Docker)

  • Docker Compose (optional, for multi-container setups)

Quick Start with Docker

Step 1: Build the Docker Image

docker build -t email-send-mcp .

This creates a Docker image with all dependencies installed.

Step 2: Run the Container

Option A: Using Environment Variables

docker run -d \
  --name email-mcp \
  -p 8888:8888 \
  -e SMTP_SERVER=smtp.gmail.com \
  -e SMTP_PORT=587 \
  -e SMTP_USERNAME=your-email@gmail.com \
  -e SMTP_PASSWORD=your-app-password \
  -e IMAP_SERVER=imap.gmail.com \
  -e IMAP_PORT=993 \
  -e IMAP_USERNAME=your-email@gmail.com \
  -e IMAP_PASSWORD=your-app-password \
  -e DEFAULT_FROM_EMAIL=your-email@gmail.com \
  email-send-mcp

Option B: Using .env File (Recommended)

docker run -d \
  --name email-mcp \
  -p 8888:8888 \
  --env-file .env \
  email-send-mcp

Step 3: Verify Container is Running

# Check container status
docker ps

# View logs
docker logs email-mcp

# Follow logs in real-time
docker logs -f email-mcp

# Test health endpoint
curl http://localhost:8888/api/health

Docker Compose Setup

For easier management, use Docker Compose:

docker-compose.yml:

version: '3.8'

services:
  email-mcp:
    build: .
    container_name: email-send-mcp
    ports:
      - "8888:8888"
    env_file:
      - .env
    restart: unless-stopped
    volumes:
      - ./logs:/app/logs
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8888/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Start with Docker Compose:

# Start in background
docker-compose up -d

# View logs
docker-compose logs -f

# Stop
docker-compose down

# Rebuild and restart
docker-compose up -d --build

Docker Management Commands

# Stop the container
docker stop email-mcp

# Start the container
docker start email-mcp

# Restart the container
docker restart email-mcp

# Remove the container
docker rm email-mcp

# Remove the image
docker rmi email-send-mcp

# View container logs
docker logs email-mcp --tail 100

# Execute commands inside container
docker exec -it email-mcp /bin/bash

# Inspect container
docker inspect email-mcp

Production Docker Best Practices

  1. Use Multi-Stage Builds (already in Dockerfile)

  2. Run as Non-Root User (already configured)

  3. Use Health Checks (see Docker Compose example)

  4. Mount Logs as Volumes for persistence

  5. Use Secrets Management for production credentials

  6. Set Resource Limits:

docker run -d \
  --name email-mcp \
  --memory="512m" \
  --cpus="0.5" \
  --env-file .env \
  email-send-mcp

☁️ Azure Container Apps Deployment

Deploy the Email MCP Server to Azure Container Apps for scalable, serverless hosting.

Prerequisites

  • Azure account with active subscription

  • Azure CLI installed (Install Azure CLI)

  • Docker installed

Deployment Steps

Step 1: Login to Azure

az login
az account set --subscription <your-subscription-id>

Step 2: Create Resource Group

az group create \
  --name email-mcp-rg \
  --location eastus

Step 3: Create Azure Container Registry (ACR)

# Create ACR
az acr create \
  --resource-group email-mcp-rg \
  --name emailmcpacr \
  --sku Basic

# Login to ACR
az acr login --name emailmcpacr

Step 4: Build and Push Image to ACR

# Build and push in one command
az acr build \
  --registry emailmcpacr \
  --image email-send-mcp:latest \
  .

# Or build locally and push
docker build -t emailmcpacr.azurecr.io/email-send-mcp:latest .
docker push emailmcpacr.azurecr.io/email-send-mcp:latest

Step 5: Create Container Apps Environment

# Create environment
az containerapp env create \
  --name email-mcp-env \
  --resource-group email-mcp-rg \
  --location eastus

Step 6: Deploy Container App

az containerapp create \
  --name email-send-mcp \
  --resource-group email-mcp-rg \
  --environment email-mcp-env \
  --image emailmcpacr.azurecr.io/email-send-mcp:latest \
  --target-port 8888 \
  --ingress external \
  --registry-server emailmcpacr.azurecr.io \
  --cpu 0.5 \
  --memory 1Gi \
  --min-replicas 1 \
  --max-replicas 3 \
  --secrets \
    smtp-password=<your-app-password> \
    imap-password=<your-app-password> \
  --env-vars \
    SMTP_SERVER=smtp.gmail.com \
    SMTP_PORT=587 \
    SMTP_USERNAME=secretref:smtp-password \
    SMTP_PASSWORD=secretref:smtp-password \
    IMAP_SERVER=imap.gmail.com \
    IMAP_PORT=993 \
    IMAP_USERNAME=secretref:imap-password \
    IMAP_PASSWORD=secretref:imap-password \
    DEFAULT_FROM_EMAIL=your-email@gmail.com

Step 7: Get Application URL

az containerapp show \
  --name email-send-mcp \
  --resource-group email-mcp-rg \
  --query properties.configuration.ingress.fqdn

Azure Container Apps Features

βœ… Auto-scaling: Automatically scales based on HTTP traffic βœ… Zero Downtime: Seamless deployments with rolling updates βœ… Built-in Load Balancing: Distributes traffic across replicas βœ… HTTPS by Default: Automatic SSL/TLS certificates βœ… Secrets Management: Secure credential storage βœ… Monitoring: Integrated with Azure Monitor and Application Insights

Update Deployment

# Update with new image
az containerapp update \
  --name email-send-mcp \
  --resource-group email-mcp-rg \
  --image emailmcpacr.azurecr.io/email-send-mcp:v2

# Update environment variables
az containerapp update \
  --name email-send-mcp \
  --resource-group email-mcp-rg \
  --set-env-vars LOG_LEVEL=DEBUG

Monitoring and Logs

# View logs
az containerapp logs show \
  --name email-send-mcp \
  --resource-group email-mcp-rg \
  --follow

# View metrics
az monitor metrics list \
  --resource /subscriptions/<subscription-id>/resourceGroups/email-mcp-rg/providers/Microsoft.App/containerApps/email-send-mcp \
  --metric-names HttpRequestsCount

Cost Optimization

  • Use consumption plan (pay only for what you use)

  • Set appropriate min/max replicas

  • Configure scale rules based on metrics

  • Use reserved capacity for predictable workloads

Security Best Practices

  1. Use Azure Key Vault for secrets

  2. Enable Managed Identity for ACR authentication

  3. Use Private Endpoints for internal-only access

  4. Configure CORS policies

  5. Enable Azure AD authentication for API access

  6. Use VNet integration for enhanced security

πŸ—οΈ Architecture

System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     MCP Client Layer                         β”‚
β”‚  (Claude Desktop, Custom Clients, Web Applications)         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚ MCP Protocol (HTTP/Stdio)
                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  FastMCP Server (main.py)                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚              MCP Tools Router                       β”‚   β”‚
β”‚  β”‚  β€’ send_email                                       β”‚   β”‚
β”‚  β”‚  β€’ receive_emails_imap                              β”‚   β”‚
β”‚  β”‚  β€’ receive_emails_pop3                              β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  EmailSender   β”‚      β”‚ EmailReceiver   β”‚
β”‚   (SMTP)       β”‚      β”‚  (IMAP/POP3)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                        β”‚
        β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”
        β”‚ β”‚   Validators & Utils      β”‚
        β”‚ β”‚  β€’ Email validation       β”‚
        β”‚ β”‚  β€’ Normalization          β”‚
        β”‚ β”‚  β€’ Formatting             β”‚
        β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”˜
        β”‚                            β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚      Email Service Providers    β”‚
        β”‚  β€’ Gmail (SMTP/IMAP)           β”‚
        β”‚  β€’ Outlook (SMTP/IMAP)         β”‚
        β”‚  β€’ Yahoo (SMTP/IMAP)           β”‚
        β”‚  β€’ Custom SMTP/IMAP Servers    β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Project Structure

email-send-mcp/
β”œβ”€β”€ main.py                      # Entry point - initializes and runs FastMCP server
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ __init__.py             # Package initialization
β”‚   β”œβ”€β”€ config.py               # Configuration management with Pydantic Settings
β”‚   β”œβ”€β”€ server.py               # FastMCP server setup and MCP tools definition
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ email_sender.py     # SMTP email sending service
β”‚   β”‚   └── email_receiver.py   # IMAP/POP3 email receiving service
β”‚   └── utils/
β”‚       β”œβ”€β”€ __init__.py
β”‚       └── validators.py        # Email validation and formatting utilities
β”œβ”€β”€ tests/                       # Test suite
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ test_config.py          # Configuration tests
β”‚   β”œβ”€β”€ test_validators.py      # Email validation tests
β”‚   └── ...
β”œβ”€β”€ logs/                        # Application logs (auto-created)
β”œβ”€β”€ Dockerfile                   # Container configuration
β”œβ”€β”€ docker-compose.yml          # Docker Compose setup (optional)
β”œβ”€β”€ pyproject.toml              # Project dependencies and metadata
β”œβ”€β”€ .env.example                # Example environment configuration
β”œβ”€β”€ .env                        # Actual environment configuration (not in git)
β”œβ”€β”€ README.md                   # This file
β”œβ”€β”€ QUICKSTART.md              # Quick start guide
β”œβ”€β”€ EMAIL_PROVIDERS.md         # Provider-specific configurations
β”œβ”€β”€ CONTRIBUTING.md            # Contribution guidelines
β”œβ”€β”€ LICENSE                    # MIT License
└── examples.py                # Usage examples

Component Details

1. main.py - Application Entry Point

  • Loads environment variables from .env

  • Configures logging (console + file)

  • Initializes FastMCP server

  • Sets up SMTP, IMAP, POP3 services

  • Starts HTTP server on port 8888

2. src/config.py - Configuration Management

  • Uses Pydantic Settings for type-safe configuration

  • Loads settings from environment variables

  • Validates port numbers and required fields

  • Provides singleton pattern for settings access

  • Supports multiple email providers

3. src/server.py - MCP Server

  • Defines MCP tools using @mcp.tool() decorator

  • Integrates EmailSender and EmailReceiver services

  • Handles tool parameter validation

  • Formats responses for AI assistants

  • Provides health check endpoint

4. src/services/email_sender.py - SMTP Service

  • Async SMTP client using aiosmtplib

  • Supports TLS (port 587) and SSL (port 465)

  • Validates all email addresses before sending

  • Handles file attachments with size limits

  • Supports CC, BCC, and HTML emails

  • Smart MIME message construction

5. src/services/email_receiver.py - IMAP/POP3 Service

  • Async IMAP client using aioimaplib

  • Sync POP3 client using poplib

  • Folder/mailbox support (IMAP)

  • Unread filtering (IMAP)

  • Email parsing with proper encoding handling

  • Attachment metadata extraction

6. src/utils/validators.py - Email Utilities

  • RFC-compliant email validation using email-validator

  • Email normalization and formatting

  • Batch email validation

  • Display name formatting

Technology Stack

Component

Technology

Purpose

MCP Framework

FastMCP 2.0

Model Context Protocol server implementation

SMTP Client

aiosmtplib

Async SMTP email sending

IMAP Client

aioimaplib

Async IMAP email receiving

POP3 Client

poplib (stdlib)

Sync POP3 email receiving

Email Validation

email-validator

RFC-compliant email address validation

Settings Management

Pydantic Settings

Type-safe configuration

Environment Vars

python-dotenv

.env file support

HTTP Server

FastAPI (via FastMCP)

HTTP transport for MCP

Package Manager

uv

Fast Python package management

Testing

pytest, pytest-asyncio

Test framework

Code Quality

black, isort, mypy, ruff

Code formatting and linting

Data Flow

Sending an Email

1. MCP Client β†’ send_email tool call
2. FastMCP Server β†’ validates parameters
3. EmailSender β†’ validates recipient addresses
4. EmailSender β†’ constructs MIME message
5. EmailSender β†’ connects to SMTP server (TLS/SSL)
6. EmailSender β†’ authenticates with credentials
7. EmailSender β†’ sends email
8. EmailSender β†’ returns success/error status
9. FastMCP Server β†’ formats response
10. Response β†’ returns to MCP Client

Receiving Emails

1. MCP Client β†’ receive_emails_imap tool call
2. FastMCP Server β†’ validates parameters
3. EmailReceiver β†’ connects to IMAP server (SSL)
4. EmailReceiver β†’ authenticates with credentials
5. EmailReceiver β†’ selects mailbox/folder
6. EmailReceiver β†’ searches for emails (filtered)
7. EmailReceiver β†’ fetches email messages
8. EmailReceiver β†’ parses email content
9. EmailReceiver β†’ extracts metadata and attachments
10. EmailReceiver β†’ returns formatted email list
11. FastMCP Server β†’ formats response
12. Response β†’ returns to MCP Client

Logging and Monitoring

  • Log Location: logs/email-send-mcp_YYYYMMDD.log

  • Log Rotation: Daily (midnight)

  • Log Format: YYYY-MM-DD HH:MM:SS - logger_name - LEVEL - message

  • Log Levels: DEBUG, INFO, WARNING, ERROR

  • Console Output: Enabled for development

  • Structured Logging: JSON-compatible format for cloud environments

Security Architecture

  1. Credential Storage: Environment variables (never hardcoded)

  2. TLS/SSL: Enforced for all email connections

  3. Input Validation: All emails validated before processing

  4. Attachment Validation: File size and existence checks

  5. Error Handling: Sensitive data not exposed in errors

  6. Logging: Passwords and secrets never logged

πŸ”§ Troubleshooting

Common Issues and Solutions

Issue: "Authentication failed" or "Invalid credentials"

Symptoms:

  • Error message: "535 Authentication failed" or similar

  • Cannot connect to SMTP/IMAP server

Solutions:

  1. Use App Password instead of regular password

    • For Gmail: Create App Password

    • For Yahoo: Account Security β†’ Generate app password

    • For Outlook: May need app-specific password or OAuth

  2. Verify credentials in .env file

    # Check your .env file
    cat .env | grep -E "USERNAME|PASSWORD"
  3. Ensure 2FA is enabled (required for app passwords)

  4. Check IMAP/SMTP access is enabled

    • Gmail: Settings β†’ See all settings β†’ Forwarding and POP/IMAP β†’ Enable IMAP

    • Outlook: Settings β†’ Sync email β†’ POP and IMAP


Issue: "Connection timeout" or "Connection refused"

Symptoms:

  • Server doesn't respond

  • Timeout errors after 60+ seconds

Solutions:

  1. Check firewall settings

    # Test SMTP connectivity
    telnet smtp.gmail.com 587
    
    # Test IMAP connectivity
    telnet imap.gmail.com 993
  2. Verify server addresses and ports

    • SMTP: Usually port 587 (TLS) or 465 (SSL)

    • IMAP: Usually port 993 (SSL)

    • POP3: Usually port 995 (SSL)

  3. Check if your ISP blocks SMTP/IMAP ports

    • Some ISPs block port 25, 587

    • Try using VPN or alternative network

  4. Verify TLS/SSL settings match your provider

    # For port 587, use:
    SMTP_USE_TLS=true
    
    # For port 465, use:
    SMTP_USE_TLS=true  # aiosmtplib handles this automatically

Issue: Gmail "Less secure app access" error

Symptoms:

  • "Please log in via your web browser" error

  • Account access blocked

Solutions:

  1. Enable 2-Factor Authentication

  2. Generate and use App Password

    • Visit App Passwords

    • Select "Mail" and your device

    • Copy the 16-character password

    • Use in .env file (remove spaces)

  3. Never use "Less secure app access" (deprecated and insecure)


Issue: "Module not found" errors

Symptoms:

ModuleNotFoundError: No module named 'fastmcp'
ModuleNotFoundError: No module named 'dotenv'

Solutions:

# Reinstall dependencies
pip install -e .

# Or with uv
uv pip install -e .

# For development dependencies
pip install -e ".[dev]"

# Verify installation
python -c "import fastmcp; print('FastMCP OK')"
python -c "import dotenv; print('dotenv OK')"

Issue: "Permission denied" or "File not found" (attachments)

Symptoms:

  • "Attachment file not found: /path/to/file.pdf"

  • Permission errors when reading attachment files

Solutions:

  1. Use absolute paths for attachments

    # βœ… Good
    attachments=["/home/user/documents/report.pdf"]
    
    # ❌ Bad
    attachments=["report.pdf"]
  2. Verify file exists and is readable

    ls -la /path/to/file.pdf
    # Should show readable permissions
  3. Check file size

    # Default max is 25MB
    du -h /path/to/file.pdf

Issue: "Tools not appearing in Claude Desktop"

Symptoms:

  • MCP server configured but tools don't show up

  • Claude doesn't recognize email commands

Solutions:

  1. Verify config file path is correct

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

  2. Use absolute paths in configuration

    {
      "mcpServers": {
        "email": {
          "command": "python",
          "args": ["/absolute/path/to/email-send-mcp/main.py"]
        }
      }
    }
  3. Restart Claude Desktop completely

    • Quit application (not just close window)

    • Restart from Applications/Start Menu

  4. Check server logs

    # View logs to see if server started
    tail -f logs/email-send-mcp_*.log

Issue: Email sends but recipient doesn't receive it

Symptoms:

  • "Email sent successfully" message

  • But recipient never receives the email

Solutions:

  1. Check recipient's spam/junk folder

  2. Verify sender email is correct

    DEFAULT_FROM_EMAIL=your-actual-email@gmail.com
  3. Check email provider's sent folder

  4. Verify recipient email address is valid

    # Test email validation
    from src.utils.validators import validate_email_address
    is_valid, result = validate_email_address("recipient@example.com")
    print(f"Valid: {is_valid}, Result: {result}")
  5. Check for bounce-back emails in your inbox


Issue: "Maximum attachment size exceeded"

Symptoms:

  • Error about attachment size limit

Solutions:

  1. Check file size

    du -h attachment.pdf
  2. Increase limit in .env

    MAX_ATTACHMENT_SIZE_MB=50  # Default is 25
  3. Compress large files before attaching

  4. Use cloud storage links for very large files


Issue: Cannot receive emails / Empty inbox

Symptoms:

  • "No emails found" message

  • IMAP returns empty results

Solutions:

  1. Verify IMAP credentials are correct

    IMAP_USERNAME=your-email@gmail.com
    IMAP_PASSWORD=your-app-password
  2. Check mailbox name is correct

    # Common mailbox names
    receive_emails_imap(mailbox="INBOX")      # βœ…
    receive_emails_imap(mailbox="Sent")       # βœ…
    receive_emails_imap(mailbox="inbox")      # ❌ Case-sensitive
  3. Verify emails exist in that folder

    • Check via web interface

    • Try different folder: "Sent", "Drafts", etc.

  4. Increase limit parameter

    receive_emails_imap(limit=50)  # Default is 10

Debugging Tips

Enable Debug Logging

Add to .env:

LOG_LEVEL=DEBUG
DEBUG=true

Restart server and check logs:

tail -f logs/email-send-mcp_$(date +%Y%m%d).log

Test SMTP Connection Manually

import asyncio
from src.services.email_sender import EmailSender

async def test():
    sender = EmailSender()
    result = await sender.send_email(
        recipient="test@example.com",
        subject="Test",
        body="Testing SMTP connection"
    )
    print(result)

asyncio.run(test())

Test IMAP Connection Manually

import asyncio
from src.services.email_receiver import EmailReceiver

async def test():
    receiver = EmailReceiver()
    result = await receiver.receive_emails_imap(limit=1)
    print(result)

asyncio.run(test())

Check Environment Variables

# Verify .env is being loaded
python -c "from src.config import get_settings; s = get_settings(); print(f'SMTP: {s.SMTP_SERVER}:{s.SMTP_PORT}')"

Getting Help

If you're still experiencing issues:

  1. Check existing issues: GitHub Issues

  2. Search discussions: GitHub Discussions

  3. Open a new issue:

    • Include error messages

    • Include relevant logs (remove sensitive data)

    • Include your configuration (without passwords)

    • Include steps to reproduce

πŸ‘₯ Contributing

We welcome contributions! Here's how you can help:

Quick Start for Contributors

  1. Fork and clone the repository

    git clone https://github.com/YOUR_USERNAME/email-send-mcp.git
    cd email-send-mcp
  2. Install development dependencies

    pip install -e ".[dev]"
  3. Create a branch

    git checkout -b feature/your-feature-name
  4. Make your changes and add tests

  5. Run tests and linting

    # Run tests
    pytest tests/ -v
    
    # Format code
    black src/ tests/ main.py
    isort src/ tests/ main.py
    
    # Type checking
    mypy src/
    
    # Linting
    ruff check src/ tests/
  6. Commit and push

    git commit -m "Add feature: description"
    git push origin feature/your-feature-name
  7. Create Pull Request

Contribution Guidelines

  • Code Style: Follow PEP 8, use Black formatter

  • Tests: Add tests for new features

  • Documentation: Update README and docstrings

  • Commits: Write clear commit messages

  • Issues: Link PRs to related issues

For detailed guidelines, see CONTRIBUTING.md.

πŸ“š Additional Resources

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • FastMCP - Excellent MCP framework by @jlowin

  • Anthropic - Model Context Protocol specification

  • Contributors - Thank you to all contributors!

πŸ“ž Support


⭐ Star this repo if you find it useful!

Made with ❀️ for the MCP community

-
security - not tested
A
license - permissive license
-
quality - not tested

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

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

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bedro96/email-send-mcp'

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