ms-365-mcp-server
ms-365-mcp-server
Microsoft 365 MCP Server
Сервер Model Context Protocol (MCP) для работы с сервисами Microsoft 365 и Microsoft Office через Graph API.
Примечание: Это внутренняя сборка A-Impact, и она не опубликована в npm. Команды
npx @a-impact/ms365-mcpниже применимы только в том случае, если вы сами публикуете пакет под этим scope. Чтобы запустить его из этого репозитория, используйтеnpm install && npm run buildи указывайте вашему MCP-клиенту наdist/index.js, как описано в разделе Local Development.
Поддерживаемые облака
Сервер поддерживает несколько облачных сред Microsoft:
Облако | Описание | URL аутентификации | URL Graph API |
Global (по умолчанию) | Международный Microsoft 365 | login.microsoftonline.com | graph.microsoft.com |
China (21Vianet) | Microsoft 365, эксплуатируемый 21Vianet | login.chinacloudapi.cn | microsoftgraph.chinacloudapi.cn |
Related MCP server: Microsoft Graph MCP Server
Предварительные требования
Node.js >= 20 (рекомендуется)
Node.js 14+ может работать с предупреждениями о зависимостях
Возможности
Аутентификация через Microsoft Authentication Library (MSAL)
Полная интеграция с сервисами Microsoft 365
Поддержка режима только для чтения для безопасных операций
Фильтрация инструментов для детального контроля доступа
Пресеты инструментов и динамическое обнаружение для уменьшения набора инструментов и расхода токенов
Формат вывода: JSON vs TOON
Сервер поддерживает два формата вывода, которые можно настроить глобально:
Формат JSON (по умолчанию)
Стандартный вывод JSON с красивым форматированием:
{
"value": [
{
"id": "1",
"displayName": "Alice Johnson",
"mail": "alice@example.com",
"jobTitle": "Software Engineer"
}
]
}(экспериментальный) TOON-формат
Token-Oriented Object Notation для эффективного использования токенов LLM:
value[1]{id,displayName,mail,jobTitle}:
"1",Alice Johnson,alice@example.com,Software EngineerПреимущества:
На 30–60% меньше токенов по сравнению с JSON
Лучше всего подходит для однородных массивов данных (списки писем, события календаря, файлы и т. д.)
Идеально для приложений, чувствительных к стоимости, при масштабировании
Использование: (экспериментально) включите TOON-формат глобально:
Через CLI-флаг:
npx @a-impact/ms365-mcp --toonЧерез конфигурацию Claude Desktop:
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp", "--toon"]
}
}
}Через переменную окружения:
MS365_MCP_OUTPUT_FORMAT=toon npx @a-impact/ms365-mcpПоддерживаемые сервисы и инструменты
Сервер предоставляет более 300 инструментов, покрывающих большую часть Microsoft Graph API. Каждый инструмент сопоставляется один к одному с конечной точкой Graph API и объявляется декларативно в src/endpoints.json.
Инструменты для личной учётной записи (доступны по умолчанию)
Электронная почта (Outlook), календарь, файлы OneDrive, Excel, OneNote, задачи To Do, Планировщик, контакты, профиль пользователя, поиск
Инструменты для организационной учётной записи (требуется флаг --org-mode)
Teams и чаты, онлайн-встречи, транскрипты и записи, отчёты о посещаемости, сайты и списки SharePoint, общие почтовые ящики и календари, управление пользователями, присутствие, виртуальные события
Требуемые разрешения Graph API
Разрешения запрашиваются динамически в зависимости от того, какие инструменты включены. Используйте --list-permissions, чтобы увидеть точные разрешения для вашей конфигурации:
# Personal mode (default)
npx @a-impact/ms365-mcp --list-permissions
# Organization mode (includes Teams, SharePoint, etc.)
npx @a-impact/ms365-mcp --org-mode --list-permissions
# Filtered by preset
npx @a-impact/ms365-mcp --preset mail --list-permissionsЭто полезно для корпоративных сред, где разрешения Graph API должны быть предварительно одобрены и согласованы администратором до развертывания новой версии.
В JSON, возвращаемый --list-permissions, входит:
toolPermissions: разрешения, подразумеваемые поверхностью инструментов до фильтрации--allowed-scopeseffectivePermissions: разрешения, подразумеваемые инструментами, которые остаются включёнными после--allowed-scopespermissions: устаревший алиас дляeffectivePermissions, сохранён для совместимости с существующими скриптамиallowedScopes: настроенный список разрешённых областей, если он переданdisabledTools: инструменты, скрытые, потому что нет перекедали их требуется области Graph не покрытыallowedScopesmissingAllowedScopesForTools: недостающие области для отключённых инструментовextraAllowedScopesNotUsedByTools
Разрешённые области
По умолчанию MSAL запрашивает области, подразумеваемые включёнными инструментами, а состав инструментов управляется параметрами --enabled-tools, --preset, --org-mode и --read-only.
Корпоративные и безголовые развертывания могут добавить границу области с помощью --allowed-scopes или MS365_MCP_ALLOWED_SCOPES. Когда указана эта настройка, сервер сначала вычисляет обычный состав инструментов, затем скрывает инструменты Graph, требуемые области которых не покрыты списком разрешений. Метаданные OAuth и поток входа запрашивают только разрешения, необходимые для инструментов, которые остаются доступными.
npx @a-impact/ms365-mcp \
--org-mode \
--enabled-tools '^(list-mail-messages|get-mail-message|list-drives|get-drive-item|download-bytes)$' \
--allowed-scopes 'User.Read Mail.Read Files.Read'Значение из CLI имеет приоритет над MS365_MCP_ALLOWED_SCOPES; если не задано ни то, ни другое, стандартное поведение на основе инструментов не меняется. Пустое значение завершает запуск ошибкой, чтобы развертывание случайно не откатилось на более широкий набор инструментов.
Области покрытия учитывают иерархию: например, Mail.ReadWrite покрывает инструменты, требующие Mail.Read, а Files.ReadWrite.All покрывает инструменты, требующие Files.Read.
SharePoint поддерживает две корпоративные модели разрешений:
Широкие области клиента, такие как
Sites.Read.All,Sites.ReadWrite.AllиSites.Manage.All.Microsoft Graph
Sites.Selected, когда доступ к сайту SharePoint предоставляется приложению на конкретных семействах сайтов, а Graph проверяет разрешения подписанного пользователя в момент запроса.
Поведение по умолчанию в режиме org-mode по-прежнему запрашивает широкие области SharePoint, используемые существующими развертываниями. Предприятиям, которым нужен доступ к выбранным сайтам SharePoint, можно разрешить список, содержащий Sites.Selected, вместо широких областей Sites.*.All. Прямые инструменты для сайтов, списков и отдельных элементов, работающие с конкретным сайтом SharePoint, могут работать с Sites.Selected; инструменты обнаружения и поиска SharePoint в пределах тенанта по-прежнему требуют широких областей.
npx @a-impact/ms365-mcp \
--org-mode \
--read-only \
--enabled-tools 'sharepoint|site|drive|planner' \
--allowed-scopes 'User.Read Files.Read Notes.Read Tasks.Read Sites.Selected'В HTTP-режиме OAuth discovery объявляет эффективные фильтрованные разрешения, чтобы клиенты запрашивали тот же объём согласия. В режиме on-behalf-of (--obo) по-прежнему указывается api://<clientId>/access_as_user для метаданных защищаемого ресурса; --allowed-scopes не изменяет этот механизм.
Запрос дополнительных областей
Настройка --allowed-scopes может только сужать запрос к API. Чтобы запросить scope Graph, который не нужен встроенному инструменту, например, для работы через graph-batch, используйте --extra-scopes (или MS365_MCP_EXTRA_SCOPES). Эти области добавляются к запросу токена дословно поверх областей, полученных из инструментов.
npx @a-impact/ms365-mcp \
--org-mode \
--extra-scopes 'CopilotPackages.ReadWrite.All'Это для вашей собственной регистрации приложения Azure (MS365_MCP_CLIENT_ID / MS365_MCP_CLIENT_SECRET): в приложении по умолчанию upstream объявлено только же lint. Спросите дополнительные области для приложения, которым управляете вы (администратор вашего тенанта даст на или уважение). Значение CLI приоритетнее значения переменной окружения; пустое значение приводит к ошибке при запуске.
Режим организации/рабочего аккаунта
Для доступа к рабочим/учебным функции (Teams, SharePoint и т. д.) включите организационный режим одним из флагов:
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp", "--org-mode"]
}
}
}Организационный режим должен быть включен с самого начала для получения функций учебных / рабочих записей. Без этого флага доступны только функции personalispersonal (почта, календарь, OneDrive и т. д.).
Доступ к общему почтовому ящику
Для доступа к общим почтовым ящикам необходимо:
Организационный режим: Инструменты общего ящика требуют флага
--org-mode(только рабочие/учебные записи)Делегированные права:
Mail.Read.FromSharedдля чтения,Mail.ReadWrite.Sharedдля создания, изменения или перемещения сообщений,Mail.Send.Sharedдля отправки, ответа и перезаписи,Calendars.Read.Sharedдля инструментов общего календаряРазрешения Exchange: Вошедший в систему пользователь должен иметь доступ к общему почтовому ящику
Использование: Используйте адрес электронной почты общего ящика как параметр
user-idв инструментах общего ящика
Как найти общие ящики: Используйте инструмент list-users, чтобы обнаружить доступных пользователей и общие ящики в организации.
Пример: list-shared-mailbox-messages с user-id = common-mailbox@company.com
Пример быстрого старта
Проверьте вход в Claude Desktop:
Примеры
Интеграция
Claude Desktop
Чтобы добавить этот лабораторный сервер MCP в Claude Desktop, отредактируйте конфигурацию.
Личная учётная запись (MSA)
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp"]
}
}
}Учебная/ рабочая учётная запись (Global)
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp", "--org-mode"]
}
}
}Учебная/ рабочая учётная запись (China 21Vianet)
{
"mcpServers": {
"ms365-china": {
"command": "npx",
"args": ["-y", "@a-impact/ms365-mcp", "--org-mode", "--cloud", "china"]
}
}
}Claude Code CLI
Личная учётная запись (MSA)
claude mcp add ms365 -- npx -y @a-impact/ms365-mcpУчебная/ рабочая учётная запись (Global)
# macOS/Linux
claude mcp add ms365 -- npx -y @a-impact/ms365-mcp --org-mode
# Windows (use cmd /c wrapper)
claude mcp add ms365 -s user -- cmd /c "npx -y @a-impact/ms365-mcp --org-mode"Учебная/ рабочая учётная запись (China 21Vianet)
# macOS/Linux
claude mcp add ms365-china -- npx -y @a-impact/ms365-mcp --org-mode --cloud china
# Windows (use cmd /c wrapper)
claude mcp add ms365-china -s user -- cmd /c "npx -y @a-impact/ms365-mcp --org-mode --cloud china"Для других интерфейсов, поддерживающие MCP, следуйте их документации для правильного подключения.
Open WebUI
Open WebUI поддерживает наличие MCP-серверов через HTTP-трансляцию с протоколом OAuth 2.1.
Запустите сервер в HTTP-режиме:
npx @a-impact/ms365-mcp --httpВ Open WebUI перейдите в Расширения на сайте → Сервисы (
/admin/settings/tools) → Добавить подключение:Тип: MCP Streamable HTTP
URL: Endpoint-scrypt MCP URL with
/mcp.Auth: OAuth 2.1
Нажмите Register Client.
Примечание: Динамическая регистрация клиента включена по умолчанию в HTTP-режиме. Используйте
--no-dynamic-registration(илиMS365_MCP_DISABLE_DCR=true), чтобы disable. При использовании своего Azure Entra app выбор платформы для Redirect URI зависит от наличия client secret: с секретом используйте «Web», без секрета — «Mobile and apps&r' "женский" (никогда не «Single-page application»).
Быстрая настройка теста с Azure-app по умолчанию (ID ms-365 и localhost:8080 предварительно запущены):
docker run -d -p 8080:8080 \
-e WEBUI_AUTH=false \
-e OPENAI_API_KEY \
ghcr.io/open-webui/open-webui:main
npx @a-impact/ms365-mcp --httpЗатем добавьте подключение с URL http://localhost:3000/mcp и ID ms-365.
Запуск в Docker за обратным прокси? Установите
--public-url https://your-domain.com, чтобы URL авторизации OAuth, который отдаётся браузеру пользователя, был достижим с внешней сети контейнера. Смотрите docs/deployment.md для полного руководства.
Локальная разработка
For local development and testing:
# From the project directory
claude mcp add ms -- npx tsx src/index.ts --org-modeИли настройте Claudion Desktop вручную:
{
"mcpServers": {
"ms365": {
"command": "node",
"args": ["/absolute/path/to/ms-365-mcp-server/dist/index.js", "--org-mode"]
}
}
}Примечание: Выполняйте
npm run buildпосле изменений кода, чтобы обновить папкуdist/.
Аутентификация
⚠️ Перед использованием инструментов выполните аутентификацию.
Сервер поддерживает три метода аутентификации:
1. Device Code Flow (по умолчанию)
Для интерактивной аутентификации через код устройства:
Вход MCP-клиента:
Вызовите
loginCustom-HTTP Tool (есть проверка токена)Если нужно, получите URL+code и открыть browser
Используйте
verify-loginдля проверки завершения
CLI login:
npx @a-impact/ms365-mcp --loginСледуйте подсказкам URL и code в терминале.
Токены хранятся в защищённом хранилище ОС (или в файле как запасной вариант).
2. OAuth Authorization Code Flow (только HTTP-режим)
Когда сервер запущен с --http, он требует OAuth-аутентификацию:
npx @a-impact/ms365-mcp --http 3000Этот режим:
Анонсирует OAuth-возможности MCP-клиентам
Предоставляет HTTP endpoint'ы OAuth по адресу
/auth/*(authorize, token, metadata)Требует токен в заголовке
Authorization: Bearer <token>для всех MCP-запросовПроверяет токены с помощью Microsoft Graph API
Отключает login/logout называют инструменты по умолчанию (для включения используйте
--enable-auth-tools)
MCP-клиенты автоматически handle OAuth flow, когда обнаруживают его capabilities.
Настройка Azure AD для тестирования OAuth
Для использования пользовательских Azure AD и настройки OAuth (рекомендуется для продакшена) нужно создать регистрацию приложения:
Создайте App Registration в Azure Active Directory:
идите на портал Azure
Перейдите Azure Active Directory → App registrations → New registration
Имя:
MS365 MCP Server
Настройте Redirect URI:
Настройте URI обратного вызова OAuth: перейдите к регистрации вашего приложения и на левой панели выберите «Аутентификация».
В разделе «Конфигурации платформ»:
Нажмите «Добавить платформу», если там ещё нет типа «Мобильные и настольные приложения» / «Публичный клиент».
Выберите «Мобильные и настольные приложения» или «Публичный клиент/нативное приложение (mobile & desktop)» (название зависит от версии портала).
Проверка с помощью MCP Inspector (
npm run inspector):
Перейдите к регистрации приложения и на левой панели выберите «Аутентификация».
В разделе «Конфигурации платформ»:
Нажмите «Добавить платформу», если у вас ещё нет платформы «Web».
Выберите «Web».
Укажите следующие URI перенаправления:
http://localhost:6274/oauth/callbackhttp://localhost:6274/oauth/callback/debughttp://localhost:3000/callback(необязательно, для серверного обратного вызова)
Получение учётных данных:
Скопируйте Идентификатор приложения (клиента) со страницы «Обзор».
Перейдите в раздел «Сертификаты и секреты» → «Создать секрет клиента» → Скопируйте значение секрета (необязательно для публичных приложений).
Настройка переменных окружения:
Создайте файл
.envв корне проекта:MS365_MCP_CLIENT_ID=your-azure-ad-app-client-id-here MS365_MCP_CLIENT_SECRET=your-secret-here # Optional for public apps MS365_MCP_TENANT_ID=common
После этих настроек сервер будет использовать ваше пользовательское приложение Azure вместо встроенного.
Примечание: файл
.envсчитывается из каталога, в котором запущен сервер, и MCP-клиент определяет, где именно это происходит. Из этого файла считываются толькоMS365_MCP_CLIENT_ID,MS365_MCP_CLIENT_SECRET,MS365_MCP_TENANT_IDиMS365_MCP_CLOUD_TYPE. Все остальные переменные, перечисленные выше, необходимо задать в вашей оболочке или в конфигурации MCP-клиента; любые другие записи, найденные в.env, игнорируются с предупреждением в stderr.
3. Использование собственного токена (BYOT)
Если вы запускаете ms-365-mcp-server в составе более крупной системы, которая управляет токенами Microsoft OAuth извне, вы можете передать токен доступа напрямую этому MCP-серверу:
MS365_MCP_OAUTH_TOKEN=your_oauth_token npx @a-impact/ms365-mcpЭтот метод:
Обходит интерактивные потоки аутентификации
Использует ваш существующий токен OAuth для запросов к Microsoft Graph API
Не выполняет обновление токена (управление жизненным циклом токена остаётся на вашей стороне)
Примечание: HTTP-режим требует аутентификации. Для тестирования без аутентификации используйте stdio-режим с потоком кода устройства.
Инструменты аутентификации: в HTTP-режиме инструменты входа/выхода по умолчанию отключены, поскольку аутентификацией занимается OAuth. Используйте
--enable-auth-tools, если они вам нужны.
Поддержка нескольких учётных записей
Используйте один экземпляр сервера для обслуживания нескольких учётных записей Microsoft. Когда выполнен вход более чем одним аккаунтом, в каждый инструмент автоматически добавляется параметр account, позволяющий указать, какую учётную запись использовать для конкретного вызова.
Вход с несколькими учётными записями (однократно, для каждого аккаунта):
# Login first account (device code flow)
npx @a-impact/ms365-mcp --login
# Follow the device code prompt, sign in as personal@outlook.com
# Login second account
npx @a-impact/ms365-mcp --login
# Follow the device code prompt, sign in as work@company.comСписок настроенных учётных записей:
npx @a-impact/ms365-mcp --list-accountsИспользование в вызовах инструментов: передавайте "account": "work@company.com" в любой запрос инструмента:
{ "tool": "list-mail-messages", "arguments": { "account": "work@company.com" } }Поведение:
При одной настроенной учётной записи она выбирается автоматически (параметр
accountне требуется).При нескольких учётных записях и отсутствии параметра
accountсервер использует выбранную по умолчанию или возвращает понятную ошибку со списком доступных аккаунтов.100% обратная совместимость: существующие конфигурации с одной учётной записью работают без изменений.
Параметр
accountпринимает адрес электронной почты (например,user@outlook.com) или MSALhomeAccountId.
Строгое закрепление учётной записи
Headless-развёртывания в stdio-режиме могут закрепить локальный кэш MSAL за одной ожидаемой учётной записью Microsoft:
# Username matching is case-insensitive
MS365_MCP_EXPECTED_USERNAME=work@company.com npx @a-impact/ms365-mcp --login
# Or pin the exact MSAL homeAccountId shown by --list-accounts
npx @a-impact/ms365-mcp --expected-home-account-id <homeAccountId> --loginИспользуйте --list-accounts, чтобы узнать значения homeAccountId. Инструмент MCP list-accounts намеренно скрывает идентификаторы учётных записей, поэтому для точного закрепления по идентификатору используйте CLI.
Закрепление является добровольным и работает только с локальным MSAL:
Значения CLI (
--expected-username,--expected-home-account-id) имеют приоритет надMS365_MCP_EXPECTED_USERNAMEиMS365_MCP_EXPECTED_HOME_ACCOUNT_ID.Передача пустого значения для закрепления приводит к ошибке при запуске, а не к игнорированию.
Имя пользователя сравнивается без учёта регистра, а
homeAccountId— точно.Если заданы оба закрепления, они должны соответствовать одному и тому же кэшированному аккаунту.
Локальный запуск в stdio-режиме быстро завершается ошибкой, если ожидаемого аккаунта нет в кэше токенов. Для начальной настройки задайте закрепление, выполните
--login, затем запустите headless-сервер.При device-code и браузерном входах отсутствующая или несовпадающая учётная запись отклоняется до сохранения выбранного аккаунта или кэша токенов.
Закрепление сворачивает режим MCP до одной учётной записи: сервер не объявляет параметр
account, и инструкции MCP не предлагают переключение аккаунтов.--http,--oboиMS365_MCP_OAUTH_TOKENиспользуют токены, предоставленные запросом, для вызовов Graph, поэтому закрепление аккаунтов в этих режимах является предупреждением. Если инструменты HTTP-аутентификации включены, закрепление по-прежнему применяется к этим локальным вспомогательным потокам MSAL.--logoutочищает все кэшированные учётные записи, включая закреплённую. Для точечной очистки лучше использовать--remove-account <id>.
Для MCP-мультиплексоров (Legate, Governor): режим нескольких аккаунтов заменяет шаблон с N процессами. Вместо запуска отдельного сервера на каждый аккаунт один экземпляр обрабатывает все учётные записи через параметр
account, уменьшая дублирование инструментов с N×110 до 110.
Пресеты инструментов
Чтобы снизить начальные накладные расходы на подключение и уменьшить использование токенов, используйте пресеты категорий инструментов вместо загрузки полного набора:
npx @a-impact/ms365-mcp --preset mail
npx @a-impact/ms365-mcp --list-presets # See all available presetsДоступные пресеты: mail, calendar, files, personal, work, excel, contacts, tasks, onenote, search, users, outlook, onedrive, teams, teams-write, all
Каждая конечная точка в endpoints.json объявляет, к каким пресетам она относится, через массив presets, поэтому каждый пресет — это точный allow-list имён инструментов, который никогда не пересекает границы приложений (например, mail не включает инструменты для общих почтовых ящиков; они находятся в work). Универсальный загрузчик двоичных данных download-bytes включён в каждый пресет, кроме teams-write, поэтому всё, что возвращает приложение (файл, вложение, фотография, запись), всегда можно получить; get-download-url (предварительно авторизованный URL для файлов drive/SharePoint) поставляется вместе с пресетами, работающими с дисками. Поэтому пресет, который может найти файл, всегда сможет прочитать его байты.
Пресеты outlook, onedrive и teams ограничены областью одного приложения: они открывают ровно одно приложение Microsoft. Используйте их для развёртываний «открыть ровно одно приложение»:
# Outlook only (mail + calendar + contacts; no shared mailboxes, no files)
npx @a-impact/ms365-mcp --preset outlook
# Teams only (requires --org-mode)
npx @a-impact/ms365-mcp --org-mode --preset teamsПресет teams-write — это отправляющий аналог --read-only: отправка в чатах, отправка/ответ в каналах, список чатов/команд/каналов по имени и уведомления о действиях — без чтения сообщений и без загрузчиков байтов. Запрашиваемые токены минимальны по построению (Chat.ReadBasic, области *.Send и базовый список команд/каналов — ничего, что могло бы прочитать содержимое сообщений):
npx @a-impact/ms365-mcp --org-mode --preset teams-writeДинамическое обнаружение инструментов
Вместо загрузки всех инструментов заранее используйте динамическое обнаружение, чтобы LLM находил и загружал инструменты только тогда, когда они нужны:
npx @a-impact/ms365-mcp --discoveryЭто сохраняет начальный контекст небольшим и уменьшает расход токенов, что особенно полезно для длительных сессий или настроенных по стоимости сценариев (например, Open WebUI, работающий с платным API).
Параметры CLI
При непосредственном вызове ms-365-mcp-server из командной строки можно использовать следующие значения:
--login Login using device code flow
--logout Log out and clear saved credentials
--verify-login Verify login without starting the server
--list-permissions List required Graph API permissions and exit (respects --org-mode, --preset, --enabled-tools, --allowed-scopes)
--org-mode Enable organization/work mode from start (includes Teams, SharePoint, etc.)
--work-mode Alias for --org-mode
--force-work-scopes Backwards compatibility alias for --org-mode (deprecated)
--cloud <type> Microsoft cloud environment: global (default) or china (21Vianet)
--allowed-scopes <scopes> Limit exposed tools to Graph scopes covered by this allowlist
--extra-scopes <scopes> Append additional Graph scopes to the token request (for use with your own app registration + graph-batch)
--expected-username <username> Require local MSAL auth to use this account username
--expected-home-account-id <id> Require local MSAL auth to use this exact homeAccountIdПараметры сервера
При работе в качестве MCP-сервера доступны следующие параметры:
-v Enable verbose logging
--read-only Start server in read-only mode, disabling write operations
--http [port] Use Streamable HTTP transport instead of stdio (optionally specify port, default: 3000)
Starts Express.js server with MCP endpoint at /mcp
--enable-auth-tools Enable login/logout tools when using HTTP mode (disabled by default in HTTP mode)
--no-dynamic-registration Disable OAuth Dynamic Client Registration (enabled by default in HTTP mode)
--enabled-tools <pattern> Filter tools using regex pattern (e.g., "excel|contact" to enable Excel and Contact tools)
--preset <names> Use preset tool categories (comma-separated). See "Tool Presets" section above
--list-presets List all available presets and exit
--toon (experimental) Enable TOON output format for 30-60% token reduction
--discovery Dynamic tool discovery: loads tools on demand to reduce initial token usage (see "Dynamic Tool Discovery" above)
--public-url <url> Public base URL for OAuth when behind a reverse proxy (see Open WebUI section and docs/deployment.md)Переменные окружения:
READ_ONLY=true|1: альтернатива флагу--read-onlyENABLED_TOOLS: фильтрация инструментов с использованием регулярного выражения (альтернатива флагу--enabled-tools)MS365_MCP_ORG_MODE=true|1: включение организационного/рабочего режима (альтернатива флагу--org-mode)MS365_MCP_FORCE_WORK_SCOPES=true|1: обратная совместимость для MS365_MCP_ORG_MODEMS365_MCP_OUTPUT_FORMAT=toon: включение формата вывода TOON (альтернатива флагу--toon)MS365_MCP_MAX_TOP=<n>: жесткий предел для Graph$top/topв списочных запросах (положительное целое число). Когда модель передаёт большое значение, сервер ограничивает его доn, чтобы ответы оставались меньше. Пример:MS365_MCP_MAX_TOP=15MS365_MCP_MAX_PAGES=<n>: максимальное количество страниц, обрабатываемых при вызове инструмента сfetchAllPages: true(положительное целое число, по умолчанию100). Ограничивает память и задержку для больших наборов результатов.MS365_MCP_MAX_ITEMS=<n>: максимальное количество накопленных элементов приfetchAllPages: true(положительное целые, по умолчанию10000). После накопления этого количества элементов пагинация останавливается, и ответ усекается.MS365_MCP_ALLOW_PAGINATION=0|false|no: полностью отключить объединение нескольких страниц. При установке параметрfetchAllPagesне объявляется в инструментах, а любой запрос, который всё равно передаёт его, возвращает только первую страницу (по умолчанию пагинация включена).MS365_MCP_BODY_FORMAT=html: возвращать тела писем в формате HTML вместо обычного текста (по умолчанию: text)MS365_MCP_MESSAGE_SIGNOFF_PREFIX=<text>: подпись, добавляемая перед исходящими сообщениями, чтобы получатели могли понять, что они отправлены агентом, напр.🤖. По умолчанию: нет. Тот же параметр в имя CLI:--message-signoff-prefix <text>(см. Message Signoff ниже)MS365_MCP_MESSAGE_SIGNOFF_SUFFIX=<text>: подпись, добавляемая в конец исходящих сообщений. По умолчанию: нет. Тот же CLI:--message-signoff-suffix <text>.--no-message-signoffотключает обе (см. Message Signoff ниже)MS365_MCP_RATE_LIMIT_DISABLED=true|1: отключить ограничение частоты запросов по IP в HTTP-режиме (по умолчанию: включено — 30 запросов/мин на/authorize,/token,/register; 120 запросов/мин на/mcp)MS365_MCP_TRUST_PROXY_HOPS=<n>: количество доверенных переходов через реверсивный прокси в HTTP-режиме (по умолчанию1). Точное ограничение запросов по IP зависит от соответствия вашей инфраструктуре — установите количество прокси, стоящих перед сервером,0для использования необработанного IP-адреса сетевого сокета или поденный запятыми список подсетейMS365_MCP_CLOUD_TYPE=global|china: облачная среда Microsoft (альтернатива флагу--cloud)LOG_LEVEL: задать уровень логирования (по умолчанию: 'info')SILENT=true|1: отключить вывод в консольMS365_MCP_REDACT_PII=false|0: отключить удаление JWT, Bearer-заголовков, полей OAuth-токенов и адресов электронной почты из сообщений логирования (по умолчанию отключено: редактирование включено). Сервер обрабатывает живые Bearer-токены Graph, поэтому редактирование включено, если вы не отключите его для подробной локальной отладки.MS365_MCP_CLIENT_ID: идентификатор клиентского приложения (по умолчанию встроенное приложение) клиента кастомного Azure-приложенияMS365_MCP_TENANT_ID: кастомный идентификатор клиента (арендатора) (по умолчанию 'common' для многотенантного режима). Для личных учётных записей Microsoft следует установить значениеconsumers— с июня 2026 года reshelf-токены, выданные через authority по умолчанию'common', будут отклонены при первом обновлении, поэтому сеансы завершаются примерно через час после входа.MS365_MCP_OAUTH_TOKEN: существующий OAuth-токен для Microsoft Graph API (метод BYOT)MS365_MCP_KEYVAULT_URL: URL Azure Key Vault для управления секретами (см раздел Azure Key Vault)MS365_MCP_TOKEN_CACHE_PATH: пользовательский путь к файлу кэша токена MSAL (см. Token Storage ниже)MS365_MCP_SELECTED_ACCOUNT_PATH: пользовательский путь к файлу метаданных выбранной учётной записи (см. Storage ниже)MS365_MCP_AUTH_CACHE_COMMAND: внешний исполняемый обёртка для провайдер-нейтрального хранилища кэша аутентификации (см. Token Storage ниже)MS365_MCP_AUTH_CACHE_COMMAND_TIMEOUT_MS: таймаут на один вызовMS365_MCP_AUTH_CACHE_COMMAND(по умолчанию:10000)MS365_MCP_EXPECTED_USERNAME: требовать, чтобы локальная аутентификация MSAL използовала имя пользователя этой учётной записи Microsoft (без учёта регистра; приоритет у CLI-флагов)MS365_MCP_EXPECTED_HOME_ACCOUNT_ID: требовать точное значение homeAccountId MSAL для локальной аутентификации MSAL (приоритет у CLI-флага)
Хранение токенов
Токены аутентификации хранятся в зашифрованном файле (AES-256-GCM). In local Only the 32-byte encryption key goes to the OS credential storage through keytar.
Сам кэш слишком велик для некоторых хранилищ учётных данных: blob Windows Credential Manager имеет максимальный размер 2560 байт, а реальный кэш токенов в несколько раз больше, поэтому в Windows запись никогда бы не могло завершиться успешно. Ключ занимает 32 байта независимо от количества учётных записей, поэтому это работает одинаково на всех платформах.
Пути по умолчанию находятся в каталоге конфигурации пользователя:
Платформа | Расположение |
Windows |
|
macOS |
|
Linux |
|
Более ранние версии по умолчанию использовали путь внутри установленного пакета, который при запуске через npx превращается в каталог кэша, хешируемый по содержимому, — такой каталог удаляется командой npm cache clean или при изменении версии пакета. Кэш, который всё ещё лежит в каталоге пакета, при первом запуске переносится в новое расположение.
Это касается глобальных и локальных установок, а также npx, если хеш не изменился. Добраться до кэша, оставленного в каталоге хеша предыдущей установки npx, невозможно, поэтому при последнем обновлении установки через npx придётся ещё раз выполнить вход. Принимать кэш из другого каталога означало бы довериться каталогу, в котором этот пакет не может подтвердить своё авторство; это не стоит одного сэкономленного входа.
Переопределите пути, если это необходимо:
export MS365_MCP_TOKEN_CACHE_PATH="$HOME/.config/ms365-mcp/.token-cache.json"
export MS365_MCP_SELECTED_ACCOUNT_PATH="$HOME/.config/ms365-mcp/.selected-account.json"Родительские каталоги создаются автоматически. Файлы записываются с правами 0600.
Без хранилища учётных данных (headless Linux, большинство контейнеров) ключ записывается в .cache-key рядом с файлом кэша с правами 0600. Это предотвращает появление токенов в случайной команде cat, в резервной копии или случайном коммите. Но это не защищает от того, кто уже может читать каталог, — ключ находится прямо там. Используйте MS365_MCP_AUTH_CACHE_COMMAND ниже, если вам нужен кэш в настоящем хранилище секретов.
Если кэш не удаётся расшифровать — ключ потерян, связка ключей заблокирована, файл изменён — вам будет предложено выполнить вход ещё раз, а не запускать сервер с ошибкой. Файл кэша остаётся ровно таким, каким был: не удаляется и не перезаписывается при новом входе. Просто заблокированная связка ключей обычно нормально читается при следующем запуске, и кэш при этом сохраняется.
Плата за это — новая сессия не сохраняется, пока длится такая ситуация, поэтому при каждом запуске вас снова просят войти. Если ключ действительно утерян и кэш уже никогда не откроется, удалите .token-cache.json, чтобы начать заново — об этомпишет журнал и указывает путь.
Размещенные / песочные среды (например, Anthropic Cowork): укажите для
MS365_MCP_TOKEN_CACHE_PATHиMS365_MCP_SELECTED_ACCOUNT_PATHпостоянный точку монтирования, чтобы токены сохранялись между сеансами.
Внешняя команда auth-cache
Для развёртываний локального MSAL без интерфейса можно заменить встроенное хранилище keytar/файлов внешней командой, нейтральной к провайдеру:
export MS365_MCP_AUTH_CACHE_COMMAND="/path/to/ms365-auth-cache-store"
export MS365_MCP_AUTH_CACHE_COMMAND_TIMEOUT_MS=10000Когда для локального потока аутентификации задана MS365_MCP_AUTH_CACHE_COMMAND, сервер использует только эту команду для кэша токенов MSAL и метаданных выбранной учётной записи. Резервное обращение к keytar или локальным файлам не выполняется. Если путь к команде отсутствует, не является исполняемым в POSIX, выход с ненулевым кодом, таймаут или возврат некорректных данных — операции с кэшем аутентификации завершаются закрытием (fail closed) с санитизированным сообщением об ошибке.
Значением должен быть реальный исполняемый файл-обёртка. Это не строка командной оболочки, и отдельной переменной окружения для аргументов нет. Помещайте настройки интерпретатора, региона, профиля или провайдера внутрь обёртки. Пользователи Windows должны указывать переменной исполняемый файл-обёртку или сценарий, который Node может запустить напрямую без разбора командной оболочки.
Сервер вызывает обёртку со следующими аргументами:
$MS365_MCP_AUTH_CACHE_COMMAND load token-cache
$MS365_MCP_AUTH_CACHE_COMMAND save token-cache
$MS365_MCP_AUTH_CACHE_COMMAND delete token-cache
$MS365_MCP_AUTH_CACHE_COMMAND load selected-account
$MS365_MCP_AUTH_CACHE_COMMAND save selected-account
$MS365_MCP_AUTH_CACHE_COMMAND delete selected-accountПротокол v1:
load <key>не читает stdin. При наличии значения завершается с кодом0и выводом{"found":true,"value":"<stored envelope string>"}. При отсутствии — код0с{"found":false}или пустой stdout.save <key>получает{"value":"<stamped envelope string>"}на stdin и должен завершиться с кодом0только после фиксации значения. В v1 нет отложенных или сводных сохранений.delete <key>не читает stdin и всегда завершается с кодом0, независимо от того, существовал ли ключ.<key>— этоtoken-cacheилиselected-account.Любой ненулевой код выхода — ошибка хранилища. Не используйте код
2для сообщения об отсутствии ключа в кэше.stderr перехватывается и усекается в санитизированных сообщениях. Данные stdin и stdout никогда не регистрируются сервером.
Полезная нагрузка кэша токенов может быть большой; обёртка должна обрабатывать значения не менее 256 КБ.
Обычные HTTP-запросы Graph без состояния не используют локальное хранилище кэша аутентификации. В HTTP-режиме командное хранилище пропускается при запуске и при каждом запросе, если явно не включены локальные инструменты аутентификации или не используется команда локальной учётной записи, такая как --login, --verify-login, --list-accounts, --select-account или --logout.
Интеграция с Azure Key Vault
Для производственных развертываний можно хранить секреты в Azure Key Vault вместо переменных окружения. Это особенно полезно для Azure Container Apps с управляемым удостоверением.
Настройка
Создайте Key Vault (если он у вас ещё нет):
az keyvault create --name your-keyvault-name --resource-group your-rg --location eastusДобавьте секреты в Key Vault:
az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-id --value "your-client-id" az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-tenant-id --value "your-tenant-id" # Optional: if using confidential client flow az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-secret --value "your-secret"Предоставьте доступ к Key Vault:
Для Azure Container Apps с управляемым удостоверением:
# Get the managed identity principal ID PRINCIPAL_ID=$(az containerapp show --name your-app --resource-group your-rg --query identity.principalId -o tsv) # Grant access to Key Vault secrets az keyvault set-policy --name your-keyvault-name --object-id $PRINCIPAL_ID --secret-permissions get listДля локальной разработки с Azure CLI:
# Your Azure CLI identity already has access if you have appropriate RBAC roles az loginНастройте сервер:
MS365_MCP_KEYVAULT_URL=https://your-keyvault-name.vault.azure.net npx @a-impact/ms365-mcp
Соответствие имён секретов
Имя секрета в Key Vault | Переменная окружения | Обязательность |
ms365-mcp-client-id | MS365_MCP_CLIENT_ID | Да |
ms365-mcp-tenant-id | MS365_MCP_TENANT_ID | Нет (по умолчанию — 'common') |
ms365-mcp-client-secret | MS365_MCP_CLIENT_SECRET | Нет |
Аутентификация
Интеграция с Key Vault использует DefaultAzureCredential из Azure Identity SDK, который автоматически пробует несколько методов аутентификации по порядку:
Переменные окружения (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID)
Управляемое удостоверение (рекомендуется для Azure Container Apps)
Учётные данные Azure CLI (для локальной разработки)
Учётные данные Visual Studio Code
Учётные данные Azure PowerShell
Необязательные зависимости
Пакеты Azure Key Vault (@azure/identity и @azure/keyvault-secrets) являются необязательными зависимостями. Они загружаются только тогда, когда настроена MS365_MCP_KEYVAULT_URL. Если вы не используете Key Vault, эти пакеты не нужны.
Подпись сообщений
Исходящие сообщения можно снабдить настраиваемой подписью (например, префикс 🤖), чтобы получатели отличали сообщения, отправленные агентом, от сообщений, набранных вами лично. По умолчанию выключено — включите с помощью --message-signoff-prefix / --message-signoff-suffix (переменные окружения: MS365_MCP_MESSAGE_SIGNOFF_PREFIX / MS365_MCP_MESSAGE_SIGNOFF_SUFFIX); --no-message-signoff или пустое значение переменной выключает её снова.
После настройки подпись применяется ко всем сообщениям Teams (отправка, ответы и редактирование, включая через graph-batch), к прямым отправкам почты (send-mail, ответ/пересылка, их варианты для общего почтового ящика и ответы в групповых обсуждениях) и к черновикам писем при записи их содержимого — send-draft-message отправляет черновик как есть, поэтому написанный вами черновик уходит без изменений. Сообщение, уже содержащее маркер, не подписывается дважды, а отправка, в тело которой нельзя добавить подпись, будет отклонена, а не отправлена без подписи.
Маркеры могут содержать разметку (например, цветной <span>), если она приводит к видимому тексту. Обратите внимание, что подпись — это защитное напоминание, а не строгая граница безопасности: агент с доступом к shell на том же компьютере может просто перезапустить сервер без неё.
Производственное развертывание
Полное руководство по размещению сервера для доступа на уровне организации см. в docs/deployment.md, включая Docker, Azure Container Apps, Azure App Service, регистрацию приложения Azure AD, настройку обратного прокси, конфигурацию клиента и открытые конечные точки.
Вклад в проект
Мы приветствуем вклад! Перед отправкой pull request убедитесь, что ваши изменения соответствуют нашим стандартам качества.
Запустите проверочный скрипт, чтобы проверить все требования к качеству кода:
npm run verifyДля разработчиков
После клонирования репозитория может потребоваться сгенерировать клиентский код из спецификации Microsoft Graph OpenAPI:
npm run generateСвязанные проекты
ms-365-admin-mcp-server от @okapi-ca: вспомогательный сервер для сценариев администратора / демона, использующий разрешения приложения (поток client credentials), охватывающий оповещения безопасности, журналы аудита, состояние сервисов и операционные отчёты.
Поддержка
Если у вас возникли проблемы или нужна помощь:
Создайте issue
Начните обсуждение
Эл. почта: eirikb@eirikb.no
Discord: https://discord.gg/WvGVNScrAZ или @eirikb
Лицензия
MIT © 2026 A-Impact
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Microsoft Graph API services including Outlook email, Calendar events, OneDrive files, and Contacts. Supports multiple Microsoft accounts with unified search across all services.
- AlicenseNot gradedqualityFmaintenanceEnables AI assistants to interact with Microsoft 365 services (users, mail, calendar, files) via Microsoft Graph API.371MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Microsoft 365 through the Microsoft Graph API, including searching Teams messages, managing chats, and sending messages.77MIT
- FlicenseNot gradedqualityDmaintenanceConnects AI assistants to Microsoft 365 via the Graph API, enabling email search, attachment extraction, and OneDrive file reading through natural conversation.
Related MCP Connectors
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
SaaS intelligence for AI agents. 5 unified tools cover 1,000+ services with 91-96% token savings.
Calendar API for AI agents: events, availability, Google/Microsoft setup, scheduling, and iCal.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/A-Impact-Pavel/ms365-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server