mcp-outlook
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-outlookShow my unread emails from this week"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-outlook
A self-hostable MCP server for on-prem Microsoft Exchange over EWS (Exchange Web Services). Built for air-gapped / no-cloud environments — it talks directly to your internal Exchange server and never touches Microsoft Graph, Azure AD, or a desktop Outlook client.
Backend:
exchangelib(EWS client)Framework: FastMCP
Transport: streamable-http (a standalone HTTP server other internal hosts connect to)
Auth to Exchange: basic or NTLM (selectable via config)
Two modes
Mode | Who it serves | How it authenticates |
| one mailbox | connects as that account (your own creds) — great for local beta testing |
| many users | validates each caller's user JWT, then acts on that user's mailbox via a service account + EWS Impersonation |
How jwt mode bridges identity. Exchange can't consume your company JWTs (Outlook is
PKINIT/Kerberos-based). So the MCP does two separate authentications that never mix:
User --(JWT)--> MCP validates the token, reads the user's email
MCP --(service account, NTLM)--> Exchange
MCP --(impersonation header = user's email)--> acts on the user's mailboxThe user's JWT is never sent to Exchange, and no user password/smart-card ever touches the
MCP — only the single service credential does. See TODO.md for what admins must
set up for jwt mode.
Related MCP server: OWA Exchange MCP Server
Tools
Tool | Purpose |
| Recent messages, newest first |
| Text + date-range + sender/recipient search |
| Full message: body, recipients, attachment names |
| Open the interactive compose widget (MCP Apps); user edits and sends |
| Open the compose widget pre-filled as a reply |
| Open the compose widget pre-filled as a forward |
| Send — callable only from the widget (app-only visibility) |
| Search contacts — callable only from the widget (app-only) |
| Toggle read status |
| Move to Deleted Items, or permanently delete |
| Set Outlook's High/Normal importance |
| Move a message to another folder |
| Available mail folder names, including subfolders |
| Calendar events in a date range |
| Full event: body, attendees, location |
| Scheduling assistant — ranks slots by attendee availability |
| Open the interactive event-draft widget |
| Create the event — callable only from the widget (app-only) |
| Respond to a meeting invite |
list_emails and search_emails also take unread_only=true to return only unread messages.
Setup
Requires Python 3.11+ and uv.
uv sync # create venv + install deps
cp .env.example .env # then edit .env with your Exchange details
uv run python -m mcp_outlookThe server binds to MCP_HOST:MCP_PORT (default 127.0.0.1:8000) and serves the
streamable-http MCP endpoint at /mcp.
Local beta testing (no admin setup needed)
Run against your own mailbox with your own username/password — no JWT, no impersonation, no service account, no smart card:
# in .env:
OUTLOOK_AUTH_MODE=static # the default
OUTLOOK_EWS_ENDPOINT=https://mail.corp.local/EWS/Exchange.asmx
OUTLOOK_USERNAME=CORP\you
OUTLOOK_PASSWORD=...
uv run python -m mcp_outlookConfiguration
All settings come from environment variables (or a .env file). See
.env.example for the full list. The essentials:
Var | Notes |
|
|
| Full asmx URL, e.g. |
| Host-only alternative (endpoint assumed at |
| The connecting account — your own (static) or the service account (jwt). |
| Mailbox to open (static mode). Optional — defaults to |
| account password. Not used with |
|
|
| Required in jwt mode — token issuer and audience to require |
| jwt mode — signing keys (JWKS URI, or a static PEM for air-gapped) |
| jwt mode — claim holding the user's SMTP address (default |
| Path to internal CA |
|
|
| HTTP bind (default |
Finding your EWS endpoint
The EWS URL is not the OWA (webmail) URL. On the Exchange server:
Get-WebServicesVirtualDirectory | fl Name,InternalUrl,ExternalUrlIn an air-gapped setup you almost always want the InternalUrl.
Testing
Unit tests need no Exchange server (config parsing + serialization only):
uv run pytestLive smoke test (with a real .env): start the server, connect an MCP client
or the MCP Inspector, then call list_folders → list_emails → send_email (to
yourself) and confirm receipt. Flip OUTLOOK_AUTH_TYPE between ntlm and basic
to confirm whichever your Exchange admin has enabled.
Compose UI (MCP Apps)
draft_email opens an interactive MCP Apps widget — a React composer built into a
single self-contained HTML file (src/mcp_outlook/widgets/compose.html). Any
MCP Apps-capable host renders it inline in the chat thread.
Widget capabilities:
To field with inline contact search — type after the last comma to search contacts; pick a result to replace the query with a chip; valid addresses render as labelled chips.
Send / Discard — Send fires
send_emaildirectly from the widget (app-only — the model cannot call it); Discard collapses the card.Supersession — opening a new draft greys out any older open draft widget.
Signature — every draft is pre-seeded with "Written with Airchat" (editable).
Air-gap guarantee: the built HTML (React + bridge JS inlined) ships with the Python package. No external asset requests are made at runtime; Node.js is only needed to rebuild the widget.
Rebuild the widget (dev only)
cd frontend
npm ci
npm run build # tsc + vite build + artifact copy → src/mcp_outlook/widgets/compose.htmlThe build script validates no external URLs ended up in the HTML before copying.
Try it visually (standalone dev preview)
cd frontend && npm run dev
# Opens http://localhost:5173 with a mock host — no Exchange needed.
# Type in To, see chips form, contact results appear, Send/Discard collapse the card.Gotchas
Basic auth is often disabled on modern Exchange — NTLM is the safer default.
Internal/self-signed certs require
OUTLOOK_CA_BUNDLE, or the connection fails on TLS verification.Multi-user (
jwt) mode needs one Exchange grant — the service account must hold theApplicationImpersonationRBAC role. SeeTODO.md.staticmode needs no such grant..envholds a plaintext password. It is git-ignored; also lock down file permissions (chmod 600 .env) on the host.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.
Microsoft Exchange MCP server - hosted, multi-user, incl. Exchange on-prem & hybrid (EWS)
Manage Microsoft 365 email, calendar, contacts and inbox rules via the Graph API with OAuth 2.0.
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Related MCP Servers
- AlicenseCqualityAmaintenanceSecure MCP server for on-prem Microsoft Exchange (EWS) with tools for email, calendar, contacts, folders, attachments, and free/busy availability.314MIT
- AlicenseAqualityDmaintenanceMCP server for any Microsoft Exchange / OWA deployment. Gives LLM agents access to email, calendar, directory search, folders, availability, and meeting analytics via 30 tools.307MIT
- AlicenseNot gradedqualityCmaintenanceEnables reading, sending, and managing Microsoft 365/Outlook emails through MCP tools with OAuth 2.1 authentication.114MIT
- FlicenseAqualityBmaintenanceMCP server for corporate Exchange that provides access to email, calendar, and people directory via OWA JSON API.20
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/ItayElizur/mcp-outlook'
If you have feedback or need assistance with the MCP directory API, please join our Discord server