mail139
Original:🇺🇸 English
Translated
1 scripts
Read and send email via IMAP/SMTP. Check for new/unread messages, fetch content, search mailboxes, mark as read/unread, and send emails with attachments. Works with any IMAP/SMTP server including Gmail, Outlook, 163.com, vip.163.com, etc.
8installs
Sourcecshen/skills
Added on
NPX Install
npx skill4agent add cshen/skills mail139Tags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →mail139 — 139.com Email Downloader 📬
Download and search emails from 139.com via IMAP using pure Python stdlib. No pip installs needed.
Prerequisites
- — 139.com email address (e.g.
MAIL139_ID)you@139.com - — account password/token (fallbacks: prompt or
MAIL139_TOKEN)MAIL139_PASSWORD - If either is missing, stop and tell the user to set them:
bash
export MAIL139_ID="you@139.com" export MAIL139_TOKEN="your-password" - IMAP access must be enabled in the 139.com account settings (设置 → POP3/SMTP/IMAP)
Tool Location
The CLI script is bundled with this skill:
{baseDir}/mail139.pyAll commands follow the pattern:
bash
python3 {baseDir}/mail139.py -u "$MAIL139_ID" -p "$MAIL139_TOKEN" <command> [options]
# or simply rely on env defaults:
MAIL139_ID=you@139.com MAIL139_TOKEN=secret python3 {baseDir}/mail139.py <command> [options]When to Use This Skill
Activate when the user wants to:
- Read, check, or view emails from their 139.com inbox
- Download or save emails to disk
- Search emails by keyword or date
- List mailbox folders on 139.com
- Export emails as JSON or files
.eml - Save email attachments from 139.com
Trigger phrases: "check my 139 email", "read my 139.com inbox", "download emails from 139", "search my 139 mail", "list my 139 folders", "save emails from 139.com", "139邮箱", "中国移动邮箱", "check inbox"
Commands Reference
List Folders
bash
python3 {baseDir}/mail139.py -u "$MAIL139_ID" -p "$MAIL139_TOKEN" list-foldersLists all IMAP mailboxes/folders on the account. Run this first if the user wants to fetch from a non-INBOX folder and you don't know the exact folder name.
Folder names are decoded from IMAP modified UTF-7 (handles Chinese names); copy the exact output when passing .
--folderFetch Emails
bash
python3 {baseDir}/mail139.py -u "$MAIL139_ID" -p "$MAIL139_TOKEN" fetch [options]| Option | Default | Description |
|---|---|---|
| | IMAP folder to fetch from |
| | Max emails to fetch (newest first) |
| — | Only emails on or after this date |
| — | Filter by text in headers or body |
| | Output format: |
| — | Directory to save output files |
| off | Save attachments (defaults to |
| off | Mark fetched emails as read on the server |
For, files are written to--format eml. If--outputis omitted, the existing--outputdirectory is used. If~/Downloadsdoes not exist, the command exits with an error.~/Downloads
HTML bodies are converted to plain text via(if installed), elsehtml2text, else an internal stripper. No HTML tags appear in printed/JSON bodies.lynx --dump
Examples:
bash
# Print latest 10 emails to console
python3 {baseDir}/mail139.py -u "$MAIL139_ID" -p "$MAIL139_TOKEN" fetch
# Fetch last 20 emails as JSON
python3 {baseDir}/mail139.py -u "$MAIL139_ID" -p "$MAIL139_TOKEN" fetch \
--limit 20 --format json
# Save as JSON to a directory
python3 {baseDir}/mail139.py -u "$MAIL139_ID" -p "$MAIL139_TOKEN" fetch \
--format json -o ./emails
# Save raw .eml files and extract attachments
python3 {baseDir}/mail139.py -u "$MAIL139_ID" -p "$MAIL139_TOKEN" fetch \
--format eml --save-attachments -o ./emails
# Fetch from Sent folder since a date
python3 {baseDir}/mail139.py -u "$MAIL139_ID" -p "$MAIL139_TOKEN" fetch \
--folder "Sent Messages" --since "01-Jan-2025" --limit 50
# Search for emails containing a keyword
python3 {baseDir}/mail139.py -u "$MAIL139_ID" -p "$MAIL139_TOKEN" fetch \
--search "invoice" --format jsonOutput Format Details
text
textPrints each email to stdout with a header block (UID, Date, From, To, Subject, Attachments) and up to 2 000 characters of body text. Ideal for quick reading.
json
jsonProduces an array of objects. Each object has:
json
{
"uid": "1234",
"date": "Mon, 10 Mar 2025 09:00:00 +0800",
"from": "sender@example.com",
"to": "you@139.com",
"subject": "Hello",
"content_type": "text/plain",
"body": "Email body text…",
"attachments": ["report.pdf"]
}Written to inside , or printed to stdout if no is given.
emails.json--output--outputeml
emlSaves each email as — a raw RFC 822 file openable in any email client. Requires .
<uid>.eml--outputImportant Details
Date Format for --since
--sinceUse IMAP date format: — e.g. , .
DD-Mon-YYYY01-Jan-202515-Mar-2026Folder Names
139.com folder names may be in Chinese. Always run first if unsure. Common folders:
list-folders- — inbox (always English)
INBOX - — sent mail
Sent Messages - — drafts
Drafts - — trash
Deleted Messages
Attachment Saving
Attachments are saved to . If is not set, attachments default to . The flag works independently of . By default attachments are saved to ~/Downloads if is not specified.
<output>/<uid>_attachments/<filename>--output~/Downloads/<uid>_attachments/--save-attachments--output--outputRead-Only by Default
Without , the script opens the mailbox read-only and leaves no server-side trace. Pass only if the user explicitly asks to mark emails as read.
--mark-read--mark-readBehavioral Rules
- Always use to invoke the script.
python3 - Prefer env vars for credentials (,
$MAIL139_IDfallback$MAIL139_TOKEN) — never echo passwords in plain text in explanations.$MAIL139_PASSWORD - If or
MAIL139_IDare not set, stop and ask the user to export them before proceeding (or be ready to prompt for password).MAIL139_TOKEN - Default to for casual "check my email" requests; use
--format textwhen the user wants to process or save data; usejsonwhen they want to archive or open in an email client.eml - When the user asks to search, use for keyword filters and
--searchfor date filters; combine both when appropriate.--since - When the user asks for a specific folder, run first if you are unsure of the exact folder name.
list-folders - Do not use unless the user explicitly asks to mark emails as read.
--mark-read - After fetching JSON, parse and summarise the results for the user — don't just dump the raw JSON unless asked.
- If a command fails, read stderr and explain the issue in plain language (e.g. wrong password, IMAP not enabled, network error).
- For attachment tasks, works without
--save-attachments— attachments will be saved to--outputby default. Only set~/Downloads/<uid>_attachments/if the user wants a specific location.--output