LLMailBot is a service that enables chatting with Large Language Models (LLMs) via email. It connects to an email account using IMAP/SMTP protocols, then automatically responds to incoming emails using LLM chat models like GPT-4, Claude, or other compatible models.
Note that sending programatically generated emails to third parties may be against the terms of service of your email provider.
- LLM Integration: Uses LangChain chat models to provide compatibility with most mainstream LLMs
- Security: Includes basic security features such as rate limiting and address filtering
- Dynamic Configuration: Supports multiple model configurations based on pattern-matching email addresses
- Scalability: Horizontally scalable architecture using Redis queues for high-volume deployments
- Flexible Deployment: Run using Pipx, Docker, or Docker Compose depending on your needs
LLMailBot has basic address filtering, but it is not extremely secure:
- LLMailBot will only reply to emails from addresses in the
AllowFromlist configured in your settings. - However, the
AllowFromfilter only checks the From header of incoming emails, which is vulnerable to spoofing.
Email spoofing is possible because email From headers are just something the sender writes, they don't need to match where the email actually comes from.
Mail servers use technologies like SPF, DKIM, and DMARC to block malicious spoofed emails, but it's not perfect. Email spoofing tends to work due to misconfigured mail servers or domains. So if you only allow addresses from major email providers you should be relatively safe.
To be even more safe, you may want to only allow emails from the same domain as the service. For example, if LLMailBot is set up on myservice@example.com, only allow myname@example.com, myfriend@example.com, etc. It should be hard to trick a mail server into accepting spoofed emails claiming to be from its own domain.
It's much more likely that example.com could be tricked into accepting spoofed emails from sketchy domains or the domains of small businesses with misconfigured domains/servers.
I developed LLMailBot for my own personal use. Use it at your own risk.
- Never connect LLMailBot to a personal email account - it may delete your emails
- Create a dedicated email account specifically for LLMailBot usage
- Configure restrictive AllowFrom settings - only allow specific addresses from domains you trust
- Set up API key limitations - use LLM API keys with rate or cost limits you're comfortable with
- Avoid sensitive information - don't send sensitive data via email or include it in system prompts
Only plain text emails are supported. But for accessibility reasons, well-behaved email clients should automatically include a text/plain alternative version when sending richly formatted emails.
LLMailBot does not store emails or track conversations. Usually, when replying, email clients copy the entire chain in the reply. LLMailBot does the same when it replies. That way the context of the conversation is saved in the emails themselves.
Emails are minimally preprocessed, so the quality of responses depends on the ability of models to "understand" nested quoted replies. Messages in the chain are usually ordered from newest to oldest, unlike chat messages. It seems to work OK with the models I tested, but your mileage may vary.
-
Install LLMailBot:
# Install from PyPI (recommended) pipx install llmailbot # Or install directly from GitHub pipx install git+https://github.com/jbchouinard/llmailbot.git
-
Add LangChain provider packages for your preferred LLMs:
# Install only the providers you need pipx inject llmailbot langchain-openai langchain-anthropic langchain-ollama -
Create your configuration:
# Interactive configuration llmailbot config interactive # Or generate an example configuration and edit it manually llmailbot config example # Then edit the generated config.yaml file
If you place the config in a standard location, you can omit the
--configoption. -
Start the service:
# Run with your configuration file llmailbot --config path/to/config.yaml run
-
Prepare your configuration:
- Use the interactive configuration command to create your config file:
llmailbot config interactive
- Or copy and edit the example configuration:
llmailbot config example # Then edit the generated config.yaml file
- Use the interactive configuration command to create your config file:
-
Choose a Docker image variant:
The
allvariant includes these langchain provider packages pre-installed:- langchain-ai21 - AI21 models (Jurassic)
- langchain-anthropic - Anthropic models (Claude)
- langchain-aws - AWS Bedrock models
- langchain-azure-ai - Azure OpenAI models
- langchain-cohere - Cohere models
- langchain-fireworks - Fireworks AI models
- langchain-google-genai - Google Gemini models
- langchain-google-vertexai - Google Vertex AI models
- langchain-groq - Groq models (LLaMA, Mixtral)
- langchain-mistralai - Mistral AI models
- langchain-nvidia-ai-endpoints - NVIDIA AI models
- langchain-openai - OpenAI models (GPT-3.5, GPT-4, etc.)
- langchain-together - Together AI models
- langchain-xai - XAI models
Run the
allvariant (works out of the box with most popular models):docker run -d --name llmailbot \ -v /absolute/path/to/config.yaml:/app/config.yaml \ jbchouinard/llmailbot:all
The
slimvariant has no langchain provider packages pre-installed, making it smaller but requiring additional setup:-
Create a
requirements.txtfile with your needed providers, e.g.:# requirements.txt langchain-openai langchain-anthropic -
Run the
slimvariant with your requirements:docker run -d --name llmailbot \ -v /absolute/path/to/config.yaml:/app/config.yaml \ -v /absolute/path/to/requirements.txt:/app/requirements.txt \ jbchouinard/llmailbot:slim
The repo has an example docker-compose.yaml, using inline configuration.
-
Start the services:
cd docker-compose docker-compose up -d -
Scale services horizontally (optional):
# Run 3 worker instances for parallel processing docker-compose up -d --scale worker=3 # You can scale any service as needed docker-compose up -d --scale fetcher=2 --scale worker=5 --scale sender=2
See examples/config.yaml for detailed configuration options and explanations.
The repo contains two example stacks for deployment with docker stack deploy:
- docker-stack.simple.yaml - Single container with in-memory queues
- docker-stack.redis.yaml - Multi-containers with Redis queues
They are the better starting point for a production-style deployment as they use docker secrets for all sensitive config.
-
Clone the repository:
git clone https://github.com/jbchouinard/llmailbot.git cd llmailbot -
Install dependencies:
# Install base dependencies poetry install # (Optional) Add additional langchain providers poetry add --group langchain langchain-ollama # Install with langchain group poetry install --with langchain
-
Run the application:
# View available commands poetry run llmailbot --help # Run with a config file poetry run llmailbot --config path/to/config.yaml run
RepliedFolder or BlockedFolder are set to null, LLMailBot will delete emails instead of moving them.
All configuration options are documented in examples/config.yaml with explanations and examples.
llmailbot loads configuration from multiple sources:
- Constructor Arguments: Values passed directly to the
LLMailBotConfigconstructor - YAML File: Loaded from one of several possible locations
- Secret Files: Loaded from
/run/secretsand/var/run/llmailbot/secrets/
If the config file location is not specified by the --config CLI options, the app searches for a YAML configuration file in the following locations (in order):
./config.yaml(current directory)~/.config/llmailbot/config.yaml(Unix convention)- OS-specific conventional location (using the
config-pathpackage):- Windows: Uses
%APPDATA%\net.pigeonland.llmailbot.yaml(typicallyC:\Users\<username>\AppData\Roaming\net.pigeonland.llmailbot.yaml) - macOS:
~/Library/Preferences/net.pigeonland.llmailbot.yaml - Linux/Other:
~/.config/net.pigeonland.llmailbot.yaml(follows XDG Base Directory Specification)
- Windows: Uses
Configuration can be loaded from secrets files (e.g. produced by Docker Secrets).
Secret files are loaded from /run/secrets or /var/run/secrets/llmailbot/. They must be in JSON format.
Each top-level block in the YAML config corresponds to a secret file:
| Configuration Section | Secret File Path |
|---|---|
| Models | secrets/models |
| ChatModelConfigurableFields | secrets/chatmodelconfigurablefields |
| SMTP | secrets/smtp |
| IMAP | secrets/imap |
| Security | secrets/security |
| ReceiveQueue | secrets/receivequeue |
| SendQueue | secrets/sendqueue |
LLMailBot supports loading provider API keys from files by setting PROVIDER_API_KEY_FILE environment variables.
For example, to load OpenAI API keys from a Docker secret, you could set set:
services:
llmailbot:
...
secrets:
- source: openai_api_key
target: /run/secrets/openai_api_key
environment:
...
- OPENAI_API_KEY_FILE=/run/secrets/openai_api_keyThis project uses GitHub Actions for continuous integration and delivery:
-
CI Workflow: Runs on push to main and pull requests
- Linting with ruff
- Code formatting with ruff format
- Unit tests with pytest
- Docker build test
-
Docker Publish Workflow: Runs on push to main, tags with 'v*' pattern, and releases
- Builds and pushes Docker images to Docker Hub
- Creates two variants:
slim(without langchain packages) andall(with langchain packages)
Apply linting and formatting fixes locally:
# Run linting checks and auto-fix issues
poetry run ruff check --fix
# Format code according to project standards
poetry run ruff formatRun the test suite locally:
# Run all tests
poetry run pytest tests
# Run with verbose output
poetry run pytest -v tests
# Run a specific test file
poetry run pytest tests/test_specific_module.pyThis project is licensed under the MIT License - see the LICENSE file for details.
Copyright 2025 Jerome Boisvert-Chouinard