Files
mail-intake/docs/wiki/03_extending.md
Vishesh 'ironeagle' Bangotra 370d1272bf docs: add wiki and refresh flat lib with mcp artifacts
- Add hand-written wiki (index, overview, how-to, extending, dev)
  following the platform anatomy
- Remove stale nested docs/lib/mail_intake and regenerate the flat
  lib reference to match docforge.nav.yml
- Regenerate MCP bundle with standardized docstrings
2026-09-16 20:02:50 +05:30

106 lines
2.5 KiB
Markdown

# 🧩 Extending Mail Intake
Mail Intake is designed to be extended through its **public contracts**.
Implement your own adapter, auth provider, or credential store to support a
new provider or storage backend.
---
## 📬 Custom adapters
Subclass `MailIntakeAdapter` to integrate a new provider. Adapters perform
read-only transport and return provider-native payloads:
```python
from mail_intake.adapters import MailIntakeAdapter
class ExchangeAdapter(MailIntakeAdapter):
def __init__(self, auth_provider):
self._auth = auth_provider
def fetch_messages(self, query):
# call the provider API, return native payloads
...
def fetch_threads(self, query):
...
```
> **Do not** subclass built-in adapters like `MailIntakeGmailAdapter` — they
> are reference implementations and may change internally without notice.
---
## 🔐 Custom auth providers
Subclass `MailIntakeAuthProvider[T]` to own a different credential flow:
```python
from mail_intake.auth import MailIntakeAuthProvider
class ExchangeAuth(MailIntakeAuthProvider[exchange_credentials]):
def get_credentials(self):
return self._store.load()
def refresh(self):
...
```
Auth providers remain decoupled from adapter logic — they only manage
credentials.
---
## 🗄️ Custom credential stores
Implement the `CredentialStore[T]` contract for a new persistence backend:
```python
from mail_intake.credentials import CredentialStore
class S3CredentialStore(CredentialStore):
def save(self, credentials):
...
def load(self):
...
def delete(self):
...
```
The store abstraction keeps tokens out of config and rotates safely.
---
## 🧪 Wiring a custom backend
```python
from mail_intake.ingestion import MailIntakeReader
auth = ExchangeAuth(store=S3CredentialStore(...))
adapter = ExchangeAdapter(auth_provider=auth)
reader = MailIntakeReader(adapter)
for message in reader.iter_messages("query"):
print(message.subject)
```
The reader only depends on the adapter contract, so the rest of the pipeline
keeps working unchanged.
---
## ✅ Extension checklist
1. Implement the **public contract** — never subclass built-in adapters.
2. Keep transport in the adapter, parsing in parsers, auth in the provider.
3. Return the provider-native payload and let parsers normalize it.
4. Inject dependencies explicitly — no global state or env reads.
---
## 📚 Read Next
- [How to Use](02_how_to_use.md) — the built-in Gmail flow.
- [Development](04_development.md) — running tests and docs.