outlook-mcp-server
A local MCP server that gives Claude read/write access to a personal Hotmail/Outlook.com mailbox via the Microsoft Graph API, exposing tools for listing, searching, sending, and drafting emails.
README
outlook-mcp-server
A local MCP server that gives Claude (Desktop or Code) read/write access to a personal Hotmail / Outlook.com mailbox via the Microsoft Graph API, using the OAuth 2.0 authorization code flow (with PKCE) against the Microsoft identity platform.
It exposes six tools: list_messages, get_message, search_messages,
send_message, create_draft, and list_folders.
Everything runs locally over stdio — there is no hosted service, and your mail never passes through anything but your machine and Microsoft's own Graph API.
How it works
- Auth: MSAL Node
runs an authorization-code + PKCE flow against
https://login.microsoftonline.com/consumers(personal accounts only — see Tenant choice), using a short-lived local HTTP server as the redirect target. Tokens (including theoffline_accessrefresh token) are cached and silently refreshed on future runs. - Storage: the token cache is serialized by MSAL, encrypted with
AES-256-GCM using a locally-generated key, and written to
~/.outlook-mcp-server/token-cache.enc(mode0600). The key itself lives in~/.outlook-mcp-server/cache.key(also0600). See Security notes for the threat model this does (and doesn't) cover. - Graph calls: a thin
fetch-based client callshttps://graph.microsoft.com/v1.0/...with the current access token. - MCP server: built on
@modelcontextprotocol/sdk, speaking stdio, so it can be launched directly by Claude Desktop / Claude Code as a child process.
Prerequisites
- Node.js 18+
- A Microsoft account (Hotmail, Outlook.com, or Live) — the mailbox you want Claude to access.
- A free Azure account to register the app (any Microsoft account can do this — it does not need to be a paid Azure subscription).
1. Install
git clone <this repo>
cd outlook-mcp-server
npm install
2. Register an app in the Azure Portal
This registration is what issues the client ID this server uses to talk to
Microsoft Graph on your behalf. npm run setup (below) walks you through
this interactively, but the steps are:
-
Go to portal.azure.com and sign in with any Microsoft account.
-
Search for App registrations → + New registration.
-
Fill in the form:
- Name: anything, e.g.
outlook-mcp-server. - Supported account types: "Personal Microsoft accounts only". This is what restricts the app to Hotmail/Outlook.com/Live accounts rather than a work/school (Azure AD) tenant.
- Redirect URI: platform "Public client/native (mobile & desktop)",
value
http://localhost:8765/callback(or another port — just be consistent when the setup script asks).
- Name: anything, e.g.
-
Click Register, then copy the Application (client) ID from the Overview page.
-
Go to API permissions → + Add a permission → Microsoft Graph → Delegated permissions, and add:
Mail.ReadMail.ReadWriteMail.Sendoffline_access(often present by default)
Personal Microsoft account delegated permissions like these don't need admin consent — you consent yourself during sign-in in step 3 below.
-
(Optional, advanced) If you'd rather use a confidential client with a client secret instead of the public-client PKCE flow, add a Web platform redirect URI and create a secret under Certificates & secrets. Most people should skip this.
3. Run setup (auth + config)
npm run setup
This will:
- Print the walkthrough above.
- Prompt for the client ID (and optional secret / tenant / redirect URI),
and save it to
~/.outlook-mcp-server/config.json. - Open your browser to sign in and consent.
- Verify the token works by calling
GET /me, printing your name/email. - Print the JSON snippet to add to your Claude config (see below).
To re-authenticate later (revoked token, switching accounts, etc.) without re-entering the app registration details:
npm run login
4. Build and register with Claude
npm run build
Claude Desktop — add to claude_desktop_config.json
(~/Library/Application Support/Claude/claude_desktop_config.json on
macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"outlook": {
"command": "node",
"args": ["/absolute/path/to/outlook-mcp-server/dist/src/index.js"]
}
}
}
Claude Code:
claude mcp add outlook -- node /absolute/path/to/outlook-mcp-server/dist/src/index.js
Restart Claude Desktop / Claude Code. The tools below should now be available.
Tools
| Tool | Description |
|---|---|
list_messages |
List messages from a folder (default inbox), with since/until date filters, unreadOnly, sorting, and pagination. |
get_message |
Fetch the full content (body, all recipients) of one message by ID. |
search_messages |
Free-text search ($search) across mail, optionally scoped to a folder. |
send_message |
Send an email immediately (to/cc/bcc, subject, text or HTML body). |
create_draft |
Create a draft in the Drafts folder without sending. |
list_folders |
List mail folders and their IDs, for use with the folder parameter above. |
All tools return JSON (as MCP text content) and surface Graph API errors as tool errors rather than crashing the server.
Tenant choice
By default this uses the consumers tenant
(https://login.microsoftonline.com/consumers), which only accepts
personal Microsoft accounts (Hotmail/Outlook.com/Live) — a work/school
account will be rejected at sign-in. If you need to support both personal
and Azure AD accounts, set the tenant to common during npm run setup
(or via OUTLOOK_MCP_TENANT=common). This project is designed and tested
for the personal-account (consumers) case.
Configuration reference
Everything can be set via npm run setup (written to
~/.outlook-mcp-server/config.json) or via environment variables, which
take precedence — see .env.example:
| Variable | Purpose |
|---|---|
OUTLOOK_MCP_CLIENT_ID |
Azure app registration's client ID. |
OUTLOOK_MCP_CLIENT_SECRET |
Only if using a confidential client (Web platform). |
OUTLOOK_MCP_TENANT |
consumers (default) or common. |
OUTLOOK_MCP_REDIRECT_URI |
Must match the Azure app registration. |
OUTLOOK_MCP_CONFIG_DIR |
Where config/token cache are stored. Defaults to ~/.outlook-mcp-server. |
Security notes
- The token cache is encrypted at rest with a locally-generated AES-256-GCM
key (
~/.outlook-mcp-server/cache.key, mode0600). This protects against casual disclosure — accidental commits, backups, other unprivileged users on a shared machine — but not against an attacker who already has read access to your user account's files, since the key sits next to the encrypted cache. For stronger protection, swap theICachePlugininsrc/auth/tokenCache.tsfor one backed by your OS keychain (e.g. viakeytar) — the plugin interface is intentionally isolated to that one file. - Never commit
~/.outlook-mcp-server/(it's outside the repo by default) or a.envfile containingOUTLOOK_MCP_CLIENT_SECRET. send_messagesends immediately with no confirmation step inside this server — Claude is expected to confirm intent with you before calling it for anything sensitive. Prefercreate_draftwhen you want a review step.- Requested scopes are limited to
Mail.Read,Mail.ReadWrite,Mail.Send, andoffline_access— no calendar, contacts, or broaderMail.*application-level access.
Troubleshooting
AADSTS50020/ "user account ... does not exist in tenant" — you're hitting a tenant that doesn't accept personal accounts, or you're signing in with a work/school account againstconsumers. Confirm the app registration's "Supported account types" is "Personal Microsoft accounts only" and thatOUTLOOK_MCP_TENANTisconsumers(orcommonif you intentionally want both).AADSTS50011/ redirect URI mismatch — theredirectUriin~/.outlook-mcp-server/config.jsonmust exactly match a redirect URI configured on the Azure app registration, including the port.- "Not signed in" tool errors — run
npm run login. - Port already in use during setup/login — another process is using
the redirect URI's port; stop it, or reconfigure the app registration and
npm run setupwith a different port.
Development
npm run dev # run the MCP server directly from TypeScript (stdio)
npm run build # compile to dist/
npm run clean # remove dist/
Project structure
src/
index.ts MCP server entrypoint (stdio transport)
config.ts Config loading (env + config file)
auth/
crypto.ts AES-256-GCM file encryption helpers
tokenCache.ts MSAL ICachePlugin backed by crypto.ts
msalClient.ts MSAL app factory + silent token acquisition
loginFlow.ts Interactive loopback OAuth flow
graph/
client.ts Generic Microsoft Graph fetch wrapper
mail.ts Mail-specific Graph calls
types.ts Graph response types
tools/ One file per MCP tool, registered in index.ts
scripts/
setup.ts Interactive one-time (and re-runnable) setup
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.