MCP Email Service

Một dịch vụ quản lý nhiều tài khoản email từ các nhà cung cấp khác nhau như 163, Gmail, QQ và Outlook.

GitHub
43
Dùng thử MCP nàyĐược tài trợ

Tài liệu

mail-use

Email, as something an AI agent can actually operate. One CLI over Gmail, QQ, 163, Outlook and any IMAP/SMTP box — every command speaks JSON, every destructive one is dry-run until you pass --confirm.

mail-use code --json          # the newest verification code, one live pass
mail-use email recent --format compact --json
mail-use email delete --from newsletter@shop.com --confirm --json

Part of the *-use family — small tools that each give an agent hands on one real thing.

Why this and not an IMAP snippet

  • A stable JSON contract, not scraped text. Every response carries success: boolean, and failures carry error_code from a fixed set (auth_failed, folder_not_found, imap_error, …). Documented in docs/CLI_JSON_CONTRACT.md.
  • It tells you when it might be wrong. Cached reads report from_cache, cache_age_seconds and cache_stale, and a snapshot old enough to mean "nothing is syncing" is refused in favour of a live fetch. An empty inbox is never a silent "nothing arrived".
  • Destructive by consent only. delete / mark / move / send return a dry-run preview — grouped per account and folder, with sample subjects — and change nothing until --confirm. --all-folders skips Sent/Drafts/Junk/Trash unless asked.
  • Built for token budgets. --format compact projects each email to the ten fields worth scanning (~30% smaller than the full shape), --with-preview folds a body snippet into the list call, and batch show reuses one IMAP connection.
  • Fast enough to call in a loop. A persistent daemon pools IMAP connections and syncs to local SQLite in the background: five sequential email list calls go from 25s to 0.83s. See the table below.
  • MCP too. mail-use mcp config --json prints a paste-ready entry; the server exposes 16 tools with the same dry-run defaults.

Renamed from Mailbox to mail-use. The command is now mail-use; mailbox still works as an alias, and your config in ~/.config/mailbox is untouched.

Supported providers

163 / 126 · QQ · Gmail · Outlook / Hotmail · any custom IMAP+SMTP server.

Search behaves differently per provider and the CLI says so: Gmail searches bodies server-side via X-GM-RAW, while QQ/163/Outlook have broken IMAP TEXT search, so --query falls back to matching subject + sender only. Use --from / --subject there for predictable results.

Install

One line, no npm, no Node

curl -fsSL https://raw.githubusercontent.com/leeguooooo/mail-use/main/install.sh | sh
mail-use --help

Downloads the prebuilt binary for your platform (macOS arm64/x64, Linux x64) from the latest GitHub Release, verifies its checksum, and installs to ~/.local/bin. Pin a version with MAIL_USE_VERSION=v2.11.2, or change the dir with MAIL_USE_INSTALL_DIR=....

The installer also drops a mailbox symlink next to it, so scripts written against the old name keep working.

There is no npm package. Distribution is GitHub Release binaries only — that keeps releases free of NPM_TOKEN and 2FA prompts, and keeps install free of a Node toolchain. The pre-rename @leeguoo/mailbox-cli packages on npm are frozen and no longer updated.

Upgrading

mail-use upgrade --check     # is there a newer release? (`mail-use 3.3.1 -> 3.3.2`)
mail-use upgrade --json      # the same check as JSON: name, current, latest, update_available, skills
mail-use upgrade             # download, verify sha256, replace in place, restart the daemon, refresh the skill
mail-use upgrade --tag v3.1.0   # pin an exact release (also the way to roll back)

Exit code 0 means the command worked (an update being available is not an error); 2 means the check or the download failed.

upgrade also refreshes every copy of the mail-use skill it finds: a Claude Code plugin (claude plugin update mail-use@leeguooooo-plugins, or printed if claude isn't on PATH), a git checkout linked into ~/.agents/skills, ~/.claude/skills or ~/.codex/skills (git pull --ff-only, never forced), or a copied folder from npx skills add (it prints npx skills update mail-use for you to run).

Any other command checks for a new release at most once a day (cached in ${XDG_CACHE_HOME:-~/.cache}/mail-use/update-check.json, 2 s timeout, failures silent) and, when one exists, prints a single line to stderr — stdout stays clean JSON: mail-use 3.3.2 is available (you have 3.3.1). Upgrade: mail-use upgrade. Set CI, MAIL_USE_NO_UPDATE_CHECK or USE_NO_UPDATE_CHECK to turn it off.

When the daemon is running it notices new releases for you: one unauthenticated GET to the GitHub releases API per day (MAILBOX_UPDATE_CHECK_HOURS, 0 disables), surfaced as update in mail-use daemon status --json. It only ever reports — it never downloads or installs anything.

upgrade is never automatic and never runs on its own: a tool that silently replaces its own executable is a supply-chain surprise, not a convenience. It refuses to install a tarball whose published .sha256 doesn't match, and refuses to run at all from a dev checkout (where process.execPath is your node). Re-running the curl … install.sh | sh line does the same job.

As an AI Skill (Claude Code / Cursor / etc.)

# Project scope — installs into ./.claude/skills/mail-use (or ./.cursor/skills/...):
npx skills add leeguooooo/mail-use --skill mail-use

# User scope — installs into ~/.claude/skills/mail-use:
npx skills add leeguooooo/mail-use --skill mail-use -g

The skill assumes the CLI is on PATH (install via the curl … install.sh | sh above). For the biggest speedup also run mail-use daemon install once.

MCP server (Claude Desktop / Code / Cursor)

mail-use mcp config --json   # prints a paste-ready mcpServers entry

From source (development)

pnpm install
pnpm test

# build a local platform binary into dist/mail-use
pnpm build:binary

If a test run is interrupted (editor task killed, agent session closed), its Vitest workers can be left behind and hold memory. Check with pgrep -fl vitest and kill what remains.

Configure accounts

mkdir -p ~/.config/mailbox
cp examples/accounts.example.json ~/.config/mailbox/auth.json

Config locations:

  • Credentials: ~/.config/mailbox/auth.json
  • Other settings: ~/.config/mailbox/config.toml

Common commands

# CLI help
mail-use --help

# newest verification code across all accounts, one live pass
mail-use code --json

# list accounts
mail-use account list --json

# list unread emails (cache by default; --from filters cache-side)
mail-use email list --unread-only --limit 20 --json
mail-use email list --account-id my_account_id --from "newsletter" --json

# show one email (response includes list_unsubscribe when the header is set)
mail-use email show 123456 --account-id my_account_id --json

# mark read (use --dry-run to validate first)
mail-use email mark 123456 --read --account-id my_account_id --folder INBOX --dry-run --json
mail-use email mark 123456 --read --account-id my_account_id --folder INBOX --confirm --json

# delete
mail-use email delete 123456 --account-id my_account_id --folder INBOX --confirm --json

# bulk mutate by sender or subject (no UID list needed)
mail-use email mark --from "support@npmjs.com" --read --confirm --account-id my_account_id --json
mail-use email delete --from "newsletter" --account-id my_account_id --json    # dry-run preview
mail-use email delete --subject "[ad]" --account-id my_account_id --confirm --json

Cache + sync

  • Cache DB default: ~/.local/share/mailbox/email_sync.db
  • Listing uses cache by default where possible. Add --live to force IMAP.
mail-use sync status --json
mail-use sync force --json
mail-use sync init
mail-use sync daemon

Persistent daemon (5-30× faster CLI calls)

Each one-shot invocation otherwise spends 1-3s on TCP+TLS+IMAP LOGIN. With the daemon running, calls reuse pooled connections and a background SQLite sync means email list usually doesn't touch IMAP at all.

The curl … install.sh | sh installer sets this up for you when accounts are already configured (MAIL_USE_NO_DAEMON=1 opts out). Otherwise:

mail-use daemon install      # autostart at login (macOS launchd / Linux systemd-user)
mail-use daemon status --json
mail-use daemon reload       # drop pooled connections after editing auth.json

Measured on Gmail INBOX, M2 MacBook over residential WAN:

OperationNo daemonDaemon (--live)Daemon (cached)
Single email list5.0s1.0s0.17s
email folders5.0s0.85sn/a
5 sequential email list25s5.3s0.83s
3 parallel email show~15s2.7s0.88s

Resource footprint (many agent sessions on one machine)

The daemon is one process per user, shared by every agent session through a Unix socket — so more sessions do not mean more IMAP connections. Measured idle on macOS with 3 accounts connected:

Idle CPU~0.15%
Idle RSS3-15 MB
Connectionsmax 3 per account (MAILBOX_POOL_MAX), reaped back to 1 after 10 min idle
12 concurrent calls1.6s wall clock, pool stayed at 1 connection per account

Knobs, if the defaults do not suit you:

EnvDefaultEffect
MAILBOX_POOL_MAX3Max concurrent IMAP connections per account
MAILBOX_POOL_IDLE_MS600000Close connections idle this long (0 disables reaping)
MAILBOX_POOL_KEEP_WARM1Connections per account kept warm through reaping
MAILBOX_NO_DAEMONunset1 makes the CLI skip the daemon entirely
MAILBOX_UPDATE_CHECK_HOURS24Daemon's passive update check (0 disables it and the CLI's daily notice)
MAIL_USE_NO_UPDATE_CHECK / USE_NO_UPDATE_CHECKunsetAny value turns off the CLI's daily "new version" notice

AI usage guide

If you're integrating this CLI into an AI agent, start here:

  • docs/AI_SKILL_MAIL_USE.md

OpenClaw integration

This repo includes an OpenClaw skill at skills/mail-use/SKILL.md.

OpenClaw loads skills from:

  • <workspace>/skills
  • ~/.openclaw/skills

Quick link helper (symlink into ~/.openclaw/skills):

./scripts/link_openclaw_skill.sh

Force replace an existing link:

./scripts/link_openclaw_skill.sh --force

To use this repo without copying files, add the repo skills directory to skills.load.extraDirs in ~/.openclaw/openclaw.json:

{
  "skills": {
    "load": {
      "extraDirs": [
        "/path/to/mcp-email-service/skills"
      ]
    }
  }
}

OpenClaw handles channel delivery and scheduling; mail-use returns structured JSON outputs and optional text summaries.

Verify OpenClaw picked up the skill:

openclaw skills list --eligible
openclaw skills check

The *-use family

Small, composable CLIs that give an AI agent hands on one real thing. Same shape everywhere: curl … install.sh | sh to install, npx skills add leeguooooo/<name> to teach your agent, JSON on stdout.

RepoGives your agent
chrome-useA real browser — logged-in sessions, forms, scraping, screenshots
mail-useEmail — read, search, send, triage across Gmail / QQ / 163 / any IMAP
iphone-useA real iPhone — tap, type, screenshot, pull on-device data
wechat-useWeChat on macOS — send messages, query contacts and history
discord-useDiscord — messages, channels, forums, webhooks (REST-only, Rust)
cookie-useMany logged-in accounts per site — capture, switch, apply sessions
profile-useYour personal profile, safely — fill signup / KYC / checkout forms
bitwarden-useBitwarden / Vaultwarden — headless passkey (FIDO2) login
chatgpt-useYour ChatGPT subscription as a coding-agent backend — no API key
computer-useThe macOS desktop itself
pixcake-useRead-only PixCake probing — snapshot / diff / SQLite inspection

Contract

  • docs/CLI_JSON_CONTRACT.md

Built by leeguooooo — field notes on AI agents, reverse engineering & Cloudflare Workers at blog.misonote.com · follow on X @leeguooooo