Outlook MCP Server
README.md
# Outlook MCP Server
> A Model Context Protocol server that lets an AI agent send or draft Outlook mail — with attachments — as the signed-in user, through Microsoft Graph.





**Built at ADF Foods Ltd — one of 14 dashboards, pipelines and automations delivered between 16 July and 12 September 2026, in under 8 weeks.**
---
## What is this project?
Several automations in this portfolio end the same way: produce a report, then get it in front of a person for review. Doing that step by hand — attach the file, write the covering note, pick the recipients — undoes much of the time the automation just saved.
This is a Model Context Protocol server that closes that gap. It exposes two tools to an AI agent:
- **`send_email`** — send immediately from the signed-in account
- **`create_draft`** — build the message and leave it unsent in Drafts, returning a link to it
Both accept multiple recipients, plain-text or HTML bodies, and any number of file attachments.
---
## How the development was done
The whole server is a single file with four dependencies. Almost all of the design effort went into authentication, because that is where this class of tool usually goes wrong.
**The problem with the obvious approach.** The quick way to give a program mailbox access is application permissions with a client secret. That grants access to *every* mailbox in the tenant, it needs a secret stored somewhere, and the secret expires and has to be rotated.
**What this does instead.** Delegated permissions with the authorization-code flow and PKCE:
- The server requests only **`Mail.Send`** and **`Mail.ReadWrite`** — it can send and draft as the signed-in user, and nothing else. No other mailbox in the organisation is reachable.
- Sign-in happens once, in a real browser. The server spins up a short-lived local HTTP listener on a loopback address, opens the browser, and captures the redirect when the user finishes signing in — multi-factor authentication and conditional access included, because it is the normal sign-in page.
- The resulting refresh token is cached locally and renewed silently, so the browser step does not recur until the token lapses through prolonged inactivity.
This is the same pattern the major cloud provider CLIs use for their `login` commands, and for the same reasons.
**Attachments** are read from local paths, base64-encoded and typed by extension, with a clear failure when a path does not exist — rather than silently sending a message with the attachment missing.
---
## What was used
Python with four dependencies: an MCP server library, Microsoft's authentication library, an HTTP client, and dotenv for configuration. Microsoft Graph v1.0 for the mail operations. The loopback redirect listener uses only the standard library.
---
## How it works currently
Configure three environment variables (see [`.env.example`](.env.example)), register the application in Entra ID as a public client with the two delegated permissions, and point an MCP-capable client at the server.
The agent then calls `create_draft` to stage a message for human review, or `send_email` to send directly. In practice the draft tool is the one that matters — several automations in this portfolio deliberately stop at a draft so a person approves before anything leaves the building.
### Security note
**This server needs no client secret.** It uses the public-client PKCE flow, where proof of possession replaces a shared secret. There is nothing long-lived to store in configuration and nothing to rotate on a schedule.
The cached token file and the environment file are both excluded from version control.
---
## Output
An AI agent that can put a finished, attachment-bearing email in front of a person — as a draft they approve, or sent directly when that is appropriate.
---
*Built at ADF Foods Ltd.*
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues