import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import nodemailer from "nodemailer";
// Configuration schema for 126 email SMTP service with SSL
export const configSchema = z.object({
debug: z.boolean().default(false).describe("Enable debug logging"),
smtp_host: z.string().default("smtp.126.com").describe("SMTP server host"),
smtp_port: z.number().default(465).describe("SMTP server port (465 for SSL)"),
smtp_secure: z.boolean().default(true).describe("Use SSL/TLS (true for SSL)"),
email_user: z.string().describe("126 email address for authentication"),
email_password: z.string().describe("126 email password or app-specific password"),
from_name: z.string().optional().describe("Display name for sender"),
});
export default function createStatelessServer({
config,
}: {
config: z.infer<typeof configSchema>;
}) {
const server = new McpServer({
name: "126 Email MCP Server",
version: "1.0.0",
});
// Create SMTP transporter with SSL
const createTransporter = () => {
return nodemailer.createTransport({
host: config.smtp_host,
port: config.smtp_port,
secure: config.smtp_secure, // true for SSL (port 465)
auth: {
user: config.email_user,
pass: config.email_password,
},
tls: {
// For SSL connections, we can be more strict
rejectUnauthorized: config.smtp_secure
}
});
};
// Add email sending tool
server.tool(
"send_email",
"Send email using 126 SMTP service",
{
to: z.string().describe("Recipient email address"),
subject: z.string().describe("Email subject"),
text: z.string().optional().describe("Plain text content"),
html: z.string().optional().describe("HTML content"),
cc: z.string().optional().describe("CC email addresses (comma separated)"),
bcc: z.string().optional().describe("BCC email addresses (comma separated)"),
},
async ({ to, subject, text, html, cc, bcc }) => {
try {
if (!text && !html) {
throw new Error("Either text or html content must be provided");
}
const transporter = createTransporter();
const mailOptions = {
from: config.from_name ? `"${config.from_name}" <${config.email_user}>` : config.email_user,
to,
subject,
text,
html,
cc: cc ? cc.split(',').map(email => email.trim()) : undefined,
bcc: bcc ? bcc.split(',').map(email => email.trim()) : undefined,
};
if (config.debug) {
console.log("Sending email with options:", JSON.stringify(mailOptions, null, 2));
}
const info = await transporter.sendMail(mailOptions);
return {
content: [
{
type: "text",
text: `Email sent successfully!\nMessage ID: ${info.messageId}\nTo: ${to}\nSubject: ${subject}`
}
],
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
return {
content: [
{
type: "text",
text: `Failed to send email: ${errorMessage}`
}
],
isError: true,
};
}
}
);
// Add email verification tool
server.tool(
"verify_smtp_connection",
"Verify SMTP connection to 126 email service",
{},
async () => {
try {
const transporter = createTransporter();
await transporter.verify();
return {
content: [
{
type: "text",
text: "SMTP connection verified successfully! Ready to send emails."
}
],
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
return {
content: [
{
type: "text",
text: `SMTP connection failed: ${errorMessage}`
}
],
isError: true,
};
}
}
);
return server.server;
}