This commit is contained in:
134
src/tools/email_tools.py
Normal file
134
src/tools/email_tools.py
Normal file
@@ -0,0 +1,134 @@
|
||||
from typing import Optional
|
||||
from fastmcp import FastMCP
|
||||
|
||||
from services.email_service import EmailService
|
||||
|
||||
|
||||
def register_email_tools(mcp: FastMCP, service: EmailService):
|
||||
"""Register all email-related MCP tools."""
|
||||
|
||||
@mcp.tool(description="List all mailboxes/folders in the email account. Returns name, path, message count, and unread count for each mailbox.")
|
||||
def list_mailboxes() -> list[dict]:
|
||||
"""List all IMAP mailboxes/folders."""
|
||||
mailboxes = service.list_mailboxes()
|
||||
return [m.model_dump() for m in mailboxes]
|
||||
|
||||
@mcp.tool(description="List emails in a mailbox with pagination. Returns email summaries including subject, from, date, and read status.")
|
||||
def list_emails(
|
||||
mailbox: str = "INBOX",
|
||||
limit: int = 50,
|
||||
offset: int = 0,
|
||||
include_body: bool = False,
|
||||
) -> dict:
|
||||
"""
|
||||
List emails in a mailbox.
|
||||
|
||||
Args:
|
||||
mailbox: The mailbox/folder to list (default: INBOX)
|
||||
limit: Maximum number of emails to return (default: 50)
|
||||
offset: Number of emails to skip for pagination (default: 0)
|
||||
include_body: Whether to include email body snippets (default: False)
|
||||
"""
|
||||
result = service.list_emails(mailbox, limit, offset, include_body)
|
||||
return result.model_dump()
|
||||
|
||||
@mcp.tool(description="Read a specific email by ID with full body content and attachment information.")
|
||||
def read_email(
|
||||
mailbox: str,
|
||||
email_id: str,
|
||||
format: str = "text",
|
||||
) -> Optional[dict]:
|
||||
"""
|
||||
Read a specific email.
|
||||
|
||||
Args:
|
||||
mailbox: The mailbox containing the email
|
||||
email_id: The unique ID of the email
|
||||
format: Body format to return - 'text', 'html', or 'both' (default: text)
|
||||
"""
|
||||
result = service.read_email(mailbox, email_id, format)
|
||||
return result.model_dump() if result else None
|
||||
|
||||
@mcp.tool(description="Search emails in a mailbox using various criteria like subject, sender, or body content.")
|
||||
def search_emails(
|
||||
query: str,
|
||||
mailbox: str = "INBOX",
|
||||
search_in: Optional[list[str]] = None,
|
||||
date_from: Optional[str] = None,
|
||||
date_to: Optional[str] = None,
|
||||
limit: int = 50,
|
||||
) -> dict:
|
||||
"""
|
||||
Search for emails matching criteria.
|
||||
|
||||
Args:
|
||||
query: Search term to look for
|
||||
mailbox: Mailbox to search in (default: INBOX)
|
||||
search_in: Fields to search - any of ['subject', 'from', 'body'] (default: all)
|
||||
date_from: Only emails after this date (format: DD-Mon-YYYY, e.g., 01-Jan-2024)
|
||||
date_to: Only emails before this date (format: DD-Mon-YYYY)
|
||||
limit: Maximum results to return (default: 50)
|
||||
"""
|
||||
if search_in is None:
|
||||
search_in = ["subject", "from", "body"]
|
||||
result = service.search_emails(query, mailbox, search_in, date_from, date_to, limit)
|
||||
return result.model_dump()
|
||||
|
||||
@mcp.tool(description="Move an email from one mailbox/folder to another.")
|
||||
def move_email(
|
||||
email_id: str,
|
||||
source_mailbox: str,
|
||||
destination_mailbox: str,
|
||||
) -> dict:
|
||||
"""
|
||||
Move an email to a different folder.
|
||||
|
||||
Args:
|
||||
email_id: The unique ID of the email to move
|
||||
source_mailbox: The current mailbox containing the email
|
||||
destination_mailbox: The target mailbox to move the email to
|
||||
"""
|
||||
result = service.move_email(email_id, source_mailbox, destination_mailbox)
|
||||
return result.model_dump()
|
||||
|
||||
@mcp.tool(description="Delete an email, either moving it to trash or permanently deleting it.")
|
||||
def delete_email(
|
||||
email_id: str,
|
||||
mailbox: str,
|
||||
permanent: bool = False,
|
||||
) -> dict:
|
||||
"""
|
||||
Delete an email.
|
||||
|
||||
Args:
|
||||
email_id: The unique ID of the email to delete
|
||||
mailbox: The mailbox containing the email
|
||||
permanent: If True, permanently delete; if False, move to Trash (default: False)
|
||||
"""
|
||||
result = service.delete_email(email_id, mailbox, permanent)
|
||||
return result.model_dump()
|
||||
|
||||
@mcp.tool(description="Send a new email via SMTP. Supports plain text and HTML content, CC, BCC, and reply-to.")
|
||||
async def send_email(
|
||||
to: list[str],
|
||||
subject: str,
|
||||
body: str,
|
||||
cc: Optional[list[str]] = None,
|
||||
bcc: Optional[list[str]] = None,
|
||||
reply_to: Optional[str] = None,
|
||||
html_body: Optional[str] = None,
|
||||
) -> dict:
|
||||
"""
|
||||
Send a new email.
|
||||
|
||||
Args:
|
||||
to: List of recipient email addresses
|
||||
subject: Email subject line
|
||||
body: Plain text email body
|
||||
cc: List of CC recipients (optional)
|
||||
bcc: List of BCC recipients (optional)
|
||||
reply_to: Reply-to address (optional)
|
||||
html_body: HTML version of the email body (optional)
|
||||
"""
|
||||
result = await service.send_email(to, subject, body, cc, bcc, reply_to, html_body)
|
||||
return result.model_dump()
|
||||
Reference in New Issue
Block a user