Skip to main content
Glama
ItayElizur

mcp-outlook

by ItayElizur

mcp-outlook

Ein selbst hostbarer MCP-Server für lokales Microsoft Exchange über EWS (Exchange Web Services). Entwickelt für Air-Gap-/Cloud-freie Umgebungen – er spricht direkt mit Ihrem internen Exchange-Server und berührt niemals Microsoft Graph, Azure AD oder einen Outlook-Desktop-Client.

  • Backend: exchangelib (EWS-Client)

  • Framework: FastMCP

  • Transport: streamable-http (ein eigenständiger HTTP-Server, mit dem sich andere interne Hosts verbinden)

  • Authentifizierung bei Exchange: Basic oder NTLM (per Konfiguration wählbar)

Zwei Modi

Modus

Wen es bedient

Wie es authentifiziert

static (Standard)

ein Postfach

verbindet sich als dieses Konto (eigene Anmeldedaten) – ideal für lokale Beta-Tests

jwt

viele Benutzer

validiert das Benutzer-JWT jedes Aufrufers und agiert dann über ein Dienstkonto + EWS-Impersonation auf dem Postfach dieses Benutzer

Wie der jwt- Modus Identitäten überbrückt. Exchange kann Ihre Unternehmens-JWTs nicht verarbeiten (Outlook basiert auf PKINIT/Kerberos). Der MCP führt daher zwei getrennte Authentifizierungen durch, die niemals vermischt werden:

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 mailbox

Das Benutzer-JWT wird niemals an Exchange gesendet, und kein Benutzerpasswort und keine Smartcard berührt jemals den MCP – nur die einzelne Dienstkonto-Anmeldeinformation. Siehe TODO.md für das, was Administratoren für den jwt-Modus einrichten müssen.

Related MCP server: OWA Exchange MCP Server

Tools

Tool

Zweck

list_emails(folder="inbox", limit=20)

Neueste Nachrichten, neueste zuerst

search_emails(query, folder, start_date, end_date, sender, recipient, limit)

Text- + Datumsbereichs- + Absender-/Empfängersuche

get_email(message_id, folder="inbox")

Vollständige Nachricht: Textkörper, Empfänger, Anhangsnamen

draft_email(to, subject, body)

Öffnet das interaktive Compose-Widget (MCP Apps); der Benutzer bearbeitet und sendet

reply_email(message_id, folder, reply_all, body)

Öffnet das Compose-Widget, vorausgefüllt als Antwort

forward_email(message_id, folder, to, body)

Öffnet das Compose-Widget, vorausgefüllt als Weiterleitung

send_email(to, subject, body, cc, bcc, html, attachments)

Senden – nur aus dem Widget heraus aufrufbar (nur für Apps sichtbar)

search_contacts(query, limit)

Kontakte suchen – nur aus dem Widget heraus aufrufbar (nur für Apps)

mark_email_read(message_id, folder) / mark_email_unread(...)

Gelesen-Status umschalten

delete_email(message_id, folder, permanent=False)

In Gelöschte Elemente verschieben oder dauerhaft löschen

flag_email_important(message_id, folder, important=True)

Outlook-Wichtigkeit auf Hoch/Normal setzen

move_email(message_id, destination, folder)

Eine Nachricht in einen anderen Ordner verschieben

list_folders()

Verfügbare E-Mail-Ordnernamen, einschließlich Unterordner

list_events(start_date, end_date, limit)

Kalenderereignisse in einem Datumsbereich

get_event(event_id)

Vollständiges Ereignis: Text, Teilnehmer, Ort

find_meeting_slots(attendees, duration_minutes, ...)

Terminplanungs-Assistent – bewertet Slots nach Verfügbarkeit der Teilnehmer

draft_event(subject, start, end, location, body, required_attendees, optional_attendees)

Öffnet das interaktive Widget zum Entwerfen von Ereignissen

create_event(subject, start, end, required_attendees, ...)

Ereignis erstellen – nur aus dem Widget heraus aufrufbar (nur für Apps)

accept_meeting(event_id) / decline_meeting(event_id)

Auf eine Besprechungseinladung antworten

list_emails und search_emails akzeptieren außerdem unread_only=true, um nur ungelesene Nachrichten zurückzugeben.

Einrichtung

Erfordert Python 3.11+ und uv.

uv sync                 # create venv + install deps
cp .env.example .env    # then edit .env with your Exchange details
uv run python -m mcp_outlook

Der Server bindet an MCP_HOST:MCP_PORT (Standard 127.0.0.1:8000) und stellt den streamable-http-MCP-Endpunkt unter /mcp bereit.

Lokale Beta-Tests (keine Admin-Einrichtung erforderlich)

Führen Sie ihn gegen Ihr eigenes Postfach mit Ihrem eigenen Benutzernamen/Passwort aus – kein JWT, keine Impersonation, kein Dienstkonto, keine Smartcard:

# 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_outlook

Konfiguration

Alle Einstellungen stammen aus Umgebungsvariablen (oder einer .env-Datei). Die vollständige Liste finden Sie in .env.example. Die wichtigsten:

Var

Hinweise

OUTLOOK_AUTH_MODE

static (Standard, ein Postfach) oder jwt (Mehrbenutzer-Tunnel)

OUTLOOK_EWS_ENDPOINT

Vollständige ASMX-URL, z. B. https://mail.corp.local/EWS/Exchange.asmx. Bevorzugt.

OUTLOOK_SERVER

Nur-Host-Alternative (Endpunkt wird unter /EWS/Exchange.asmx angenommen)

OUTLOOK_USERNAME

Das verbindende Konto – Ihr eigenes (static) oder das Dienkonto (jwt). DOMAIN\user für NTLM oder E-Mail für Basic. Nicht verwendet bei sspi

OUTLOOK_EMAIl

Zu öffnendes Postfach (static-Modus). Optional – standardmäßig OUTLOOK_USERNAME, wenn es eine E-Mail ist; im jwt-Modus ignoriert; erforderlich bei sspi (kein Benutzername als Standard verfügbar)

OUTLOOK_PASSWORD

Konto-Passwort. Nicht verwendet bei sspi

OUTLOOK_AUTH_TYPE

ntlm (Standard), basic oder sspi (Windows-integrierte Authentifizierung – authentifiziert sich als die eigene AD-Identität dieses Prozesses, ohne Benutzername/Passwort; nur Windows; benötigt uv sync --extra sspi)

OUTLOOK_JWT_ISSUER / _AUDIENCE

Erforderlich im jwt-Modus – Token-Aussteller und Audience, die verlangt werden

OUTLOOK_JWT_JWKS_URI / _PUBLIC_KEY

jwt-Modus – Signaturschlüssel (JWKS-URI oder ein statisches PEM für Air-Gap-Umgebungen)

OUTLOOK_JWT_EMAIL_CLAIM

jwt-Modus – Claim mit der SMTP-Adresse des Benutzers (Standard email)

OUTLOOK_CA_BUNDLE

Pfad zu einem internen CA-.pem (für selbstsignierte / interne CA)

OUTLOOK_VERIFY_SSL

true (Standard); false deaktiviert die TLS-Verifizierung (nur Entwicklung)

MCP_HOST / MCP_PORT

HTTP-Bind (Standard 127.0.0.1:8000)

So finden Sie Ihren EWS-Endpunkt

Die EWS-URL ist nicht die OWA-URL (Webmail). Auf dem Exchange-Server:

Get-WebServicesVirtualDirectory | fl Name,InternalUrl,ExternalUrl

In einer Air-Gap-Umgebung möchten Sie fast immer die InternalUrl.

Testen

Unit-Tests benötigen keinen Exchange-Server (nur Konfigurations-Parsing + Serialisierung):

uv run pytest

Live-Smoke-Test (mit einer echten .env): Server starten, einen MCP-Client oder den MCP Inspector verbinden, dann list_folderslist_emailssend_email (an sich selbst) aufrufen und den Empfang bestätigen. Stellen Sie OUTLOOK_AUTH_TYPE zwischen ntlm und basic um, um zu bestätigen, welche Variante Ihr Exchange-Administrator aktiviert hat.

Compose-UI (MCP Apps)

draft_email öffnet ein interaktives MCP Apps-Widget – einen React-Composer, der in eine einzelne eigenständige HTML-Datei (src/mcp_outlook/widgets/compose.html) eingebettet ist. Jeder Host mit MCP-Apps-Unterstützung rendert es inline im Chat-Verlauf.

Widget-Funktionen:

  • An-Feld mit Inline-Kontaktsuche – Nach dem letzten Komma tippen, um Kontakte zu suchen; ein Ergebnis auswählen, um die Abfrage durch einen Chip zu ersetzen; gültige Adressen werden als beschriftete Chips dargestellt.

  • Senden / Verwerfen – Senden löst send_email direkt aus dem Widget aus (nur für Apps – das Modell kann es nicht aufrufen); Verwerfen klappt die Karte zusammen.

  • Ersetzung – Beim Öffnen eines neuen Entwurfs wird jedes ältere geöffnete Entwurfs-Widget ausgegraut.

  • Signatur – Jeder Entwurf ist mit „Written with Airchat“ vorausgefüllt (bearbeitbar).

Air-Gap-Garantie: Das gebaute HTML (React + Bridge-JS inline) wird mit dem Python-Paket ausgeliefert. Zur Laufzeit werden keine externen Ressourcen angefordert; Node.js wird nur zum Neuerstellen des Widgets benötigt.

Widget neu erstellen (nur Entwicklung)

cd frontend
npm ci
npm run build     # tsc + vite build + artifact copy → src/mcp_outlook/widgets/compose.html

Das Build-Skript prüft, bevor es kopiert, dass keine externen URLs in das HTML gelangt sind.

Visuell ausprobieren (eigenständige Entwicklervorschau)

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.

Stolperfallen

  • Basic-Auth ist auf modernen Exchange-Servern oft deaktiviert – NTLM ist die sicherere Standardwahl.

  • Interne/selbstsignierte Zertifikate erfordern OUTLOOK_CA_BUNDLE, andernfalls schlägt die Verbindung bei der TLS-Verifizierung fehl.

  • Der Mehrbenutzermodus (jwt) benötigt eine Exchange-Berechtigung – das Dienstkonto muss über die RBAC-Rolle ApplicationImpersonation verfügen. Siehe TODO.md. Der static- Modus benöticht keine solche Berechtigung.

  • .env enthält ein Klartext-Passwort. Sie ist git-ignoriert; schränken Sie außerdem die Dateiberechtigungen (chmod 600 .env) auf dem Host ein.

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

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    MCP server for any Microsoft Exchange / OWA deployment. Gives LLM agents access to email, calendar, directory search, folders, availability, and meeting analytics via 30 tools.
    30
    7
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables reading, sending, and managing Microsoft 365/Outlook emails through MCP tools with OAuth 2.1 authentication.
    114
    MIT

Latest Blog Posts

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