An AI-powered email agent that syncs your emails via IMAP and provides intelligent analysis using OpenAI, Anthropic, or local Ollama.
# Clone the repository
git clone https://github.com/peterretief/emailai.git
cd emailai
# Build
go build -o emailai .
# Or install directly
go install github.com/peterretief/emailai@latest
# Copy the example config
cp config.example.json config.json
# Edit with your settings
nano config.json
{
"imap": {
"host": "imap.gmail.com",
"port": 993,
"username": "you@gmail.com",
"password": "your-app-password",
"tls": true
},
"smtp": {
"host": "smtp.gmail.com",
"port": 587,
"username": "you@gmail.com",
"password": "your-app-password",
"tls": true
}
}
Choose one of the supported AI providers:
OpenAI:
{
"ai": {
"enabled": true,
"provider": "openai",
"api_key": "sk-your-key-here",
"model": "gpt-4"
}
}
Anthropic:
{
"ai": {
"enabled": true,
"provider": "anthropic",
"api_key": "sk-ant-your-key-here",
"model": "claude-3-opus-20240229"
}
}
Ollama (Local, free):
Install Ollama from https://ollama.com, then pull a local model:
ollama pull llama3.1:8b
Make sure the Ollama server is running:
ollama serve
Configure EmailAI to use the local model:
{
"ai": {
"enabled": true,
"provider": "ollama",
"api_key": "",
"model": "llama3.1:8b",
"max_tokens": 2048
}
}
Good free local model choices include llama3.1:8b, qwen2.5:7b, and mistral:7b. For email analysis and structured extraction, qwen2.5:7b is also worth trying:
ollama pull qwen2.5:7b
Then set ai.model to qwen2.5:7b.
# Sync all emails
./emailai -action sync
# Sync specific folder
./emailai -action sync -folder INBOX
# Force a complete rescan when needed
./emailai -action sync -full-sync
# Run as continuous sync server
./emailai -action serve
# Analyze emails with AI
./emailai -action analyze -query "meeting"
# List contacts found in downloaded mail
./emailai -action contacts -limit 100
# View sync stats
./emailai -action stats
# Search email text and locally extracted OCR text
./emailai -action search -folder INBOX -query "driver licence"
# Restrict the search to image attachments
./emailai -action search -folder INBOX -attach jpg -query "driver licence"
# Send test email
./emailai -action send
For large Gmail mailboxes, increase the batch size in config.json so each sync run imports more messages:
{
"sync": {
"maildir_path": "",
"store_path": "./emails",
"max_batch_size": 1000
}
}
Run sync repeatedly until each folder is up to date:
while ./emailai -action sync; do sleep 10; done
Press Ctrl+C to stop the loop.
emailai/
βββ main.go # Entry point and CLI
βββ config/
β βββ config.go # Configuration management
βββ sync/
β βββ sync.go # IMAP sync engine
βββ store/
β βββ store.go # Local email storage
βββ ai/
β βββ ai.go # AI processing (OpenAI/Anthropic/Ollama)
βββ smtp/
β βββ smtp.go # Email sending
βββ config.example.json # Example configuration
βββ README.md
| Option | Description | Default |
|---|---|---|
imap.host | IMAP server hostname | imap.gmail.com |
imap.port | IMAP server port | 993 |
imap.username | Email address | - |
imap.password | App password | - |
imap.tls | Use TLS encryption | true |
smtp.host | SMTP server hostname | smtp.gmail.com |
smtp.port | SMTP server port | 587 |
ai.enabled | Enable AI features | false |
ai.provider | AI provider (openai, anthropic, ollama) | openai |
ai.model | Model to use | gpt-4 |
sync.interval | Sync interval in seconds | 300 |
sync.folders | Folders to sync (empty = all) | [] |
sync.max_batch_size | Max emails per sync batch | 100 |
sync.store_path | Local storage path | ./emails |
sync.timeout_seconds | Maximum time for one IMAP command | 120 |
sync.maildir_path | Local Maildir root managed by mbsync/isync | empty |
filters.exclude_newsletters | Exclude matching newsletter/marketing emails from local search and analyze results | false |
filters.exclude_from | Sender substrings to exclude when newsletter filtering is enabled | newsletter/no-reply/etc. |
filters.exclude_subject | Subject substrings to exclude when newsletter filtering is enabled | newsletter/digest/etc. |
filters.exclude_body | Body substrings to exclude when newsletter filtering is enabled | unsubscribe/etc. |
ocr.enabled | Run local OCR on image attachments | false |
ocr.command | OCR executable | tesseract |
ocr.languages | Tesseract language list | eng |
ocr.timeout_seconds | Maximum OCR runtime per image | 60 |
ocr.max_bytes | Maximum image size sent to OCR | 10485760 |
When ocr.enabled is true, image attachments are processed locally with Tesseract during sync. Extracted text is stored in the local email JSON and included in search. Attachment image bytes are not stored by the OCR feature.
Normal syncs store a per-folder IMAP UID watermark and fetch only newer messages. Use -full-sync to rescan every message, for example after enabling OCR or changing message parsing.
Set filters.exclude_newsletters to true to keep obvious newsletters, promotions, and automated bulk mail out of search and analyze results. Tune the exclude_from, exclude_subject, and exclude_body lists for your mailbox.
To use mbsync/isync for mailbox synchronization, set sync.maildir_path to the Maildir root. When this is configured, the application reads local Maildir files and does not connect to IMAP. Run mbsync first, then run ./emailai -action sync to import new messages and process OCR.
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)This project is licensed under the MIT License - see the LICENSE file for details.
config.json file (it's in .gitignore)emails/ directory contains your synced emails - treat it as sensitive dataIf you have any questions or issues, please open an issue on GitHub.
14 commits
Go
97.0%
Makefile
3.0%
An AI-powered email agent that syncs your emails via IMAP and provides intelligent analysis using OpenAI, Anthropic, or local Ollama.
# Clone the repository
git clone https://github.com/peterretief/emailai.git
cd emailai
# Build
go build -o emailai .
# Or install directly
go install github.com/peterretief/emailai@latest
# Copy the example config
cp config.example.json config.json
# Edit with your settings
nano config.json
{
"imap": {
"host": "imap.gmail.com",
"port": 993,
"username": "you@gmail.com",
"password": "your-app-password",
"tls": true
},
"smtp": {
"host": "smtp.gmail.com",
"port": 587,
"username": "you@gmail.com",
"password": "your-app-password",
"tls": true
}
}
Choose one of the supported AI providers:
OpenAI:
{
"ai": {
"enabled": true,
"provider": "openai",
"api_key": "sk-your-key-here",
"model": "gpt-4"
}
}
Anthropic:
{
"ai": {
"enabled": true,
"provider": "anthropic",
"api_key": "sk-ant-your-key-here",
"model": "claude-3-opus-20240229"
}
}
Ollama (Local, free):
Install Ollama from https://ollama.com, then pull a local model:
ollama pull llama3.1:8b
Make sure the Ollama server is running:
ollama serve
Configure EmailAI to use the local model:
{
"ai": {
"enabled": true,
"provider": "ollama",
"api_key": "",
"model": "llama3.1:8b",
"max_tokens": 2048
}
}
Good free local model choices include llama3.1:8b, qwen2.5:7b, and mistral:7b. For email analysis and structured extraction, qwen2.5:7b is also worth trying:
ollama pull qwen2.5:7b
Then set ai.model to qwen2.5:7b.
# Sync all emails
./emailai -action sync
# Sync specific folder
./emailai -action sync -folder INBOX
# Force a complete rescan when needed
./emailai -action sync -full-sync
# Run as continuous sync server
./emailai -action serve
# Analyze emails with AI
./emailai -action analyze -query "meeting"
# List contacts found in downloaded mail
./emailai -action contacts -limit 100
# View sync stats
./emailai -action stats
# Search email text and locally extracted OCR text
./emailai -action search -folder INBOX -query "driver licence"
# Restrict the search to image attachments
./emailai -action search -folder INBOX -attach jpg -query "driver licence"
# Send test email
./emailai -action send
For large Gmail mailboxes, increase the batch size in config.json so each sync run imports more messages:
{
"sync": {
"maildir_path": "",
"store_path": "./emails",
"max_batch_size": 1000
}
}
Run sync repeatedly until each folder is up to date:
while ./emailai -action sync; do sleep 10; done
Press Ctrl+C to stop the loop.
emailai/
βββ main.go # Entry point and CLI
βββ config/
β βββ config.go # Configuration management
βββ sync/
β βββ sync.go # IMAP sync engine
βββ store/
β βββ store.go # Local email storage
βββ ai/
β βββ ai.go # AI processing (OpenAI/Anthropic/Ollama)
βββ smtp/
β βββ smtp.go # Email sending
βββ config.example.json # Example configuration
βββ README.md
| Option | Description | Default |
|---|---|---|
imap.host | IMAP server hostname | imap.gmail.com |
imap.port | IMAP server port | 993 |
imap.username | Email address | - |
imap.password | App password | - |
imap.tls | Use TLS encryption | true |
smtp.host | SMTP server hostname | smtp.gmail.com |
smtp.port | SMTP server port | 587 |
ai.enabled | Enable AI features | false |
ai.provider | AI provider (openai, anthropic, ollama) | openai |
ai.model | Model to use | gpt-4 |
sync.interval | Sync interval in seconds | 300 |
sync.folders | Folders to sync (empty = all) | [] |
sync.max_batch_size | Max emails per sync batch | 100 |
sync.store_path | Local storage path | ./emails |
sync.timeout_seconds | Maximum time for one IMAP command | 120 |
sync.maildir_path | Local Maildir root managed by mbsync/isync | empty |
filters.exclude_newsletters | Exclude matching newsletter/marketing emails from local search and analyze results | false |
filters.exclude_from | Sender substrings to exclude when newsletter filtering is enabled | newsletter/no-reply/etc. |
filters.exclude_subject | Subject substrings to exclude when newsletter filtering is enabled | newsletter/digest/etc. |
filters.exclude_body | Body substrings to exclude when newsletter filtering is enabled | unsubscribe/etc. |
ocr.enabled | Run local OCR on image attachments | false |
ocr.command | OCR executable | tesseract |
ocr.languages | Tesseract language list | eng |
ocr.timeout_seconds | Maximum OCR runtime per image | 60 |
ocr.max_bytes | Maximum image size sent to OCR | 10485760 |
When ocr.enabled is true, image attachments are processed locally with Tesseract during sync. Extracted text is stored in the local email JSON and included in search. Attachment image bytes are not stored by the OCR feature.
Normal syncs store a per-folder IMAP UID watermark and fetch only newer messages. Use -full-sync to rescan every message, for example after enabling OCR or changing message parsing.
Set filters.exclude_newsletters to true to keep obvious newsletters, promotions, and automated bulk mail out of search and analyze results. Tune the exclude_from, exclude_subject, and exclude_body lists for your mailbox.
To use mbsync/isync for mailbox synchronization, set sync.maildir_path to the Maildir root. When this is configured, the application reads local Maildir files and does not connect to IMAP. Run mbsync first, then run ./emailai -action sync to import new messages and process OCR.
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)This project is licensed under the MIT License - see the LICENSE file for details.
config.json file (it's in .gitignore)emails/ directory contains your synced emails - treat it as sensitive dataIf you have any questions or issues, please open an issue on GitHub.
14 commits
Go
97.0%
Makefile
3.0%