2.7 KiB
This file documents the email (IMAP/SMTP) subsystem. Claude Code auto-loads it when a file under devplacepy/services/email/ is read or edited.
Email via Devii (services/email/ + services/devii/email/)
A signed-in user's Devii can connect to their OWN external mailbox over IMAP/SMTP (non-platform, external protocol tools).
Protocol engine and adapter
The protocol engine services/email/ (EmailAccount dataclass + EmailClient) is built over the Python stdlib imaplib/smtplib/email - no new dependency, since IMAP/SMTP are not HTTP the stealth-client rule does not apply. It is wrapped by the Devii adapter services/devii/email/EmailController (handler="email", registered in registry.py, specs in actions/email_actions.py, routed in dispatcher.py). Every blocking protocol call runs through asyncio.to_thread in the controller so the single worker loop never stalls (same discipline as correction.py).
Tools
- Connection CRUD:
email_account_set/email_account_get/email_accounts_list/email_account_delete. - Message ops:
email_list_folders,email_list_messages,email_search,email_read_message(read);email_mark/email_set_flags/email_move_message(organise);email_delete_message;email_send.
All are requires_auth=True AND additionally guarded to owner_kind == "user" (guests never reach email), gated by the admin devii_email_enabled flag (default on) / devii_email_timeout on the Devii service config ("Email" service-config group).
Credentials
Credentials live in the soft-deletable per-owner email_accounts table (one row per (owner_kind, owner_id, label); helpers list/get/set/delete_email_account in database/, sensible defaults imap 993/ssl + smtp 587/starttls applied in set_email_account). The password is stored plaintext (consistent with api_key/gateway_api_key) and is NEVER echoed back - email_account_get/email_accounts_list mask it as password_set.
Configuration surface
Configuration is Devii-only (no HTTP route or profile UI), like the CSS/JS customization feature.
Destructive actions and SSRF guard
email_send is a real outbound action, and the two delete tools (email_account_delete, email_delete_message) are confirmation-gated (CONFIRM_REQUIRED, each declaring a confirm param). The IMAP/SMTP host is run through net_guard.guard_public_host_sync before every connect (private/loopback addresses refused - SSRF/internal-scan defense, mirroring guard_public_url).
Audit and metering
Audited via the existing _audit_mechanic choke point under the email.* domain (category email). Mutations are not metered into the gateway ledger (no LLM call is made).