This repository currently contains a working V1 implementation plus a documented V2 redesign path.
Current baseline documents:
docs/development.mddocs/mailu-fork-architecture.mddocs/openapi.yamldocs/openapi-v2.yamldocs/db/schema.sql
Recommended redesign documents:
docs/redesign-architecture.mddocs/redesign-schema.mddocs/mailagents-v2-technical-design.mddocs/openapi-v2.yamldocs/openapi-admin-v2.yamldocs/db-migration-v2.sqldocs/sprint-1-implementation-plan.md
Start with the customer-facing guide: docs/user-guide.md.
Operational handoff documents:
docs/project-retrospective.mddocs/current-production-state.md
If the project is being evolved instead of patched incrementally, start from:
docs/redesign-architecture.mddocs/redesign-schema.md
Current capabilities:
- SIWE challenge/verify (
mockandstrictmodes) - JWT auth (HS256)
- Mailbox allocate/release
- Latest message fetch
- Webhook creation
- Usage summary and invoice query
- x402-style protection (
mockandhmac) - Switchable storage backend:
memory(default) /postgres - Dual runtime support: Node server + Cloudflare Worker entry
- Live Admin Dashboard backed by
/v1/admin/* - Postgres-backed admin persistence for tenant quotas, webhook delivery state, risk policies, and risk events
- Free usage within tenant/agent limits, then paid bypass at
0.001 USDCper over-limit request - Admin-editable runtime limits persisted in storage (
memoryin-process,postgresacross restarts) - Configurable mailbox domain via
MAILBOX_DOMAIN - Mail backend adapter layer with
noopandmailubackends - Local
mailu-devsimulator for Mailu fork integration development
npm startDefault URL: http://localhost:3000
Health endpoint: GET /healthz
Admin dashboard URL (same deployment): /admin
User app URL (same deployment): /app
If a browser wallet is available, /app now prefers real wallet signing for SIWE and falls back to mock signature only when needed.
- Create env file:
cp .env.example .env- Start services:
docker compose up --build- API URL:
http://localhost:3000
Compose automatically:
- starts PostgreSQL
- starts
mailu-devsimulator - runs migrations
- runs seed data
- starts API with
postgresbackend andMAIL_PROVIDER=mailu - provisions the admin persistence schema used by the dashboard
After docker compose up --build, run:
npm run smoke:mailuThis validates:
- mailbox allocation through the mail backend adapter
- mailbox provisioning in
mailu-dev - inbound relay from
mailu-devinto/internal/inbound/events - OTP/link extraction through
messages/latest
cp .env.production.example .env.production
npm run preflight:prod
docker compose -f docker-compose.prod.yml up --build -dProduction rollout details live in docs/production-runbook.md.
If you want everything in one place, use docs/single-host-deployment.md.
Cloudflare DNS and MX details live in docs/cloudflare-dns-setup.md.
Mailu host preparation details live in docs/mailu-host-prep.md.
Outbound mail auth details for Gmail-class receivers live in docs/mail-auth-setup.md.
npm installThe repository already includes wrangler.toml with:
main = "src/worker.js"compatibility_flags = ["nodejs_compat"]
Update vars values as needed.
npx wrangler secret put JWT_SECRET
npx wrangler secret put X402_HMAC_SECRET
npx wrangler secret put DATABASE_URLnpm run worker:devnpm run worker:deployNote:
- If using Postgres in Worker runtime, configure
DATABASE_URLvia Hyperdrive connection string. - For first migration/seed, run them from CI or trusted backend job, not from Worker cold start.
docs/db/schema.sqlis a bootstrap schema; upgrading an existing database requires applying equivalent ALTER/CREATE statements before switching Worker runtime topostgres.
make helpCommon targets:
make up/make downmake logsmake psmake migratemake seedmake smoke
npm testnpm run db:migrate- Applydocs/db/schema.sqlnpm run db:bootstrap- Apply schema only when the database is emptynpm run db:upgrade- Apply additive schema upgrades for existing databasesnpm run db:seed- Seed tenant/agent/mailboxes/invoice datanpm run reconcile:mailboxes- Compare control-plane mailbox state with backend mailbox state (-- --repairto apply safe repairs)npm run siwe:verify- Verify SIWE message + signature from CLInpm run preflight:prod- Validate production readiness of current env varsnpm run verify:prod- Basic post-deploy production verificationnpm run verify:mail-auth- Validate PTR, SPF, DKIM, and DMARC visibility for the live mail domainnpm run verify:dns -- mailagents.net 149.28.123.3- Validate API and mailbox DNS recordsnpm run smoke- Local API smoke testnpm run mailu-dev- Run the local Mailu dev simulatornpm run smoke:mailu- Local API +mailu-devintegration smoke testnpm run worker:dev- Run Worker locally with Wranglernpm run worker:deploy- Deploy Worker
Core:
PORT(default:3000)JWT_SECRETADMIN_API_TOKENBASE_CHAIN_ID(default:84532)MAILBOX_DOMAIN(default:inbox.mailagents.netin current deployment)MAIL_PROVIDER(noopormailu)STORAGE_BACKEND(memoryorpostgres)DATABASE_URL(required forpostgres)MAILU_BASE_URLMAILU_API_TOKENMAILU_RELEASE_MODEMAILU_QUOTA_BYTESMAILU_AUTH_SCHEMEMAIL_SMTP_HOSTMAIL_SMTP_PORTMAIL_SMTP_SECUREINTERNAL_API_TOKENWEBHOOK_SECRET_ENCRYPTION_KEYWEBHOOK_TIMEOUT_MSWEBHOOK_RETRY_ATTEMPTS
SIWE:
SIWE_MODE(mockdefault, orstrict)SIWE_DOMAIN(default:localhost)SIWE_URI(default:http://localhost)SIWE_STATEMENTSIWE_CHALLENGE_TTL_MS(default:300000)
x402:
PAYMENT_MODE(mockorhmac)X402_HMAC_SECRETX402_HMAC_SKEW_SEC(default:300)
Seed:
SEED_WALLET_ADDRESSSEED_TENANT_NAMESEED_AGENT_NAMESEED_MAILBOX_COUNT
SIWE verify CLI:
SIWE_MESSAGEor stdinSIWE_SIGNATURE- optional:
SIWE_ADDRESS,SIWE_NONCE
- Set
ADMIN_API_TOKENto protect/v1/admin/*with a dedicated admin credential. - Run
npm run preflight:prodbefore production deployment. - For existing databases, run
npm run db:upgradebefore switching application code. - After
db:upgrade, rotate existing webhook secrets sosecret_encis populated and outbound webhook signing is enabled. - In production, use:
SIWE_MODE=strictPAYMENT_MODE=hmacMAIL_PROVIDER=mailuSTORAGE_BACKEND=postgres
On-chain settlement, Redis queues, and full mail backend integrations are not implemented yet.
Setting MAILBOX_DOMAIN changes allocated mailbox addresses to your chosen domain. The current recommended pattern is api.mailagents.net for API traffic and inbox.mailagents.net for mailbox addresses. Real inbound email still requires DNS, MX, and a mail ingestion backend.
Mailu fork architecture notes live in docs/mailu-fork-architecture.md.
Current transitional adapter notes live in docs/mailu-integration.md.
Internal Mailu-to-control-plane contract lives in docs/mailu-internal-api.md.
Mailbox reconciliation notes live in docs/mailbox-reconciliation.md.
Production rollout notes live in docs/production-runbook.md.
Real Mailu cutover notes live in docs/mailu-cutover-checklist.md.
Cloudflare DNS setup notes live in docs/cloudflare-dns-setup.md.
Mailu host preparation notes live in docs/mailu-host-prep.md.
mailu-dev is a local development simulator only; it is not the final Mailu fork implementation.
An example host Nginx reverse proxy for Mailu web UI lives in deploy/nginx/mailu-web.conf.example.
Mailu setup download notes live in docs/mailu-setup-download.md.
Mailu colocated rewrite notes live in docs/mailu-colocated-rewrite.md.
Mailu certificate renewal notes live in docs/mailu-cert-renewal.md.
Mail authentication rollout notes live in docs/mail-auth-setup.md.
docker-compose.prod.yml now includes a mailu-sync sidecar for Maildir-to-control-plane ingestion.
Use npm run reparse:messages -- --apply to re-run the current parser against historical inbound messages stored in PostgreSQL.