Connects Claude to Microsoft 365 Outlook and Google Gmail APIs for email search, invoice detection, attachment handling, folder/label management, and draft creation. Uses Anthropic OAuth for secure authentication.
SaferSkills independently audited outlook_mcp (MCP Server) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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.
┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Claude │────►│ Anthropic │────►│ Microsoft/ │
│ Client │ │ (OAuth) │ │ Google OAuth │
└─────────────┘ └──────────────┘ └─────────────────┘
│
▼
┌──────────────┐
│ Email MCP │ ◄── Bearer token on every request
│ (Vercel) │
└──────────────┘Key points:
Authorization: Bearer <token> with each requestThe MCP uses short IDs instead of long Graph/Gmail IDs:
Graph ID: AAMkADQ5NWE3...longstring...AAAA=
↓
Short ID: 1Benefits:
Note: Short IDs are stored in-memory and reset when the session ends.
Mail.ReadWrite, User.Read, offline_accesshttps://claude.ai/api/mcp/auth_callbackhttps://claude.ai/api/mcp/auth_callbackhttps://www.googleapis.com/auth/gmail.readonlyhttps://www.googleapis.com/auth/gmail.modifyhttps://www.googleapis.com/auth/gmail.labelsvercel linkAZURE_CLIENT_ID - Azure app client IDAZURE_TENANT_ID - Azure tenant IDvercel deploy --prodNote: Client secrets are NOT stored in the MCP server - Anthropic handles OAuth securely.
After deployment:
| 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) |
| 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) |
1. m365_search_invoice_emails(year: 2024) → Find invoices
2. m365_create_folder(displayName: "Invoices") → Create folder
3. m365_move_emails(messageIds: [...], destinationFolderName: "Invoices")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"])1. google_search_emails(sender: "[email protected]")
2. google_read_thread(threadId: ...)| 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" |
| 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 |
| 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
npm run dev # Start local Next.js server
# Connect MCP Inspector to http://localhost:3000/api/mcpnpm run build # Build for productionThe server searches for emails containing these keywords:
Only downloads invoice-relevant files:
Skips:
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.