{
  "schemaVersion": "1.0",
  "item": {
    "slug": "mail-client",
    "name": "Mail Client",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/Romain-Grosos/mail-client",
    "canonicalUrl": "https://clawhub.ai/Romain-Grosos/mail-client",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/mail-client",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=mail-client",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md",
      "config.example.json",
      "references/troubleshooting.md",
      "scripts/_retry.py",
      "scripts/init.py"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/mail-client"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/mail-client",
    "agentPageUrl": "https://openagent3.xyz/skills/mail-client/agent",
    "manifestUrl": "https://openagent3.xyz/skills/mail-client/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/mail-client/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "mail-client",
        "body": "IMAP read/search + SMTP send for any standard mail server.\nPython stdlib only, zero external dependencies."
      },
      {
        "title": "Trigger phrases",
        "body": "\"check my email\"\n\"do I have unread messages\"\n\"read the email from Alice\"\n\"search emails about invoice\"\n\"send an email to Bob\"\n\"move that email to the Archive folder\"\n\"mark that as read\"\n\"delete that message\"\n\"list my mail folders\""
      },
      {
        "title": "Quick Start",
        "body": "python3 scripts/setup.py   # interactive setup: credentials + permissions\npython3 scripts/init.py    # validate all configured capabilities\npython3 scripts/mail.py config  # show current config (no secrets)"
      },
      {
        "title": "1. Run setup wizard",
        "body": "python3 scripts/setup.py\n\nThe wizard collects:\n\nSMTP host/port, IMAP host/port\nMail user and app key (application password)\nWhich capabilities to enable (all false by default)\nDefault folder and max results"
      },
      {
        "title": "2. Validate",
        "body": "python3 scripts/init.py\n\nExpected output: all checks OK or SKIP (none FAIL)."
      },
      {
        "title": "3. Enable capabilities in config.json",
        "body": "Edit ~/.openclaw/config/mail-client/config.json:\n\n{\n  \"allow_send\": true,\n  \"allow_read\": true,\n  \"allow_search\": true,\n  \"allow_delete\": false,\n  \"smtp_port\": 587,\n  \"imap_port\": 993,\n  \"mail_from\": \"you@example.com\",\n  \"default_folder\": \"INBOX\",\n  \"max_results\": 20\n}"
      },
      {
        "title": "Storage and credentials",
        "body": "PathWritten byPurposeContains secrets~/.openclaw/secrets/mail_credssetup.pySMTP/IMAP credentials + app keyYES - chmod 600, never committed~/.openclaw/config/mail-client/config.jsonsetup.pyBehavior restrictions, folder/limit defaultsNO - behavior only, not in skill dir - survives clawhub updates"
      },
      {
        "title": "~/.openclaw/secrets/mail_creds",
        "body": "Written by setup.py, chmod 600, never committed to git. Contains:\n\nMAIL_SMTP_HOST=mail.example.com\nMAIL_IMAP_HOST=mail.example.com\nMAIL_USER=user@example.com\nMAIL_APP_KEY=app-password-here\n\nPorts (smtp_port, imap_port) and sender address (mail_from) are set in config.json - they are configuration, not credentials.\n\nCredentials can also be provided via environment variables (MAIL_USER, MAIL_APP_KEY, MAIL_SMTP_HOST, MAIL_IMAP_HOST). Environment variables take precedence over file values. The skill checks env vars first, then falls back to the creds file."
      },
      {
        "title": "~/.openclaw/config/mail-client/config.json",
        "body": "Written by setup.py. Controls behavior restrictions (which capabilities are enabled).\nContains no secrets. Not in the skill directory - survives clawhub updates.\nStart from config.example.json in the skill dir if you prefer to create it manually.\n\nCleanup on uninstall: clawhub uninstall mail-client removes the skill directory. To also remove credentials and config:\n\npython3 scripts/setup.py --cleanup\n\nOn reinstall, any existing config at ~/.openclaw/config/mail-client/config.json is picked up automatically."
      },
      {
        "title": "Module usage",
        "body": "Import MailClient directly in Python:\n\nfrom scripts.mail import MailClient\n\nclient = MailClient()\n\n# List 5 unread messages\nmsgs = client.list_messages(limit=5, unseen_only=True)\nfor m in msgs:\n    print(m[\"from\"], m[\"subject\"])\n\n# Read a message\nmsg = client.read_message(\"42\")\nprint(msg[\"body\"])\n\n# Send a message\nresult = client.send(\n    to=\"alice@example.com\",\n    subject=\"Hello\",\n    body=\"Hi Alice, how are you?\",\n)\nprint(result)\n\n# Send with attachments\nresult = client.send(\n    to=\"alice@example.com\",\n    subject=\"Report Q1\",\n    body=\"Please find attached the Q1 report.\",\n    attachments=[\"report.pdf\", \"data.xlsx\"],\n)\nprint(result)\n\n# Search\nfound = client.search_messages(from_addr=\"bob@example.com\", unseen_only=True)"
      },
      {
        "title": "CLI reference",
        "body": "python3 scripts/mail.py <subcommand> [options]\n\nSubcommandRequiresDescriptionlistallow_readList messages (newest first)read <uid>allow_readRead a full message by UIDsearchallow_searchSearch with filterssendallow_sendSend an email (with optional --attachment)move <uid> <folder>allow_deleteMove message to foldermark-read <uid>allow_readMark as readmark-unread <uid>allow_readMark as unreaddelete <uid>allow_deleteDelete a messagefoldersallow_readList IMAP foldersquotanoneGet mailbox quotaconfignoneShow current config"
      },
      {
        "title": "Examples",
        "body": "# List last 10 messages\npython3 scripts/mail.py list --limit 10\n\n# List unread only\npython3 scripts/mail.py list --unseen\n\n# Read message UID 42\npython3 scripts/mail.py read 42\n\n# Search from a sender since a date\npython3 scripts/mail.py search --from-addr alice@example.com --since 01-Jan-2026\n\n# Search by subject containing \"invoice\"\npython3 scripts/mail.py search --subject \"invoice\"\n\n# Send with CC\npython3 scripts/mail.py send \\\n  --to recipient@example.com \\\n  --subject \"Report\" \\\n  --body \"Please find attached.\" \\\n  --cc manager@example.com\n\n# Send with attachments\npython3 scripts/mail.py send \\\n  --to recipient@example.com \\\n  --subject \"Report Q1\" \\\n  --body \"See attached.\" \\\n  --attachment report.pdf data.xlsx\n\n# Move UID 42 to Archive\npython3 scripts/mail.py move 42 Archive\n\n# Mark as unread\npython3 scripts/mail.py mark-unread 42\n\n# Delete UID 42\npython3 scripts/mail.py delete 42\n\n# List folders\npython3 scripts/mail.py folders\n\n# Check quota\npython3 scripts/mail.py quota"
      },
      {
        "title": "Agent: check and summarize unread emails",
        "body": "from scripts.mail import MailClient\n\nclient = MailClient()\nmsgs = client.list_messages(unseen_only=True, limit=10)\nif not msgs:\n    print(\"No unread messages.\")\nelse:\n    for m in msgs:\n        print(f\"[{m['uid']}] From: {m['from']} | {m['subject']}\")"
      },
      {
        "title": "Agent: send a notification email",
        "body": "from scripts.mail import MailClient\n\nclient = MailClient()\nclient.send(\n    to=\"admin@example.com\",\n    subject=\"Alert: disk usage high\",\n    body=\"Disk usage has exceeded 90% on server prod-01.\",\n)"
      },
      {
        "title": "Agent: search and archive old invoices",
        "body": "from scripts.mail import MailClient\n\nclient = MailClient()\ninvoices = client.search_messages(subject=\"invoice\", since=\"01-Jan-2025\")\nfor msg in invoices:\n    client.move_message(msg[\"uid\"], \"Archive/Invoices\")"
      },
      {
        "title": "Ideas",
        "body": "Daily digest: list unread messages each morning and summarize senders + subjects\nAuto-archive: move messages matching certain criteria to archive folders\nSend alerts from monitoring scripts (disk, backups, errors)\nDraft-style send: compose body via LLM then send via this skill\nCombined with calendar skill: send meeting summaries by email"
      },
      {
        "title": "Combine with",
        "body": "nextcloud-files - attach or save email attachments to Nextcloud\nghost-admin - email notification when a Ghost post is published\nAny monitoring or automation skill for alert delivery"
      },
      {
        "title": "Troubleshooting",
        "body": "See references/troubleshooting.md for:\n\nConnection refused\nAuthentication failed\nIMAP folder not found\nSMTP relay rejected\nSelf-signed certificate workaround (local servers only)"
      }
    ],
    "body": "mail-client\n\nIMAP read/search + SMTP send for any standard mail server. Python stdlib only, zero external dependencies.\n\nTrigger phrases\n\"check my email\"\n\"do I have unread messages\"\n\"read the email from Alice\"\n\"search emails about invoice\"\n\"send an email to Bob\"\n\"move that email to the Archive folder\"\n\"mark that as read\"\n\"delete that message\"\n\"list my mail folders\"\nQuick Start\npython3 scripts/setup.py   # interactive setup: credentials + permissions\npython3 scripts/init.py    # validate all configured capabilities\npython3 scripts/mail.py config  # show current config (no secrets)\n\nSetup\n1. Run setup wizard\npython3 scripts/setup.py\n\n\nThe wizard collects:\n\nSMTP host/port, IMAP host/port\nMail user and app key (application password)\nWhich capabilities to enable (all false by default)\nDefault folder and max results\n2. Validate\npython3 scripts/init.py\n\n\nExpected output: all checks OK or SKIP (none FAIL).\n\n3. Enable capabilities in config.json\n\nEdit ~/.openclaw/config/mail-client/config.json:\n\n{\n  \"allow_send\": true,\n  \"allow_read\": true,\n  \"allow_search\": true,\n  \"allow_delete\": false,\n  \"smtp_port\": 587,\n  \"imap_port\": 993,\n  \"mail_from\": \"you@example.com\",\n  \"default_folder\": \"INBOX\",\n  \"max_results\": 20\n}\n\nStorage and credentials\nPath\tWritten by\tPurpose\tContains secrets\n~/.openclaw/secrets/mail_creds\tsetup.py\tSMTP/IMAP credentials + app key\tYES - chmod 600, never committed\n~/.openclaw/config/mail-client/config.json\tsetup.py\tBehavior restrictions, folder/limit defaults\tNO - behavior only, not in skill dir - survives clawhub updates\n~/.openclaw/secrets/mail_creds\n\nWritten by setup.py, chmod 600, never committed to git. Contains:\n\nMAIL_SMTP_HOST=mail.example.com\nMAIL_IMAP_HOST=mail.example.com\nMAIL_USER=user@example.com\nMAIL_APP_KEY=app-password-here\n\n\nPorts (smtp_port, imap_port) and sender address (mail_from) are set in config.json - they are configuration, not credentials.\n\nCredentials can also be provided via environment variables (MAIL_USER, MAIL_APP_KEY, MAIL_SMTP_HOST, MAIL_IMAP_HOST). Environment variables take precedence over file values. The skill checks env vars first, then falls back to the creds file.\n\n~/.openclaw/config/mail-client/config.json\n\nWritten by setup.py. Controls behavior restrictions (which capabilities are enabled). Contains no secrets. Not in the skill directory - survives clawhub updates. Start from config.example.json in the skill dir if you prefer to create it manually.\n\nCleanup on uninstall: clawhub uninstall mail-client removes the skill directory. To also remove credentials and config:\n\npython3 scripts/setup.py --cleanup\n\n\nOn reinstall, any existing config at ~/.openclaw/config/mail-client/config.json is picked up automatically.\n\nModule usage\n\nImport MailClient directly in Python:\n\nfrom scripts.mail import MailClient\n\nclient = MailClient()\n\n# List 5 unread messages\nmsgs = client.list_messages(limit=5, unseen_only=True)\nfor m in msgs:\n    print(m[\"from\"], m[\"subject\"])\n\n# Read a message\nmsg = client.read_message(\"42\")\nprint(msg[\"body\"])\n\n# Send a message\nresult = client.send(\n    to=\"alice@example.com\",\n    subject=\"Hello\",\n    body=\"Hi Alice, how are you?\",\n)\nprint(result)\n\n# Send with attachments\nresult = client.send(\n    to=\"alice@example.com\",\n    subject=\"Report Q1\",\n    body=\"Please find attached the Q1 report.\",\n    attachments=[\"report.pdf\", \"data.xlsx\"],\n)\nprint(result)\n\n# Search\nfound = client.search_messages(from_addr=\"bob@example.com\", unseen_only=True)\n\nCLI reference\npython3 scripts/mail.py <subcommand> [options]\n\nSubcommand\tRequires\tDescription\nlist\tallow_read\tList messages (newest first)\nread <uid>\tallow_read\tRead a full message by UID\nsearch\tallow_search\tSearch with filters\nsend\tallow_send\tSend an email (with optional --attachment)\nmove <uid> <folder>\tallow_delete\tMove message to folder\nmark-read <uid>\tallow_read\tMark as read\nmark-unread <uid>\tallow_read\tMark as unread\ndelete <uid>\tallow_delete\tDelete a message\nfolders\tallow_read\tList IMAP folders\nquota\tnone\tGet mailbox quota\nconfig\tnone\tShow current config\nExamples\n# List last 10 messages\npython3 scripts/mail.py list --limit 10\n\n# List unread only\npython3 scripts/mail.py list --unseen\n\n# Read message UID 42\npython3 scripts/mail.py read 42\n\n# Search from a sender since a date\npython3 scripts/mail.py search --from-addr alice@example.com --since 01-Jan-2026\n\n# Search by subject containing \"invoice\"\npython3 scripts/mail.py search --subject \"invoice\"\n\n# Send with CC\npython3 scripts/mail.py send \\\n  --to recipient@example.com \\\n  --subject \"Report\" \\\n  --body \"Please find attached.\" \\\n  --cc manager@example.com\n\n# Send with attachments\npython3 scripts/mail.py send \\\n  --to recipient@example.com \\\n  --subject \"Report Q1\" \\\n  --body \"See attached.\" \\\n  --attachment report.pdf data.xlsx\n\n# Move UID 42 to Archive\npython3 scripts/mail.py move 42 Archive\n\n# Mark as unread\npython3 scripts/mail.py mark-unread 42\n\n# Delete UID 42\npython3 scripts/mail.py delete 42\n\n# List folders\npython3 scripts/mail.py folders\n\n# Check quota\npython3 scripts/mail.py quota\n\nTemplates\nAgent: check and summarize unread emails\nfrom scripts.mail import MailClient\n\nclient = MailClient()\nmsgs = client.list_messages(unseen_only=True, limit=10)\nif not msgs:\n    print(\"No unread messages.\")\nelse:\n    for m in msgs:\n        print(f\"[{m['uid']}] From: {m['from']} | {m['subject']}\")\n\nAgent: send a notification email\nfrom scripts.mail import MailClient\n\nclient = MailClient()\nclient.send(\n    to=\"admin@example.com\",\n    subject=\"Alert: disk usage high\",\n    body=\"Disk usage has exceeded 90% on server prod-01.\",\n)\n\nAgent: search and archive old invoices\nfrom scripts.mail import MailClient\n\nclient = MailClient()\ninvoices = client.search_messages(subject=\"invoice\", since=\"01-Jan-2025\")\nfor msg in invoices:\n    client.move_message(msg[\"uid\"], \"Archive/Invoices\")\n\nIdeas\nDaily digest: list unread messages each morning and summarize senders + subjects\nAuto-archive: move messages matching certain criteria to archive folders\nSend alerts from monitoring scripts (disk, backups, errors)\nDraft-style send: compose body via LLM then send via this skill\nCombined with calendar skill: send meeting summaries by email\nCombine with\nnextcloud-files - attach or save email attachments to Nextcloud\nghost-admin - email notification when a Ghost post is published\nAny monitoring or automation skill for alert delivery\nTroubleshooting\n\nSee references/troubleshooting.md for:\n\nConnection refused\nAuthentication failed\nIMAP folder not found\nSMTP relay rejected\nSelf-signed certificate workaround (local servers only)"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/Romain-Grosos/mail-client",
    "publisherUrl": "https://clawhub.ai/Romain-Grosos/mail-client",
    "owner": "Romain-Grosos",
    "version": "1.1.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/mail-client",
    "downloadUrl": "https://openagent3.xyz/downloads/mail-client",
    "agentUrl": "https://openagent3.xyz/skills/mail-client/agent",
    "manifestUrl": "https://openagent3.xyz/skills/mail-client/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/mail-client/agent.md"
  }
}