HomeBrowseUpload
← Back to registry
// Skill profile

clawMail Skill

name: claw-mail

by borgcube · published 2026-03-22

邮件处理日历管理加密货币
Total installs
0
Stars
★ 0
Last updated
2026-03
// Install command
$ claw add gh:borgcube/borgcube-claw-mail
View on GitHub
// Full documentation

---

name: claw-mail

description: >

Multi-account email management skill for IMAP/SMTP. Fetches, reads, searches,

composes, sends, replies, forwards, and organizes emails across multiple accounts.

Features IMAP Outbox for reliable delivery, secure credential storage via 1Password

and macOS Keychain, TLS 1.2+ with hardened ciphers, OAuth2 authentication,

IMAP IDLE push monitoring, connection pooling, S/MIME signing, calendar invitations,

mail merge, conversation threading, webhook rule actions, and configurable

dated-folder archival.

license: MIT

metadata:

author: openclaw

version: "0.7.0"

compatibility: >

Requires Python 3.11+ and PyYAML. Optional: 1Password CLI (op) for op:// credentials,

macOS for keychain:// credentials, cryptography package for S/MIME.

allowed-tools: Bash(python3 *) Read Write

---

# clawMail Skill

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.

Multi-Account Model

  • **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`.

    Security

  • **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`).

    Available Scripts

    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.

    Core Scripts

    | Script | Purpose |

    |--------|---------|

    | `scripts/fetch_mail.py` | Fetch emails from an IMAP folder |

    | `scripts/read_mail.py` | Read/render an email by Message-ID; save attachments to disk |

    | `scripts/search_mail.py` | Search emails by subject, sender, body, date, flags |

    | `scripts/send_mail.py` | Send rich HTML emails via SMTP (Outbox + fallback); attach files |

    | `scripts/compose_mail.py` | Compose rich HTML emails from templates; attach files |

    | `scripts/reply_mail.py` | Reply to an email with original-message quoting |

    | `scripts/forward_mail.py` | Forward an email inline-quoted or with attachments |

    | `scripts/draft_mail.py` | Save, list, resume, or send drafts via IMAP Drafts folder |

    | `scripts/process_mail.py` | Run emails through the rule-based processing pipeline |

    | `scripts/manage_folders.py` | List, create, delete, rename, and move IMAP folders |

    | `scripts/move_mail.py` | Move emails between IMAP folders (batch support) |

    | `scripts/heartbeat.py` | Run a full heartbeat cycle (drains Outbox, fetches, processes) |

    | `scripts/idle_monitor.py` | Monitor a mailbox via IMAP IDLE (push notifications) |

    | `scripts/retry_send.py` | Retry sending messages stuck in the IMAP Outbox |

    | `scripts/calendar_invite.py` | Compose and send iCalendar meeting invitations |

    | `scripts/mail_merge.py` | Batch personalised sends from template + CSV/JSON data |

    | `scripts/thread_mail.py` | Group messages into conversation threads |

    | `scripts/archive_mail.py` | Auto-archive old messages into dated folders (daily/weekly/monthly/yearly) |

    Library Modules

    | Module | Purpose |

    |--------|---------|

    | `scripts/lib/imap_client.py` | IMAP client with IDLE, search, folder management, TLS 1.2+ |

    | `scripts/lib/smtp_client.py` | SMTP client with TLS 1.2+, RFC 5322, OAuth2, MIME building |

    | `scripts/lib/composer.py` | Rich HTML email composer with templates, reply, forward |

    | `scripts/lib/processor.py` | Rule-based processing pipeline with webhook actions |

    | `scripts/lib/account_manager.py` | Multi-account manager with SMTP fallback and Outbox |

    | `scripts/lib/outbox.py` | IMAP Outbox — temporary folder for reliable delivery |

    | `scripts/lib/credential_store.py` | Secure credential storage (1Password, Keychain, env) |

    | `scripts/lib/pool.py` | Connection pool for IMAP/SMTP reuse |

    | `scripts/lib/send_queue.py` | Legacy file-backed send queue (superseded by Outbox) |

    | `scripts/lib/smime.py` | S/MIME signing and encryption |

    | `scripts/lib/oauth2.py` | OAuth2 (XOAUTH2) token management |

    | `scripts/lib/models.py` | Data models (EmailMessage, EmailAddress, etc.) |

    Reference Documents

    | Reference | When to read |

    |-----------|-------------|

    | `references/REFERENCE.md` | API overview, all script arguments and output formats |

    | `references/TEMPLATES.md` | Available email templates and template variables |

    | `references/RULES.md` | How to configure processing rules |

    | `ROADMAP.md` | Feature roadmap and progress tracker |

    Quick Start

    Fetching Mail

    python3 scripts/fetch_mail.py --config config.yaml
    
    python3 scripts/fetch_mail.py --account personal --unread-only --format cli --config config.yaml

    Sending Rich Emails

    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

    Replying and Forwarding

    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

    Searching Emails

    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

    Working with Drafts

    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

    Outbox & Send Retry

    python3 scripts/retry_send.py --config config.yaml
    python3 scripts/retry_send.py --config config.yaml --list

    Heartbeat Cycle

    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

    Archiving Old Messages

    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.

    Calendar Invitations

    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

    Mail Merge

    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

    Configuration

    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`.

    Secure Credential Storage

    Passwords in config support four backends:

    | Scheme | Backend | Example |

    |--------|---------|---------|

    | `op://` | 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) |

    OAuth2 Authentication (Gmail, Outlook 365)

    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"

    Legacy Single-Account Config

    Flat `imap:` / `smtp:` at root is automatically treated as a single account

    named "default".

    // Comments
    Sign in with GitHub to leave a comment.
    // Related skills

    More tools from the same signal band