Skip to main content
Glama
samihalawa

SMTP MCP Server

send-email

Send emails to recipients with HTML support, CC/BCC options, and template management through the SMTP MCP Server.

Instructions

Send an email to one or more recipients

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
toYesArray of recipients
subjectYesEmail subject
bodyYesEmail body (HTML supported)
fromNoSender information. If not provided, the default SMTP user will be used.
ccNoArray of CC recipients
bccNoArray of BCC recipients
templateIdNoID of the email template to use. If not provided, the email will use the subject and body provided.
templateDataNoData to be used for template variable substitution
smtpConfigIdNoID of the SMTP configuration to use. If not provided, the default configuration will be used.

Implementation Reference

  • Input schema and description for the 'send-email' tool, defining parameters like to, subject, body, cc, bcc, templates, etc.
    "send-email": {
      name: "send-email",
      description: "Send an email to one or more recipients",
      inputSchema: {
        type: "object",
        properties: {
          to: {
            type: "array",
            items: {
              type: "object",
              properties: {
                email: { type: "string" },
                name: { type: "string" }
              },
              required: ["email"]
            },
            description: "Array of recipients"
          },
          subject: {
            type: "string",
            description: "Email subject"
          },
          body: {
            type: "string",
            description: "Email body (HTML supported)"
          },
          from: {
            type: "object",
            properties: {
              email: { type: "string" },
              name: { type: "string" }
            },
            description: "Sender information. If not provided, the default SMTP user will be used."
          },
          cc: {
            type: "array",
            items: {
              type: "object",
              properties: {
                email: { type: "string" },
                name: { type: "string" }
              },
              required: ["email"]
            },
            description: "Array of CC recipients"
          },
          bcc: {
            type: "array",
            items: {
              type: "object",
              properties: {
                email: { type: "string" },
                name: { type: "string" }
              },
              required: ["email"]
            },
            description: "Array of BCC recipients"
          },
          templateId: {
            type: "string",
            description: "ID of the email template to use. If not provided, the email will use the subject and body provided."
          },
          templateData: {
            type: "object",
            description: "Data to be used for template variable substitution"
          },
          smtpConfigId: {
            type: "string",
            description: "ID of the SMTP configuration to use. If not provided, the default configuration will be used."
          }
        },
        required: ["to", "subject", "body"]
      }
    },
  • src/index.ts:59-62 (registration)
    Registers all tools including 'send-email' by calling createToolDefinitions() and passing to setupRequestHandlers(server, TOOLS). This makes the tool available via MCP.
    const TOOLS = createToolDefinitions();
    
    // Setup request handlers
    await setupRequestHandlers(server, TOOLS);
  • Dispatches 'send-email' tool calls to the handleSendEmail function in the CallToolRequestSchema handler.
    case "send-email":
      return await handleSendEmail(toolParams);
  • Handler wrapper that normalizes input parameters and delegates to the core sendEmail function from emailService.
    async function handleSendEmail(parameters: any) {
      try {
        // If "to" is a single object, convert it to an array
        const to = Array.isArray(parameters.to) ? parameters.to : [parameters.to];
        
        // Prepare the email data
        const emailData: EmailData = {
          to: to,
          subject: parameters.subject,
          body: parameters.body,
          from: parameters.from,
          cc: parameters.cc,
          bcc: parameters.bcc,
          templateId: parameters.templateId,
          templateData: parameters.templateData
        };
        
        // Send the email
        const result = await sendEmail(emailData, parameters.smtpConfigId);
        
        return {
          success: result.success,
          message: result.message
        };
      } catch (error) {
        logToFile('Error in handleSendEmail:');
        logToFile(error instanceof Error ? error.message : 'Unknown error');
        return {
          success: false,
          message: error instanceof Error ? error.message : 'Unknown error'
        };
      }
    }
  • Core implementation of email sending using nodemailer: creates transport, processes templates, formats recipients, sends mail, and logs activity.
    export async function sendEmail(data: EmailData, smtpConfigId?: string): Promise<{ success: boolean; message?: string }> {
      try {
        const transport = await createTransport(smtpConfigId);
        const smtpConfig = smtpConfigId 
          ? (await getSmtpConfigs()).find(c => c.id === smtpConfigId) 
          : await getDefaultSmtpConfig();
        
        if (!smtpConfig) {
          return { success: false, message: 'SMTP configuration not found' };
        }
        
        // Generate email content from template if templateId is provided
        const { subject, body } = await generateEmailContent(
          data.templateId,
          data.templateData,
          data.subject,
          data.body
        );
        
        // Create mail options
        const mailOptions = {
          from: data.from 
            ? (data.from.name ? `"${data.from.name}" <${data.from.email}>` : data.from.email)
            : (smtpConfig.auth.user),
          to: formatRecipients(data.to),
          subject,
          html: body,
          cc: data.cc ? formatRecipients(data.cc) : undefined,
          bcc: data.bcc ? formatRecipients(data.bcc) : undefined
        };
        
        // Send email
        const info = await transport.sendMail(mailOptions);
        
        // Log email activity
        const recipients = Array.isArray(data.to) ? data.to : [data.to];
        for (const recipient of recipients) {
          const logEntry: EmailLogEntry = {
            timestamp: new Date().toISOString(),
            smtpConfig: smtpConfig.id,
            templateId: data.templateId,
            recipient: recipient.email,
            subject,
            success: true,
            message: `Message sent: ${info.messageId}`
          };
          await logEmailActivity(logEntry);
        }
        
        return { success: true, message: `Message sent: ${info.messageId}` };
      } catch (error) {
        logToFile(`Error sending email: ${error}`);
        
        // Log failed email activity
        if (data.to) {
          const recipients = Array.isArray(data.to) ? data.to : [data.to];
          for (const recipient of recipients) {
            const logEntry: EmailLogEntry = {
              timestamp: new Date().toISOString(),
              smtpConfig: smtpConfigId || 'unknown',
              templateId: data.templateId,
              recipient: recipient.email,
              subject: data.subject,
              success: false,
              message: error instanceof Error ? error.message : 'Unknown error sending email'
            };
            await logEmailActivity(logEntry);
          }
        }
        
        return { 
          success: false, 
          message: error instanceof Error ? error.message : 'Unknown error sending email'
        };
      }
    }
Behavior2/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. It states the action ('Send an email') but does not cover critical traits like required permissions, rate limits, error handling, or whether it's a synchronous/asynchronous operation. This leaves significant gaps in understanding how the tool behaves beyond its basic function.

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

Conciseness5/5

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

The description is a single, efficient sentence that directly states the tool's purpose without unnecessary words. It is front-loaded and wastes no space, making it easy to grasp quickly while leaving detailed information to the structured schema.

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

Completeness2/5

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

For a complex tool with 9 parameters, no annotations, and no output schema, the description is insufficient. It lacks context on behavioral aspects, error handling, and output expectations, failing to compensate for the absence of structured metadata. This makes it inadequate for guiding an AI agent in proper tool invocation.

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?

The input schema has 100% description coverage, clearly documenting all 9 parameters and their purposes. The description adds no additional semantic details beyond what the schema provides, such as explaining parameter interactions or usage nuances. Given the high schema coverage, a baseline score of 3 is appropriate as the schema does the heavy lifting.

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

Purpose4/5

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

The description 'Send an email to one or more recipients' clearly states the verb ('Send') and resource ('email'), specifying the action and target. However, it does not differentiate from sibling tools like 'send-bulk-emails', which might handle similar functionality but with different scopes or methods, leaving some ambiguity in sibling distinction.

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

Usage Guidelines2/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, such as 'send-bulk-emails' for mass emailing or other email-related tools. It lacks explicit context, prerequisites, or exclusions, offering minimal usage direction beyond the basic action stated.

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/samihalawa/mcp-server-smtp'

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