Skip to main content

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 like anthropic/claude-3.5-sonnet.

Configure inside the app with /llm_url, /model, and /api_key.

2. Gmail credentials

  1. In the Google Cloud Console, create a project and enable the Gmail API.
  2. Configure the OAuth consent screen (add your address as a test user).
  3. Create an OAuth client ID of type Desktop app and download the JSON.
  4. In MixMail, run /mail_creds and 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, and client_secret*.json are git-ignored. Don't commit them. If you ever did, rotate the credentials.
  • Read-only is the default. Grant full access only when you want MixMail to send or modify mail.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mixmail-2.0.0.tar.gz (28.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mixmail-2.0.0-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

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

Hashes for mixmail-2.0.0.tar.gz
Algorithm Hash digest
SHA256 bd431c27da222f9cd1815a5860c2c5ac555eb366b162f614c88f78b1db030b28
MD5 3896b6cb49015bcaf0ced48cfd590843
BLAKE2b-256 c2528e634d42f0f856b573741c5af9cba14f93bbde61a7482bee1f9d44b7cea1

See more details on using hashes here.

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

Hashes for mixmail-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5251ce2a3df17c2d3f83aaca1b5b2a6494c3bdfa68031f8518b2df4aaedcd6a0
MD5 a91c507ae4a3ec39a2d171c25d396a3c
BLAKE2b-256 198991129f3fd4d982aa87e49141d0e7ba5ff0c0c51d091667f8a50008580897

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page