easy-agent-email

This skill provides script-based email operations for an agent. It includes functionalities for managing mailboxes, reading/searching emails, sending/replyin...

MIT-0 · Free to use, modify, and redistribute. No attribution required.
0 · 32 · 0 current installs · 0 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
Name/description match the code and SKILL.md: all scripts implement mailbox/IMAP and SMTP operations (list, read, send, reply, forward, move, delete, folder management). Nothing requested by the skill (no unrelated cloud creds, binaries, or system paths) is disproportionate to an email client skill. Note: package origin is unknown (no homepage), but functionality itself is coherent.
Instruction Scope
Runtime instructions are narrow and explicit: copy config.sample.toml to scripts/config.toml and provide account credentials; scripts accept JSON via stdin and return JSON on stdout. The scripts read only the local config file and communicate with IMAP/SMTP servers and, when using OAuth2, the token URL supplied in the config. There are no instructions to read unrelated host files or to post data to unexpected third-party endpoints.
Install Mechanism
No install spec; this is an instruction-plus-scripts package. All code ships with the skill bundle—there are no remote downloads or archive extraction steps in the install phase. That reduces supply-chain risk compared with remote installs, though running the included Python will execute code from an unverified source.
Credentials
The skill requests no platform environment variables but requires storing email credentials (username/password, app-password, or OAuth2 refresh token/client secret) in scripts/config.toml. This is appropriate for an email skill but means sensitive secrets live in a local file: ensure config.toml is protected and not committed to VCS. The OAuth2 token flow uses the token_url/client_secret/refresh_token from config—expected behavior for OAuth2-enabled accounts.
Persistence & Privilege
always is false and the skill does not request to modify other skills or global agent settings. Model invocation is allowed (platform default) — the skill can be invoked autonomously by the agent if the agent's policy allows it; this is normal for skills and not a defect by itself.
Assessment
This skill appears to do exactly what it says: programmatic IMAP/SMTP mailbox operations. Before using it, review and protect the configuration file (scripts/config.toml) because it will contain email credentials (passwords or OAuth refresh tokens and client secrets). Use a throwaway or test account the first time to validate behavior. Because the source/publisher and homepage are missing, prefer running the scripts in an isolated environment (or container) and manually inspect the code (common.py and the mail/*.py scripts) for anything you don't expect. If you enable OAuth2, double-check the token_url in your config points to the legitimate provider. Finally, ensure config.toml is .gitignored and never include production credentials until you trust the code and its origin.

Like a lobster shell, security has layers — review code before you run it.

Current versionv1.0.0
Download zip
latestvk979vk1eqd51wdmx588m68488s83pv7j

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

SKILL.md

easy-agent-email

1. Overview

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.

2. Configuration

Configure this skill with ./scripts/config.toml. Configuration method see ./scripts/config.sample.toml.

  • Start from ./scripts/config.sample.toml and copy it to ./scripts/config.toml.
  • Fill in a real account entry in config.toml before using the skill.

3. Data Exchange Contract

3.1. Overview

All scripts follow the same JSON-over-stdin contract:

  1. Agent sends one JSON object to stdin.
  2. Script writes one JSON object to stdout.
  3. Logs and diagnostics are written to stderr.

3.2. Request Schema

{
  "requestId": "optional-trace-id",
  "schemaVersion": "1.0",
  "account": "optional-account-name-in-config",
  "data": {}
}

3.3. Success Response Schema

{
  "ok": true,
  "requestId": "same-as-request",
  "schemaVersion": "1.0",
  "data": {}
}

Response data field definitions in this document describe possible fields; fields that are not applicable to a specific operation may be omitted.

3.4. Error Response Schema

{
  "ok": false,
  "requestId": "same-as-request",
  "schemaVersion": "1.0",
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Human-readable message",
    "details": {}
  }
}

4. Scripts

4.1. Overview

All scripts are under scripts/.

4.2. folder_create.py

Create mailbox.

Request data fields:

  • name: string, required

Response data fields:

  • account: string - Account name used
  • name: string - Mailbox name created
  • created: boolean - true on success

4.3. folder_delete.py

Delete mailbox.

Request data fields:

  • name: string, required

Response data fields:

  • account: string - Account name used
  • name: string - Mailbox name deleted
  • deleted: boolean - true on success

4.4. folder_list.py

List mailboxes.

Request data fields: none ({}).

Response data fields:

  • account: string - Account name used
  • mailboxes: array of objects - Parsed mailbox list
    • name: string - Mailbox name
    • delimiter: string or null - Hierarchy delimiter reported by server
    • flags: string[] - IMAP LIST flags (e.g., \HasNoChildren, \Noselect)
    • raw: string - Original LIST row for diagnostics/compatibility

4.5. folder_rename.py

Rename mailbox.

Request data fields:

  • oldName: string, required
  • newName: string, required

Response data fields:

  • account: string - Account name used
  • oldName: string - Original mailbox name
  • newName: string - New mailbox name
  • renamed: boolean - true on success

4.6. mail_copy.py

Copy email(s) from one mailbox to another.

Request data fields:

  • uids: string[] or comma-separated string, required
  • sourceFolder: string, optional, default INBOX
  • targetFolder: string, required

Response data fields:

  • account: string - Account name used
  • uids: string[] - UIDs copied
  • sourceFolder: string - Source mailbox name
  • targetFolder: string - Target mailbox name
  • copied: boolean - true on success

4.7. mail_delete.py

Delete email(s).

Request data fields:

  • uids: string[] or comma-separated string, required
  • folder: string, optional, default INBOX
  • expunge: boolean, optional, default false (soft delete)

Response data fields:

  • account: string - Account name used
  • uids: string[] - UIDs deleted
  • folder: string - Mailbox name used
  • deleted: boolean - true on success
  • expunged: boolean - true if hard delete (expunge) was performed; otherwise false.

4.8. mail_forward.py

Forward email with optional additional body and attachments.

Behavior notes:

  • If bodyHtml is provided without bodyText, the script derives a plain-text fallback automatically.
  • When the original message contains HTML, the forwarded message preserves an HTML body alongside the plain-text forwarded content whenever possible.

Request data fields:

  • uid: string, required
  • folder: string, optional, default INBOX
  • to: string or string[], required
  • cc: string or string[], optional
  • bcc: string or string[], optional
  • bodyText: string, optional (prepended to forwarded content)
  • bodyHtml: string, optional
  • attachments: array of { filename: string, contentBase64: string }, optional

Response data fields:

  • account: string - Account name used
  • forwarded: boolean - true on success
  • uid: string - UID of original email
  • sourceFolder: string - Source mailbox name
  • to: string[] - Recipient list
  • cc: string[] - CC recipient list
  • bccCount: integer - Number of BCC recipients
  • subject: string - Forwarded subject (with Fwd: prefix)
  • originalAttachmentCount: integer - Number of original attachments
  • additionalAttachmentCount: integer - Number of additional attachments

Automatically includes original email and attachments in forwarded message.

4.9. mail_mark.py

Mark email(s) with various flags.

Request data fields:

  • uids: string[] or comma-separated string, required
  • markType: string, optional, default read. Allowed values:
    • read: Mark as read (\Seen flag)
    • unread: Mark as unread (remove \Seen flag)
    • flag: Add star/flag (\Flagged flag)
    • unflag: Remove star/flag
    • spam: Mark as spam (\Spam flag)
    • notspam: Mark as not spam
    • junk: Mark as junk (\Junk flag)
    • notjunk: Mark as not junk
  • folder: string, optional, default INBOX

Response data fields:

  • account: string - Account name used
  • uids: string[] - UIDs marked
  • folder: string - Mailbox name used
  • markType: string - Mark type applied
  • flag: string - IMAP flag name
  • marked: boolean - true on success

4.10. mail_move.py

Move email(s) from one mailbox to another.

Request data fields:

  • uids: string[] or comma-separated string, required
  • sourceFolder: string, optional, default INBOX
  • targetFolder: string, required

Response data fields:

  • account: string - Account name used
  • uids: string[] - UIDs moved
  • sourceFolder: string - Source mailbox name
  • targetFolder: string - Target mailbox name
  • moved: boolean - true on success

4.11. mail_read.py

Read email content and metadata.

Behavior notes:

  • If an attachment cannot be decoded, the script returns a structured MAIL_OPERATION_ERROR instead of an internal crash.

Request data fields:

  • uid: string, required
  • folder: string, optional, default INBOX

This command attempts to mark the message as read (\Seen) after successful fetch. If marking as read fails, the script will return an error and no content will be returned.

Response data fields:

  • account: string - Account name used
  • uid: string - Email UID
  • folder: string - Mailbox name used
  • subject: string - Email subject
  • from: string - Sender address
  • to: string - Recipient addresses
  • cc: string - CC addresses (empty if not present)
  • date: string - Email date header value
  • messageId: string - Email Message-ID
  • bodyText: string - Plain text body (null if no text body)
  • bodyHtml: string - HTML body (null if no HTML body)
  • attachments: array of { filename: string, contentBase64: string, size: integer } - Attachment list
  • attachmentCount: integer - Number of attachments
  • flags: string[] - Raw IMAP flags reported by server
  • systemTags: string[] - System flags such as \Seen, \Answered, \Flagged
  • keywords: string[] - Non-system IMAP keywords/tags
  • gmailLabels: string[] - Gmail labels when server supports X-GM-LABELS
  • tags: string[] - Combined deduplicated list of flags and labels

4.12. mail_reply.py

Reply email.

Behavior notes:

  • If bodyHtml is provided without bodyText, the script derives a plain-text fallback automatically.
  • The script keeps quoted original content aligned between the plain-text and HTML reply bodies whenever possible.

Request data fields:

  • uid: string, required
  • folder: string, optional, default INBOX
  • bodyText: string, optional
  • bodyHtml: string, optional
  • replyAll: boolean, optional, default false
  • priority: string, optional, default normal. Allowed: high, normal, low
  • readReceipt: boolean, optional, default false
  • inReplyTo: string, optional (overrides auto-generated reply thread header)
  • references: string, optional (overrides auto-generated references header)
  • attachments: array of { filename: string, contentBase64: string }, optional

Response data fields:

  • account: string - Account name used
  • uid: string - UID of original email
  • folder: string - Mailbox name used
  • sent: boolean - true on success
  • to: string[] - Reply recipients
  • cc: string[] - CC recipients
  • attachmentCount: integer - Number of attachments sent
  • priority: string - Priority applied
  • readReceipt: boolean - Read receipt setting applied
  • inReplyTo: string - In-Reply-To header used
  • references: string - References header used
  • subject: string - Reply subject (with Re: prefix)

4.13. mail_list.py

List emails using IMAP search query.

Request data fields:

  • query: string, optional, default UNSEEN (IMAP search syntax, e.g., "FROM user@example.com", "SUBJECT test", "ALL")
  • folder: string, optional, default INBOX
  • maxResults: integer, optional, default 10

The script first tries UID SEARCH CHARSET UTF-8 <query>, then falls back to UID SEARCH <query> for compatibility.

Response data fields:

  • account: string - Account name used
  • folder: string - Mailbox name searched
  • query: string - Search query executed
  • uids: string[] - Matching email UIDs
  • count: integer - Number of results returned
  • totalCount: integer - Total number of matches before limiting by maxResults
  • hasMore: boolean - true if more results exist beyond maxResults
  • summary: array - Summary list:
    • uid: string
    • subject: string
    • from: string
    • date: string
    • flags: string[] - Raw IMAP flags reported by server
    • systemTags: string[] - System flags such as \Seen, \Answered, \Flagged
    • keywords: string[] - Non-system IMAP keywords/tags
    • gmailLabels: string[] - Gmail labels when server supports X-GM-LABELS
    • tags: string[] - Combined deduplicated list of flags and labels

4.14. mail_send.py

Send a new email.

Behavior notes:

  • If both bodyText and bodyHtml are provided, clients typically display the HTML part and keep the text part as a compatibility fallback.
  • If only bodyHtml is provided, the script derives a plain-text fallback automatically.

Request data fields:

  • to: string or string[], required
  • subject: string, required
  • bodyText: string, optional
  • bodyHtml: string, optional
  • cc: string or string[], optional
  • bcc: string or string[], optional
  • from: string, optional, defaults to account email
  • priority: string, optional, default normal. Allowed: high, normal, low
  • readReceipt: boolean, optional, default false
  • inReplyTo: string, optional
  • references: string, optional
  • attachments: array of { filename: string, contentBase64: string }, optional

Response data fields:

  • account: string - Account name used
  • sent: boolean - true on success
  • to: string[] - Recipient list
  • cc: string[] - CC recipient list
  • bccCount: integer - Number of BCC recipients
  • attachmentCount: integer - Number of attachments sent
  • priority: string - Priority applied
  • readReceipt: boolean - Read receipt setting applied
  • inReplyTo: string - In-Reply-To header used
  • references: string - References header used
  • subject: string - Sent email subject

5. Examples

Suppose the mailbox is already configured.

Windows PowerShell

# List new emails
@'
{"requestId":"req-list","schemaVersion":"1.0","data":{"maxResults":10}}
'@ | python scripts/mail_list.py

# Read the new email with UID `2`
@'
{"requestId":"req-read","schemaVersion":"1.0","data":{"uid":"2"}}
'@ | python scripts/mail_read.py

# Reply to the new email with UID `2`
@'
{"requestId":"req-reply","schemaVersion":"1.0","data":{"uid":"2","bodyText":"Thanks. Received and noted."}}
'@ | python scripts/mail_reply.py

Linux/Mac Terminal

# List new emails
echo '{"requestId":"req-list","schemaVersion":"1.0","data":{"maxResults":10}}' | python3 scripts/mail_list.py

# Read the new email with UID `2`
echo '{"requestId":"req-read","schemaVersion":"1.0","data":{"uid":"2"}}' | python3 scripts/mail_read.py

# Reply to the new email with UID `2`
echo '{"requestId":"req-reply","schemaVersion":"1.0","data":{"uid":"2","bodyText":"Thanks. Received and noted."}}' | python3 scripts/mail_reply.py

Files

17 total
Select a file
Select a file to preview.

Comments

Loading comments…