Giving AI Email Access
AI can write a perfect follow-up email in two seconds. It can draft a proposal, compose a cold outreach sequence, and format a meeting recap before you've finished your coffee. But then you have to copy it, open your email client, paste it, double-check the address, and hit send. Every single time.
The AI is fast. The human is the bottleneck. I wanted to remove that bottleneck.
So I built an MCP server that gives Claude direct access to Gmail. Read messages, send emails, create drafts, reply to threads. All from within the same conversation where the content was written. No copy-paste. No context switching. No manual step between "write this" and "send this."
The Problem
Every AI workflow I was building had the same gap. The AI could research a company, draft an outreach email, even personalize it with details from a CRM. But the last mile — actually sending it — always required me to leave the AI environment, open Gmail, and do the mechanical work of addressing, formatting, and sending.
For one email, that's nothing. For a pipeline of fifty follow-ups on a Monday morning, it's an hour of copy-paste that adds zero value. The AI already did the thinking. I was just acting as a human API between the model and the mail server.
I wanted the AI to be the API.
The Architecture
The stack is intentionally minimal.
Claude (AI Agent)
|
v
Python MCP Server (Tool Interface)
|
v
Gmail API (OAuth2)
|
v
Email Sent / Read / Drafted
Claude calls a tool. The MCP server translates that tool call into a Gmail API request. The API does the work. The result comes back up the chain. Four components, one direction, no surprises.
The server is written in Python using the MCP SDK, google-auth, and google-api-python-client. Python was the right choice here because Google's API client libraries are most mature in Python, and the auth flow is well-documented.
The Security Model
This is the part that matters most. Giving an AI access to your email is a trust decision, and the security model has to earn that trust.
OAuth2 with minimal scopes. The server requests exactly two permissions: GMAIL_READONLY (read messages and threads) and GMAIL_SEND (send and draft emails). That's it. Not GMAIL_FULL_ACCESS. Not GMAIL_MODIFY. The AI can read and send. It cannot delete messages, modify labels, manage filters, or change account settings. The scope boundary is enforced by Google, not by my code.
Credentials stored in the OS keychain. OAuth tokens live in macOS Keychain — encrypted at rest, protected by the operating system, accessible only to the authorized process. No token files sitting in a project directory. No credentials in environment variables. No .env file that could end up in a git commit. The keychain is the right place for secrets because it was designed for exactly this purpose.
Automatic token refresh. OAuth tokens expire. The server handles refresh transparently. When a token is near expiration, it re-authenticates using the stored refresh token. No manual intervention, no expired-token errors interrupting a workflow.
The security model was the first thing I designed, not the last. Every other decision flowed from it. If I couldn't get credential storage right, the rest didn't matter.
What It Can Do
The MCP server exposes seven tools that cover the two core workflows: reading email and sending email.
Reading
The read side handles inbox queries, message retrieval, and thread context. You can ask the AI to check for unread messages, search by sender or subject, or pull the full text of a specific thread. The AI gets structured data back — sender, recipient, subject, body, timestamp, thread ID — and can reason over it in conversation.
This is useful beyond the obvious "read my email" case. The AI can cross-reference inbox contents with other data sources. "Check if anyone from the pipeline responded to last week's outreach" becomes a single tool call that searches Gmail for replies from CRM contacts. The AI connects the dots across systems that would normally require a human to tab back and forth.
Sending
The send side covers three operations: sending an email immediately, creating a draft for human review, and replying to an existing thread.
Draft creation is the safety valve. For any high-stakes communication — client proposals, formal outreach, anything with legal or financial implications — the AI creates a draft instead of sending directly. I review it in Gmail, make any edits, and send it myself. The AI did 95% of the work. I provided the final approval. This pattern preserves human oversight where it matters without reintroducing the copy-paste bottleneck for routine messages.
Alias support lets the AI send from different addresses on the same account. A professional alias for client communication, a general alias for outreach, a personal address for direct messages. The Gmail sendAs API makes this possible without switching accounts. The AI picks the right sender address based on context.
Thread replies maintain conversation context. The AI reads a thread, composes a reply, and sends it as part of the existing conversation. The recipient sees it as a normal email reply, not a new message. This matters for professional communication — breaking a thread is sloppy, and clients notice.
Design Patterns Worth Noting
Separation of auth from logic. The authentication module is completely isolated from the email operations module. Auth handles tokens, refresh, and keychain access. Operations handle message construction, API calls, and response parsing. Neither knows about the other's internals. This makes the auth layer reusable for any Google API integration, not just Gmail.
Structured output from reads. When the AI reads a message, it gets clean JSON with parsed fields, not a raw MIME blob. Subject, sender, recipient, date, body text, and thread ID are extracted and structured before the data reaches the model. This means the AI can immediately reason about the content without spending tokens on parsing email headers.
Idempotent operations. Sending the same email twice would be bad. The server includes request deduplication for send operations, using a hash of the recipient, subject, and body within a time window. If the same message is submitted twice within a few minutes — say, due to a retry — the second request is caught and blocked. Small safeguard. Prevents real embarrassment.
What I Learned
The hardest part of giving AI email access isn't the API. Google's Gmail API is well-documented. The Python client library is mature. Building the CRUD operations took a day. The hard part is the security model.
Every design decision comes back to one question: what's the blast radius if something goes wrong? Minimal OAuth scopes mean the worst case is a sent email, not a deleted inbox. Keychain storage means a compromised project directory doesn't leak credentials. Draft-first workflow means a bad AI output gets caught before it reaches a client.
You're not just building an integration. You're building a trust boundary. The API is the easy part. The security model is the work.
I also learned that the draft pattern changes how you think about AI communication tools. Once the AI can create a draft that's ready to send, the workflow shifts from "AI helps me write" to "AI writes and I approve." The human role changes from author to editor. That's a meaningful productivity gain, but only if the security model supports it. You need to trust the system before you can trust the output.
The whole server is about 400 lines of Python. Auth module, operations module, MCP tool definitions. Small codebase, narrow scope, high leverage. That's the pattern. Build the smallest thing that solves the actual bottleneck, secure it properly, and ship it.
Email was the last manual step in my AI workflows. Now it's not.