Skip to main content
Glama
ChurikovSV

outlook-mcp-server

by ChurikovSV

outlook-mcp-server

Локальный MCP-сервер для Microsoft Outlook в Windows: создание черновиков писем, подготовка встреч, работа с календарём и получение занятости сотрудников.

Почта и календарь используют настроенный профиль Outlook через pywin32 / win32com. Для занятости дополнительно реализованы прямые HTTP-запросы к Outlook Web App (OWA) и запросы из авторизованной вкладки браузера через Chrome DevTools Protocol (CDP).

Сервер не вызывает Outlook Send(). Письма создаются как черновики; приглашения, обновления встреч и отмены автоматически не отправляются. Инструменты календаря при этом могут сохранять, изменять и удалять элементы.

Требования

  • Windows и установленный Outlook с поддержкой COM-автоматизации.

  • Настроенный профиль Outlook и права на необходимые ящики и календари.

  • Python 3.11 или новее.

  • Разрешение корпоративных политик на используемые операции Outlook.

  • Для OWA — доступ к корпоративному серверу и подходящая авторизация.

  • Для браузерного OWA — запущенный Chromium-совместимый браузер с доступным CDP и авторизованной вкладкой OWA.

OWA-реализация настроена на https://mail.sberbank.ru и часовой пояс Russian Standard Time. Эти значения заданы в коде; автоматического обнаружения другого сервера Exchange нет.

Related MCP server: Outlook MCP Server

Установка

В PowerShell:

git clone https://github.com/ChurikovSV/outlook-mcp-server.git
cd outlook-mcp-server
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e .

Активация виртуального окружения не требуется. Зависимости перечислены в pyproject.toml: MCP SDK, pywin32, Pydantic, openpyxl, requests, SSPI, truststore и Playwright.

Установка из исходников в режиме -e сохраняет ожидаемое расположение каталога templates.

Запуск и подключение MCP-клиента

Streamable HTTP — по умолчанию

.\.venv\Scripts\python.exe -m outlook_mcp.server

Адрес MCP: http://127.0.0.1:8000/mcp.

Другой порт:

.\.venv\Scripts\python.exe -m outlook_mcp.server --port 8765

В MCP-клиенте выберите Streamable HTTP и укажите адрес сервера. Клиент должен иметь сетевой доступ к компьютеру с сервером: 127.0.0.1 обозначает компьютер самого клиента.

stdio

.\.venv\Scripts\python.exe -m outlook_mcp.server --transport stdio

Для stdio клиент сам запускает процесс. В настройках клиента укажите абсолютный путь к .venv\Scripts\python.exe как команду и -m, outlook_mcp.server, --transport, stdio как отдельные аргументы.

SSE

.\.venv\Scripts\python.exe -m outlook_mcp.server --transport sse --port 8765

Используйте этот режим для клиента с поддержкой SSE. Путь SSE при стандартных настройках FastMCP — /sse.

Параметр

По умолчанию

Назначение

--transport

streamable-http

streamable-http, stdio или sse

--host

127.0.0.1

Адрес привязки HTTP/SSE

--port

8000

Порт HTTP/SSE

Также доступна команда outlook-mcp из виртуального окружения.

В проекте не настроена аутентификация MCP-клиентов. Для локальной работы оставьте привязку к 127.0.0.1; при сетевом размещении отдельно ограничьте доступ.

Доступные инструменты

Сервер регистрирует 22 инструмента.

Письма

Инструмент

Назначение

create_draft

Один черновик с текстом, таблицами и вложениями

create_bulk_drafts

Отдельный черновик каждому получателю с общим содержимым

create_drafts_batch

Пакет писем с индивидуальными адресатами и содержимым

create_draft_from_markdown

Черновик из Markdown, файла или именованного шаблона

create_bulk_drafts_from_template

Персональный черновик для каждой строки CSV/XLSX

Календарь и занятость

Инструмент

Назначение

list_calendar_events

Чтение основного календаря или календаря дополнительного хранилища

prepare_calendar_meeting

Открытие окна встречи для проверки и ручной отправки

create_calendar_event

Создание и сохранение события

update_calendar_event

Изменение и сохранение события

delete_calendar_event

Удаление элемента по entry_id

get_employee_free_busy

Занятость одного сотрудника через Outlook COM

get_owa_free_busy

Занятость нескольких сотрудников через прямой HTTP-запрос к OWA

get_browser_owa_free_busy

Занятость через авторизованную вкладку OWA и CDP

Диагностика

Инструмент

Назначение

get_outlook_status

Проверка создания почтового объекта, версия Outlook

diagnose_outlook

Поэтапная проверка COM, MAPI и учётных записей

diagnose_calendar

Проверка основного календаря и фильтрации

diagnose_mailbox_calendar

Проверка календаря дополнительного/общего хранилища

diagnose_send_as_account

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

diagnose_meeting_attendee

Проверка добавления и разрешения адреса участника

diagnose_free_busy

Проверка получения занятости через COM

diagnose_owa_free_busy

Проверка прямого HTTP-доступа к OWA

diagnose_browser_owa

Проверка CDP, вкладки OWA и получения canary-токена

Письма

JSON ниже — аргументы соответствующего MCP-инструмента.

Один черновик

create_draft:

{
  "to": ["user@example.com"],
  "subject": "Протокол встречи",
  "body": "Коллеги, направляю протокол встречи.",
  "cc": ["manager@example.com"],
  "attachments": ["C:\\Work\\reports\\protocol.pdf"]
}

Поддерживаются cc, bcc и from_email. Для другого отправителя используется свойство Outlook SentOnBehalfOfName. Создание черновика не подтверждает право отправки от имени этого ящика.

Получатели из TXT, CSV или XLSX

Для create_draft и create_bulk_drafts можно указать recipient_file. Адреса из файла объединяются с переданными напрямую; дубликаты удаляются без учёта регистра.

{
  "recipient_file": "C:\\Work\\mail\\users.xlsx",
  "recipient_file_sheet": "Получатели",
  "recipient_file_column": "Почта",
  "subject": "Уведомление",
  "body": "Коллеги, встреча начнётся в 15:30."
}
  • TXT: адреса в текстовом файле.

  • CSV: строка заголовков и столбец адресов; разделитель определяется среди запятой, точки с запятой и табуляции.

  • XLSX: по умолчанию первый лист и столбец email; лист и столбец можно выбрать параметрами.

  • TXT и CSV читаются в UTF-8, в том числе с BOM.

Для общего письма используйте create_draft, для отдельных писем каждому адресату — create_bulk_drafts:

{
  "recipients": ["user1@example.com", "user2@example.com"],
  "subject": "Уведомление",
  "body": "Напоминаю о встрече."
}

Разные письма в одном вызове

create_drafts_batch:

{
  "drafts": [
    {
      "to": ["user1@example.com"],
      "subject": "Задача по проекту",
      "body": "Подготовьте отчёт к пятнице."
    },
    {
      "to": ["user2@example.com"],
      "subject": "Согласование",
      "body": "Проверьте приложенный документ.",
      "attachments": ["C:\\Work\\agreement.docx"]
    }
  ]
}

Массовые операции возвращают created, failed и drafts. При частичной ошибке уже созданные черновики остаются. Повтор всего запроса может создать дубликаты.

Вложения через MCP-клиент

Если клиент может передать содержимое файла, используйте uploaded_attachments. Пример с корректным Base64 небольшого текстового файла:

{
  "to": ["user@example.com"],
  "subject": "Вложение",
  "uploaded_attachments": [
    {
      "filename": "hello.txt",
      "content_base64": "SGVsbG8K"
    }
  ]
}

Сервер проверяет Base64, создаёт временный файл, прикладывает его, сохраняет черновик и удаляет временную копию. Лимит декодированного файла — 20 МиБ на вложение. Поддерживаются Base64 data URL.

attachments и uploaded_attachments можно сочетать. Все локальные пути относятся к компьютеру сервера; загрузка файла в чат сама по себе не делает файл доступным серверу.

Таблицы

Аргументы create_draft:

{
  "to": ["user@example.com"],
  "subject": "План работ",
  "body": "Согласованные действия:",
  "tables": [
    {
      "title": "Задачи",
      "columns": ["Задача", "Ответственный", "Срок"],
      "rows": [["Подготовить отчёт", "Иванов", "25.09.2026"]]
    }
  ]
}

Текст и таблицы преобразуются в HTML. Произвольный HTML в обычном body экранируется.

Markdown и персональные шаблоны

create_draft_from_markdown принимает ровно один источник:

  • markdown — текст в запросе;

  • markdown_file — путь к локальному файлу .md или .markdown;

  • template_name — имя шаблона из каталога templates.

Поддерживаются заголовки H1–H3, абзацы, жирный и курсивный текст, HTTP(S)-ссылки, списки, горизонтальные линии и таблицы Markdown. Это ограниченный набор Markdown; исходный HTML экранируется.

{
  "to": ["user@example.com"],
  "subject": "Статус проекта {{project}}",
  "markdown": "# {{project}}\n\n{{name}}, добрый день.\n\nСтатус: **готово**.",
  "variables": {
    "project": "Внедрение",
    "name": "Анна"
  }
}

Переменные {{name}} подставляются в тему и текст. Отсутствие нужной переменной вызывает ошибку. Для одного получателя переменная email добавляется автоматически, если не задана явно.

В репозитории есть test_personalized_email.md с переменными project, first_name, status и deadline.

Персонализация по строкам CSV/XLSX

Пример CSV в UTF-8:

email,first_name,project,status,deadline
anna@example.com,Анна,Внедрение,В работе,25.09.2026
ivan@example.com,Иван,Миграция,На согласовании,28.09.2026

Вызов create_bulk_drafts_from_template:

{
  "recipient_file": "C:\\Work\\mail\\projects.csv",
  "template_name": "test_personalized_email",
  "subject": "Статус проекта {{project}}"
}

Каждый столбец доступен шаблону как переменная. Служебные столбцы:

Столбец

Назначение

email

Получатель; другое имя задаётся через email_column

subject или Тема

Тема строки с приоритетом над общим аргументом subject

cc, bcc

Дополнительные адресаты через запятую или точку с запятой

from_email

Отправитель строки с приоритетом над общим аргументом

Для XLSX лист выбирается аргументом sheet, а не recipient_file_sheet. Параметр subject_column задаёт другое имя столбца темы. Вложения, переданные инструменту, общие для всех строк.

Календарь

Передавайте местное время в ISO-формате без Z и смещения: 2026-09-21T15:30:00. Конец интервала должен быть позже начала. Для OWA используется московское время.

Чтение событий

list_calendar_events:

{
  "start": "2026-09-21T00:00:00",
  "end": "2026-09-22T00:00:00",
  "limit": 100
}

Для дополнительного/общего хранилища добавьте store_name — его отображаемое имя в Outlook. Допускается точное или однозначное частичное совпадение. Проверить доступ можно через diagnose_mailbox_calendar с тем же именем.

limit — от 1 до 500, по умолчанию 100. Ответ содержит события с entry_id, временем, темой, местом, текстом и участниками, а также счётчики просмотра.

Подготовка встречи для ручной отправки

prepare_calendar_meeting:

{
  "subject": "Обсуждение проекта",
  "start": "2026-09-21T15:30:00",
  "end": "2026-09-21T16:00:00",
  "attendees": ["user1@example.com", "user2@example.com"],
  "location": "Переговорная 301",
  "body": "Обсудить текущий статус.",
  "reminder_minutes": 15
}

Нужен хотя бы один участник. Инструмент открывает окно встречи без программного сохранения и отправки. При блокировке Recipients.Add пробует RequiredAttendees. Проверьте участников в Outlook и отправьте приглашение вручную.

Создание события

Те же аргументы можно передать в create_calendar_event; attendees здесь необязателен. Поддерживаются all_day и reminder_minutes (по умолчанию 15; null отключает напоминание).

Если Outlook блокирует сохранение встречи с участниками, сервер пытается открыть её окно. Проверяйте status, event_saved, window_opened и manual_send_required: открытое окно не означает сохранённое событие.

Изменение и удаление

update_calendar_event:

{
  "entry_id": "OUTLOOK_EVENT_ENTRY_ID",
  "location": "Переговорная 302",
  "start": "2026-09-21T16:00:00",
  "end": "2026-09-21T16:30:00",
  "disable_reminder": true
}

Можно также менять subject, body, all_day и reminder_minutes.

delete_calendar_event:

{
  "entry_id": "OUTLOOK_EVENT_ENTRY_ID"
}

Используйте ID нужного события. Сервер не отправляет участникам обновления и отмены: изменение календаря организатора не означает уведомление участников. Параметр store_name предусмотрен только для чтения; инструменты изменения и удаления не принимают store_id.

Занятость сотрудников

Через Outlook COM

get_employee_free_busy:

{
  "email": "user@example.com",
  "start": "2026-09-21T09:00:00",
  "end": "2026-09-21T18:00:00",
  "slot_minutes": 30
}

Ответ содержит slots, free_slots и объединённые intervals. Размер слота — от 5 до 1440 минут; COM-вариант ограничивает запрос 1440 слотами. Корпоративные политики могут блокировать разрешение адреса или получение занятости.

Через прямой HTTP-запрос к OWA

get_owa_free_busy:

{
  "emails": ["user1@example.com", "user2@example.com"],
  "start": "2026-09-21T09:00:00",
  "end": "2026-09-21T18:00:00",
  "slot_minutes": 30
}

Используется внутренний вызов OWA GetUserAvailabilityInternal. По умолчанию применяется Windows Integrated Authentication через SSPI.

Если обе переменные OUTLOOK_MCP_OWA_COOKIE и OUTLOOK_MCP_OWA_CANARY заданы в окружении процесса сервера, используются данные браузерной сессии. Cookie и canary — секреты сессии: не сохраняйте их в репозитории и не включайте в диагностические сообщения.

Проверка TLS использует системное хранилище доверенных сертификатов Windows через truststore. При привязке авторизации к браузеру прямой запрос может вернуть authentication_required или authentication_redirect.

Через авторизованный браузер

  1. Запустите Chromium-совместимый браузер с включённым CDP согласно настройкам корпоративной среды.

  2. Откройте https://mail.sberbank.ru и выполните вход.

  3. Проверьте подключение через diagnose_browser_owa.

  4. Вызовите get_browser_owa_free_busy с теми же аргументами, что у HTTP-варианта; при необходимости добавьте cdp_url.

Приоритет адреса CDP: аргумент cdp_url → переменная OUTLOOK_MCP_CDP_URL → http://127.0.0.1:9222.

Пример настройки перед запуском:

$env:OUTLOOK_MCP_CDP_URL = "http://127.0.0.1:9222"
.\.venv\Scripts\python.exe -m outlook_mcp.server

Переменная только указывает адрес: она не запускает браузер и не включает CDP. Playwright подключается к существующему браузеру. Сервер ищет вкладку OWA, получает canary и выполняет запрос внутри неё. Cookie и canary не возвращаются в обычном диагностическом результате.

Оба браузерных инструмента перезагружают выбранную вкладку OWA для получения canary. Перед вызовом завершите работу с несохранёнными формами. Не предоставляйте посторонним доступ к порту CDP.

Статусы занятости: free, tentative, busy, out_of_office, working_elsewhere; неизвестные коды отображаются как unknown. Пустой ответ не следует считать подтверждением свободного времени.

Диагностика и текущие ограничения

Начните с get_outlook_status и diagnose_outlook, затем используйте диагностику нужного сценария. Для другого отправителя передавайте diagnose_send_as_account явный аргумент email, для общего календаря — store_name. В коде есть корпоративные значения по умолчанию, которые могут не соответствовать вашему профилю.

  • Просмотр календаря начинается с ранних записей и ограничен 10 000 элементов. При большой истории ответ может быть неполным даже со статусом ok. Проверяйте scanned, skipped и comparison_errors; отдельного признака усечения пока нет.

  • delete_calendar_event не проверяет тип найденного объекта. Ошибочный ID письма может привести к удалению письма.

  • В нескольких операциях смещение часового пояса отбрасывается без преобразования. Используйте время без смещения в ожидаемом местном поясе; OWA зафиксирован на московском времени.

  • Именованные шаблоны ищутся относительно дерева исходников. Их включение в устанавливаемый wheel пока не настроено.

  • Работа зависит от профиля Outlook, прав на ящики, корпоративных политик и развёртывания OWA. Наличие инструмента не гарантирует доступность операции.

  • В репозитории пока нет автоматического набора тестов и конфигурации CI.

Структура проекта

Файл или каталог

Назначение

server.py

MCP-инструменты и параметры запуска

models.py

Модели запросов

outlook.py

Черновики, получатели, таблицы и вложения

markdown_email.py

Преобразование Markdown в HTML

markdown_draft.py

Шаблоны и Markdown-черновики

bulk_template.py

Персонализация по CSV/XLSX

calendar.py

Основной календарь и встречи

mailbox_calendar.py

Чтение дополнительных календарей

freebusy.py

Занятость через COM

owa_freebusy.py

Занятость через HTTP

browser_owa_freebusy.py

Занятость через браузер и CDP

templates

Именованные Markdown-шаблоны

Диагностические функции также вынесены в diagnostics.py, mailbox_calendar_diagnostics.py и send_as_diagnostics.py.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to manage Microsoft Outlook emails, calendar events, contacts, and folders via COM automation.
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides LLMs with access to Microsoft Outlook email functionality, allowing them to read, search, compose, and manage emails through a standardized MCP interface on Windows.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to read, send, and manage Outlook mail locally on Windows via COM/MAPI, without cloud APIs.
    196 npm
    1
    MIT