从协议原理到源码实现,一文搞懂如何让AI发送、读取和管理邮件
为什么需要邮箱MCP Server? Model Context Protocol(MCP)是一种让AI助手与外部工具和数据源连接的开放协议。 简单来说,MCP Server就是AI的"工具箱",让它能够执行各种实际操作。 通用邮箱MCP Server让AI能够发送邮件、读取最近邮件、查看邮件详情、自动识别主流邮箱并配置。 |
一、项目技术架构
核心技术栈
依赖 | 版本 | 用途 |
@modelcontextprotocol/sdk | ^1.29.0 | MCP协议实现 |
nodemailer | ^8.0.7 | SMTP邮件发送 |
imap | ^0.8.17 | IMAP邮件接收 |
poplib | ^0.1.7 | POP3邮件接收 |
mailparser | ^3.7.3 | 邮件内容解析 |
核心类结构
方法 | 功能 |
sendEmail | 发送邮件 |
getRecentEmails | 获取邮件列表 |
getEmailContent | 获取邮件详情 |
setupEmailAccount | 自动配置邮箱 |
configureEmailServer | 手动配置服务器 |
createSMTPTransporter | 创建SMTP连接 |
createIMAPConnection | 创建IMAP连接 |
detectEmailProvider | 检测邮箱类型 |
二、支持的功能一览
工具列表
工具名称 | 功能 | 核心参数 |
send_email | 发送邮件 | to, subject, text, cc, bcc, html, attachments |
get_recent_emails | 获取邮件列表 | limit, days |
get_email_content | 获取邮件详情 | uid |
setup_email_account | 自动配置邮箱 | email, password, provider |
configure_email_server | 手动配置服务器 | smtpHost, imapHost, user... |
test_email_connection | 测试连接 | testType |
list_supported_providers | 列出支持的邮箱 | 无 |
支持的邮箱类型
提供商 | 标识 | 域名 | 推荐协议 |
QQ邮箱 | qq.com | IMAP | |
网易邮箱 | 163 | 163.com, 126.com, yeah.net | POP3 |
Gmail | gmail | gmail.com, googlemail.com | IMAP |
Outlook | outlook | outlook.com, hotmail.com, live.com | IMAP |
腾讯企业邮箱 | exmail | exmail.qq.com | IMAP |
阿里云邮箱 | aliyun | aliyun.com, alibaba-inc.com | IMAP |
新浪邮箱 | sina | sina.com, sina.cn | IMAP |
搜狐邮箱 | sohu | sohu.com | IMAP |
邮件服务器配置
邮箱类型 | SMTP服务器 | SMTP端口 | IMAP服务器 | IMAP端口 |
QQ邮箱 | smtp.qq.com | 587 | imap.qq.com | 993 |
网易邮箱 | smtp.163.com | 465 | imap.163.com | 993 |
Gmail | smtp.gmail.com | 587 | imap.gmail.com | 993 |
Outlook | smtp-mail.outlook.com | 587 | outlook.office365.com | 993 |
腾讯企业邮箱 | smtp.exmail.qq.com | 465 | imap.exmail.qq.com | 993 |
阿里云邮箱 | smtp.mxhichina.com | 465 | imap.mxhichina.com | 993 |
三、MCP Server开发实战
3.1 创建项目基础结构
mkdir email-mcp cd email-mcp npm init -y npm install @modelcontextprotocol/sdk nodemailer imap poplib mailparser
3.2 引入依赖并初始化
import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'; import nodemailer from 'nodemailer'; import Imap from 'imap'; import { simpleParser } from 'mailparser'; import POP3Client from 'poplib'; // 初始化MCP Server const server = new Server( { name: 'universal-email-server', version: '1.0.0' }, { capabilities: { tools: {} } } );
3.3 定义工具列表(ListToolsRequestSchema)
server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'send_email', description: '发送邮件', inputSchema: { type: 'object', properties: { to: { type: 'array', items: { type: 'string' }, description: '收件人邮箱地址列表' }, subject: { type: 'string', description: '邮件主题' }, text: { type: 'string', description: '纯文本邮件内容' }, cc: { type: 'array', items: { type: 'string' }, description: '抄送邮箱地址列表(可选)' }, bcc: { type: 'array', items: { type: 'string' }, description: '密送邮箱地址列表(可选)' }, html: { type: 'string', description: 'HTML格式邮件内容(可选)' }, attachments: { type: 'array', description: '邮件附件列表(可选)' } }, required: ['to', 'subject', 'text'] } }, // 更多工具... ] }; });
3.4 实现工具处理逻辑(CallToolRequestSchema)
server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case 'send_email':return await this.sendEmail(args); case 'get_recent_emails': return await this.getRecentEmails(args); case 'get_email_content':return await this.getEmailContent(args); case 'setup_email_account': return await this.setupEmailAccount(args); case 'list_supported_providers': return await this.listSupportedProviders(args); case 'configure_email_server': return await this.configureEmailServer(args); case 'test_email_connection': return await this.testConnection(args); default: throw new Error('未知的工具: ${name}'); } } catch (error) { return { content: [{ type: 'text', text: '错误: ${error.message}' }] }; } });
3.5 启动服务
async function run() { const transport = new StdioServerTransport(); await server.connect(transport); console.error('MCP服务器已启动'); } run().catch(console.error);
四、MCP协议核心概念
4.1 两个核心Schema
ListToolsRequestSchema — 声明服务器提供哪些工具:
{ name: '工具名', description: '工具描述', inputSchema: { type: 'object', properties: { /* 参数定义 */ }, required: ['必填参数'] } }
CallToolRequestSchema — 执行工具调用:
{ name: '工具名', arguments: { /* 参数值 */ } }
4.2 工具返回格式
return { content: [ { type: 'text', text: '返回内容' } ] };
4.3 MCP协议工作流程
MCP协议通过两个核心Schema实现客户端与服务器的通信:
客户端发送 ListToolsRequest → 服务器返回工具列表 → 客户端发送 CallToolRequest → 服务器执行并返回结果。
五、配置与使用
5.1 环境变量配置 — MCP-X 配置示例:
{ "mcpServers": { "universal-email": { "command": "npx", "args": ["mcp-email"], "env": { "EMAIL_USER": "your-email@domain.com", "EMAIL_PASSWORD": "your-password-or-auth-code", "EMAIL_TYPE": "auto" } } } }
5.2 运行时配置(动态)— 使用 setup_email_account 工具:
{ "email": "user@lenovo.com", "password": "your-auth-code", "provider": "outlook" }
5.3 获取授权码 — Outlook/Microsoft 365 企业版:
1. 登录 Microsoft 安全基础页面
2. 进入"高级安全选项"或 Azure AD 条件访问
3. 启用多因素身份验证 (MFA)
4. 在"应用密码"部分创建新密码
5. 使用该应用密码作为授权码
六、工具使用示例
发送邮件:
{ "to": ["recipient@example.com"], "subject": "测试邮件", "text": "这是一封测试邮件" }
带附件和抄送:
{ "to": ["recipient1@example.com", "recipient2@example.com"], "cc": ["manager@example.com"], "subject": "项目报告", "text": "请查看项目报告", "html": "
项目报告
项目进展顺利。
", "attachments": [ { "filename": "report.pdf", "path": "/path/to/report.pdf" } ] }
获取邮件列表:
{ "limit": 10, "days": 7 }
七、安全最佳实践
要点 | 说明 |
使用授权码而非真实密码 | 大多数邮箱都支持客户端专用密码 |
环境变量存储敏感信息 | 不要硬编码邮箱账号和密码 |
定期轮换授权码 | 建议每3-6个月更新一次 |
企业邮箱务必设置 EMAIL_TYPE 字段 | 避免自动识别失败 |
网络隔离 | 确保运行MCP Server的网络环境安全 |
八、故障排除
常见错误
错误信息 | 原因 | 解决方案 |
535 Error: authentication failed | 认证失败 | 重新生成授权码,检查密码是否正确 |
ECONNREFUSED | 连接被拒绝 | 检查网络、防火墙设置 |
EXAMINE Unsafe Login | 网易邮箱安全限制 | 系统会自动切换到POP3协议 |
诊断工具
# 测试邮箱配置 node test-auto-config.js # 在MCP客户端中调用 test_email_connection
九、总结与展望
项目亮点
亮点 | 说明 |
自动配置机制 | 根据域名自动识别QQ、163、Gmail等主流邮箱 |
协议智能切换 | 163自动用POP3,其他用IMAP;IMAP失败自动降级到POP3 |
统一接口设计 | 7个工具覆盖邮件收、发、查、配全场景 |
企业邮箱支持 | 通过 EMAIL_TYPE 字段支持各类企业邮箱 |
开发MCP Server的关键点
1. 理解MCP协议的两个核心Schema
2. 使用 @modelcontextprotocol/sdk 提供的工具
3. 通过 StdioServerTransport 实现标准输入输出通信
4. 合理的错误处理和返回格式
相关资源
资源 | 地址 |
MCP协议文档 | modelcontextprotocol.io |
项目GitHub地址 | github.com/TimeCyber/email-mcp |
npm包地址 | npmjs.com/package/mcp-email |
本文基于开源项目 mcp-email 整理,遵循 MIT License 来源:github.com/TimeCyber/email-mcp
夜雨聆风