send_email
Send emails using a specified account on the MCP Email Server. Define recipients, subject, body, and optional CC/BCC fields for efficient email dispatch.
Instructions
Send an email using the specified account. Recipient should be a list of email addresses.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| account_name | Yes | The name of the email account to send from. | |
| bcc | No | A list of BCC email addresses. | |
| body | Yes | The body of the email. | |
| cc | No | A list of CC email addresses. | |
| recipients | Yes | A list of recipient email addresses. | |
| subject | Yes | The subject of the email. |
Implementation Reference
- mcp_email_server/app.py:105-138 (registration)MCP tool registration for 'send_email' including the input schema via Annotated parameters and Pydantic Fields. Dispatches to the handler for execution.@mcp.tool( description="Send an email using the specified account. Recipient should be a list of email addresses. Optionally attach files by providing their absolute paths.", ) async def send_email( account_name: Annotated[str, Field(description="The name of the email account to send from.")], recipients: Annotated[list[str], Field(description="A list of recipient email addresses.")], subject: Annotated[str, Field(description="The subject of the email.")], body: Annotated[str, Field(description="The body of the email.")], cc: Annotated[ list[str] | None, Field(default=None, description="A list of CC email addresses."), ] = None, bcc: Annotated[ list[str] | None, Field(default=None, description="A list of BCC email addresses."), ] = None, html: Annotated[ bool, Field(default=False, description="Whether to send the email as HTML (True) or plain text (False)."), ] = False, attachments: Annotated[ list[str] | None, Field( default=None, description="A list of absolute file paths to attach to the email. Supports common file types (documents, images, archives, etc.).", ), ] = None, ) -> str: handler = dispatch_handler(account_name) await handler.send_email(recipients, subject, body, cc, bcc, html, attachments) recipient_str = ", ".join(recipients) attachment_info = f" with {len(attachments)} attachment(s)" if attachments else "" return f"Email sent successfully to {recipient_str}{attachment_info}"
- Core handler implementation in EmailClient class that constructs the email message (MIMEText/MIMEMultipart, handling HTML, attachments via helper methods, CC/BCC headers) and sends it using aiosmtplib.SMTP.async def send_email( self, recipients: list[str], subject: str, body: str, cc: list[str] | None = None, bcc: list[str] | None = None, html: bool = False, attachments: list[str] | None = None, ): # Create message with or without attachments if attachments: msg = self._create_message_with_attachments(body, html, attachments) else: content_type = "html" if html else "plain" msg = MIMEText(body, content_type, "utf-8") # Handle subject with special characters if any(ord(c) > 127 for c in subject): msg["Subject"] = Header(subject, "utf-8") else: msg["Subject"] = subject # Handle sender name with special characters if any(ord(c) > 127 for c in self.sender): msg["From"] = Header(self.sender, "utf-8") else: msg["From"] = self.sender msg["To"] = ", ".join(recipients) # Add CC header if provided (visible to recipients) if cc: msg["Cc"] = ", ".join(cc) # Note: BCC recipients are not added to headers (they remain hidden) # but will be included in the actual recipients for SMTP delivery async with aiosmtplib.SMTP( hostname=self.email_server.host, port=self.email_server.port, start_tls=self.smtp_start_tls, use_tls=self.smtp_use_tls, ) as smtp: await smtp.login(self.email_server.user_name, self.email_server.password) # Create a combined list of all recipients for delivery all_recipients = recipients.copy() if cc: all_recipients.extend(cc) if bcc: all_recipients.extend(bcc) await smtp.send_message(msg, recipients=all_recipients) async def delete_emails(self, email_ids: list[str], mailbox: str = "INBOX") -> tuple[list[str], list[str]]:
- Handler method in ClassicEmailHandler that delegates the send_email call to its outgoing_client (EmailClient instance). This is the direct handler called by the MCP tool wrapper.async def send_email( self, recipients: list[str], subject: str, body: str, cc: list[str] | None = None, bcc: list[str] | None = None, html: bool = False, attachments: list[str] | None = None, ) -> None: await self.outgoing_client.send_email(recipients, subject, body, cc, bcc, html, attachments)
- Helper method in EmailClient to create MIMEMultipart message with text body and attachments.def _create_message_with_attachments(self, body: str, html: bool, attachments: list[str]) -> MIMEMultipart: """Create multipart message with attachments.""" msg = MIMEMultipart() content_type = "html" if html else "plain" text_part = MIMEText(body, content_type, "utf-8") msg.attach(text_part) for file_path in attachments: try: path = self._validate_attachment(file_path) attachment_part = self._create_attachment_part(path) msg.attach(attachment_part) except Exception as e: logger.error(f"Failed to attach file {file_path}: {e}") raise return msg