A Model Context Protocol (MCP) server that provides email sending capabilities via HTTP API with API key authentication and Gmail SMTP integration. Supports both local stdio transport and cloud-based HTTP/SSE transport for deployment to Heroku.
- 🔐 API key-based authentication for secure API access
- 📧 Gmail SMTP integration for reliable email delivery
- 🚀 MCP protocol compliance for tool discovery and execution
- 🌐 HTTP/SSE transport for cloud deployment
- 🖥️ Stdio transport for local development
- 🛡️ Security middleware (CORS, rate limiting, helmet)
- 📊 Comprehensive logging and monitoring with request tracking
- ☁️ Heroku deployment ready
- ✅ Constitution-compliant architecture and development practices
- Node.js 18+
- Gmail account with app password
- API keys for authentication
- Clone the repository:
git clone https://github.com/your-username/mail-mcp-server.git
cd mail-mcp-server- Install dependencies:
npm install- Create environment file:
cp env.example .env- Configure environment variables in
.env:
# Server Configuration
PORT=3000
NODE_ENV=development
# API Key Configuration
API_KEYS=mcp_key1_abc123def456,mcp_key2_xyz789uvw012
# Gmail SMTP Configuration
GMAIL_USER=marlin@trymarlin.ai
GMAIL_PASS=your-app-password-here
GMAIL_HOST=smtp.gmail.com
GMAIL_PORT=587
# SMTP tuning (optional)
SMTP_SECURE=false # true for port 465 SSL, false for STARTTLS on 587
SMTP_REQUIRE_TLS=false # require STARTTLS upgrade on 587
SMTP_FAMILY= # set 4 to force IPv4
SMTP_DEBUG=false # enable verbose SMTP logs
LOG_SMTP_PASSWORD=false # if true, logs full password on failures (dangerous)
# CORS Configuration
CORS_ORIGIN=http://localhost:3000
# Rate Limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100- Start the server:
npm startGET /health- Basic health checkGET /health/detailed- Detailed health check with service statusGET /health/ready- Readiness checkGET /health/live- Liveness check
GET /mcp- MCP protocol discoveryGET /mcp/sse- SSE endpoint for real-time MCP communicationPOST /mcp/message- JSON-RPC message endpointGET /mcp/tools- List available MCP tools (requires API key)POST /mcp/tools/send_email- Send email via MCP tool (requires API key)GET /mcp/tools/send_email/schema- Get tool input schema (requires API key)GET /mcp/tools/send_email/status- Check tool availability (requires API key)POST /mcp/generate-key- Generate new API keyGET /mcp/api-key-status- Get API key status
All MCP endpoints require API key authentication. Include the API key in the X-API-Key header:
X-API-Key: <your-api-key>
You can generate new API keys using the built-in endpoint:
curl -X POST http://localhost:3000/mcp/generate-key \
-H "Content-Type: application/json" \
-d '{"prefix": "my-app"}'- API keys are stored in the
API_KEYSenvironment variable as a comma-separated list - Each key should be unique and secure
- Keys are validated on every request
- All API key usage is logged for security auditing
The server supports the standard MCP protocol over HTTP using JSON-RPC 2.0:
curl -X POST http://localhost:3000/mcp/message \
-H "X-API-Key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {"roots": {"listChanged": true}, "sampling": {}},
"clientInfo": {"name": "my-client", "version": "1.0.0"}
}
}'curl -X POST http://localhost:3000/mcp/message \
-H "X-API-Key: <your-api-key>" \
-H "X-Session-ID: <session-id-from-initialize>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}'curl -X POST http://localhost:3000/mcp/message \
-H "X-API-Key: <your-api-key>" \
-H "X-Session-ID: <session-id-from-initialize>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "send_email",
"arguments": {
"to": "recipient@example.com",
"subject": "Test Email",
"body": "This is a test email sent via MCP server."
}
}
}'Tool Name: send_email
Input Schema:
{
"to": "recipient@example.com",
"subject": "Email Subject",
"body": "Email body content",
"from": "sender@example.com" // optional, defaults to marlin@trymarlin.ai
}The server also maintains backward compatibility with REST endpoints:
curl -X POST http://localhost:3000/mcp/tools/send_email \
-H "X-API-Key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"subject": "Test Email",
"body": "This is a test email sent via MCP server."
}'- Create a new Heroku app:
heroku create your-app-name- Set environment variables:
heroku config:set API_KEYS=your-api-key-1,your-api-key-2
heroku config:set GMAIL_PASS=your-gmail-app-password
heroku config:set NODE_ENV=production- Deploy:
git push heroku main- Test your deployment:
heroku openTo use the Heroku-deployed MCP server with Cursor, update your Cursor MCP configuration:
{
"mcpServers": {
"mail-mcp-server": {
"url": "https://your-app-name.herokuapp.com/mcp",
"headers": {
"X-API-Key": "your-api-key"
}
}
}
}For local development, you can still use the stdio transport:
{
"mcpServers": {
"mail-mcp-server": {
"command": "node",
"args": ["/path/to/your/mail-mcp/src/mcp-stdio.js"],
"cwd": "/path/to/your/mail-mcp",
"env": {
"JWT_SECRET": "your-super-secret-jwt-key-here",
"GMAIL_PASS": "your-gmail-app-password"
}
}
}
}| Variable | Description | Required | Default |
|---|---|---|---|
PORT |
Server port | No | 3000 |
NODE_ENV |
Environment | No | development |
API_KEYS |
Comma-separated API keys | Yes | - |
GMAIL_USER |
Gmail account | No | marlin@trymarlin.ai |
GMAIL_PASS |
Gmail app password | Yes | - |
GMAIL_HOST |
SMTP host | No | smtp.gmail.com |
GMAIL_PORT |
SMTP port | No | 587 |
SMTP_SECURE |
Use SSL on connect (465) | No | false |
SMTP_REQUIRE_TLS |
Require STARTTLS on 587 | No | false |
SMTP_FAMILY |
Force IP family (4 or 6) | No | - |
SMTP_DEBUG |
Nodemailer debug logging | No | false |
LOG_SMTP_PASSWORD |
Log full password on failure | No | false |
CORS_ORIGIN |
CORS origin | No | http://localhost:3000 |
RATE_LIMIT_WINDOW_MS |
Rate limit window | No | 900000 |
RATE_LIMIT_MAX_REQUESTS |
Max requests per window | No | 100 |
IMAP_HOST |
IMAP host (diagnostic) | No | imap.gmail.com |
IMAP_PORT |
IMAP port (diagnostic) | No | 993 |
IMAP_SECURE |
IMAP SSL (diagnostic) | No | true |
POP3_HOST |
POP3 host (diagnostic) | No | pop.gmail.com |
POP3_PORT |
POP3 port (diagnostic) | No | 995 |
POP3_SECURE |
POP3 SSL (diagnostic) | No | true |
GET /health/imap— attempts IMAP TLS connection and returns the greeting bannerGET /health/pop3— attempts POP3 TLS connection and returns the greeting banner
npm testnpm run lint
npm run lint:fixnpm run formatsrc/
├── index.js # Express application entry point
├── models/
│ ├── EmailRequest.js # Email request model
│ ├── EmailResponse.js # Email response model
│ └── AuthToken.js # JWT token model
├── services/
│ ├── emailService.js # Gmail SMTP service
│ └── authService.js # JWT authentication service
├── routes/
│ ├── health.js # Health check endpoints
│ └── mcp.js # MCP protocol endpoints
├── middleware/
│ ├── auth.js # Authentication middleware
│ └── errorHandler.js # Error handling middleware
└── config/
├── logger.js # Logging configuration
└── production.js # Production configuration
This server is built according to the project constitution principles:
- MCP HTTP Service: Always serves MCP tools at
/mcp/toolsendpoint - API Key Authentication: All MCP endpoints require secure API key authentication
- Email Service Reliability: Comprehensive health checks and connection testing
- Comprehensive Logging: Structured logging with request tracking and user context
- Error Handling & Validation: Robust input validation and consistent error responses
- CORS configuration for cross-origin requests
- Rate limiting to prevent abuse
- Helmet security headers
- Secure credential management via environment variables
- Request ID tracking for audit trails
- Code follows linting and formatting standards
- Comprehensive test coverage including constitution compliance tests
- Environment configuration management
- Health check endpoints for monitoring
- API documentation maintained and up-to-date
Run the constitution compliance tests:
npm run test:constitutionThis will verify that all constitution principles are properly implemented.
MIT License - see LICENSE file for details.