Adapters
mxr keeps provider-specific logic in adapters. The rest of the app works against one internal model.
Current adapter surface
Section titled “Current adapter surface”| Adapter | Sync | Send | Labels / folders | Mutations | Notes |
|---|---|---|---|---|---|
| Gmail | yes | yes | labels | yes | direct Gmail adapter |
| IMAP | yes | no | folders | yes | usually paired with SMTP |
| SMTP | no | yes | no | no | send-only adapter |
| Outlook Personal | yes | yes | folders/categories | yes | Microsoft consumer accounts |
| Outlook Work | yes | yes | folders/categories | yes | Microsoft 365 work/school accounts |
| Fake | yes | yes | fixture labels | yes | tests and local development |
Why this boundary matters
Section titled “Why this boundary matters”- Store and search do not need provider-specific code.
- The daemon can swap providers without being rewritten.
- New adapters have one contract to satisfy instead of a pile of hidden assumptions.
Contract
Section titled “Contract”The daemon talks to providers through MailSyncProvider and MailSendProvider.
That means:
- core defines the traits
- adapters depend on core
- daemon uses the traits, not provider-specific client types
Provider weirdness stops here. Above this layer, the daemon and IPC should speak internal mail/runtime concepts, not Gmail- or IMAP-specific payloads.
Conformance
Section titled “Conformance”mxr-provider-fake exports conformance helpers and canonical fixtures so adapter authors can test behavior before plugging anything into the daemon.
That suite is there to keep adapter work boring in the best way. If an adapter passes the contract, the rest of the system should not have to care where the mail came from.
Writing a new adapter
Section titled “Writing a new adapter”- Create a crate that depends only on
mxr-core. - Implement one or both provider traits.
- Map provider state into the mxr internal model.
- Run the conformance and fixture tests.
For the detailed contract, see: