{"id":47981749,"url":"https://github.com/bestlux/mail-agent","last_synced_at":"2026-04-04T11:06:10.264Z","repository":{"id":348193825,"uuid":"1196829759","full_name":"bestlux/mail-agent","owner":"bestlux","description":"Fastmail-first Codex plugin and local MCP daemon for agent-friendly mail, calendar, and contacts workflows.","archived":false,"fork":false,"pushed_at":"2026-03-31T07:08:51.000Z","size":158,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-31T08:35:20.554Z","etag":null,"topics":["caldav","calendar","carddav","codex","codex-plugin","contacts","email","fastmail","jmap","mcp","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bestlux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":"SUPPORT.md","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-03-31T04:44:17.000Z","updated_at":"2026-03-31T07:07:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bestlux/mail-agent","commit_stats":null,"previous_names":["bestlux/mail-agent"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/bestlux/mail-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestlux%2Fmail-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestlux%2Fmail-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestlux%2Fmail-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestlux%2Fmail-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bestlux","download_url":"https://codeload.github.com/bestlux/mail-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestlux%2Fmail-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31397056,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["caldav","calendar","carddav","codex","codex-plugin","contacts","email","fastmail","jmap","mcp","typescript"],"created_at":"2026-04-04T11:06:10.076Z","updated_at":"2026-04-04T11:06:10.250Z","avatar_url":"https://github.com/bestlux.png","language":"TypeScript","readme":"# mail-agent\n\n`mail-agent` is a Codex plugin plus local daemon for email, calendar, and contacts workflows.\n\nThe idea is simple: give Codex structured tools for mail instead of making it pretend a human mail client is an API.\n\nRight now the repo supports Fastmail and Google. Fastmail uses native protocol access. Google uses OAuth plus the Gmail, Calendar, and People APIs.\n\n## What you get\n\nThe repo ships three coordinated pieces:\n\n- `mail-agent`: the public CLI and Codex plugin bundle\n- `@iomancer/mail-agent-daemon`: the local MCP daemon that exposes structured tools\n- `@iomancer/mail-agent-shared`: shared runtime, config, policy, and secret-store logic\n\nMost people only care about `mail-agent`. The other two packages exist so the plugin can stay cleanly split between CLI, daemon, and shared runtime code.\n\n## Current support\n\nv1 currently supports two providers:\n\n- Fastmail\n  - mail via `JMAP`\n  - calendar via `CalDAV`\n  - contacts via `CardDAV`\n- Google\n  - mail via the Gmail API\n  - calendar via the Google Calendar API\n  - contacts via the People API\n\nAcross those providers, the daemon exposes the same agent-facing tool surface:\n\n- `list_mailboxes`\n- `search_messages`\n- `read_message_batch`\n- `read_thread`\n- `compose_message`\n- `draft_reply`\n- `send_message`\n- `archive_messages`\n- `move_messages`\n- `tag_messages`\n- `mark_messages`\n- `delete_messages` with explicit confirmation\n- `list_calendars`\n- `get_events`\n- `search_contacts`\n- `get_contact`\n\nThe tool names are provider-generic on purpose. The adapter layer handles the provider-specific transport and semantics underneath.\n\n## Why this exists\n\nMost mailbox integrations for agents land in one of two camps:\n\n- vendor-specific APIs with weak workflow guidance\n- general-purpose mail clients that were designed for humans, not models\n\n`mail-agent` takes a different route:\n\n- structured tool contracts instead of terminal scraping\n- skills that teach Codex how to search, shortlist, summarize, draft, and mutate safely\n- local-first setup so credentials stay on your machine\n- provider-native integrations instead of flattening everything to IMAP first\n- an explicit safety model for sends and destructive actions\n\n## Mental model\n\nAt runtime the flow is:\n\n1. Codex loads the local `Mail Agent` plugin bundle.\n2. The plugin starts a local stdio MCP server named `mail-agent`.\n3. The daemon reads local account config plus secrets from the OS keychain or a file-backed development store.\n4. The daemon talks to the configured provider through native APIs or protocols:\n   - Fastmail: `JMAP`, `CalDAV`, `CardDAV`\n   - Google: Gmail API, Google Calendar API, People API\n5. Skills tell the agent how to use the tools well, not just that the tools exist.\n\nThat last point matters. Tools make actions possible. Skills make the agent behave like it has some judgment.\n\n## What Codex sees\n\nAfter install, Codex sees:\n\n- a plugin called `Mail Agent`\n- a local MCP server called `mail-agent`\n- workflow skills:\n  - `mail-agent`\n  - `mail-agent-inbox-triage`\n  - `calendar-brief`\n  - `contacts-lookup`\n\nExample prompts:\n\n- \"Use `mail-agent` to summarize the latest recruiter thread and draft the reply.\"\n- \"Use `mail-agent-inbox-triage` to sort unread inbox mail into urgent, reply soon, waiting, and FYI.\"\n- \"Use `calendar-brief` to summarize my next two days and flag conflicts.\"\n- \"Use `contacts-lookup` to find Jane from Acme and confirm her best email.\"\n\n## If You Just Want To Run It\n\n```powershell\ngit clone https://github.com/bestlux/mail-agent.git\ncd mail-agent\ncorepack pnpm install\ncorepack pnpm build\nnode packages/plugin/dist/bin/mail-agent.js install\n```\n\nThen auth whichever account you want first:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js auth fastmail --account personal --email you@fastmail.com\n```\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js auth google --account gmail --email you@gmail.com --client-id \u003cclient-id\u003e\n```\n\nIf browser launch is flaky on your machine:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js auth google --account gmail --email you@gmail.com --client-id \u003cclient-id\u003e --no-open-browser\n```\n\nThen check the runtime:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js doctor\n```\n\n## Requirements\n\n- Node `22+`\n- `pnpm` via Corepack\n- Codex with plugins enabled\n- At least one supported account:\n  - Fastmail with a `JMAP API token` plus an `app password` for CalDAV/CardDAV\n  - Google with a Google Cloud OAuth desktop client and the Gmail, Calendar, and People APIs enabled\n\nNotes:\n\n- v1 supports Fastmail credentials directly and Google via OAuth loopback auth.\n- v1 does not support calendar or contact writes.\n- `delete_messages` is always gated, even in trusted mode.\n\n## Install from source\n\nClone and build the workspace:\n\n```powershell\ngit clone https://github.com/bestlux/mail-agent.git\ncd mail-agent\ncorepack pnpm install\ncorepack pnpm build\n```\n\nInstall the local plugin bundle into Codex:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js install\n```\n\nAuth a Fastmail account:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js auth fastmail --account personal --email you@fastmail.com\n```\n\nAuth a Google account:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js auth google --account gmail --email you@gmail.com --client-id \u003cclient-id\u003e\n```\n\nRun a health check:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js doctor\n```\n\n## Install from npm\n\nThe public package name is `mail-agent`.\n\nThe repo still publishes `@iomancer/mail-agent-daemon` and `@iomancer/mail-agent-shared` alongside it because the CLI is split into a public plugin package plus two internal support packages. Most users should ignore that and just install `mail-agent`.\n\nOnce the first npm release is live, the normal install paths will be:\n\n```powershell\nnpx mail-agent install\n```\n\nor, if you want the CLI on your path:\n\n```powershell\nnpm install -g mail-agent\nmail-agent install\nmail-agent auth fastmail --account personal --email you@fastmail.com\nmail-agent auth google --account gmail --email you@gmail.com --client-id \u003cclient-id\u003e\nmail-agent doctor\n```\n\n## Releases\n\nReleases are meant to go out through GitHub Actions, not from somebody's laptop.\n\nThe happy path is:\n\n1. Bump the workspace version across the root package plus the three publishable packages.\n2. Push a tag like `v0.2.0`.\n3. Let `.github/workflows/publish.yml` build, test, dry-run, and publish the workspace to npm.\n\nThe repo is set up for npm trusted publishing from GitHub Actions. For a brand-new package bootstrap, you can still use an `NPM_TOKEN` repository secret for the first release, then switch to trusted publishers for steady-state releases.\n\nRelease details live in [RELEASING.md](./RELEASING.md).\n\n## Fastmail setup\n\nYou need two credentials:\n\n1. `JMAP API token`\n2. `app password` for CalDAV/CardDAV\n\nThe interactive auth flow prompts for both. You can also pass them non-interactively:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js auth fastmail `\n  --account personal `\n  --email you@fastmail.com `\n  --jmap-token \u003ctoken\u003e `\n  --app-password \u003capp-password\u003e\n```\n\nFastmail uses two auth surfaces by design:\n\n- mail uses `JMAP` with the API token\n- calendar and contacts use `CalDAV` and `CardDAV` with the app password\n\n## Google setup\n\nGoogle support uses installed-app OAuth with a local loopback redirect. The flow opens your browser, asks for consent, and stores the resulting refresh token locally so the daemon can refresh access tokens without prompting every run.\n\nBefore running `auth google`, set up Google Cloud:\n\n1. Create or choose a Google Cloud project.\n2. Configure the OAuth consent screen or Google Auth platform branding.\n3. Set user type to `External`.\n4. Keep the app in `Testing`.\n5. Add your Gmail account under `Test users`.\n6. Enable the Gmail API, Google Calendar API, and People API.\n7. Create an OAuth client with application type `Desktop app`.\n8. Use that client ID when running `mail-agent auth google`.\n\nFor personal Gmail usage, the expected setup is:\n\n- `External` user type\n- `Testing` publishing status\n- your own Gmail added under `Test users`\n- `Desktop app` OAuth client\n\nIf your Gmail is not listed as a test user, Google will block the app even if the APIs and client are configured correctly.\n\nExample:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js auth google `\n  --account gmail `\n  --email you@gmail.com `\n  --client-id \u003cclient-id\u003e\n```\n\nOptional flags:\n\n- `--client-secret \u003csecret\u003e` if your Google client includes one\n- `--full-gmail-access` if you want permanent Gmail delete support\n- `--no-open-browser` if you want to open the OAuth URL yourself\n- `--redirect-host 127.0.0.1`\n- `--redirect-port 4567`\n\nCurrent default Google scopes:\n\n- `https://www.googleapis.com/auth/gmail.modify`\n- `https://www.googleapis.com/auth/calendar.readonly`\n- `https://www.googleapis.com/auth/contacts.readonly`\n\nIf you want Gmail `delete_messages` to permanently delete instead of stopping with a scope error, re-auth with:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js auth google `\n  --account gmail `\n  --email you@gmail.com `\n  --client-id \u003cclient-id\u003e `\n  --full-gmail-access\n```\n\nThat swaps the mail scope to `https://mail.google.com/`, which is broader than the default.\n\nGoogle Contacts notes:\n\n- `search_contacts` only searches actual Google Contacts data\n- it does not search everyone you have ever emailed\n- an empty result can just mean the person is not saved in Google Contacts\n\nUseful official references:\n\n- [Google OAuth for desktop apps](https://developers.google.com/identity/protocols/oauth2/native-app)\n- [Gmail API quickstart for Node.js](https://developers.google.com/workspace/gmail/api/quickstart/nodejs)\n- [Google Calendar API scopes](https://developers.google.com/workspace/calendar/api/auth)\n- [People API contacts guide](https://developers.google.com/people/v1/contacts)\n\nTwo practical notes:\n\n- sensitive scopes can trigger the \"unverified app\" screen during testing\n- the redirect URI used by the loopback flow must exactly match the configured OAuth client redirect\n\n## Runtime and secret storage\n\nRuntime state lives under your OS config directory:\n\n- Windows: `%APPDATA%\\mail-agent`\n- macOS: `~/Library/Application Support/mail-agent`\n- Linux: `$XDG_CONFIG_HOME/mail-agent` or `~/.config/mail-agent`\n\nSecrets default to the OS keychain via `keytar`.\n\nFor testing or CI you can force file-backed secrets:\n\n```powershell\n$env:MAIL_AGENT_SECRET_BACKEND='file'\n```\n\nThat stores credentials in the runtime directory instead of the OS keychain. Fine for local development and CI. Not ideal for day-to-day use.\n\nIf your package manager blocks native postinstall scripts, `keytar` may need explicit build approval before the keychain backend works.\n\nStored secret material depends on the provider:\n\n- Fastmail stores `username`, `JMAP` token, and DAV password\n- Google stores the OAuth access token, refresh token, expiry, scopes, and client metadata needed for refresh\n\n## Safety model\n\n`mail-agent` is meant to be useful without being reckless.\n\n- `send_message` is available only after account auth and policy allow it\n- archive, move, tag, and mark are allowed in trusted mode\n- `delete_messages` is always a two-step flow\n- calendar and contacts are read-only in v1\n\nDelete is intentionally explicit:\n\n1. first call requests a confirmation token\n2. second call repeats the delete with that token\n\nThat keeps permanent deletion out of the \"oops, the agent inferred too much\" category.\n\n## Search notes that matter in real use\n\nThe search tool is where most real workflows start, so the useful details are worth calling out:\n\n- `collapseThreads: true` keeps broad scans readable\n- `mailboxRole` is better than hardcoded mailbox names when possible\n- `excludeMailingLists: true` helps for person-to-person scans\n- `since` and `until` accept RFC3339 timestamps or `YYYY-MM-DD`\n- `refresh: true` bypasses short-lived cache entries when polling after send or mutation\n\nProvider notes:\n\n- Fastmail exposes real mailboxes\n- Gmail exposes labels plus a pseudo `Archive` mailbox role\n- the tool contract normalizes those differences enough for agents to work reliably, but `list_mailboxes` is still worth using before mutations\n\nThose knobs are there because they make real agent workflows noticeably better.\n\n## Repo layout\n\n```text\npackages/\n  plugin/   Codex plugin bundle, CLI, installer, skills\n  daemon/   local MCP daemon and provider adapters\n  shared/   runtime paths, config, cache, policy, secret handling\n\n.github/    CI and contributor-facing GitHub configuration\n```\n\n## Development\n\nInstall dependencies:\n\n```powershell\ncorepack pnpm install\n```\n\nBuild everything:\n\n```powershell\ncorepack pnpm build\n```\n\nRun tests:\n\n```powershell\ncorepack pnpm test\n```\n\nCheck package contents before publishing:\n\n```powershell\ncorepack pnpm pack:check\n```\n\nDry-run the workspace publish flow:\n\n```powershell\ncorepack pnpm release:dry-run\n```\n\nRun the daemon directly:\n\n```powershell\nnode packages/plugin/dist/bin/mail-agent.js daemon\n```\n\n## Support policy\n\nSupported in v1:\n\n- Fastmail mail via `JMAP`\n- Fastmail calendars via `CalDAV` read operations\n- Fastmail contacts via `CardDAV` read operations\n- Google mail via Gmail API\n- Google calendars via Google Calendar API read operations\n- Google contacts via People API read operations\n\nNot supported in v1:\n\n- calendar writes\n- contact writes\n- full local mailbox mirroring\n- Microsoft Graph\n- generic IMAP/SMTP or generic CalDAV/CardDAV onboarding as first-class flows\n\n## Caveats\n\n- Fastmail mail auth and DAV auth are separate by design\n- Google OAuth requires a Google Cloud OAuth desktop client\n- Gmail semantics are label-based, so archive and mailbox-like moves are normalized rather than perfectly folder-native\n- contact search is a pragmatic address-book scan, not a server-side indexed search engine\n- event parsing is intentionally lightweight and does not aim to be a full iCalendar implementation yet\n\n## Docs\n\n- [CONTRIBUTING.md](./CONTRIBUTING.md)\n- [SECURITY.md](./SECURITY.md)\n- [PRIVACY.md](./PRIVACY.md)\n- [TERMS.md](./TERMS.md)\n- [SUPPORT.md](./SUPPORT.md)\n- [RELEASING.md](./RELEASING.md)\n\n## Roadmap\n\nNear-term improvements:\n\n- stronger recurrence and event parsing\n- richer contact matching\n- Microsoft Graph support\n- generic protocol fallback adapters\n- optional local indexing for heavier research workflows\n- more polished release automation\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbestlux%2Fmail-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbestlux%2Fmail-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbestlux%2Fmail-agent/lists"}