Show HN: Mailflare – self-hosted email, custom domain with Cloudflare Mailflare, a self-hosted email platform, now allows users to manage custom domains through Cloudflare's API for inbound routing and sending. The open-source tool provides an AI-powered inbox with features like message summaries, urgency scoring, and automated reply drafting, while requiring a Cloudflare token with specific permissions for domain setup. The project aims to give users full control over their email infrastructure without relying on third-party dashboard interfaces. A self-hosted, AI-powered email inbox with custom domains, powered by Cloudflare - Domain onboarding through Cloudflare, including inbound Email Routing DNS and sending DNS setup. - Domain removal cleanup for linked Cloudflare routing rules and sending subdomain resources. - Mailbox creation with automatic Cloudflare Email Routing rules. - Mailbox management with a grid view, mailbox detail page, and editable display name. - Inbox, sent, drafts, spam, and trash folders backed by a shared mail list component. - Popup composer with autosaved drafts and draft resume from the drafts folder. - Outbound send API, API keys, message read status, spam/trash moves, and seeded demo data. - Search, filtering, and richer mailbox/folder counts. - Advanced routing rules for catch-all addresses, forwarding, reject/block rules, and priorities. - Webhook management UI and delivery retry visibility. - Attachment support and richer compose formatting. - Message intelligence with summaries, intent classification, urgency scoring, and extracted entities. - Agent task queue for proposed replies, follow-ups, triage actions, and missing-information requests. - Human-approved actions for draft replies, folder moves, forwarding, contact creation, and webhook calls. - Agent rules for learned post-receipt policies such as prioritization, auto-triage, and reply templates. - Agent inbox view organized by action state, including needs reply, waiting on me, waiting on them, FYI, auto-handled, and needs approval. - Thread and contact memory for prior summaries, user preferences, relationship notes, commitments, and open loops. - Tool execution for trusted actions such as sending email, creating drafts, updating message status, calling webhooks, and creating contacts. Domains are not dashboard-only. This app calls Cloudflare when you add/remove a domain: | Action | Cloudflare API | |---|---| | List DNS / status | GET /zones/{zone id}/email/routing/dns | | Enable inbound routing + MX/SPF/DKIM | POST /zones/{zone id}/email/routing/dns | | Disable routing | DELETE /zones/{zone id}/email/routing/dns | | Enable subdomain sending + DNS | POST /zones/{zone id}/email/sending/subdomains | | Remove subdomain sending | DELETE /zones/{zone id}/email/sending/subdomains/{tag} | | Subdomain sending DNS records | GET .../subdomains/{tag}/dns | Requirements: Prefer CF TOKEN with Zone Read + Email Routing Edit + Email Sending Edit + Email Routing Rules Write or broader . If you use a legacy Global API Key instead, set CF API KEY and CF EMAIL . The hostname must be the account's Cloudflare zone apex or a subdomain under that zone. Root-domain sending uses the Cloudflare Email Service binding, while subdomain sending can also provision the sending-subdomain DNS records. Mailbox creation creates a Cloudflare Email Routing rule that sends that address to CF EMAIL WORKER NAME mailflare by default . App routes: GET/POST /api/domains — list / add calls Cloudflare GET/DELETE /api/domains/ id — get / remove disables routing & sending on CF GET /api/domains/ id /dns — routing + sending DNS snapshot cp .dev.vars.example .dev.vars Add CF TOKEN and optionally CF ACCOUNT ID. For a legacy Global API Key, use CF API KEY + CF EMAIL instead. npm install npm run db:migrate:local npm run dev Register at /register , complete /onboarding , or seed dev data: curl -X POST http://localhost:3000/api/seed Publish this repository to GitHub, then replace hieunc229/mailflare in the button at the top of this README with the public repository path. The deploy flow reads wrangler.jsonc , provisions the Worker bindings, prompts for values from .dev.vars.example , runs D1 migrations, builds the OpenNext Worker, and deploys it. Keep wrangler.jsonc committed. Cloudflare's deploy button uses it to detect the Worker entrypoint and required bindings. Do not commit .dev.vars ; deploy-time secrets should be entered through Cloudflare's setup flow or set locally in .dev.vars . Required setup values: CF TOKEN — runtime scoped Cloudflare API token with Zone Read, Email Routing Edit, Email Sending Edit, and Email Routing Rules Write. This is separate from Cloudflare's deploy/build token; Cloudflare does not automatically expose the deploy token to this app. CF ACCOUNT ID — optional unless your token can access multiple accounts. CF EMAIL WORKER NAME — must match the Worker name in wrangler.jsonc ; default is mailflare . If you rename the Worker, also update related literal resource names in wrangler.jsonc : name , services .service for WORKER SELF REFERENCE , CF EMAIL WORKER NAME , and any D1/R2/Queue names you want renamed. Cloudflare service bindings require the target Worker name to exist exactly; they cannot currently reference name dynamically. After deployment, route inbound mail to the Worker in Cloudflare Email Routing. If onboarding fails with Cloudflare API 403 ... code 9109: Invalid access token , Cloudflare rejected the credential before checking domain permissions. The Deploy to Cloudflare flow can authenticate and deploy the Worker, but it does not create a runtime CF TOKEN for Mailflare's onboarding API calls. Create CF TOKEN manually from Cloudflare dashboard user API tokens and enter it as a deploy secret/variable. Verify the token: curl "https://api.cloudflare.com/client/v4/user/tokens/verify" \ -H "Authorization: Bearer