Skip to main content
Glama
ItayElizur

mcp-outlook

by ItayElizur

mcp-outlook

Разворачиваемый у себя MCP-сервер для локального Microsoft Exchange через EWS (Exchange Web Services). Создан для сред с изоляцией от внешних сетей / без облака — он общается напрямую с вашим внутреним Exchange-сервером и никогда не обращается к Microsoft Graph, Azure AD или настольном клиенту Outlook.

  • Бэкенд: exchangelib (клиент EWS)

  • Фреймворк: FastMCP

  • Транспорт: streamable-http (автономный HTTP-сервер, к которому подключаются другие внутренние хосты)

  • Аутентификация в Exchange: basic или NTLM (выбирается через конфигурацию)

Два режима

Режим

Для кого

Как аутентифицируется

static (по умолчанию)

один почтовый ящик

подключается как эта учётная запись (ваши собственные учётные данные) — отлично подходит для локального бета-тестирования

jwt

много пользователей

проверяет пользовательский JWT у каждого вызывающего, затем работает с почтовым ящиком этого пользователя через служебную учётную запись + EWS Impersonation

Как режим jwt связывает идентичность. Exchange не может использовать JWT вашей компании (Outlook основан на PKINIT/Kerberos). Поэтому MCP выполняет два отдельных процесса аутентификации, которые никогда не смешиваются:

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

JWT пользователя никогда не отправляется в Exchange, и ни пароль пользователя, ни смарт-карта никогда не касаются MCP — только единственные учётные данные службы. О том, что администраторы должны настроить для режима jwt, см. TODO.md.

Related MCP server: OWA Exchange MCP Server

Инструменты

Инструмент

Назначение

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

Последние сообщения, сначала новые

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

Поиск по тексту + диапазону дат + отправителю/получателю

get_email(message_id, folder="inbox")

Полное сообщение: тело, получатели, имена вложений

draft_email(to, subject, body)

Открывает интерактивный виджет создания письма (MCP Apps); пользовател редактирует и отправляет

reply_email(message_id, folder, reply_all, body)

Открывает виджет создания письма, предварително заполненный как ответ

forward_email(message_id, folder, to, body)

Открывает виджет создания письма, предварително заполненный как пересылка

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

Отправка — вызывается только из виджета (только для приложения)

search_contacts(query, limit)

Поиск контактов — вызывается только из виджета (только для приложения)

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

Переключение статуса прочтеня

delete_email(message_id, folder, permanent=False)

Переместить в «Удалённые» или удалить безвозвратно

flag_email_important(message_id, folder, important=True)

Устанавливает важность High/Normal в Outlook

move_email(message_id, destination, folder)

Перемещает сообщение в другую папку

list_folders()

Имена доступных почтовых папок, включая вложенные

list_events(start_date, end_date, limit)

События календаря в заданном диапазоне дат

get_event(event_id)

Полное событие: описание, участники, место

find_meeting_slots(attendees, duration_minutes, ...)

Помощник планирования — ранжирует слоты по доступности участников

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

Открывает интерактивный виджет создания события

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

Создание события — вызывается только из виджета (только для приложения)

accept_meeting(event_id) / decline_meeting(event_id)

Ответить на приглашение на собрание

list_emails и search_emails также принимают unread_only=true, чтобы возвращать только непрочитанные сообщения.

Установка

Требуется Pythorn 3.11+ и uv.

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

Сервер привязывается к MCP_HOST:MCP_PORT (по умолчанию 127.0.0.1:8000) и обслуживает MCP-endpoинт streamable-http по адресу /mcp.

Локалное бета-тестирование (без настройки администратором)

Запустите с вашим собственным почтовым ящиком и вашими именем пользователя/паролем — без JWT, олицетворения, служебной учётной записи и смарт-карты:

# 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

Конфигурация

Все настройки задаются через переменные окружения (или файл .env). Полный список см. в .env.example. Основное:

Переменная

Примечания

OUTLOOK_AUTH_MODE

static (по умолчанию, один почтовый ящик) или jwt (много-пользовательский туннель)

OUTLOOK_EWS_ENDpoinT

Полный asmx URL, например https://mail.corp.local/EWS/Exchange.asmx. Предпочтително.

OUTLOOK_SERVER

Альтернатива только с именем хоста (конечная точка предпоагается по адресу /EWS/Exchange.asmx)

OUTLOOK_USERNAME

Подключаемая учётная запись — ваша собственная (static) или служебная (jwt). DOMAIN\user для NTLM или email для basic. Не используется с sspi

OUTLOOK_EMAIL

Почтовый ящик для открытия (режим static). Необязательно — по умолчанию OUTLOOK_USERNAME, если это email; игнорируется в режиме jwt; обязательно при sspi (нет имени пользователя для значения по умолчанию)

OUTLOOK_PASSWORD

пароль учётной записи. Не испоьзуется с sspi

OUTLOOK_AUTH_TYPE

ntlm (по умолчанию), basic или sspi (встроенная аутентификация Windows — выполняется от имени AD-идентичности этого процесса, без имени пользователя/пароля; только Windows, требуется uv sync --extra sspi)

OUTLOOK_JWT_ISSUER / _AUDIENCE

Обязательно в режиме jwt — издатель токена и аудитория, которые требуется проверять

OUTLOOK_JWT_JWKS_URI / _PUBLIC_KEY

режим jwt — ключи подписи (JWKS URI или статический PEM для изолированных сред)

OUTLOOK_JWT_EMAIL_CLAIM

режим jwt — утверждение (claim), содержащее SMTP-адрес пользователя (по умолчанию email)

OUTLOOK_CA_BUNDLE

Путь к внутреннему CA .pem (для самоподписанных / внутренних CA)

OUTLOOK_VERIFY_SSL

true (по умолчанию); false отключает проверку TLS (только для разработки)

MCP_HOST / MCP_PORT

HTTP-привязка (по умолчанию 127.0.0.1:8000)

Поиск конечной точки EWS

URL EWS — это не URL OWA (веб-почты). На сервере Exchange:

Get-WebServicesVirtualDirectory | fl Name,InternalUrl,ExternalUrl

В изолированной (air-gapped) среде почти всегда нужен InternalUrl.

Тестирование

Модульные тесты не требуют сервера Exchange (только разбор конфигурации + сериализация):

uv run pytest

Живой смоук-тест (с реальным .env): запустите сервер, подключите MCP-клиент или MCP Inspector, затем вызовите list_folders → list_emails → send_email (себе) и подтвердите получение. Переключайте OUTLOOK_AUTH_TYPE между ntlm и basic, чтобы подтвердить тот вариант, который включён вашим администратором Exchange.

Интерфейс создания (MCP Apps)

draft_email открывает интерактивный виджет MCP Apps — React-композер, встроенный в один автономный HTML-файл (src/mcp_outlook/widgets/compose.html). Любой хост, поддерживающий MCP Apps, отображает его прямо в ветке чата.

Возможности виджета:

  • Поле «Кому» со встроенным поиском контактов — после последней запятой начните вводить текст для поиска контактов; выберите результат, чтобы заменить запрос чипом; корректные адреса отображаются как подписанные чипы.

  • Send / Discard — Send вызывает send_email прямо из виджета (только для приложения — модель не может его вызвать); Discard сворачивает карточку.

  • Замещение — открытие нового черновика затемняет любой более старый открытый виджет черновика.

  • Подпись — каждый черновик предварительно заполняется строкой "Written with Airchat" (можно редактировать).

Гарантия автономности (Air-gap): собранный HTML (React + встроенный bridge JS) поставляется с Python-пакетом. Во время выполнения не выполняется никаких внешних запросов ресурсов; Node.js нужен только для пересборки виджета.

Пересборка виджета (только для разработки)

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

Скрипт сборки перед копированием проверяет, что в HTML не попало внешних URL.

Попробуйте визуально (автономное превью для разработки)

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.

Подводные камни

  • Базовую аутентификацию часто отключают на современных Exchange — NTLM является более безопасным вариантом по умолчанию.

  • Внутренние/самоподписанные сертификаты требуют OUTLOOK_CA_BUNDLE, иначе соединение не пройдёт проверку TLS.

  • Многопользовательскому режиму (jwt) нужно одно разрешение Exchange — служебная учётная запись должна иметь роль RBAC ApplicationImpersonation. См. TODO.md. Режим static не требует такого разрешения.

  • В .env хранится пароль в открытом виде. Он игнорируется git; также ограничьте права на файл (chmod 600 .env) на хосте.

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
    46 PyPI
    11
    MIT
  • -
    license
    Not graded
    quality
    B
    maintenance
    Secure MCP server for Microsoft Exchange. It enables authorized users to list, search, read, download attachments, send, and reply to email via EWS with strict access control and audit.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables searching, reading full conversations, and sending email across multiple IMAP/SMTP mailboxes from any MCP client, with multi-user support and per-user API tokens.
    MIT