outlook-mcp-server

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.

Category
Visit Server

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 the offline_access refresh 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 (mode 0600). The key itself lives in ~/.outlook-mcp-server/cache.key (also 0600). See Security notes for the threat model this does (and doesn't) cover.
  • Graph calls: a thin fetch-based client calls https://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:

  1. Go to portal.azure.com and sign in with any Microsoft account.

  2. Search for App registrations → + New registration.

  3. 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).
  4. Click Register, then copy the Application (client) ID from the Overview page.

  5. Go to API permissions → + Add a permission → Microsoft Graph → Delegated permissions, and add:

    • Mail.Read
    • Mail.ReadWrite
    • Mail.Send
    • offline_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.

  6. (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:

  1. Print the walkthrough above.
  2. Prompt for the client ID (and optional secret / tenant / redirect URI), and save it to ~/.outlook-mcp-server/config.json.
  3. Open your browser to sign in and consent.
  4. Verify the token works by calling GET /me, printing your name/email.
  5. 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, mode 0600). 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 the ICachePlugin in src/auth/tokenCache.ts for one backed by your OS keychain (e.g. via keytar) — the plugin interface is intentionally isolated to that one file.
  • Never commit ~/.outlook-mcp-server/ (it's outside the repo by default) or a .env file containing OUTLOOK_MCP_CLIENT_SECRET.
  • send_message sends immediately with no confirmation step inside this server — Claude is expected to confirm intent with you before calling it for anything sensitive. Prefer create_draft when you want a review step.
  • Requested scopes are limited to Mail.Read, Mail.ReadWrite, Mail.Send, and offline_access — no calendar, contacts, or broader Mail.* 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 against consumers. Confirm the app registration's "Supported account types" is "Personal Microsoft accounts only" and that OUTLOOK_MCP_TENANT is consumers (or common if you intentionally want both).
  • AADSTS50011 / redirect URI mismatch — the redirectUri in ~/.outlook-mcp-server/config.json must 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 setup with 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

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.

Official
Featured
TypeScript
Magic Component Platform (MCP)

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.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

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.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

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.

Official
Featured
TypeScript
Kagi MCP Server

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.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

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.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured