#!/usr/bin/env python3 """Email MCP Server — Send and check email from Open WebUI.""" from fastmcp import FastMCP import smtplib, imaplib, email, os from email.mime.text import MIMEText mcp = FastMCP('Email', version='1.0.0') SMTP_HOST = 'mail.germainebrown.com' SMTP_PORT = 2525 IMAP_HOST = 'mail.germainebrown.com' IMAP_PORT = 993 def _get_pass(filename): with open(f'/root/.config/himalaya/{filename}') as f: return f.read().strip() @mcp.tool(description="Send an email from g@germainebrown.com") async def send_email(to: str, subject: str, body: str) -> str: """Send an email via SMTP.""" pw = _get_pass('g-germainebrown.pass') msg = MIMEText(body) msg['From'] = 'g@germainebrown.com' msg['To'] = to msg['Subject'] = subject with smtplib.SMTP(SMTP_HOST, SMTP_PORT, timeout=15) as s: s.starttls() s.login('g@germainebrown.com', pw) s.send_message(msg) return f'Sent email to {to}: "{subject}"' @mcp.tool(description="Check recent emails in shonuff@germainebrown.com inbox") async def check_inbox(limit: int = 10) -> str: """Read recent inbox emails.""" pw = _get_pass('shonuff.pass') with imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT) as imap: imap.login('shonuff@germainebrown.com', pw) imap.select('INBOX') _, msgs = imap.search(None, 'ALL') ids = msgs[0].split()[-limit:] results = [] for mid in reversed(ids): _, data = imap.fetch(mid, '(RFC822)') msg = email.message_from_bytes(data[0][1]) results.append(f'From: {msg["From"]} | Subject: {msg["Subject"]} | Date: {msg["Date"]}') return f'Last {len(results)} emails:\n' + '\n'.join(results) @mcp.tool(description="Search shonuff@ inbox by subject or sender") async def search_email(query: str, limit: int = 10) -> str: """Search inbox.""" pw = _get_pass('shonuff.pass') with imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT) as imap: imap.login('shonuff@germainebrown.com', pw) imap.select('INBOX') _, msgs = imap.search(None, f'SUBJECT "{query}"') subject_ids = msgs[0].split() _, msgs = imap.search(None, f'FROM "{query}"') from_ids = msgs[0].split() all_ids = list(set(list(subject_ids) + list(from_ids)))[-limit:] results = [] for mid in reversed(all_ids): _, data = imap.fetch(mid, '(RFC822)') msg = email.message_from_bytes(data[0][1]) results.append(f'From: {msg["From"]} | Subject: {msg["Subject"]} | Date: {msg["Date"]}') return f'Found {len(results)} matches for "{query}":\n' + '\n'.join(results) if __name__ == '__main__': mcp.run(transport='http', host='0.0.0.0', port=8902, path='/mcp')