outlook_mcp
by megedtal
README.md
# Email MCP Server
A remote MCP (Model Context Protocol) server that connects Claude to **Microsoft 365 Outlook** and **Google Gmail** via their respective APIs. Deployed on Vercel with **Claude Connector OAuth** - Anthropic handles all authentication.
## Architecture
```
┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Claude │────►│ Anthropic │────►│ Microsoft/ │
│ Client │ │ (OAuth) │ │ Google OAuth │
└─────────────┘ └──────────────┘ └─────────────────┘
│
▼
┌──────────────┐
│ Email MCP │ ◄── Bearer token on every request
│ (Vercel) │
└──────────────┘
```
**Key points:**
- Users connect via Claude Settings → Connectors
- Anthropic handles the OAuth flow (authorization, token refresh, secure storage)
- MCP server receives `Authorization: Bearer <token>` with each request
- Server is **stateless** - no token storage, no auth tools, no database
## Features
### Microsoft 365 (Outlook)
- Search emails by date, sender, subject, attachments, read status
- Invoice detection with multi-language keywords (English + Hebrew)
- Read full email content
- Download attachments with PDF text extraction
- Folder management (list, create, find)
- Move emails between folders (single or batch)
- Create drafts
### Google (Gmail)
- Search with Gmail query syntax
- Invoice detection with keyword matching
- Read emails and full conversation threads
- Download attachments
- Label management (list, create, delete, modify)
- Create drafts
### Shared Features
- **Session-based short IDs** - Uses 1, 2, 3... instead of long API IDs
- **Invoice keyword detection** - invoice, receipt, billing, payment, חשבונית, חשבוניות
- **Provider extraction** - Extracts vendor names from email domains
- **PDF text extraction** - Extracts text from PDF attachments
- **Image vision** - Returns images for Claude to analyze
## Session-Based Short IDs
The MCP uses short IDs instead of long Graph/Gmail IDs:
```
Graph ID: AAMkADQ5NWE3...longstring...AAAA=
↓
Short ID: 1
```
**Benefits:**
- Reduces token usage
- Easier to reference in follow-up commands
- Works with messages, folders, attachments, and labels
**Note:** Short IDs are stored in-memory and reset when the session ends.
## Setup
### Prerequisites
1. **Vercel account** - [vercel.com](https://vercel.com)
2. **Azure AD App Registration** (for Microsoft 365)
3. **Google Cloud OAuth credentials** (for Gmail)
### Azure AD Setup
1. Go to [Azure Portal](https://portal.azure.com) → Azure Active Directory → App registrations
2. Create new registration
3. Add API permissions: `Mail.ReadWrite`, `User.Read`, `offline_access`
4. **Add redirect URI:** `https://claude.ai/api/mcp/auth_callback`
5. Copy the Application (client) ID and Directory (tenant) ID
### Google Cloud Setup
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
2. Enable the Gmail API
3. Configure OAuth consent screen
4. Create OAuth 2.0 credentials
5. **Add redirect URI:** `https://claude.ai/api/mcp/auth_callback`
6. Add scopes:
- `https://www.googleapis.com/auth/gmail.readonly`
- `https://www.googleapis.com/auth/gmail.modify`
- `https://www.googleapis.com/auth/gmail.labels`
### Deployment
1. Clone the repository
2. Link to Vercel: `vercel link`
3. Set environment variables in Vercel Dashboard:
- `AZURE_CLIENT_ID` - Azure app client ID
- `AZURE_TENANT_ID` - Azure tenant ID
4. Deploy: `vercel deploy --prod`
**Note:** Client secrets are NOT stored in the MCP server - Anthropic handles OAuth securely.
### Connecting to Claude
After deployment:
1. Go to Claude.ai → Settings → Connectors
2. Add your Vercel deployment URL
3. Authorize with Microsoft and/or Google when prompted
4. Start using email tools in Claude
## Available Tools
### Microsoft 365 (Outlook)
| Tool | Description |
|------|-------------|
| `m365_search_emails` | Search emails with flexible filtering |
| `m365_search_invoice_emails` | Find invoice emails with keyword detection |
| `m365_read_email` | Read full email content |
| `m365_list_attachments` | List attachments of an email |
| `m365_download_attachment` | Download a specific attachment |
| `m365_download_attachment_by_name` | Download attachment by filename |
| `m365_download_all_invoices` | Batch download invoice attachments |
| `m365_list_folders` | List mail folders |
| `m365_find_folder` | Find folder by path or name |
| `m365_get_folder_tree` | Get complete folder hierarchy |
| `m365_create_folder` | Create a new mail folder |
| `m365_move_email` | Move a single email |
| `m365_move_emails` | Move multiple emails |
| `m365_list_providers` | List vendors from invoice emails |
| `m365_create_draft` | Create a draft (does not send) |
### Google (Gmail)
| Tool | Description |
|------|-------------|
| `google_search_emails` | Search with Gmail query syntax |
| `google_search_invoice_emails` | Find invoice emails |
| `google_read_email` | Read full message content |
| `google_read_thread` | Read entire conversation thread |
| `google_list_attachments` | List attachments of a message |
| `google_download_attachment` | Download attachment by filename |
| `google_list_labels` | List all Gmail labels |
| `google_get_label` | Get label details |
| `google_create_label` | Create a new label |
| `google_delete_label` | Delete a label |
| `google_modify_labels` | Add/remove labels from messages |
| `google_list_providers` | List vendors from invoice emails |
| `google_create_draft` | Create a draft (does not send) |
## Example Workflows
### Organize Invoices (Microsoft 365)
```
1. m365_search_invoice_emails(year: 2024) → Find invoices
2. m365_create_folder(displayName: "Invoices") → Create folder
3. m365_move_emails(messageIds: [...], destinationFolderName: "Invoices")
```
### Search and Label (Gmail)
```
1. google_search_emails(query: "from:amazon.com has:attachment")
2. google_search_invoice_emails(year: 2024)
3. google_modify_labels(messageIds: [...], addLabelIds: ["Label_123"])
```
### Read Conversation
```
1. google_search_emails(sender: "support@company.com")
2. google_read_thread(threadId: ...)
```
## Tool Parameters
### General Email Search
| Parameter | Type | Description |
|-----------|------|-------------|
| `startDate` | string | Start date (ISO format) |
| `endDate` | string | End date (ISO format) |
| `year` | number | Year to search |
| `month` | number | Month (1-12) |
| `sender` | string | Sender email address |
| `subject` | string | Subject contains |
| `hasAttachments` | boolean | Filter by attachments |
| `isUnread` | boolean | Filter by read status |
| `folderId`/`labelId` | string | Search within folder/label |
| `maxResults` | number | Maximum results |
| `format` | string | "full", "summary", "minimal", "ids" |
### Invoice Search
| Parameter | Type | Description |
|-----------|------|-------------|
| `year` | number | **Required.** Year to search |
| `month` | number | Month (1-12) |
| `sender` | string | Sender email address |
| `keywords` | string[] | Custom search keywords |
| `maxResults` | number | Maximum results |
### Move Emails (M365)
| Parameter | Type | Description |
|-----------|------|-------------|
| `messageId`/`messageIds` | string/string[] | Email ID(s) to move |
| `destinationFolderId` | string | Folder ID or well-known name |
| `destinationFolderName` | string | Folder display name |
| `createIfNotExists` | boolean | Create folder if missing |
Well-known folders: `inbox`, `drafts`, `sentitems`, `deleteditems`, `archive`, `junkemail`, `outbox`
## Development
### Local Testing
```bash
npm run dev # Start local Next.js server
# Connect MCP Inspector to http://localhost:3000/api/mcp
```
### Build
```bash
npm run build # Build for production
```
## Invoice Detection
The server searches for emails containing these keywords:
- English: invoice, receipt, bill, payment, billing, statement, order confirmation, tax invoice
- Hebrew: חשבונית, קבלה, תשלום, חשבונית מס, אישור הזמנה
## Attachment Filtering
Only downloads invoice-relevant files:
- PDF files
- Images (PNG, JPG, JPEG, TIFF)
Skips:
- Calendar files (.ics)
- Contact files (.vcf)
- HTML files
- Signature images (files containing "signature", "logo", "banner")
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues