diff --git a/mail/server.py b/mail/server.py index b737eb8..71f1ffb 100644 --- a/mail/server.py +++ b/mail/server.py @@ -3,8 +3,11 @@ import os import sys import contextlib +import imaplib import mailbox from email.header import decode_header +from email.mime.text import MIMEText +from email.utils import formatdate from pathlib import Path from typing import Annotated @@ -17,7 +20,25 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from common import get_current_user, OAUTH_ROUTES, BearerAuthMiddleware from common import load_config as _lc -MAIL_ROOTS = _lc()["mail_roots"] +_cfg = _lc() +MAIL_ROOTS = _cfg["mail_roots"] + +IMAP_ACCOUNTS = { + "stefan": { + "host": "imap.1blu.de", + "user": "d370128_0-slohmaier", + "password": _cfg["imap_passwords"]["stefan"], + "drafts_folder": "Drafts", + "from_addr": "stefan@slohmaier.de", + }, + "kati": { + "host": "imap.gmail.com", + "user": "akpolke@gmail.com", + "password": _cfg["imap_passwords"]["kati"], + "drafts_folder": "[Google Mail]/Entw&APw-rfe", + "from_addr": "akpolke@gmail.com", + }, +} mcp = FastMCP("Mail", stateless_http=True, transport_security={"enable_dns_rebinding_protection": False}) @@ -171,6 +192,41 @@ def read_mail( ) +@mcp.tool() +def create_draft( + to: Annotated[str, Field(description="Recipient email address, e.g. 'max@example.com'")], + subject: Annotated[str, Field(description="Email subject line")], + body: Annotated[str, Field(description="Email body text (plain text)")], + cc: Annotated[str, Field(description="CC recipients, comma-separated")] = "", + account: Annotated[str, Field(description="Which account to create the draft in. Leave empty for default account.")] = "", +) -> str: + """Create an email draft in the Drafts folder. The draft can then be reviewed and sent from Roundcube or phone. Does NOT send the email.""" + user = get_current_user() + if not user: return "Error: not authenticated" + acct = IMAP_ACCOUNTS.get(user) + if not acct: return f"Kein IMAP-Account fuer {user} konfiguriert" + + msg = MIMEText(body, "plain", "utf-8") + msg["From"] = acct["from_addr"] + msg["To"] = to + if cc: + msg["Cc"] = cc + msg["Subject"] = subject + msg["Date"] = formatdate(localtime=True) + msg["X-Mailer"] = "MCP Mail Server" + + try: + imap = imaplib.IMAP4_SSL(acct["host"]) + imap.login(acct["user"], acct["password"]) + status, _ = imap.append(acct["drafts_folder"], "\\Draft", None, msg.as_bytes()) + imap.logout() + if status == "OK": + return f"Entwurf erstellt: An {to}, Betreff \"{subject}\". Oeffne Roundcube oder die Mail-App um ihn zu senden." + return f"Fehler beim Erstellen des Entwurfs: {status}" + except Exception as e: + return f"IMAP-Fehler: {e}" + + def create_app(): from contextlib import asynccontextmanager mcp_app = mcp.streamable_http_app()