{"id":50992761,"url":"https://github.com/mxcd/mailotron","last_synced_at":"2026-06-20T05:04:03.540Z","repository":{"id":365343243,"uuid":"1271626147","full_name":"mxcd/mailotron","owner":"mxcd","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-16T23:10:48.000Z","size":69,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-17T01:10:04.129Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mxcd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-16T21:19:49.000Z","updated_at":"2026-06-16T23:10:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mxcd/mailotron","commit_stats":null,"previous_names":["mxcd/mailotron"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/mxcd/mailotron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmailotron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmailotron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmailotron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmailotron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mxcd","download_url":"https://codeload.github.com/mxcd/mailotron/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmailotron/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34557553,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-20T05:03:58.506Z","updated_at":"2026-06-20T05:04:03.534Z","avatar_url":"https://github.com/mxcd.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mailotron\n\nA non-interactive email CLI built to be driven by AI agents. Compose responsive\nHTML + plain-text emails from **Markdown** and **MJML** templates, send them via\n**SMTP** or **Resend**, and manage **IMAP** mailboxes — every feature is a\ncommand with flags, and every command speaks JSON.\n\n- **Write Markdown, not HTML.** Bodies are Markdown by default; frames and\n  signatures are authored in MJML and compiled to responsive, email-safe HTML\n  with the native Go [`gomjml`](https://github.com/preslavrachev/gomjml) library\n  (no Node.js).\n- **Agent-first.** `-o json` on any command, deterministic exit codes, no\n  prompts, and a baked-in operating manual: `mailotron guide`.\n- **Multi-account.** Configure any number of mailboxes in\n  `~/.mailotron/config.yml`; pick one with `-a/--account`.\n- **Full IMAP management.** List/create/rename/delete folders; list, read,\n  move, copy, flag, delete and download messages and attachments.\n- **Mailbox backup \u0026 restore.** Pull an entire mailbox into a directory of\n  individual files (one `.eml` per message, no archive) and append it back.\n  Incremental and restic-friendly, so an external backup tool can ship it to S3.\n\n## Install\n\n```sh\ngo install github.com/mxcd/mailotron/cmd/mailotron@latest\n```\n\nOr grab a binary from the [releases](https://github.com/mxcd/mailotron/releases)\n(Linux, macOS, Windows; amd64 + arm64).\n\n## Quick start\n\n```sh\nmailotron config init          # writes ~/.mailotron/config.yml + seeds default templates/signatures\n# edit ~/.mailotron/config.yml and export the referenced secrets, then:\nexport SMTP_PASSWORD=...  IMAP_PASSWORD=...\nmailotron config validate\nmailotron account test -a personal\n\n# send a Markdown email through a template\nmailotron send -a personal \\\n  --to \"Jane \u003cjane@example.com\u003e\" --subject \"Hello\" \\\n  --template default --signature default \\\n  --var Name=Jane \\\n  --body $'# Hi Jane\\n\\nThis is **Markdown**, rendered into a responsive template.'\n\n# triage an inbox\nmailotron message list -a personal --unseen -o json\nmailotron message show 4213 -a personal -o json\nmailotron message move 4213 --to-folder Archive -a personal\n```\n\n## For agents\n\nRun `mailotron guide` for the full operating manual (mental model, JSON output\ncontract, exit codes, every command with examples). `mailotron guide -o json`\nadds a machine-readable command catalog generated from the live command tree.\n\n## Configuration\n\n`~/.mailotron/config.yml` holds any number of accounts. Secrets are referenced\nas `${ENV_VAR}` and resolved from the environment at load time — they are never\nwritten to disk by mailotron.\n\n```yaml\ndefaults:\n  account: personal\n  template: default\n  signature: default\n\naccounts:\n  personal:\n    from: \"Your Name \u003cyou@example.com\u003e\"\n    outbound: { type: smtp, host: smtp.example.com, port: 587, tls: starttls,\n                username: you@example.com, password: ${SMTP_PASSWORD} }\n    imap:     { host: imap.example.com, port: 993, tls: tls,\n                username: you@example.com, password: ${IMAP_PASSWORD} }\n\n  newsletter:                       # send-only via Resend (no imap block)\n    from: \"News \u003cnews@example.com\u003e\"\n    outbound: { type: resend, api_key: ${RESEND_API_KEY} }\n```\n\nOverride the location with `--config \u003cpath\u003e` or `MAILOTRON_CONFIG` /\n`MAILOTRON_CONFIG_DIR`.\n\n## Templates \u0026 signatures\n\nTemplates are MJML \"frames\" with `{{.Body}}`/`{{.Signature}}` slots plus\narbitrary `{{.Var}}` variables; signatures are MJML snippets. Both live under\n`~/.mailotron/` and are managed with `mailotron template …` and\n`mailotron signature …`. Discover a template's required variables with\n`mailotron template show \u003cname\u003e --vars`.\n\nThe body is Markdown by default; use `--body-format mjml|text|html` for other\ninputs.\n\n## Mailbox backup \u0026 restore\n\n`mailotron backup` mirrors a whole mailbox into a directory of plain files — one\n`.eml` per message (verbatim RFC822) plus a JSON index per folder and a\ntop-level `manifest.json`. There is no zip: the directory is the contract with a\ncontent-addressed backup tool such as [restic](https://restic.net), which\nmailotron intentionally does **not** wrap. Because every message lands at a\nstable path with identical bytes across runs, restic deduplicates it and each\nincremental snapshot is tiny.\n\n```sh\n# Pull the mailbox (incremental — only new messages download):\nmailotron backup --out ./backup -a work\n\n# Ship it to S3 with restic (run separately; mailotron does not call restic):\nexport RESTIC_PASSWORD=…  AWS_ACCESS_KEY_ID=…  AWS_SECRET_ACCESS_KEY=…\nrestic -r s3:s3.amazonaws.com/your-bucket/mailbox backup ./backup\n\n# Recover, into a namespace so live folders are untouched (idempotent):\nmailotron restore --in ./backup --prefix \"Restored/\" -a work\n```\n\nBackups are **additive** by default (messages deleted on the server are kept);\nadd `--mirror` to prune them so each restic snapshot is an exact point-in-time\ncopy. Restore matches messages by `Message-ID` and skips ones already present,\nso it is safe to re-run.\n\n## Development\n\n```sh\njust test          # unit tests (race)\njust e2e           # end-to-end tests (Docker: GreenMail + Mailpit)\njust build         # ./bin/mailotron\njust snapshot      # local cross-platform GoReleaser build\n```\n\nCI runs `vet`, unit tests, and the e2e suite on every push/PR. Pushing a `v*`\ntag builds and publishes cross-platform binaries via GoReleaser.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmxcd%2Fmailotron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmxcd%2Fmailotron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmxcd%2Fmailotron/lists"}