Send Email Skill
Send emails via SMTP from Claude Code. Supports plain text, HTML, attachments, and template-based workflow.
Execution Rule
Run the user's requested command directly without pre-checking dependencies, environment variables, or configuration. If something is wrong, the script will fail with a clear error — check and fix only then.
python scripts/send.py <to> <subject> <mode> <body> [attachment...]
Modes
| Mode | Purpose | Example Body |
|---|---|---|
--text |
Plain text email | "Just saying hi" |
--html |
Inline HTML string | "<b>Alert</b>" |
--file |
HTML from file | ~/.wmyskills/send-email/msg/my.html |
Long/complex HTML must use --file with a file inside ~/.wmyskills/send-email/msg/.
Examples
Plain text:
python scripts/send.py user@example.com "Hello" --text "Just saying hi"
Inline HTML (short):
python scripts/send.py user@example.com "Alert" --html "<b>Server is down</b>"
HTML from file (long/complex HTML):
python scripts/send.py user@example.com "Newsletter" --file ~/.wmyskills/send-email/msg/my_newsletter.html
With attachment (any mode):
python scripts/send.py user@example.com "Files" --text "See attached" report.pdf
Email Content Rules
Never add reply prompts in the email body. This skill is send-only and has no ability to receive or read emails. Do not include phrases like "reply to this email", "if you have any questions, feel free to reply", or any other wording that invites the recipient to respond by email — the response would go to an inbox nobody reads.
File Storage Rules
Violating these rules is a bug. Every email HTML file must go through the designated directories:
| Directory | Purpose |
|---|---|
~/.wmyskills/send-email/templates/ |
Read-only HTML templates. Copy from here, do not edit in place. |
~/.wmyskills/send-email/msg/ |
The ONLY directory for --file HTML files. Save here, then pass the path. |
Rules:
- All email HTML files must be saved in
~/.wmyskills/send-email/msg/before sending with--file - Do NOT save HTML in the repo directory, /tmp, Downloads, Desktop, or any other location
- Do NOT create a different directory structure — send.py discovers files relative to this path
- The repo stores code, not runtime data. Runtime data goes in
~/.wmyskills/<skill-name>/
Contacts
Send to a named recipient instead of a full email address. The name-to-address mapping lives in a user-editable YAML file:
~/.wmyskills/send-email/contacts.yaml (~ = user home directory)
小明: xiaoming@example.com
张三: zhangsan@example.com
Lookup rule: when the recipient is a name (not a full address containing
@), read this file and match the name exactly. Use the resolved email as the
<to> argument. Never guess or invent an address.
| Situation | Action |
|---|---|
Recipient contains @ |
Use as-is, no lookup |
| Name not found in file | Tell the user; list the available names from the file |
| File missing | Show the structure above and let the user create it, or use the address the user provided |
| YAML parse error | Ask the user to check the file format |
Security
Never read, display, or share the contents of scripts/.env or ~/.wmyskills/.env. They contain SMTP credentials. Use the table below only as a reference for which variables exist — do not read the actual .env files.
| Variable | Default | Description |
|---|---|---|
EMAIL_HOST |
— | SMTP server hostname |
EMAIL_PORT |
465 |
SMTP server port |
EMAIL_USER |
— | Sender email address |
EMAIL_AUTH |
— | SMTP password / app token |
EMAIL_NAME |
ClaudeCode |
Sender display name |
On Error
If sending fails:
Connection refused / timeout — EMAIL_HOST or EMAIL_PORT may be wrong; check with your provider.
Authentication failed — EMAIL_USER/EMAIL_AUTH may be wrong; some providers require an app-specific password.
smtplib exception — missing or incorrect env vars; SMTP exceptions are not caught and will print a traceback. Check EMAIL_HOST, EMAIL_USER, and EMAIL_AUTH are set correctly.
"file not found" / "attachment not found" — the path to the HTML file or attachment is invalid. Check the path and try again.
Notes
- Escape sequences (
\n,\t, etc.) in--textand--htmlbody arguments are decoded automatically - No
argparseis used — arguments are positional and order-sensitive - The
EMAIL_PORTdefaults to465(SSL); STARTTLS (587) is not supported - The
--filemode path supports~for home directory expansion