Observed since 20 Oct, 22:17 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
A Model Context Protocol (MCP) server exposing Gmail operations for AI agents
A Model Context Protocol server that lets AI agents work with a Gmail account safely — read, search, summarize, and (opt-in) forward/archive/label — behind a layered safety model.
🔐 You bring your own Google app. This is a local tool, not a hosted service — you create your own OAuth client in your own Google Cloud project and authorize your own mailbox. Your credentials and token never leave your machine, and because the app only ever authorizes you, there's no central service and no Google verification to wait for.
ℹ️ Status:
0.1.0— available on PyPI:pip install agentic-mail-mcp(oruvx agentic-mail-mcp).
| 📥 Email operations | Search, read, forward, archive, delete, draft, and label |
| 🧠 Intelligence | Caller-first prompts (summarize, classify, reply, action items) + optional server-side digests |
| 🔎 Semantic search | Natural-language vector search over your mail |
| 🔔 Notifications | Webhook / Redis event fan-out |
| 🛡️ Railguards | Read-only by default, allowlists, rate limits, archive-first delete, draft-first send, audit log |
You need Python 3.11+ and a Google account. Five minutes end to end.
flowchart LR
A[1. Install] --> B[2. Google<br/>credentials]
B --> C[3. Configure<br/>.env]
C --> D[4. Authorize<br/>agentic-mail-mcp auth]
D --> E[5. Connect agent<br/>or run HTTP]
1. Install from PyPI (see Installation for extras & Docker):
pip install agentic-mail-mcp # or: uvx agentic-mail-mcp
2. Get Google credentials — in your Google Cloud project, enable the Gmail
API, make a Desktop-app OAuth client, and download its credentials.json.
Full walkthrough with the exact clicks:
Getting your Google credentials 👉.
3. Configure — run the guided wizard, which writes a valid .env for you
(and auto-generates the token encryption key):
agentic-mail-mcp init
Press Enter to accept each default; point it at the credentials.json you
downloaded when asked. Prefer to do it by hand? Copy .env.example to .env
and set at least:
# Point at the credentials.json you downloaded.
AGENTIC_MAIL_MCP_GMAIL_CLIENT_SECRETS_FILE=/path/to/credentials.json
AGENTIC_MAIL_MCP_GMAIL_TOKEN_ENCRYPTION_KEY=<any long random string>
# 🔒 Writes are denied by default. Keep read_only until you trust the setup.
AGENTIC_MAIL_MCP_RAILGUARDS_ACCESS_LEVEL=read_only
4. Authorize (one-time browser consent — stores an encrypted token):
agentic-mail-mcp auth
Confirm it worked at any time — this checks the token against Gmail and prints
the authorized account (exit code 0 on success, non-zero on failure, so it's
scriptable):
agentic-mail-mcp verify-auth
5. Use it — connect an AI agent over stdio or run the HTTP server. See Usage.
credentials.json (a Desktop-app client from your
Google Cloud project — how to get it)From PyPI (recommended):
pip install agentic-mail-mcp
💡 For MCP clients, prefer
uvx agentic-mail-mcp/pipx run agentic-mail-mcp— it runs the published package in an isolated environment with no virtualenv to manage.
Optional extras (combine as needed, e.g. "agentic-mail-mcp[postgresql,search]"):
| Extra | Adds |
|---|---|
postgresql | PostgreSQL + pgvector backends |
search | local embeddings + sqlite-vec semantic search |
notifications | Redis pub/sub notifications |
llm | local llama.cpp inference |
dev | test / lint / build tooling |
pip install "agentic-mail-mcp[search,llm]"
From source (development, or to track main):
pip install "git+https://github.com/CoolDevGuys/agentic-mail-mcp.git"
# or, from a clone:
pip install .
Docker: docker compose up --build (see HTTP server).
Set environment variables with the AGENTIC_MAIL_MCP_ prefix, or use a .env file
(copy .env.example). The table below covers the essentials; every setting,
with defaults and purpose — and the Google OAuth walkthrough — is in
specs/docs/configuration.md.
ℹ️
.envis optional — it's just a carrier for these variables, read from the server's working directory. Env vars take precedence. How you deliver config differs by transport: for stdio the MCP client launches the server (put vars in itsenvblock; a project.envusually isn't seen), while for HTTP you launch it yourself (a.envor exported vars both work). Full walkthrough: Configuration workflows: stdio vs HTTP.
| Variable | Description | Default |
|---|---|---|
AGENTIC_MAIL_MCP_GMAIL_CLIENT_SECRETS_FILE | Path to your downloaded credentials.json (recommended) | (one of these two) |
AGENTIC_MAIL_MCP_GMAIL_OAUTH_CLIENT_ID / _SECRET | …or the OAuth client id/secret directly | (one of these two) |
AGENTIC_MAIL_MCP_GMAIL_TOKEN_ENCRYPTION_KEY | Secret used to encrypt the stored token | (required to store tokens) |
AGENTIC_MAIL_MCP_GMAIL_TOKEN_STORAGE_PATH | Encrypted token file path (set outside the repo in prod) | token.json |
AGENTIC_MAIL_MCP_DATABASE_URL | SQLAlchemy URL (synchronous driver) | sqlite:///./agentic_mail_mcp.db |
AGENTIC_MAIL_MCP_RAILGUARDS_ACCESS_LEVEL | read_only or read_write — writes denied by default | read_only |
AGENTIC_MAIL_MCP_LLM_PROVIDER | openai (HTTP) or llamacpp (local) | openai |
AGENTIC_MAIL_MCP_LLM_API_KEY | LLM API key | (required for intelligence) |
AGENTIC_MAIL_MCP_MCP_TRANSPORT | stdio (default) or http | stdio |
AGENTIC_MAIL_MCP_MCP_HOST / AGENTIC_MAIL_MCP_MCP_PORT | HTTP transport bind address | 127.0.0.1 / 8080 |
The server speaks MCP over two transports:
| Transport | Best for | How |
|---|---|---|
| stdio (default) | one user on a laptop (Claude Desktop, IDE agents) | agent launches the process |
| HTTP (streamable) | shared / containerized deployments | long-running server on a port |
⚠️ Authorize first. Run
agentic-mail-mcp authonce (browser consent) before starting the server — it stores the encrypted token the server reads on every start. Details: Authorize.Headless server (no browser)?
authneeds a browser + loopback redirect, so you don't run it on the server. Authorize once on a machine that has a browser, then copy the encrypted token file across withscp— it's a binary file, so a clipboard copy-paste (cat token.json | pbcopy) corrupts it and the server can't decrypt it. See Headless / server deployment.
Point your MCP client at the server. With uvx the client runs the published
package directly — nothing to install globally:
{
"mcpServers": {
"gmail": {
"command": "uvx",
"args": ["agentic-mail-mcp", "serve"],
"env": {
"AGENTIC_MAIL_MCP_GMAIL_OAUTH_CLIENT_ID": "...",
"AGENTIC_MAIL_MCP_GMAIL_OAUTH_CLIENT_SECRET": "...",
"AGENTIC_MAIL_MCP_GMAIL_TOKEN_ENCRYPTION_KEY": "...",
"AGENTIC_MAIL_MCP_RAILGUARDS_ACCESS_LEVEL": "read_only"
}
}
}
}
If you installed with
pip, use"command": "agentic-mail-mcp","args": ["serve"].
💡 Prefer a file over inline vars? Run
agentic-mail-mcp initto create a.env, then point the server at it and leaveenvempty:"args": ["agentic-mail-mcp", "serve", "--env-file", "/abs/path/.env"]. See Configuration workflows.
The agent then discovers the tools, resources, and prompts described in the
MCP API reference. Start with read_only and enable
read_write deliberately once you understand the railguards.
Run a standalone streamable-HTTP server:
AGENTIC_MAIL_MCP_MCP_TRANSPORT=http AGENTIC_MAIL_MCP_MCP_HOST=0.0.0.0 AGENTIC_MAIL_MCP_MCP_PORT=8080 \
agentic-mail-mcp serve
Or with Docker (the compose file already sets HTTP transport and a health check):
docker compose up --build # server on http://localhost:8080
🔑 Auth on a headless host: authorize on your laptop and mount the encrypted token into the container (e.g.
-v /etc/agentic-mail-mcp:/secrets:ro) — full steps under Headless / server deployment.
The server exposes the streamable-HTTP endpoint at the /mcp path, so the
URL is http://<host>:<port>/mcp — by default http://localhost:8080/mcp.
Point an HTTP-capable MCP client at it:
{
"mcpServers": {
"gmail": {
"type": "http",
"url": "http://localhost:8080/mcp"
}
}
}
Notes:
AGENTIC_MAIL_MCP_MCP_HOST / _PORT. Binding
0.0.0.0 makes it reachable on all interfaces; clients still connect via a
concrete hostname/IP, and the path is always /mcp..env (via agentic-mail-mcp init) or exported vars, and run
agentic-mail-mcp auth once first."transport": "http" /
"streamable-http"); a stdio-only client (e.g. classic Claude Desktop) needs a
bridge such as mcp-remote pointed at the same /mcp URL.Full input/output schemas, resources, prompts, and error formats are in the MCP API reference.
search_emails — Search emails by subject, sender, recipient, date range, labels, attachments, unread statusget_email — Read a specific email by IDget_thread — Read a conversation threadlist_unread — List unread emailslist_labels — List labels (system, user, or all)read_write access)forward_email — Forward an email (recipient allowlist enforced)archive_email — Archive an email or threaddelete_email — Delete an email (trash by default, archive-first policy)create_draft — Create a draft for reviewsend_draft — Send a reviewed draftadd_label — Add a label to an emailThe calling agent is itself an LLM, so per-email reasoning ships as MCP prompts
the agent runs on data it fetches with get_email — no server-side inference,
no added latency, no LLM key required:
summarize_email · classify_email · draft_reply · extract_action_itemsInternal LLM inference is reserved for where it pays off (map-reduce over many emails), and registers only when an LLM is configured:
daily_digest · weekly_digestAGENTIC_MAIL_MCP_LLM_INTERNAL_TOOLS=true to also expose the per-email
ones as server-side tools. See ADR 0006.semantic_search — natural-language vector search (needs the search extra)agentic_mail_mcp/
Bootstrap/ CLI, Settings, Logging, Lifespan, DI Container
Common/ Shared domain primitives
Gmail/ Gmail bounded context
Intelligence/ LLM-powered email analysis
Search/ Semantic/vector search
Notification/ Event notifications
MCP/ MCP server, tools, resources, prompts
tests/
unit/ Unit tests
integration/ Integration tests
fakes/ Test doubles
Writes are denied by default. Safety is layered so an AI agent cannot mutate a mailbox unless a human deliberately enables it:
read_only (default) or read_write. The master switch.
Under read_only, write tools are not even registered with the MCP server
(defense in depth), so the agent never sees them — not merely blocked at call
time.@example.com).{"forward": 50}).send_draft is a separate, explicit step.A railguard denial surfaces to the agent as a structured permission_denied
error, never as an unhandled exception. See the
railguards configuration and
ADR 0004.
A Makefile wraps the common tasks (run make to list them):
make setup # first-time: create .venv, install dev deps, .env, run migrations
make auth # one-time Google authorization (browser consent)
make run # start the server (stdio); make run-http for HTTP transport
make test # full test suite with coverage gates (as CI runs)
make check # lint (ruff) + type-check (mypy) + tests
make format # auto-format and fix imports
make migrate # apply DB migrations; make migration m="..." to autogenerate
make build # build the sdist + wheel and validate metadata
Prefer raw tools? They work too: pytest, ruff check agentic_mail_mcp tests, mypy agentic_mail_mcp,
alembic upgrade head. All make targets run inside a local .venv.
openspec/ — propose a change,
generate its spec deltas, implement, then archive.Domain/, ≥80% overall) and
ensure ruff check and mypy agentic_mail_mcp/ pass before opening a PR.The recommended distribution is a PyPI package launched via uvx / pipx,
not a compiled binary. MCP clients already know how to run
command: "uvx" / "pipx run", so users get a one-line config with no
virtualenv to manage, and Python-native OAuth/optional-dependency handling stays
simple. A single-file binary would fight the OAuth browser flow and the optional
native extras (llama.cpp, sentence-transformers, sqlite-vec) for little gain. The
Docker image covers HTTP/server deployments.
Releases are fully automated by the publish job in
.github/workflows/ci.yml. Publishing a GitHub
Release is the entire flow — it builds the sdist + wheel and uploads them to
PyPI via Trusted Publishing (OIDC), so no API token is stored in the repo.
One-time PyPI setup (per project, done once in the PyPI web UI):
agentic-mail-mcpci.yml · Environment name: pypipypi
(optionally add required reviewers to gate publishes).To cut a release:
project.version in pyproject.toml, move the CHANGELOG.md
[Unreleased] section under the new version, and merge to main.v0.1.0)
→ Publish release.publish job builds and
uploads to PyPI. Done — uvx agentic-mail-mcp now resolves the new version.Released under the MIT License.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.6.0 | 4 Sept 2026 | 27 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 22:17 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:de79b29044d4d4aabed20756f6b5a36502a63d912162ef9da30b9e66aae83d3e