Skip to main content
Glama
Ali-Zia3500

email-agent-mcp-server

by Ali-Zia3500
README.md
# Email Triage Agent

An AI agent that reads your Gmail inbox, classifies incoming emails, drafts replies for anything important, and only sends after you review and approve — built with LangGraph, Gemini, and exposed as an MCP server so it can be used directly from Claude Desktop.

## What it does

1. **Fetches unread emails** from Gmail (full body parsing, not just snippets)
2. **Classifies** each one — `spam`, `important`, `promotional`, `social`, or `updates` — with urgency, topic, and summary
3. **Drafts a reply** for anything classified as `important`, personalized with the real sender name and company name
4. **Pauses for human review** — a conversational loop where you can approve, reject, or give feedback to revise the draft (as many rounds as needed)
5. **Sends the final approved reply** as a real email via the Gmail API, correctly threaded

## Architecture

```
Gmail (OAuth) → read_email → classify_intent → draft_response → human_review → send_reply
                                    ↓ (not important)
                                   END
```

The same pipeline is exposed two ways:
- **Directly** — run `email_agent.py`, review in the terminal
- **Via MCP** — run `mcp_server.py`, which wraps the pipeline as two tools (`check_unread_emails`, `submit_review_feedback`) callable from Claude Desktop or any MCP client, so you can review and approve emails just by talking to Claude naturally

## Tech stack

- `langgraph` — agent orchestration, state management, human-in-the-loop via `interrupt()`
- `langchain-google-genai` — Gemini (`gemini-2.5-flash`) for classification and drafting
- `google-api-python-client` + `google-auth-oauthlib` — Gmail API (read + send)
- `fastmcp` — MCP server exposing the agent as callable tools

## Setup

### 1. Install dependencies
```bash
pip install -r requirements.txt
```

### 2. Google Cloud setup
- Create a project in [Google Cloud Console](https://console.cloud.google.com)
- Enable the **Gmail API**
- Create an **OAuth client ID** (Desktop app type) under Credentials
- Download the credentials file and save it as `credentials.json` in the project root
- Add yourself as a test user under **Audience** (while the app is in Testing mode)

### 3. Gemini API key
Get a key from [Google AI Studio](https://aistudio.google.com/apikey), then create a `.env` file:
```
GEMINI_API_KEY=your_key_here
```

### 4. First run — authorize Gmail access
```bash
python email_agent.py
```
This opens a browser window for one-time Google sign-in and authorization. A `token.pickle` file is saved afterward so you won't need to re-authorize on future runs.

## Running it

### Option A: Standalone script (terminal review)
```bash
python email_agent.py
```
Fetches unread emails, processes each one, and walks you through review in the terminal — approve, reject, or type feedback to revise the draft.

### Option B: MCP server (for Claude Desktop or any MCP client)
```bash
python mcp_server.py
```
Exposes two tools:
- `check_unread_emails(max_results)` — runs the full pipeline, returns classifications and any drafts pending review
- `submit_review_feedback(email_id, feedback)` — resumes a paused review with `"approve"`, `"reject"`, or free-text revision instructions

### Connecting to Claude Desktop
Add this to your `claude_desktop_config.json` under `mcpServers`:
```json
"email-agent": {
  "command": "path/to/venv/Scripts/python.exe",
  "args": ["path/to/mcp_server.py"]
}
```
Restart Claude Desktop, then just ask it to "check my unread emails" — it will call the tools and let you review/approve drafts conversationally.

## Notes

- Uses `MemorySaver` for checkpointing, which is in-memory only — review state won't survive a process restart. A persistent checkpointer would be needed for long-running production use.
- Retry policies are attached to `classify_intent`, `draft_response`, and `send_reply` to handle transient failures.
- Requires absolute paths for `.env`, `credentials.json`, and `token.pickle` when run by Claude Desktop, since it doesn't launch from the project's working directory by default.

## License
MIT (or your preference)

Maintenance

ActivitySlowing
ResponsivenessNo issues