Enables sending emails through Gmail's SMTP server, including support for HTML emails, attachments, bulk sending, and template-based emails with variable substitution.
Enables sending emails through Mailgun's SMTP service, including support for HTML emails, attachments, bulk sending, and template-based emails with variable substitution.
Enables sending emails through SendGrid's SMTP service, including support for HTML emails, attachments, bulk sending, and template-based emails with variable substitution.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Sendmail Serversend a welcome email to newuser@example.com with subject 'Welcome!' and HTML body"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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_PASSWORDQuick 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 8080Option 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:latestOption 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.shManual 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 downImportant: 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 server hostname |
|
| SMTP server port |
|
| SMTP username/email | `` |
| 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 requests with session management |
GET |
| Open SSE stream for server notifications |
GET |
| 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 |
| Plain JSON-RPC 2.0 (no sessions) |
GET |
| Legacy SSE (deprecated) |
JSON-RPC Methods
Method | Description |
| Initialize MCP session (returns session ID) |
| Keep-alive ping |
| List available tools |
| 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 dependenciesSMTP 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 passwordOutlook/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-slimSize: ~150-200MB (optimized with multi-stage build)
User: Non-root
mcpuserHealth 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.
This server cannot be installed
Resources
Looking for Admin?
Admins can modify the Dockerfile, update the server description, and track usage metrics. If you are the server author, to access the admin panel.