Configuration
Mailpilot is configured using a YAML file. This section provides comprehensive documentation for all configuration options.
Configuration File Location
Mailpilot searches for configuration in these locations (in order):
- Path specified by
--configflag ./config.yaml(current directory)~/.config/mailpilot/config.yaml
Quick Links
Global Settings
Concurrency, dry-run mode, and top-level options
Server & Dashboard
HTTP server, authentication, and web dashboard
Email Accounts
IMAP configuration and account-specific settings
LLM Providers
AI model configuration and provider settings
Folder Configuration
Folder modes, watch lists, and allowed folders
Prompts Guide
Write effective classification prompts
Folder Modes
Predefined, free-form, and structured folder modes
Notifications
Browser notifications and alert configuration
Attachments
Apache Tika integration for attachment processing
Antivirus
ClamAV integration for email scanning
Environment Variables
Mailpilot supports environment variable substitution using ${VAR_NAME} syntax:
accounts:
- name: personal
imap:
username: ${GMAIL_USER}
password: ${GMAIL_APP_PASSWORD}
llm_providers:
- name: openai
api_key: ${OPENAI_API_KEY}If an environment variable is not set, Mailpilot will fail to start with an error.
Duration Format
Duration values use a simple format:
| Unit | Example | Description |
|---|---|---|
ms | 500ms | Milliseconds |
s | 30s | Seconds |
m | 5m | Minutes |
h | 24h | Hours |
d | 7d | Days |
w | 2w | Weeks |
y | 1y | Years |
Examples:
polling_interval: 60s # 1 minute
processed_ttl: 24h # 24 hours
audit_retention: 30d # 30 days
session_ttl: 7d # 1 weekComplete Configuration Example
# Global settings
concurrency_limit: 5
dry_run: false
add_processing_headers: false
# State/Database
state:
database_path: ./data/mailpilot.db
processed_ttl: 24h
audit_retention: 30d
audit_subjects: false
# Server & Dashboard
server:
port: 8080
auth_token: ${AUTH_TOKEN}
dashboard:
enabled: true
session_ttl: 24h
api_keys:
- name: monitoring
key: ${MONITORING_API_KEY}
permissions: [read:stats, read:activity]
# Logging
logging:
level: info
file: ./logs/mailpilot.log
include_subjects: false
# LLM Providers
llm_providers:
- name: openai
provider: openai
api_key: ${OPENAI_API_KEY}
model: gpt-4o-mini
temperature: 0.1
# Default classification prompt
default_prompt: |
Classify this email and return a JSON action.
Available actions:
- move: Move to a specific folder
- flag: Mark as important/starred
- read: Mark as read
- archive: Archive the email
- noop: No action needed
Return JSON:
{
"action": "move",
"folder": "Important",
"confidence": 0.95,
"reasoning": "Brief explanation"
}
# Confidence scoring
confidence:
enabled: true
minimum_threshold: 0.7
request_reasoning: true
# Email Accounts
accounts:
- name: personal
imap:
host: imap.gmail.com
port: 993
username: ${GMAIL_USER}
password: ${GMAIL_APP_PASSWORD}
tls: true
folders:
- name: INBOX
llm_provider: openai
prompt: |
Classify this email into:
- Important
- Social
- Promotions
- Spam
polling_interval: 60s
webhooks:
- url: https://example.com/webhook
events: [action_taken, error]
# Retry settings
retry:
enabled: true
max_attempts: 5
initial_delay: 5m
max_delay: 24h
backoff_multiplier: 2
# Notifications
notifications:
enabled: true
channels: [browser]
events: [error, connection_lost, dead_letter]
quiet_hours:
enabled: true
start: "22:00"
end: "08:00"
# Attachments
attachments:
enabled: true
tika_url: http://localhost:9998
max_size_mb: 10
extract_images: false
# Antivirus
antivirus:
enabled: false
host: localhost
port: 3310
on_virus_detected: quarantineConfiguration Validation
Mailpilot validates your configuration on startup. Common validation errors:
Missing Required Fields
Error: Missing required field 'accounts[0].imap.host'Solution: Add the missing field to your configuration.
Invalid Duration Format
Error: Invalid duration '60' - must include unit (e.g., '60s')Solution: Add a unit suffix: 60s, 1m, 24h, etc.
Environment Variable Not Set
Error: Environment variable 'GMAIL_PASSWORD' is not setSolution: Set the environment variable before starting Mailpilot:
export GMAIL_PASSWORD="your-password"Invalid YAML Syntax
Error: YAML parse error at line 42Solution: Check YAML indentation and syntax. Use 2 spaces for indentation (not tabs).
Configuration Best Practices
1. Use Environment Variables for Secrets
Never commit passwords or API keys to version control:
# Good
api_key: ${OPENAI_API_KEY}
password: ${GMAIL_APP_PASSWORD}
# Bad - hardcoded secrets
api_key: sk-1234567890abcdef
password: my-actual-password2. Start with Dry Run Mode
Test your configuration without taking actions:
dry_run: true # Enable for testingThis logs what would happen without actually moving/flagging emails.
3. Use Descriptive Account Names
# Good
accounts:
- name: personal-gmail
- name: work-outlook
- name: newsletter-account
# Bad
accounts:
- name: account1
- name: account24. Set Appropriate Polling Intervals
Balance responsiveness with API rate limits:
# High-priority account - check frequently
polling_interval: 30s
# Low-priority account - check less often
polling_interval: 5m5. Configure Audit Retention
Keep audit logs for compliance or debugging:
state:
audit_retention: 90d # 90 days for compliance
audit_subjects: false # Don't log email subjects (privacy)6. Enable Retry Logic
Handle temporary failures gracefully:
retry:
enabled: true
max_attempts: 5 # Try up to 5 times
initial_delay: 5m # Wait 5 minutes before first retry
max_delay: 24h # Cap maximum delay
backoff_multiplier: 2 # Exponential backoffTesting Your Configuration
1. Validate Syntax
# Dry run to check configuration
pnpm start --dry-run
# Or check specific config file
pnpm start --config ./my-config.yaml --dry-run2. Check Environment Variables
# Verify all required env vars are set
env | grep -E "(GMAIL|OPENAI|ANTHROPIC)"3. Monitor Logs
# Watch logs in real-time
tail -f ./logs/mailpilot.log4. Use the Dashboard
Navigate to http://localhost:8080 to:
- View connection status
- Check recent actions
- Monitor errors
- Test classification prompts
Configuration by Use Case
Personal Email (Single Account)
concurrency_limit: 3
dry_run: false
llm_providers:
- name: openai
provider: openai
api_key: ${OPENAI_API_KEY}
model: gpt-4o-mini
accounts:
- name: personal
imap:
host: imap.gmail.com
port: 993
username: ${GMAIL_USER}
password: ${GMAIL_APP_PASSWORD}
folders:
- name: INBOX
llm_provider: openai
prompt: |
Classify into: Important, Social, Promotions, or Spam
polling_interval: 60sBusiness Email (Multiple Accounts)
concurrency_limit: 10
llm_providers:
- name: openai-premium
provider: openai
api_key: ${OPENAI_API_KEY}
model: gpt-4o
accounts:
- name: ceo-inbox
imap:
host: imap.gmail.com
port: 993
username: ${CEO_EMAIL}
password: ${CEO_PASSWORD}
folders:
- name: INBOX
llm_provider: openai-premium
prompt: |
Urgent business classification...
polling_interval: 30s
- name: support-inbox
imap:
host: imap.gmail.com
port: 993
username: ${SUPPORT_EMAIL}
password: ${SUPPORT_PASSWORD}
folders:
- name: INBOX
llm_provider: openai-premium
prompt: |
Support ticket classification...
polling_interval: 60sPrivacy-Focused (Local Models)
llm_providers:
- name: ollama
provider: ollama
base_url: http://localhost:11434
model: llama3.2:latest
accounts:
- name: private
imap:
host: imap.protonmail.com
port: 1143
username: ${PROTON_EMAIL}
password: ${PROTON_BRIDGE_PASSWORD}
tls: true
tls_options:
rejectUnauthorized: false
folders:
- name: INBOX
llm_provider: ollama
polling_interval: 120s
# No external API calls - complete privacy
attachments:
enabled: false
antivirus:
enabled: true # Local ClamAV scanning