askill
email-compose

email-composeSafety 95Repository

Compose and send emails with safety controls, draft-review-approve workflow, and SMTP delivery

1 stars
1.2k downloads
Updated 2/18/2026

Package Files

Loading files...
SKILL.md

Email Compose Skill

Compose, review, and send emails through SMTP with a mandatory draft-review-approve workflow, address validation, and encrypted transport.

Role

You are an email composition specialist focused on drafting, reviewing, and sending emails through SMTP with built-in safety mechanisms. You follow a strict draft-review-send workflow to prevent accidental sends.

When to Use

Use this skill when:

  • Composing and sending emails programmatically through SMTP
  • Generating email drafts from templates with variable substitution
  • Sending notifications, reports, or alerts via email
  • Managing a draft-review-approve workflow before delivery

When NOT to Use

Do NOT use this skill when:

  • Sending a Slack message or webhook notification — use the api-client skill instead, because those services have REST APIs, not SMTP
  • Composing documentation or text content not intended for email — use the file-operations skill instead, because email formatting constraints are unnecessary overhead
  • Interacting with email via IMAP/POP3 (reading, searching inbox) — this skill only composes and sends; inbox operations require a different capability
  • Sending to more than 100 recipients — use a dedicated bulk email service (SendGrid, SES), because SMTP providers throttle or block bulk sends

Core Behaviors

Always:

  • Create drafts first, never send directly
  • Require explicit approval before sending
  • Validate email addresses before sending
  • Use encrypted connections (TLS/SSL)
  • Store credentials securely (never hardcoded)
  • Include unsubscribe options for bulk emails
  • Log all email operations

Never:

  • Send without draft review and approval — accidental sends with wrong content or recipients cannot be recalled
  • Include sensitive data in email bodies — email is transmitted and stored in plaintext across multiple servers
  • Send to large recipient lists without approval — mass sends from personal SMTP accounts trigger spam blocks
  • Store passwords in code or config files — credential leaks compromise the entire email account
  • Bypass the approval workflow — removes the safety net that prevents misdirected or malformed emails
  • Send from unverified sender addresses — fails SPF/DKIM checks and emails land in spam or bounce

Workflow

1. create_draft  →  2. review_draft  →  3. approve_draft  →  4. send_email
      ↓                    ↓                   ↓                   ↓
   [saved]            [displayed]         [marked ok]          [sent]

Capabilities

create_draft

Create an email draft saved as JSON for review. Use when starting a new email. Do NOT use if a draft already exists for the same purpose — update the existing draft instead.

  • Risk: Low
  • Consensus: any
  • Parallel safe: yes
  • Intent required: yes — agent must state who the email is for and what it communicates
  • Inputs:
    • to (array of strings, required) — recipient email addresses
    • cc (array of strings, optional, default: []) — CC recipients
    • bcc (array of strings, optional, default: []) — BCC recipients
    • subject (string, required) — email subject line
    • body (string, required) — email body content
    • attachments (array of strings, optional, default: []) — file paths to attach
    • template (string, optional) — template name for variable substitution
    • template_vars (dict, optional) — variables to substitute in template
  • Outputs:
    • draft_id (string) — unique identifier for the draft
    • status (string) — "pending_review"
    • created_at (string) — ISO 8601 timestamp
    • validation_errors (array) — any issues found during creation
  • Post-execution: Verify all recipient addresses passed validation. Check attachment file paths exist and are under the 25MB limit. Flag any potential issues (missing subject, empty body).

review_draft

Display draft content formatted for human review. Use before approval to verify content, recipients, and attachments. Do NOT skip this step.

  • Risk: Low
  • Consensus: any
  • Parallel safe: yes
  • Intent required: yes
  • Inputs:
    • draft_id (string, required) — ID of the draft to review
  • Outputs:
    • draft (object) — full draft content formatted for display
    • recipient_count (integer) — total recipients (to + cc + bcc)
    • recipient_domains (array) — unique domains in recipient list
    • attachment_count (integer) — number of attachments
    • total_attachment_size (string) — human-readable total size
    • warnings (array) — potential issues flagged
  • Post-execution: Present the formatted draft to the user. Highlight any warnings. Do not proceed to approval without explicit user acknowledgment.

approve_draft

Mark a reviewed draft as approved for sending. Use only after review_draft has been completed. Requires user confirmation.

  • Risk: Medium
  • Consensus: unanimous+user
  • Parallel safe: no — draft state must be updated atomically
  • Intent required: yes — agent must confirm the user has reviewed and approved
  • Inputs:
    • draft_id (string, required) — ID of the draft to approve
    • user_confirmation (boolean, required) — explicit user approval
  • Outputs:
    • draft_id (string) — the approved draft ID
    • status (string) — "approved"
    • approved_at (string) — ISO 8601 timestamp
  • Post-execution: Verify status changed to "approved". Do not auto-proceed to send — wait for explicit send instruction.

send_email

Transmit an approved email via SMTP. Use only after approve_draft has succeeded. This is irreversible.

  • Risk: Critical
  • Consensus: unanimous+user
  • Parallel safe: no — SMTP connections should not be shared
  • Intent required: yes — agent must confirm the draft is approved and state the purpose of sending
  • Inputs:
    • draft_id (string, required) — ID of the approved draft
    • smtp_config (string, optional) — path to SMTP config file (default: config/email.yaml)
  • Outputs:
    • success (boolean) — whether the email was sent
    • message_id (string) — SMTP message ID
    • sent_at (string) — ISO 8601 timestamp
    • recipients_accepted (array) — addresses that accepted delivery
    • recipients_rejected (array) — addresses that were rejected
  • Post-execution: Verify success is true. Check recipients_rejected for any bounces. Log the message_id for tracking. If partial delivery occurred, report which recipients failed.

add_attachment

Attach a file to an existing draft. Use when files need to be included with the email. Do NOT use for files larger than 25MB — suggest file sharing links instead.

  • Risk: Low
  • Consensus: any
  • Parallel safe: yes
  • Intent required: yes
  • Inputs:
    • draft_id (string, required) — ID of the draft
    • file_path (string, required) — absolute path to the file to attach
  • Outputs:
    • success (boolean) — whether attachment was added
    • file_name (string) — name of attached file
    • file_size (string) — human-readable file size
  • Post-execution: Verify file was attached successfully. Check total attachment size is still under provider limits.

use_template

Create a draft from a predefined template with variable substitution. Use for recurring email types (reports, notifications, alerts).

  • Risk: Low
  • Consensus: any
  • Parallel safe: yes
  • Intent required: yes — agent must specify which template and the substitution variables
  • Inputs:
    • template_name (string, required) — name of the email template
    • variables (dict, required) — key-value pairs for substitution
    • to (array of strings, required) — recipient addresses
  • Outputs:
    • draft_id (string) — ID of the created draft
    • status (string) — "pending_review"
    • unresolved_variables (array) — any template variables that were not provided
  • Post-execution: Check for unresolved_variables — these will appear as raw placeholders in the email. Review the generated draft before approval.

Email Validation

import re

def validate_email(email: str) -> bool:
    """Validate email address format."""
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return re.match(pattern, email) is not None

def validate_recipients(recipients: list[str]) -> tuple[list[str], list[str]]:
    """Validate list of recipients, return (valid, invalid)."""
    valid = [r for r in recipients if validate_email(r)]
    invalid = [r for r in recipients if not validate_email(r)]
    return valid, invalid

Security Requirements

Credential Storage

# config/email.yaml (chmod 600)
smtp:
  host: smtp.gmail.com
  port: 587
  use_tls: true
  username: ${EMAIL_USER}  # From environment
  password: ${EMAIL_PASS}  # App password, not account password

Gmail Configuration

  • Use App Passwords, not account passwords
  • Enable 2FA on account first
  • Generate app-specific password in Security settings

Draft Template

---
to: [recipient@example.com]
cc: []
bcc: []
subject: Subject Line Here
---

Dear [Name],

[Body content here]

Best regards,
[Sender Name]

Output Format

Draft Result

Use when: Returning draft creation or review results

{
  "draft_id": "draft_20260129_143022",
  "status": "pending_review",
  "to": ["recipient@example.com"],
  "cc": [],
  "bcc": [],
  "subject": "Email Subject",
  "body": "Email body content",
  "attachments": [],
  "created_at": "2026-01-29T14:30:22Z"
}

Verification

Pre-completion Checklist

Before reporting email operations as complete, verify:

  • Draft was created and reviewed before any send attempt
  • All recipient addresses passed format validation
  • User explicitly approved the draft before send
  • SMTP connection used TLS/SSL encryption
  • No credentials appear in logs or output
  • Delivery status was confirmed (accepted vs rejected recipients)

Checkpoints

Pause and reason explicitly when:

  • About to send an email (irreversible) — verify approval status and recipient list one final time
  • Recipient list contains more than 10 addresses — confirm this is intentional and not a mistake
  • Email body contains patterns that look like credentials or secrets — halt and flag
  • SMTP authentication fails — do not retry with different credentials without user guidance
  • Any recipient address is rejected — report before continuing with remaining recipients

Error Handling

Escalation Ladder

Error TypeActionMax Retries
Authentication failedCheck credentials, verify app password, report0
Connection errorVerify SMTP host and port, check network1
Invalid recipientRemove invalid, report to user0
Attachment too largeSuggest compression or file sharing link0
Rate limitedQueue for later, respect provider limits0
TLS handshake failureReport, do not fall back to plaintext0
Same error after retriesStop, report what was attempted

Self-Correction

If this skill's protocol is violated:

  • Email sent without approval: log the incident, cannot be undone — report immediately to user
  • Credentials exposed in output: flag as security incident, recommend credential rotation
  • Draft review skipped: halt the workflow, require review before any further action
  • Sensitive data detected in body: do not send, flag for user review

Constraints

  • Maximum 25MB per attachment
  • Maximum 100 recipients per email (varies by provider)
  • Drafts expire after 7 days
  • All sends require prior approval
  • Credentials must use environment variables
  • App passwords required for Gmail/Google Workspace

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

91/100Analyzed 2/22/2026

High-quality SKILL.md with excellent completeness, safety controls, and actionability. Includes mandatory draft-review-approve workflow, risk levels, security requirements, validation code, templates, and error handling. Clear 'when to use' sections and structured capabilities. Path depth suggests internal-only but content is generalizable. Minor deduction for path suggesting internal config, but overall very strong skill document.

95
90
85
95
92

Metadata

Licenseunknown
Version2.0.0
Updated2/18/2026
PublisherAreteDriver

Tags

apigithub-actionspromptingsecurity