outlook-mcp
outlook-mcp
An MCP server that gives AI agents structured access to a Microsoft Outlook mailbox through the Microsoft Graph API — with one deliberate constraint at its core:
Agents read and draft. Only humans send.
There is no send tool in this server, and the OAuth token it holds does not include the Mail.Send scope. Even a fully compromised or badly prompted agent cannot send email through it — the capability doesn't exist at the token level. Everything outbound lands in your Drafts folder for human review.
I built this to power an autonomous operations pipeline: scheduled headless agent sessions sweep the mailbox twice a day, reconcile every open commitment and follow-up into a dashboard, and queue reply drafts for review. It runs identically under Claude Code and OpenAI Codex — one integration layer, two vendors' agents.
Permission model
Capability | Agent | Notes |
List/search/read mail | ✅ | Full mailbox visibility |
Organize (folders, move, batch triage) | ✅ | Reversible operations only |
Create drafts / reply drafts | ✅ | Lands in Drafts, never sent |
Send email | ❌ | No tool, and no |
Delete email | ❌ | Not implemented |
Auth is MSAL Authorization Code Flow with PKCE through a localhost-only callback. Tokens cache to ~/.outlook-mcp/ with 0600 permissions.
Tools (10)
Tool | Purpose |
| Folder tree with counts |
| Create a mail folder |
| Page through a folder (subject, sender, preview, unread) |
| KQL search across all folders ( |
| Full message body (HTML converted to clean text), recipients, attachments list |
| Move messages between folders |
| Bulk triage in one call |
| New outbound draft |
| Reply/reply-all draft on an existing thread |
| Folder statistics (volume, unread, top senders) |
Setup
1. Register a (free) app in Entra ID
Microsoft Entra admin center → App registrations → New registration:
Supported account types: your tenant only, or multi-tenant + personal accounts (then use
OUTLOOK_MCP_TENANT_ID=common)Redirect URI: platform Mobile and desktop applications → add
http://localhost:3847/auth/callbackAuthentication → enable Allow public client flows
API permissions → Microsoft Graph → Delegated →
Mail.ReadWrite,MailboxSettings.Read
No client secret is needed (public client + PKCE).
2. Build and authenticate
npm install
npm run build
export OUTLOOK_MCP_CLIENT_ID=<your app client id>
export OUTLOOK_MCP_TENANT_ID=<your tenant id or "common">
npm run auth # opens browser once; token cache persists at ~/.outlook-mcp/3. Connect an agent
Claude Code — .mcp.json in your project (or claude mcp add):
{
"mcpServers": {
"outlook": {
"command": "node",
"args": ["/path/to/outlook-mcp/dist/index.js"],
"env": {
"OUTLOOK_MCP_CLIENT_ID": "<client id>",
"OUTLOOK_MCP_TENANT_ID": "<tenant id>"
}
}
}
}OpenAI Codex — ~/.codex/config.toml:
[mcp_servers.outlook]
command = "node"
args = ["/path/to/outlook-mcp/dist/index.js"]
env = { OUTLOOK_MCP_CLIENT_ID = "<client id>", OUTLOOK_MCP_TENANT_ID = "<tenant id>" }Same server, same tools, either agent. That portability is the point of MCP.
Architecture
┌─────────────┐ stdio ┌──────────────┐ HTTPS ┌─────────────────┐
│ Claude Code │◄──────────────►│ │◄─────────────►│ Microsoft Graph │
├─────────────┤ JSON-RPC │ outlook-mcp │ REST v1.0 │ /me/messages │
│ OpenAI Codex│◄──────────────►│ (Node/TS) │ │ /me/mailFolders│
└─────────────┘ └──────┬───────┘ └─────────────────┘
│
┌──────┴───────┐
│ MSAL + PKCE │ Mail.ReadWrite only —
│ token cache │ no Mail.Send on the token
└──────────────┘Transport: stdio (JSON-RPC), one process per agent session
Auth: MSAL Auth Code Flow + PKCE, localhost callback, silent refresh from disk cache
Bodies: HTML mail converted to clean plain text before it reaches the model (token efficiency)
Validation: every tool input validated with zod before any Graph call
Development
npm run dev # tsc --watch
npm run inspect # MCP Inspector against the built serverLicense
MIT © Don Fournier
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/dbfournier33/outlook-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server