← Back to Skills Marketplace
tyxiang

ai-agent-email-skill

by Tyxiang · GitHub ↗ · v1.0.6 · MIT-0
cross-platform ✓ Security Clean
139
Downloads
1
Stars
0
Active Installs
7
Versions
Install in OpenClaw
/install ai-agent-email-skill
Description
This skill provides script-based email operations for an agent. It includes functionalities for managing mailboxes, reading/searching emails, sending/replyin...
README (SKILL.md)

\r \r

AI Agent Email Skill (aaes)\r

\r

Overview\r

\r This skill provides script-based email operations for an agent. It includes functionalities for managing mailboxes, reading/searching emails, sending/replying/forwarding emails, and managing attachments, allowing agents to perform comprehensive email-related tasks programmatically.\r \r

Features\r

\r

  • IMAP operations: Read, list, mark, move, delete, copy emails\r
  • SMTP operations: Send, reply, forward emails with attachments\r
  • Folder management: Create, delete, rename, list mailboxes\r
  • Dual-format bodies: Supports both plain-text and HTML, with automatic fallback generation\r
  • Attachment handling: Supports base64-encoded attachments\r
  • Multi-account support: Configure multiple accounts\r
  • Authentication: Password or OAuth2 via environment variables (auto-detected)\r
  • Signatures: Automatic signature appending to outgoing emails\r
  • Thread support: Proper In-Reply-To and References header handling\r \r

When to use\r

\r Use this skill when you need an agent to:\r \r

  • Check inbox for new emails and summarize them\r
  • Read specific emails and extract content\r
  • Send new emails with attachments\r
  • Reply to or forward emails\r
  • Organize emails by moving/copying between folders\r
  • Create or manage mailbox folders\r
  • Mark emails as read/unread, flagged, spam, or junk\r \r

Requirements\r

\r

  • Python 3.14+\r
  • IMAP/SMTP access to your email provider\r
  • Network access to email servers\r \r

Configuration\r

\r

Basic Setup\r

\r Configure this skill with ./scripts/config.toml:\r \r

  1. Copy ./config.default.toml to ./scripts/config.toml.\r
  2. Edit ./scripts/config.toml - fill in email address and server addresses.\r \r

Authentication Setup\r

\r Only one authentication method is required, configured via environment variables. \r \r Password-based authentication\r \r | Variable | Description |\r | ---------------- | ------------------------------------- |\r | EMAIL_USERNAME | Login username (required) |\r | EMAIL_PASSWORD | User password or app password |\r \r

# Linux/Mac\r
export EMAIL_USERNAME="me"\r
export EMAIL_PASSWORD="my-password"\r
\r
# Windows (PowerShell)\r
$env:EMAIL_USERNAME="me"\r
$env:EMAIL_PASSWORD="my-password"\r
\r
# Windows (CMD)\r
set EMAIL_USERNAME=me\r
set EMAIL_PASSWORD=my-password\r
```\r
\r
**OAuth2 authentication**\r
\r
| Variable                     | Description               |\r
| ---------------------------- | ------------------------- |\r
| `EMAIL_OAUTH2_CLIENT_ID`     | OAuth2 client ID          |\r
| `EMAIL_OAUTH2_CLIENT_SECRET` | OAuth2 client secret      |\r
| `EMAIL_OAUTH2_REFRESH_TOKEN` | OAuth2 refresh token      |\r
| `EMAIL_OAUTH2_TOKEN_URL`     | OAuth2 token endpoint URL |\r
\r
```bash\r
# Linux/Mac\r
export EMAIL_OAUTH2_CLIENT_ID="xxx"\r
export EMAIL_OAUTH2_CLIENT_SECRET="xxx"\r
export EMAIL_OAUTH2_REFRESH_TOKEN="xxx"\r
export EMAIL_OAUTH2_TOKEN_URL="https://oauth2.example.com/token"\r
\r
# Windows (PowerShell)\r
$env:EMAIL_OAUTH2_CLIENT_ID="xxx"\r
$env:EMAIL_OAUTH2_CLIENT_SECRET="xxx"\r
$env:EMAIL_OAUTH2_REFRESH_TOKEN="xxx"\r
$env:EMAIL_OAUTH2_TOKEN_URL="https://oauth2.example.com/token"\r
\r
# Windows (CMD)\r
set EMAIL_OAUTH2_CLIENT_ID=xxx\r
set EMAIL_OAUTH2_CLIENT_SECRET=xxx\r
set EMAIL_OAUTH2_REFRESH_TOKEN=xxx\r
set EMAIL_OAUTH2_TOKEN_URL="https://oauth2.example.com/token"\r
```\r
\r
### Test\r
\r
```bash\r
# Linux/Mac\r
echo '{"requestId":"test","schemaVersion":"1.0","data":{"maxResults":5}}' | python3 scripts/mail_list.py\r
\r
# Windows (PowerShell)\r
echo '{"requestId":"test","schemaVersion":"1.0","data":{"maxResults":5}}' | python scripts/mail_list.py\r
\r
# Windows (CMD)\r
echo "{\"requestId\":\"test\",\"schemaVersion\":\"1.0\",\"data\":{\"maxResults\":5}}" | python scripts/mail_list.py\r
```\r
\r
## Data Exchange Contract\r
\r
### Overview\r
\r
All scripts follow the same JSON-over-stdin contract:\r
\r
1. Agent sends one JSON object to stdin\r
2. Script writes one JSON object to stdout\r
3. Logs and diagnostics are written to stderr\r
\r
### Request Schema\r
\r
```json\r
{\r
  "requestId": "optional-trace-id",\r
  "schemaVersion": "1.0",\r
  "account": "optional-account-name-in-config",\r
  "data": {}\r
}\r
```\r
\r
### Success Response Schema\r
\r
```json\r
{\r
  "ok": true,\r
  "requestId": "same-as-request",\r
  "schemaVersion": "1.0",\r
  "data": {}\r
}\r
```\r
\r
### Error Response Schema\r
\r
```json\r
{\r
  "ok": false,\r
  "requestId": "same-as-request",\r
  "schemaVersion": "1.0",\r
  "error": {\r
    "code": "ERROR_CODE",\r
    "message": "Human-readable message",\r
    "details": {}\r
  }\r
}\r
```\r
\r
| Error Code             | Description                            |\r
| ---------------------- | -------------------------------------- |\r
| `VALIDATION_ERROR`     | Invalid input data or parameters       |\r
| `CONFIG_ERROR`         | Configuration file missing or invalid  |\r
| `AUTH_ERROR`           | Authentication failed                  |\r
| `NETWORK_ERROR`        | Network connection failed              |\r
| `MAIL_OPERATION_ERROR` | IMAP/SMTP operation failed             |\r
| `MAILBOX_ERROR`        | Mailbox selection or management failed |\r
| `INTERNAL_ERROR`       | Unexpected internal error              |\r
\r
## Scripts\r
\r
### `folder_create.py`\r
\r
Create mailbox folder.\r
\r
| Request fields |                  |\r
| -------------- | ---------------- |\r
| `name`         | string, required |\r
\r
| Response fields |                     |\r
| --------------- | ------------------- |\r
| `account`       | Account name used   |\r
| `name`          | Folder name created |\r
| `created`       | `true` on success   |\r
\r
### `folder_delete.py`\r
\r
Delete mailbox folder.\r
\r
| Request fields |                  |\r
| -------------- | ---------------- |\r
| `name`         | string, required |\r
\r
| Response fields |                     |\r
| --------------- | ------------------- |\r
| `account`       | Account name used   |\r
| `name`          | Folder name deleted |\r
| `deleted`       | `true` on success   |\r
\r
### `folder_list.py`\r
\r
List mailbox folders.\r
\r
| Request fields |     |\r
| -------------- | --- |\r
| (none)         |     |\r
\r
| Response fields |                         |\r
| --------------- | ----------------------- |\r
| `account`       | Account name used       |\r
| `mailboxes`     | Array of folder objects |\r
\r
### `folder_rename.py`\r
\r
Rename mailbox folder.\r
\r
| Request fields |                  |\r
| -------------- | ---------------- |\r
| `oldName`      | string, required |\r
| `newName`      | string, required |\r
\r
| Response fields |                      |\r
| --------------- | -------------------- |\r
| `account`       | Account name used    |\r
| `oldName`       | Original folder name |\r
| `newName`       | New folder name      |\r
| `renamed`       | `true` on success    |\r
\r
### `mail_copy.py`\r
\r
Copy email(s) between folders.\r
\r
| Request fields |                                    |\r
| -------------- | ---------------------------------- |\r
| `uids`         | string[] or comma-separated string |\r
| `sourceFolder` | optional, default `INBOX`          |\r
| `targetFolder` | required                           |\r
\r
| Response fields |                   |\r
| --------------- | ----------------- |\r
| `account`       | Account name used |\r
| `uids`          | UIDs copied       |\r
| `sourceFolder`  | Source folder     |\r
| `targetFolder`  | Target folder     |\r
| `copied`        | `true` on success |\r
\r
### `mail_delete.py`\r
\r
Delete email(s).\r
\r
| Request fields |                                    |\r
| -------------- | ---------------------------------- |\r
| `uids`         | string[] or comma-separated string |\r
| `folder`       | optional, default `INBOX`          |\r
| `expunge`      | boolean, default `false`           |\r
\r
| Response fields |                        |\r
| --------------- | ---------------------- |\r
| `account`       | Account name used      |\r
| `uids`          | UIDs deleted           |\r
| `folder`        | Folder name            |\r
| `deleted`       | `true` on success      |\r
| `expunged`      | `true` if hard deleted |\r
\r
### `mail_forward.py`\r
\r
Forward email with optional additions.\r
\r
| Request fields |                                          |\r
| -------------- | ---------------------------------------- |\r
| `uid`          | string, required                         |\r
| `folder`       | optional, default `INBOX`                |\r
| `to`           | string or string[], required             |\r
| `cc`           | optional                                 |\r
| `bcc`          | optional                                 |\r
| `bodyText`     | optional, prepended to forwarded content |\r
| `bodyHtml`     | optional                                 |\r
| `attachments`  | optional                                 |\r
\r
| Response fields |                    |\r
| --------------- | ------------------ |\r
| `account`       | Account name used  |\r
| `forwarded`     | `true` on success  |\r
| `uid`           | Original email UID |\r
| `to`            | Recipients         |\r
| `cc`            | CC recipients      |\r
| `subject`       | Forwarded subject  |\r
\r
Automatically includes original email and attachments.\r
\r
### `mail_mark.py`\r
\r
Mark email(s) with flags.\r
\r
| Request fields |                                                                                    |\r
| -------------- | ---------------------------------------------------------------------------------- |\r
| `uids`         | string[] or comma-separated string, required                                       |\r
| `markType`     | `read`, `unread`, `flag`, `unflag`, `spam`, `notspam`, `junk`, `notjunk`, required |\r
| `folder`       | optional, default `INBOX`                                                          |\r
\r
| Response fields |                   |\r
| --------------- | ----------------- |\r
| `account`       | Account name used |\r
| `uids`          | UIDs marked       |\r
| `markType`      | Mark type applied |\r
| `marked`        | `true` on success |\r
\r
### `mail_move.py`\r
\r
Move email(s) between folders.\r
\r
| Request fields |                                    |\r
| -------------- | ---------------------------------- |\r
| `uids`         | string[] or comma-separated string |\r
| `sourceFolder` | optional, default `INBOX`          |\r
| `targetFolder` | required                           |\r
\r
| Response fields |                   |\r
| --------------- | ----------------- |\r
| `account`       | Account name used |\r
| `uids`          | UIDs moved        |\r
| `sourceFolder`  | Source folder     |\r
| `targetFolder`  | Target folder     |\r
| `moved`         | `true` on success |\r
\r
### `mail_read.py`\r
\r
Read email content and metadata.\r
\r
| Request fields |                           |\r
| -------------- | ------------------------- |\r
| `uid`          | string, required          |\r
| `folder`       | optional, default `INBOX` |\r
\r
| Response fields |                           |\r
| --------------- | ------------------------- |\r
| `account`       | Account name used         |\r
| `uid`           | Email UID                 |\r
| `subject`       | Email subject             |\r
| `from`          | Sender                    |\r
| `to`            | Recipients                |\r
| `cc`            | CC recipients             |\r
| `date`          | Email date                |\r
| `bodyText`      | Plain text body           |\r
| `bodyHtml`      | HTML body                 |\r
| `attachments`   | Attachment list           |\r
| `tags`          | Combined flags and labels |\r
\r
Marks message as read after fetch.\r
\r
### `mail_reply.py`\r
\r
Reply to email.\r
\r
| Request fields |                           |\r
| -------------- | ------------------------- |\r
| `uid`          | string, required          |\r
| `folder`       | optional, default `INBOX` |\r
| `bodyText`     | optional                  |\r
| `bodyHtml`     | optional                  |\r
| `replyAll`     | boolean, default `false`  |\r
| `priority`     | `high`, `normal`, `low`   |\r
| `attachments`  | optional                  |\r
\r
| Response fields   |                                          |\r
| ----------------- | ---------------------------------------- |\r
| `account`         | Account name used                        |\r
| `uid`             | Original email UID                       |\r
| `folder`          | Original email folder                    |\r
| `sent`            | `true` on success                        |\r
| `to`              | Reply recipients                         |\r
| `cc`              | CC recipients                            |\r
| `attachmentCount` | Number of attachments                    |\r
| `priority`        | Priority level (`high`, `normal`, `low`) |\r
| `readReceipt`     | `true` if read receipt requested         |\r
| `inReplyTo`       | In-Reply-To message ID                   |\r
| `references`      | References header value                  |\r
| `subject`         | Reply subject                            |\r
\r
### `mail_list.py`\r
\r
List emails using IMAP search.\r
\r
| Request fields |                            |\r
| -------------- | -------------------------- |\r
| `query`        | optional, default `UNSEEN` |\r
| `folder`       | optional, default `INBOX`  |\r
| `maxResults`   | optional, default `10`     |\r
\r
| Response fields |                        |\r
| --------------- | ---------------------- |\r
| `account`       | Account name used      |\r
| `folder`        | Folder searched        |\r
| `query`         | Search query           |\r
| `uids`          | Matching UIDs          |\r
| `count`         | Results returned       |\r
| `totalCount`    | Total matches          |\r
| `hasMore`       | More results available |\r
| `summary`       | Email summaries        |\r
\r
| Query                   | Description      |\r
| ----------------------- | ---------------- |\r
| `UNSEEN`                | Unread messages  |\r
| `FROM [email protected]` | From sender      |\r
| `SUBJECT "keyword"`     | Subject contains |\r
| `SINCE 2024-01-01`      | Since date       |\r
| `ALL`                   | All messages     |\r
\r
### `mail_send.py`\r
\r
Send new email.\r
\r
| Request fields |                              |\r
| -------------- | ---------------------------- |\r
| `to`           | string or string[], required |\r
| `subject`      | string, required             |\r
| `bodyText`     | optional                     |\r
| `bodyHtml`     | optional                     |\r
| `cc`           | optional                     |\r
| `bcc`          | optional                     |\r
| `priority`     | `high`, `normal`, `low`      |\r
| `attachments`  | optional                     |\r
\r
| Response fields   |                                          |\r
| ----------------- | ---------------------------------------- |\r
| `account`         | Account name used                        |\r
| `sent`            | `true` on success                        |\r
| `to`              | Recipients                               |\r
| `cc`              | CC recipients                            |\r
| `bccCount`        | Number of BCC recipients                 |\r
| `attachmentCount` | Number of attachments                    |\r
| `priority`        | Priority level (`high`, `normal`, `low`) |\r
| `readReceipt`     | `true` if read receipt requested         |\r
| `inReplyTo`       | In-Reply-To message ID                   |\r
| `references`      | References header value                  |\r
| `subject`         | Sent subject                             |\r
\r
## Examples\r
\r
### List new emails\r
\r
```bash\r
echo '{"requestId":"test","schemaVersion":"1.0","data":{"maxResults":10}}' | python3 scripts/mail_list.py\r
```\r
\r
### Read email by UID\r
\r
```json\r
{ "requestId": "read", "schemaVersion": "1.0", "data": { "uid": "123" } }\r
```\r
\r
### List from sender\r
\r
```json\r
{\r
  "requestId": "search",\r
  "schemaVersion": "1.0",\r
  "data": { "query": "FROM [email protected]" }\r
}\r
```\r
\r
### Send email\r
\r
```json\r
{\r
  "requestId": "send",\r
  "schemaVersion": "1.0",\r
  "data": {\r
    "to": ["[email protected]"],\r
    "subject": "Hello",\r
    "bodyText": "Hello world!"\r
  }\r
}\r
```\r
\r
### Reply to email\r
\r
```json\r
{\r
  "requestId": "reply",\r
  "schemaVersion": "1.0",\r
  "data": { "uid": "123", "bodyText": "Thanks!" }\r
}\r
```\r
\r
### Mark and move\r
\r
```json\r
{"requestId":"mark","schemaVersion":"1.0","data":{"uids":"123","markType":"read"}}\r
{"requestId":"move","schemaVersion":"1.0","data":{"uids":"123","targetFolder":"Archive"}}\r
```\r
\r
## Troubleshooting\r
\r
### AUTH_ERROR\r
\r
- If password auth: Ensure both `EMAIL_USERNAME` and `EMAIL_PASSWORD` are set\r
- If OAuth2 auth: All four variables required: `EMAIL_OAUTH2_CLIENT_ID`, `EMAIL_OAUTH2_CLIENT_SECRET`, `EMAIL_OAUTH2_REFRESH_TOKEN`, `EMAIL_OAUTH2_TOKEN_URL`\r
- For 2FA accounts, use app password for `EMAIL_PASSWORD`\r
- OAuth2 takes priority if all four `EMAIL_OAUTH2_*` variables are set\r
\r
### NETWORK_ERROR\r
\r
- Verify IMAP port 993 (SSL) or 143 (STARTTLS)\r
- Verify SMTP port 465 (SSL) or 587 (STARTTLS)\r
- Check firewall settings\r
\r
### CONFIG_ERROR\r
\r
- Ensure `config.toml` exists and is valid TOML\r
- Check `email`, `imap.host`, `smtp.host` are configured\r
\r
### Security Warnings\r
\r
⚠️ **SSL Verification**: Setting `ssl_verify = false` in config disables certificate validation and exposes connections to man-in-the-middle attacks. Only disable for local development/testing.\r
\r
⚠️ **IMAP Injection Protection**: User-provided search queries are validated against a whitelist of safe commands. Custom queries containing `()";` characters will be rejected.\r
\r
### Debugging\r
\r
Check stderr for detailed error logs with `code`, `message`, and `details`.\r
Usage Guidance
This skill appears to be a straightforward email client implementation and requires access to your mailbox credentials (EMAIL_USERNAME and EMAIL_PASSWORD) or OAuth tokens. Before installing: only provide an app- or mailbox-scoped password (not a broad account credential), prefer OAuth and short-lived/rotatable tokens where possible, and ensure the ./scripts/config.toml contains only intended server/account entries. Note the skill can read and send email and — if allowed to run autonomously — could perform those actions without further confirmation. If you do not fully trust this skill's source, do not place primary/personal credentials in its environment; instead use a dedicated account or an app-specific password and limit network access to only necessary mail servers. Finally, be aware the SKILL metadata does not explicitly list the OAuth environment variables even though the code supports them; verify any environment variables you set are intentional.
Capability Analysis
Type: OpenClaw Skill Name: ai-agent-email-skill Version: 1.0.6 The email skill bundle provides a comprehensive and well-structured set of tools for IMAP and SMTP operations. It includes explicit security measures such as input validation for IMAP search queries and folder names (in scripts/common/validators.py) to prevent injection attacks, and it uses a strict regex for UID normalization (in scripts/common/parsers.py). The code follows standard practices for handling sensitive credentials via environment variables and supports OAuth2, with no evidence of data exfiltration, unauthorized execution, or malicious prompt injection.
Capability Assessment
Purpose & Capability
Name/description (email operations) match the code and declared requirements. The scripts implement IMAP/SMTP operations, folder management, attachments, and refer to an on-disk config for server details — all expected for an agent-driven email client.
Instruction Scope
SKILL.md and scripts constrain operations to reading/writing email via IMAP/SMTP and fetching OAuth tokens when configured. The runtime contract uses JSON-over-stdin/stdout. The scripts read only the declared config path and environment variables for credentials; there are no instructions to access unrelated local files or external endpoints beyond the OAuth token URL and the mail servers (which are required for the skill to work).
Install Mechanism
No install step is provided (instruction-only plus bundled Python scripts) so nothing is fetched from third-party URLs during install. The code uses only standard Python libraries; no external package downloads were observed in the provided files.
Credentials
The skill declares EMAIL_USERNAME and EMAIL_PASSWORD as required (primary credential EMAIL_PASSWORD), which is appropriate for password-based auth. The code also supports OAuth2 via EMAIL_OAUTH2_CLIENT_ID / SECRET / REFRESH_TOKEN / TOKEN_URL — these OAuth env vars are used by the code and documented in SKILL.md but are not listed in the openclaw 'requires.env' metadata. This is a metadata omission (not a functional mismatch), but users should be aware the skill can accept either plain password or OAuth-related environment variables.
Persistence & Privilege
always:false (normal) and disable-model-invocation:false (normal). The skill can be invoked autonomously by an agent (the platform default). Because it reads credentials and can send/read emails, granting it autonomous invocation gives it the ability to act on your mailbox without interactive approval — consider this sensitivity when enabling the skill.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install ai-agent-email-skill
  3. After installation, invoke the skill by name or use /ai-agent-email-skill
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.6
- Documentation updated to clarify that authentication is configured via environment variables. - No functional or code changes in this release.
v1.0.5
- Added EMAIL_USERNAME as a required environment variable in the skill metadata for password-based authentication. - Updated documentation to indicate EMAIL_USERNAME is required instead of optional.
v1.0.4
- Added configuration file requirement (`./scripts/config.toml`) to the skill metadata for improved environment setup clarity. - Updated metadata structure to explicitly indicate both required environment variables and configuration files. - No changes to code or functionality; documentation and metadata improvements only.
v1.0.3
- Added an optionalEnv section to metadata, clarifying which environment variables are optional for configuration. - No changes to code or functionality; documentation and metadata update only.
v1.0.2
**Version 1.0.2 Changelog** - Updated environment variable requirements and metadata to simplify password-based authentication. - Revised documentation in SKILL.md for improved clarity around authentication setup. - No functional or interface changes to IMAP or SMTP utility scripts.
v1.0.1
- Improved OAuth2 authentication handling: OAuth2 is now prioritized if all relevant variables are present, with new clarifications on configuration. - Updated required environment variables and metadata in SKILL.md for authentication setup. - Added explicit security warnings about `EMAIL_OAUTH2_TOKEN_URL`. - Revised SKILL.md instructions to clarify recommended authentication practices.
v1.0.0
AI Agent Email Skill 1.0.0 – Initial Release - Provides script-based operations for emails, including reading, searching, sending, replying, and managing attachments. - Supports mailbox/folder management such as create, delete, list, and rename. - Offers both password and OAuth2 authentication via environment variables. - Includes multi-account support and signature management for outgoing emails. - All scripts use a standardized JSON-over-stdin/stdout data contract with clear error codes.
Metadata
Slug ai-agent-email-skill
Version 1.0.6
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 7
Frequently Asked Questions

What is ai-agent-email-skill?

This skill provides script-based email operations for an agent. It includes functionalities for managing mailboxes, reading/searching emails, sending/replyin... It is an AI Agent Skill for Claude Code / OpenClaw, with 139 downloads so far.

How do I install ai-agent-email-skill?

Run "/install ai-agent-email-skill" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is ai-agent-email-skill free?

Yes, ai-agent-email-skill is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does ai-agent-email-skill support?

ai-agent-email-skill is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created ai-agent-email-skill?

It is built and maintained by Tyxiang (@tyxiang); the current version is v1.0.6.

💬 Comments