Skip to main content
Glama
TimeCyber

Email MCP Server

by TimeCyber

send_email

Send emails with attachments to multiple recipients using the Email MCP Server. Specify recipients, subject, content, and optional CC/BCC fields.

Instructions

发送邮件

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
toYes收件人邮箱地址列表
ccNo抄送邮箱地址列表(可选)
bccNo密送邮箱地址列表(可选)
subjectYes邮件主题
textYes纯文本邮件内容
htmlNoHTML格式邮件内容(可选)
attachmentsNo邮件附件列表(可选)

Implementation Reference

  • The core handler function for the 'send_email' tool. It destructures input arguments, creates an SMTP transporter using createSMTPTransporter helper, prepares mail options including handling attachments, sends the email via nodemailer, and returns a success message with details.
    async sendEmail(args) {
      const { to, cc, bcc, subject, text, html, attachments } = args;
    
      const transporter = this.createSMTPTransporter();
    
      const mailOptions = {
        from: process.env.EMAIL_USER || process.env.WECHAT_EMAIL_USER,
        to: Array.isArray(to) ? to.join(', ') : to,
        cc: cc ? (Array.isArray(cc) ? cc.join(', ') : cc) : undefined,
        bcc: bcc ? (Array.isArray(bcc) ? bcc.join(', ') : bcc) : undefined,
        subject,
        text,
        html
      };
    
      // 处理附件
      if (attachments && attachments.length > 0) {
        mailOptions.attachments = attachments.map(att => {
          if (att.content) {
            return {
              filename: att.filename,
              content: att.content,
              encoding: 'base64'
            };
          } else if (att.path) {
            return {
              filename: att.filename,
              path: att.path
            };
          }
          return att;
        });
      }
    
      const result = await transporter.sendMail(mailOptions);
    
      return {
        content: [
          {
            type: 'text',
            text: `邮件发送成功!\n消息ID: ${result.messageId}\n收件人: ${Array.isArray(to) ? to.join(', ') : to}\n主题: ${subject}`
          }
        ]
      };
    }
  • Input schema definition for the 'send_email' tool, specifying parameters like to, cc, bcc, subject, text, html, attachments, with required fields to, subject, text.
    inputSchema: {
      type: 'object',
      properties: {
        to: {
          type: 'array',
          items: { type: 'string' },
          description: '收件人邮箱地址列表'
        },
        cc: {
          type: 'array',
          items: { type: 'string' },
          description: '抄送邮箱地址列表(可选)'
        },
        bcc: {
          type: 'array',
          items: { type: 'string' },
          description: '密送邮箱地址列表(可选)'
        },
        subject: {
          type: 'string',
          description: '邮件主题'
        },
        text: {
          type: 'string',
          description: '纯文本邮件内容'
        },
        html: {
          type: 'string',
          description: 'HTML格式邮件内容(可选)'
        },
        attachments: {
          type: 'array',
          items: {
            type: 'object',
            properties: {
              filename: { type: 'string', description: '附件文件名' },
              path: { type: 'string', description: '附件文件路径' },
              content: { type: 'string', description: '附件内容(base64编码)' }
            }
          },
          description: '邮件附件列表(可选)'
        }
      },
      required: ['to', 'subject', 'text']
    }
  • index.js:166-214 (registration)
    Registration of the 'send_email' tool in the ListToolsRequestSchema handler response, including name, description, and inputSchema.
    {
      name: 'send_email',
      description: '发送邮件',
      inputSchema: {
        type: 'object',
        properties: {
          to: {
            type: 'array',
            items: { type: 'string' },
            description: '收件人邮箱地址列表'
          },
          cc: {
            type: 'array',
            items: { type: 'string' },
            description: '抄送邮箱地址列表(可选)'
          },
          bcc: {
            type: 'array',
            items: { type: 'string' },
            description: '密送邮箱地址列表(可选)'
          },
          subject: {
            type: 'string',
            description: '邮件主题'
          },
          text: {
            type: 'string',
            description: '纯文本邮件内容'
          },
          html: {
            type: 'string',
            description: 'HTML格式邮件内容(可选)'
          },
          attachments: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                filename: { type: 'string', description: '附件文件名' },
                path: { type: 'string', description: '附件文件路径' },
                content: { type: 'string', description: '附件内容(base64编码)' }
              }
            },
            description: '邮件附件列表(可选)'
          }
        },
        required: ['to', 'subject', 'text']
      }
    },
  • index.js:346-347 (registration)
    Dispatch registration in the CallToolRequestSchema switch statement that routes 'send_email' calls to the sendEmail handler method.
    case 'send_email':
      return await this.sendEmail(args);
  • Helper method to create the nodemailer SMTP transporter, handling auto-configuration based on email provider detection from environment variables.
    createSMTPTransporter() {
      try {
        // 如果已经有手动配置的设置,直接使用
        if (process.env.EMAIL_SMTP_HOST || process.env.WECHAT_EMAIL_HOST) {
          const config = {
            host: process.env.EMAIL_SMTP_HOST || process.env.WECHAT_EMAIL_HOST,
            port: parseInt(process.env.EMAIL_SMTP_PORT || process.env.WECHAT_EMAIL_PORT) || 587,
            secure: (process.env.EMAIL_SMTP_SECURE || process.env.WECHAT_EMAIL_SECURE) !== 'false',
            auth: {
              user: process.env.EMAIL_USER || process.env.WECHAT_EMAIL_USER,
              pass: process.env.EMAIL_PASSWORD || process.env.WECHAT_EMAIL_PASSWORD
            },
            connectionTimeout: 30000,
            greetingTimeout: 30000,
            socketTimeout: 30000
          };
          console.log('使用手动配置的SMTP设置:', { host: config.host, port: config.port, secure: config.secure });
          return nodemailer.createTransport(config);
        }
    
        // 自动配置
        const emailUser = process.env.EMAIL_USER || process.env.WECHAT_EMAIL_USER;
        const emailType = process.env.EMAIL_TYPE; // 手动指定的邮箱类型
        
        if (!emailUser) {
          throw new Error('缺少邮箱用户名配置。请设置 EMAIL_USER 环境变量。');
        }
    
        const provider = this.detectEmailProvider(emailUser, emailType);
        if (!provider) {
          throw new Error(`无法识别邮箱类型: ${emailUser}。如果是企业邮箱,请设置 EMAIL_TYPE 环境变量(如: 'exmail' 代表腾讯企业邮箱)`);
        }
    
        const emailConfig = EMAIL_CONFIGS[provider];
        const config = {
          host: emailConfig.smtp.host,
          port: emailConfig.smtp.port,
          secure: emailConfig.smtp.secure,
          auth: {
            user: emailUser,
            pass: process.env.EMAIL_PASSWORD || process.env.WECHAT_EMAIL_PASSWORD
          },
          connectionTimeout: 30000,
          greetingTimeout: 30000,
          socketTimeout: 30000
        };
    
        // 验证必需的配置项
        if (!config.auth.pass) {
          throw new Error('缺少邮箱密码配置。请设置 EMAIL_PASSWORD 环境变量。');
        }
    
        console.log(`自动配置SMTP设置 - 邮箱类型: ${emailConfig.name}`, { host: config.host, port: config.port, secure: config.secure });
        return nodemailer.createTransport(config);
      } catch (error) {
        console.error('创建SMTP传输器失败:', error.message);
        throw error;
      }
    }
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure but offers none. It doesn't mention whether this requires authentication, has rate limits, what happens on failure, whether emails are queued or sent immediately, or any other behavioral characteristics. For a mutation tool with zero annotation coverage, this is a critical gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

While extremely concise with just two characters, this represents under-specification rather than effective conciseness. The description doesn't front-load important information and fails to provide the necessary context for a tool with 7 parameters and multiple sibling alternatives.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with 7 parameters, no annotations, no output schema, and multiple sibling tools, the description is completely inadequate. It provides no behavioral context, no usage guidance, and minimal purpose clarification beyond the tool name itself.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 7 parameters thoroughly with Chinese descriptions. The description adds no additional parameter information beyond what's in the schema, which meets the baseline expectation when schema coverage is complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description '发送邮件' (Send email) is a tautology that restates the tool name in Chinese. While it clearly indicates the general action, it lacks specificity about what resources or capabilities are involved and doesn't differentiate from sibling tools like 'configure_email_server' or 'get_recent_emails'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. There are multiple sibling tools for email operations (configure_email_server, get_email_content, get_recent_emails, etc.), but the description offers no context about when this specific send_email tool is appropriate versus those other tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TimeCyber/email-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server