outlook-mcp

outlook-mcp

Secure MCP server for on-prem Microsoft Exchange (EWS) with tools for email, calendar, contacts, folders, attachments, and free/busy availability.

Category
Visit Server

README

outlook-mcp

Python MCP Exchange Status

outlook-mcp is an MCP server for on-prem Microsoft Exchange via EWS (exchangelib). It gives MCP-compatible clients access to email, calendar, contacts, folders, attachments, and availability data through a single, testable Python service.

Short description

Secure MCP server for on-prem Microsoft Exchange (EWS) with tools for email, calendar, contacts, folders, attachments, and free/busy availability.

Suggested repository topics / tags

mcp, model-context-protocol, exchange, microsoft-exchange, ews, outlook, email, calendar, contacts, python, automation, exchangelib

Highlights

  • email operations: list, search, read, send, reply, forward, move, copy, delete, mark
  • calendar operations: list, create, update, delete, respond to invites, find free slots
  • contacts operations: search, read, create, update, delete
  • folder operations and attachment download
  • Exchange auth via NTLM and Basic
  • MCP transport via stdio and SSE
  • centralized error mapping and a single ExchangeClient abstraction
  • privacy-safer smoke check output by default
  • Docker support and GitLab CI/CD pipeline included

Tool catalog

System

  • ping_exchange
  • get_mailbox_info

Email

  • list_emails
  • get_email
  • search_emails
  • send_email
  • reply_email
  • forward_email
  • move_email
  • copy_email
  • delete_email
  • mark_email
  • list_folders
  • create_folder
  • create_draft
  • send_draft
  • get_attachment

Calendar

  • list_events
  • get_event
  • create_event
  • update_event
  • delete_event
  • respond_to_invite
  • find_free_slots
  • get_my_availability
  • list_calendars

Contacts

  • search_contacts
  • get_contact
  • create_contact
  • update_contact
  • delete_contact

Typical use cases

  • connect Claude Desktop or another MCP client to on-prem Exchange
  • search inbox messages and fetch full email content
  • send or draft emails from AI workflows
  • inspect calendars and create meetings
  • check free/busy windows for scheduling
  • search personal contacts or the GAL
  • expose Exchange operations through a controlled MCP boundary instead of direct mailbox scripting

Security notes

What the current code does:

  • connects only to the Exchange/EWS endpoint configured in EXCHANGE_SERVER
  • does not contain telemetry, analytics, or third-party data export logic
  • keeps secrets in environment variables / .env
  • ignores local secret files via .gitignore (.env, .env.*, while keeping .env.example)
  • logs only tool name, status, duration, and error code; it does not log message bodies, attachment contents, or passwords
  • excludes .env, tests, caches, and VCS metadata from Docker build context via .dockerignore

What you should still be careful with:

  • EXCHANGE_VERIFY_SSL=false disables TLS certificate verification and should be used only for trusted internal/self-signed environments
  • get_attachment writes files to disk, so choose a safe destination directory
  • outlook-mcp-smoke is privacy-safe by default and prints only masked mailbox info plus counts; set OUTLOOK_MCP_SMOKE_INCLUDE_DATA=true only if you explicitly want real inbox/event data in stdout
  • if you enable file logging with LOG_FILE, protect that file with OS permissions
  • if you publish Docker images from CI, protect GitLab/GitHub project access and registry permissions

Quick start

uv venv
source .venv/bin/activate
uv pip install -e .[dev]
cp .env.example .env
outlook-mcp

By default the server runs in stdio mode. Set MCP_TRANSPORT=sse to start an HTTP server.

Configuration

Example .env:

EXCHANGE_SERVER=https://mail.company.com/EWS/Exchange.asmx
EXCHANGE_USERNAME=DOMAIN\\username
EXCHANGE_PASSWORD=secret
EXCHANGE_EMAIL_ADDRESS=user@company.com
EXCHANGE_VERIFY_SSL=true
EXCHANGE_AUTH_TYPE=NTLM
EXCHANGE_VERSION=EXCHANGE_2016
EXCHANGE_TIMEOUT=30
EXCHANGE_MAX_RETRIES=3
EXCHANGE_TIMEZONE=Europe/Moscow
EXCHANGE_IMPERSONATE_AS=
ATTACHMENT_MAX_SIZE_MB=10
MCP_TRANSPORT=stdio
MCP_SSE_HOST=127.0.0.1
MCP_SSE_PORT=8080
LOG_LEVEL=INFO
LOG_FILE=

Notes:

  • set EXCHANGE_EMAIL_ADDRESS when EXCHANGE_USERNAME is not an SMTP address
  • OAuth2 is reserved in config, but this build currently supports live auth with NTLM or Basic
  • EXCHANGE_IMPERSONATE_AS enables mailbox impersonation when Exchange permissions are configured accordingly
  • ATTACHMENT_MAX_SIZE_MB is enforced before sending/replying/forwarding/drafting with local attachments

Claude Desktop example

{
  "mcpServers": {
    "outlook": {
      "command": "outlook-mcp",
      "env": {
        "EXCHANGE_SERVER": "https://mail.company.com/EWS/Exchange.asmx",
        "EXCHANGE_USERNAME": "DOMAIN\\username",
        "EXCHANGE_PASSWORD": "secret",
        "EXCHANGE_EMAIL_ADDRESS": "user@company.com",
        "EXCHANGE_AUTH_TYPE": "NTLM"
      }
    }
  }
}

Smoke check

After filling .env, run:

outlook-mcp-smoke

Default output is sanitized for safer verification. If you intentionally want sample mailbox/event data in the output:

OUTLOOK_MCP_SMOKE_INCLUDE_DATA=true outlook-mcp-smoke

Docker

docker build -t outlook-mcp .
docker run --rm --env-file .env outlook-mcp

GitLab CI/CD

The repository includes .gitlab-ci.yml with these stages:

  • lint — runs ruff
  • test — runs pytest
  • build — builds Python package artifacts into dist/
  • release — builds and pushes a Docker image to the GitLab Container Registry on the default branch and on tags

Default image tagging behavior:

  • default branch: pushes :$CI_COMMIT_SHORT_SHA and :latest
  • git tag: pushes :$CI_COMMIT_TAG

GitLab built-in registry variables are used:

  • CI_REGISTRY
  • CI_REGISTRY_USER
  • CI_REGISTRY_PASSWORD
  • CI_REGISTRY_IMAGE

Development

uv run --python 3.12 --with '.[dev]' ruff check .
uv run --python 3.12 --with '.[dev]' pytest -q

Project notes

  • The implementation is centered around a single ExchangeClient abstraction so auth, transport, retries, and error mapping stay centralized.
  • Errors are returned in a structured JSON form suitable for MCP isError=true handling.
  • RTK.md is not present in this repository, so the implementation follows PLAN.md.

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
Qdrant Server

Qdrant Server

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

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