MCP Sendmail Server
Enables sending emails via SMTP with support for HTML content, attachments, bulk sending, and template-based emails. Features session management and full MCP Streamable HTTP transport compliance.
README
MCP Sendmail Server
A Model Context Protocol (MCP) server with Streamable HTTP transport for sending emails via SMTP.
Features
- ✅ MCP Streamable HTTP - Full MCP specification compliance (2024-11-05)
- ✅ Stateful Sessions - Session management with automatic cleanup
- ✅ Bidirectional Communication - SSE for server-to-client messaging
- ✅ Stream Resumability - Reconnect and resume from last event
- ✅ Email Tools - Send emails, bulk emails, and template-based emails
- ✅ SMTP Support - Full SMTP/TLS support with authentication
- ✅ Attachments - Support for email attachments (base64 encoded)
- ✅ Docker Ready - Multi-stage build, production-optimized
- ✅ Type Safe - Full Python type hints and Pydantic models
- ✅ Async Support - FastAPI async/await patterns
- ✅ Backward Compatible - Legacy JSON-RPC 2.0 endpoints still work
Configuration
SMTP credentials are configured via environment variables. The repository includes .env.sh for easy configuration:
# Source SMTP settings
source .env.sh
# Your settings are now available:
# SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD
Quick Start
Option 1: Local Development
# Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Load SMTP settings from .env.sh
source .env.sh
# Run server
uvicorn src.server:app --reload --port 8080
Option 2: Docker
# Build and run with Docker
docker build -t mcp-sendmail-server:latest .
docker run -d -p 8080:8080 \
-e SMTP_HOST="smtp.gmail.com" \
-e SMTP_PORT="587" \
-e SMTP_USER="your-email@gmail.com" \
-e SMTP_PASSWORD="your-password" \
-v $(pwd)/logs:/app/logs \
--name mcp-sendmail \
mcp-sendmail-server:latest
Option 3: Docker Compose (Recommended)
Quick Start with Convenience Scripts
# Start the server (automatically loads .env.sh)
./start.sh
# View logs
docker compose logs -f
# Stop the server
./stop.sh
Manual Start
Configure your SMTP credentials using .env.sh:
# 1. Edit .env.sh with your SMTP credentials (already configured in this repo)
nano .env.sh
# Example .env.sh contents:
export SMTP_HOST="mail.example.com"
export SMTP_PORT="25"
export SMTP_USER="test@example.com"
export SMTP_PASSWORD="your-password"
# 2. Source the environment variables
source .env.sh
# 3. Start services (will use variables from .env.sh)
docker compose up -d
# View logs
docker compose logs -f
# Stop services
docker compose down
Important: Always run source .env.sh before docker compose up to load the SMTP configuration, or use the ./start.sh script which does this automatically.
How it works: The docker-compose.yml reads environment variables from your shell using ${SMTP_HOST} syntax. If variables aren't set, it falls back to safe defaults (localhost:587).
Environment Variables
| Variable | Description | Default |
|---|---|---|
SMTP_HOST |
SMTP server hostname | localhost |
SMTP_PORT |
SMTP server port | 587 |
SMTP_USER |
SMTP username/email | `` |
SMTP_PASSWORD |
SMTP password | `` |
Testing the Server
MCP Streamable HTTP (Recommended)
# Check health
curl http://localhost:8080/health
# Initialize MCP session (note the /mcp endpoint)
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "curl-client", "version": "1.0"}
}
}'
# Save the Mcp-Session-Id from response headers!
# Example: Mcp-Session-Id: 318a19a9-b757-4c0b-9ddb-a8dc1b40d240
# List available tools
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: YOUR_SESSION_ID_HERE" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'
# Verify SMTP connection
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: YOUR_SESSION_ID_HERE" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "verify_connection",
"arguments": {}
}
}'
# Send an email
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: YOUR_SESSION_ID_HERE" \
-d '{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "send_email",
"arguments": {
"to": "recipient@example.com",
"subject": "Test Email",
"body": "This is a test email sent via MCP Sendmail Server"
}
}
}'
# Send an HTML email
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: YOUR_SESSION_ID_HERE" \
-d '{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "send_email",
"arguments": {
"to": "recipient@example.com",
"subject": "HTML Test Email",
"body": "<h1>Hello</h1><p>This is an <strong>HTML</strong> email!</p>",
"html": true
}
}
}'
# Send bulk emails
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: YOUR_SESSION_ID_HERE" \
-d '{
"jsonrpc": "2.0",
"id": 6,
"method": "tools/call",
"params": {
"name": "send_bulk_email",
"arguments": {
"recipients": ["user1@example.com", "user2@example.com", "user3@example.com"],
"subject": "Bulk Email",
"body": "This email was sent to multiple recipients"
}
}
}'
# Send template email
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: YOUR_SESSION_ID_HERE" \
-d '{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "send_template_email",
"arguments": {
"to": "recipient@example.com",
"subject": "Welcome {name}!",
"template": "Hello {name},\n\nWelcome to {company}!\n\nYour account is: {account}",
"variables": {
"name": "John Doe",
"company": "Acme Corp",
"account": "john.doe@acme.com"
}
}
}
}'
Available MCP Tools
1. send_email
Send an email with optional attachments, CC, and BCC.
Parameters:
to(string, required): Recipient email addresssubject(string, required): Email subjectbody(string, required): Email body contentfrom_addr(string, optional): Sender email address (defaults to SMTP_USER)cc(array, optional): List of CC recipientsbcc(array, optional): List of BCC recipientshtml(boolean, optional): Whether body is HTML (default: false)attachments(array, optional): List of attachments with filename and base64 content
Example:
{
"to": "recipient@example.com",
"subject": "Meeting Tomorrow",
"body": "Hi, let's meet tomorrow at 10 AM.",
"cc": ["manager@example.com"],
"html": false
}
2. send_bulk_email
Send the same email to multiple recipients.
Parameters:
recipients(array, required): List of recipient email addressessubject(string, required): Email subjectbody(string, required): Email body contentfrom_addr(string, optional): Sender email address (defaults to SMTP_USER)html(boolean, optional): Whether body is HTML (default: false)
Example:
{
"recipients": ["user1@example.com", "user2@example.com", "user3@example.com"],
"subject": "System Maintenance Notice",
"body": "The system will be down for maintenance on Saturday."
}
3. send_template_email
Send an email using a template with variable substitution.
Parameters:
to(string, required): Recipient email addresssubject(string, required): Email subjecttemplate(string, required): Email template with {variable} placeholdersvariables(object, required): Dictionary of variable names and valuesfrom_addr(string, optional): Sender email address (defaults to SMTP_USER)html(boolean, optional): Whether template is HTML (default: false)
Example:
{
"to": "customer@example.com",
"subject": "Order Confirmation",
"template": "Dear {customer_name},\n\nYour order #{order_id} has been confirmed.\n\nTotal: ${total}",
"variables": {
"customer_name": "Jane Smith",
"order_id": "12345",
"total": "99.99"
}
}
4. verify_connection
Verify SMTP connection and credentials.
Parameters: None
Returns: Connection status, server details, and port information
API Endpoints
MCP Streamable HTTP (Primary)
| Method | Endpoint | Description |
|---|---|---|
| POST | /mcp |
MCP requests with session management |
| GET | /mcp |
Open SSE stream for server notifications |
| GET | /health |
Health check |
Required Headers:
Mcp-Session-Id: Session ID (after initialize)Mcp-Protocol-Version:2024-11-05Accept:application/json, text/event-stream
Legacy Endpoints (Backward Compatible)
| Method | Endpoint | Description |
|---|---|---|
| POST | /, /rpc, /jsonrpc |
Plain JSON-RPC 2.0 (no sessions) |
| GET | /sse |
Legacy SSE (deprecated) |
JSON-RPC Methods
| Method | Description |
|---|---|
initialize |
Initialize MCP session (returns session ID) |
ping |
Keep-alive ping |
tools/list |
List available tools |
tools/call |
Execute a tool |
Project Structure
mcp-mail/
├── src/
│ ├── server.py # FastAPI server with tool registration
│ ├── mcp_handler.py # MCP protocol implementation
│ ├── mcp_transport.py # MCP transport layer
│ ├── mcp_session.py # Session management
│ ├── email/
│ │ ├── __init__.py
│ │ └── email_operations.py # Email sending via SMTP
│ ├── jsonrpc/
│ │ ├── __init__.py
│ │ ├── handler.py # JSON-RPC handler
│ │ └── models.py # JSON-RPC models
│ └── utils/
│ ├── errors.py # Custom exceptions
│ ├── validation.py # Input validation
│ └── security.py # Security utilities
├── tests/ # Test suite
├── logs/ # Application logs
├── Dockerfile # Docker image definition
├── docker-compose.yml # Docker Compose setup
└── requirements.txt # Python dependencies
SMTP Configuration Examples
Gmail
export SMTP_HOST="smtp.gmail.com"
export SMTP_PORT="587"
export SMTP_USER="your-email@gmail.com"
export SMTP_PASSWORD="your-app-password" # Use App Password, not regular password
Outlook/Office 365
export SMTP_HOST="smtp.office365.com"
export SMTP_PORT="587"
export SMTP_USER="your-email@outlook.com"
export SMTP_PASSWORD="your-password"
SendGrid
export SMTP_HOST="smtp.sendgrid.net"
export SMTP_PORT="587"
export SMTP_USER="apikey"
export SMTP_PASSWORD="your-sendgrid-api-key"
Mailgun
export SMTP_HOST="smtp.mailgun.org"
export SMTP_PORT="587"
export SMTP_USER="postmaster@your-domain.mailgun.org"
export SMTP_PASSWORD="your-mailgun-smtp-password"
Amazon SES
export SMTP_HOST="email-smtp.us-east-1.amazonaws.com"
export SMTP_PORT="587"
export SMTP_USER="your-ses-smtp-username"
export SMTP_PASSWORD="your-ses-smtp-password"
Security Features
- TLS Encryption: All SMTP connections use TLS by default
- Secure Credentials: SMTP credentials stored in environment variables
- Input Validation: Email addresses and content validated
- Non-root User: Docker runs as
mcpuser(UID 1000)
Development
# Install dev dependencies
pip install -r requirements.txt
# Run tests
pytest tests/ -v
# Type checking
mypy src/
# Linting
ruff check src/
# Code formatting
black src/
Docker Image Details
- Base Image:
python:3.11-slim - Size: ~150-200MB (optimized with multi-stage build)
- User: Non-root
mcpuser - Health Checks: Built-in
- Volumes:
/app/logs(logs)
Troubleshooting
Gmail Authentication Issues
If you're using Gmail, you need to:
- Enable 2-factor authentication
- Generate an App Password (not your regular password)
- Use the App Password in
SMTP_PASSWORD
Connection Timeouts
If you get connection timeouts:
- Check your firewall settings
- Verify the SMTP host and port
- Try port 465 (SSL) instead of 587 (TLS)
- Use the
verify_connectiontool to test
Certificate Errors
If you get SSL certificate errors:
- Make sure you're using a valid SMTP server
- Check if your network has SSL inspection enabled
- Verify the server's certificate is valid
License
MIT License
Contributing
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
Support
For issues and questions, please open an issue on GitHub.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.