A natural-language CLI agent for Gmail, powered by any OpenAI-compatible LLM (local or hosted).
Project description
📧 MixMail
Talk to your Gmail in plain English. MixMail is a command-line agent that turns natural-language requests — "summarize the visa thread", "draft a reply saying I'm available Friday", "archive this month's promotions" — into real Gmail actions. It runs on any OpenAI-compatible LLM, local or hosted.
pip install mixmail
mixmail
You ❯ what came in from recruiters this week, and star anything urgent
· Searching Gmail…
MixMail ▸
You have 3 recruiter emails this week:
1. Amazon Recruiting — "ML Engineer, Seattle" (Tue) ★ starred
2. Deloitte Talent — "Interview scheduling" (Mon)
3. Stealth Startup — "Founding engineer" (Mon)
What it can do
| Read | Organise | Compose |
|---|---|---|
| Natural-language search | Mark read / unread | Draft emails |
| Read full messages & bodies | Star / unstar | Send email (confirmed) |
| Summarise whole threads | Archive | Reply / reply-all (confirmed) |
| List labels | Move to Trash (confirmed) | |
| Download attachments |
- Safety first. Sending, replying, and trashing always show a preview and
ask for confirmation. Gmail access defaults to read-only until you opt in
to
full. - Streaming. Answers stream as they're generated, with live progress for each tool the agent runs.
- Bring your own model. Local (LM Studio, llama.cpp, Ollama, vLLM) or hosted (OpenAI, Groq, Together, OpenRouter). Use OpenRouter to run Claude or Gemini through the same interface.
Install
pip install mixmail # from PyPI
mixmail # first run launches a guided setup wizard
Or from source:
git clone <your-fork> && cd MixMail
pip install -e ".[dev]"
Setup
On first launch MixMail walks you through setup. You can re-run it anytime with
/wizard. You'll need two things:
1. A language model
MixMail talks to an OpenAI-compatible Chat Completions endpoint.
- Local (no API key): start your server and use its base URL, e.g.
http://localhost:1200/v1. - Hosted: set the base URL and an API key, e.g. OpenAI
(
https://api.openai.com/v1), Groq, Together, or OpenRouter. For Claude or Gemini, use OpenRouter's base URL and a model id likeanthropic/claude-3.5-sonnet.
Configure inside the app with /llm_url, /model, and /api_key.
2. Gmail credentials
- In the Google Cloud Console, create a project and enable the Gmail API.
- Configure the OAuth consent screen (add your address as a test user).
- Create an OAuth client ID of type Desktop app and download the JSON.
- In MixMail, run
/mail_credsand paste the JSON or its file path.
On your first query MixMail opens a browser for Google sign-in and stores the token automatically.
Choosing access level
/scope
readonly(default) — search and read only.full— also send, reply, draft, label, archive, and trash.
Switching scope requires re-authenticating: delete the token shown in /setup
and sign in again.
Commands
| Command | Action |
|---|---|
| (plain text) | Ask anything about your email |
help |
Show usage tips |
reset |
Clear conversation history |
/wizard |
Re-run guided setup |
/llm_url · /model · /api_key |
Configure the LLM |
/mail_creds |
Paste or import Google OAuth JSON |
/scope |
Switch between readonly and full |
/setup |
Show current config locations |
quit |
Exit |
Configuration
All settings live in ~/.mixmail/.env (or a .env in the working directory).
See .env.example. Key variables:
| Variable | Default | Purpose |
|---|---|---|
LLM_BASE_URL |
http://localhost:1200/v1 |
OpenAI-compatible endpoint |
LLM_MODEL |
qwen2.5-coder-1.5b-instruct |
Model id |
LLM_API_KEY |
(empty) | Key for hosted providers |
GMAIL_SCOPE_MODE |
readonly |
readonly or full |
MAX_RESULTS |
10 |
Emails per search |
How it works
You ──▶ mixmail CLI ──▶ EmailAgent ──▶ LLM (tool-calling)
│ │
│ tool calls (search, send, …)
▼ ▼
confirmation Gmail API
The agent sends your message plus tool descriptions to the model, runs whatever tools the model requests (asking you first for destructive ones), feeds results back, and repeats until it has a final answer — which it streams to you.
Development
pip install -e ".[dev]"
python -m unittest discover -s tests -t . # or: pytest
python -m build # build a wheel + sdist
The test suite stubs out Google and network access, so it runs anywhere without touching your real inbox.
Security notes
- MixMail runs entirely on your machine; your email and API key never leave it except to the LLM endpoint and Gmail you configure.
.env,token.json, andclient_secret*.jsonare git-ignored. Don't commit them. If you ever did, rotate the credentials.- Read-only is the default. Grant
fullaccess only when you want MixMail to send or modify mail.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mixmail-2.0.0.tar.gz.
File metadata
- Download URL: mixmail-2.0.0.tar.gz
- Upload date:
- Size: 28.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd431c27da222f9cd1815a5860c2c5ac555eb366b162f614c88f78b1db030b28
|
|
| MD5 |
3896b6cb49015bcaf0ced48cfd590843
|
|
| BLAKE2b-256 |
c2528e634d42f0f856b573741c5af9cba14f93bbde61a7482bee1f9d44b7cea1
|
File details
Details for the file mixmail-2.0.0-py3-none-any.whl.
File metadata
- Download URL: mixmail-2.0.0-py3-none-any.whl
- Upload date:
- Size: 25.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5251ce2a3df17c2d3f83aaca1b5b2a6494c3bdfa68031f8518b2df4aaedcd6a0
|
|
| MD5 |
a91c507ae4a3ec39a2d171c25d396a3c
|
|
| BLAKE2b-256 |
198991129f3fd4d982aa87e49141d0e7ba5ff0c0c51d091667f8a50008580897
|