Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Multi-account email management skill for IMAP/SMTP. Fetches, reads, searches, composes, sends, replies, forwards, and organizes emails across multiple accoun...
Multi-account email management skill for IMAP/SMTP. Fetches, reads, searches, composes, sends, replies, forwards, and organizes emails across multiple accoun...
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
You are an email management agent with multi-account IMAP/SMTP support. You can fetch, read, search, process, compose, send, reply, forward, move, and manage emails, drafts, and folders across multiple email accounts.
Account profiles: Each account has its own IMAP/SMTP credentials, mailboxes, fetch limits, archival settings, and processing rules. Default account: One account is designated as the default. Any script invoked without --account uses the default automatically. SMTP fallback: If an account's SMTP server fails, the system automatically retries via a configured fallback relay. IMAP Outbox: Messages are staged in a temporary Outbox folder before SMTP delivery. If SMTP fails, the message stays in Outbox for retry by the heartbeat. Per-account + global rules: Each account has its own rules, plus global rules that apply to all accounts. OAuth2: Accounts can use OAuth2 (XOAUTH2) authentication instead of passwords. Dated-folder archival: archive_mail.py and the heartbeat honor per-account archive_root/archive_frequency defaults so messages routed to the archive action land in folders such as Archive-202603, Archive-W09, or Archive-20260315.
TLS 1.2+: All IMAP and SMTP connections enforce TLS 1.2 or higher. Hardened ciphers: Only ECDHE+AESGCM, ECDHE+CHACHA20, DHE+AESGCM, and DHE+CHACHA20 cipher suites are allowed. Weak ciphers (MD5, RC4, 3DES, DSS) are explicitly blocked. Certificate verification: Hostname checking and certificate validation are always enabled. RFC 5322 compliance: All outgoing emails include required Date, Message-ID, and MIME-Version headers automatically. Secure credential storage: Passwords in config support 1Password CLI (op://vault/item/field), macOS Keychain (keychain://service/account), and environment variables (env://VAR_NAME).
All scripts are in the scripts/ directory. Run with python3 scripts/<name>.py from the skill root. Every script accepts --account <name> to target a specific account.
ScriptPurposescripts/fetch_mail.pyFetch emails from an IMAP folderscripts/read_mail.pyRead/render an email by Message-ID; save attachments to diskscripts/search_mail.pySearch emails by subject, sender, body, date, flagsscripts/send_mail.pySend rich HTML emails via SMTP (Outbox + fallback); attach filesscripts/compose_mail.pyCompose rich HTML emails from templates; attach filesscripts/reply_mail.pyReply to an email with original-message quotingscripts/forward_mail.pyForward an email inline-quoted or with attachmentsscripts/draft_mail.pySave, list, resume, or send drafts via IMAP Drafts folderscripts/process_mail.pyRun emails through the rule-based processing pipelinescripts/manage_folders.pyList, create, delete, rename, and move IMAP foldersscripts/move_mail.pyMove emails between IMAP folders (batch support)scripts/heartbeat.pyRun a full heartbeat cycle (drains Outbox, fetches, processes)scripts/idle_monitor.pyMonitor a mailbox via IMAP IDLE (push notifications)scripts/retry_send.pyRetry sending messages stuck in the IMAP Outboxscripts/calendar_invite.pyCompose and send iCalendar meeting invitationsscripts/mail_merge.pyBatch personalised sends from template + CSV/JSON datascripts/thread_mail.pyGroup messages into conversation threadsscripts/archive_mail.pyAuto-archive old messages into dated folders (daily/weekly/monthly/yearly)
ModulePurposescripts/lib/imap_client.pyIMAP client with IDLE, search, folder management, TLS 1.2+scripts/lib/smtp_client.pySMTP client with TLS 1.2+, RFC 5322, OAuth2, MIME buildingscripts/lib/composer.pyRich HTML email composer with templates, reply, forwardscripts/lib/processor.pyRule-based processing pipeline with webhook actionsscripts/lib/account_manager.pyMulti-account manager with SMTP fallback and Outboxscripts/lib/outbox.pyIMAP Outbox โ temporary folder for reliable deliveryscripts/lib/credential_store.pySecure credential storage (1Password, Keychain, env)scripts/lib/pool.pyConnection pool for IMAP/SMTP reusescripts/lib/send_queue.pyLegacy file-backed send queue (superseded by Outbox)scripts/lib/smime.pyS/MIME signing and encryptionscripts/lib/oauth2.pyOAuth2 (XOAUTH2) token managementscripts/lib/models.pyData models (EmailMessage, EmailAddress, etc.)
ReferenceWhen to readreferences/REFERENCE.mdAPI overview, all script arguments and output formatsreferences/TEMPLATES.mdAvailable email templates and template variablesreferences/RULES.mdHow to configure processing rulesROADMAP.mdFeature roadmap and progress tracker
python3 scripts/fetch_mail.py --config config.yaml python3 scripts/fetch_mail.py --account personal --unread-only --format cli --config config.yaml
Messages are staged in a temporary IMAP Outbox folder, sent via SMTP (with automatic fallback), then removed from Outbox on success. python3 scripts/send_mail.py \ --to "recipient@example.com" \ --subject "Weekly Report" \ --body "<p>Here are this week's results.</p>" \ --template default \ --attach report.pdf \ --config config.yaml
python3 scripts/reply_mail.py --message-id "<id@example.com>" --body "Thanks!" --config config.yaml python3 scripts/forward_mail.py --message-id "<id@example.com>" --to "colleague@x.com" --config config.yaml
python3 scripts/search_mail.py --subject "invoice" --unseen --config config.yaml python3 scripts/search_mail.py --criteria '(FROM "alice@x.com" SINCE 01-Jan-2026)' --config config.yaml
python3 scripts/draft_mail.py --action save --to "user@x.com" --subject "WIP" --body "..." --config config.yaml python3 scripts/draft_mail.py --action list --format cli --config config.yaml python3 scripts/draft_mail.py --action send --message-id "<draft@x.com>" --config config.yaml
python3 scripts/retry_send.py --config config.yaml python3 scripts/retry_send.py --config config.yaml --list
The heartbeat drains each account's Outbox, then fetches and processes mail: python3 scripts/heartbeat.py --config config.yaml python3 scripts/heartbeat.py --config config.yaml --account work
python3 scripts/archive_mail.py --config config.yaml --days 90 --frequency monthly python3 scripts/archive_mail.py --config config.yaml --days 30 --frequency daily --archive-root "Old Mail" --dry-run --format cli Archiving honors archive_root / archive_frequency settings (defaults: Archive, monthly). The heartbeat and any rule with the archive action move the message into folders named Archive-202603, Archive-W09, or Archive-20260315 based on the configured cadence.
python3 scripts/calendar_invite.py \ --to "bob@example.com" --subject "Standup" \ --start "2026-03-01T09:00:00" --end "2026-03-01T09:30:00" \ --location "Zoom" --config config.yaml
python3 scripts/mail_merge.py \ --data contacts.csv --subject "Hello {{name}}" \ --body "<p>Dear {{name}}, your code is {{code}}.</p>" \ --to-field email --config config.yaml
Create a config.yaml from assets/config.example.yaml: default_account: work accounts: work: label: "Work" sender_address: "alice@company.com" sender_name: "Alice Smith" imap: host: imap.company.com port: 993 username: "alice@company.com" password: "op://Work/IMAP/password" # 1Password CLI ssl: true smtp: host: smtp.company.com port: 587 username: "alice@company.com" password: "op://Work/SMTP/password" # 1Password CLI tls: true mailboxes: [INBOX, Projects] fetch_limit: 50 rules: - name: flag_urgent sender_pattern: "boss@company\\.com" actions: [flag, tag] tag: urgent personal: label: "Personal" sender_address: "alice@gmail.com" imap: host: imap.gmail.com password: "keychain://imap.gmail.com/alice@gmail.com" # macOS Keychain smtp: host: smtp.gmail.com password: "keychain://smtp.gmail.com/alice@gmail.com" # macOS Keychain You can also define archive_root (e.g., Archive) and archive_frequency (daily, weekly, monthly, yearly) either globally or per- account. These defaults drive both the archive_mail.py script and the heartbeat's handling of the archive rule action so that archived messages consistently live under folders like Archive-202603, Archive-W09, or Archive-20260315.
Passwords in config support four backends: SchemeBackendExampleop://1Password CLI"op://Work/IMAP/password"keychain://macOS Keychain"keychain://imap.gmail.com/alice"env://Environment variable"env://GMAIL_APP_PASSWORD"(plain text)Literal value"my-password" (logs a warning)
For providers that require OAuth2, set auth: oauth2 on the IMAP/SMTP block: imap: host: imap.gmail.com username: "user@gmail.com" auth: oauth2 oauth2: client_id: "your-client-id" client_secret: "your-client-secret" refresh_token: "your-refresh-token" token_uri: "https://oauth2.googleapis.com/token"
Flat imap: / smtp: at root is automatically treated as a single account named "default".
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.