io.github.trsdn/mcp-server-word
WordMcp — Microsoft Word MCP Server
Сервер MCP, который позволяет ИИ-ассистентам управлять Microsoft Word для Windows через COM-автоматизацию: открывать документы, читать и редактировать текст, управлять абзацами и таблицами, задавать свойства документа и экспортировать в PDF.
Только Windows. Требуется локальная установка Microsoft Word — этот сервер управляет реальным приложением, а не разбирает файлы
.docx.
Требования
ОС | Windows 10/11 |
Среда выполнения | .NET 9 SDK или среда выполнения |
Office | Microsoft Word 2016 или новее (настольная версия, не версия из Microsoft Store) |
Related MCP server: Word Document MCP Server
Установка
dotnet tool install --global WordMcp.McpServerПосле этого инструмент доступен как mcp-word.
mcp-word --version
mcp-word --helpЧтобы позже обновить или удалить его:
dotnet tool update --global WordMcp.McpServer
dotnet tool uninstall --global WordMcp.McpServerЧтобы вместо этого запускать невыпущенную сборку, упакуйте её локально и установите из выходной папки:
dotnet pack src\WordMcp.McpServer\WordMcp.McpServer.csproj -c Release -o artifacts
dotnet tool install --global --add-source .\artifacts WordMcp.McpServerБез установки
Сервер значится в реестре MCP как io.github.trsdn/mcp-server-word. Клиенты, которые сами разрешают пакеты, могут запускать его через dnx, который загружает версию по требованию, а не держит глобальный инструмент:
{
"servers": {
"word": {
"type": "stdio",
"command": "dnx",
"args": ["WordMcp.McpServer@0.1.0", "--yes"]
}
}
}Настройка клиента
Сервер работает через stdio.
VS Code / GitHub Copilot
.vscode/mcp.json:
{
"servers": {
"word": {
"type": "stdio",
"command": "mcp-word"
}
}
}Claude Desktop
%APPDATA%\Claude\claude_desktop_config.json:
{
"mcpServers": {
"word": {
"command": "mcp-word"
}
}
}Copilot CLI
copilot mcp add word --command mcp-wordПонятия
Каждая операция выполняется в рамках сеанса. Сеанс владеет одним экземпляром Word и одним открытым документом и идентифицируется по session_id, например word-a1b2c3d4e5f6g.
file(open|create) ──► session_id ──► text / paragraph / table / document ──► file(save) ──► file(close)Пути должны быть абсолютными (
C:\Users\me\Documents\report.docx).Поддерживаемые входные форматы:
.docx,.docm,.doc,.dotx,.dotm,.rtf.Документ не должен быть уже открыт в Word — WordMcp нужен исключительный доступ.
Word незаметно работает в фоне и завершается, когда сеанс закрывается.
Служба сеансов
Сеансы обычно живут внутри процесса MCP-сервера и исчезают вместе с ним. WordMcp.Service.exe — это опциональный фоновый демон, который хранит их вместо этого, поэтому сеанс переживает перезапуск клиента и может использоваться несколькими клиентами:
WordMcp.Service.exe --daemon [--idle-minutes 30] # listen until idle or stopped
WordMcp.Service.exe --status # what is it doing?
WordMcp.Service.exe --stop # save open documents and exitЗапускать его вручную почти не требуется — клиент, настроенный на его использование, запускает его по требованию. Канал, который он слушает, содержит ваш SID и ограничен ACL для него, поэтому сеансы никогда не разделяются между учётными записями. Он завершается сам, если после истечения тайм-аута простоя не было открыто ни одного сеанса.
Чтобы использовать его, задайте WORDMCP_SERVICE_MODE=daemon для MCP-сервера. Тогда каждый вызов инструмента уходит к демону, а не выполняется в собственном процессе сервера. Без этого сервер держит сеансы у себя, что как раз нужно одному клиенту: никакого второго процесса и никакого ожидания при запуске.
Инструменты
Пятнадцать инструментов, каждый с параметром action.
file — жизненный цикл сеанса
Действие | Назначение |
| Открыть существующий документ и начать сеанс |
| Создать новый документ по пути |
| Сохранить открытый документ |
| Сохранить (если нужно) и закрыть сеанс |
| Перечислить все активные сеансы |
| Проверить, можно ли автоматизировать Word на этом компьютере |
file(action: "open", path: "C:\\Users\\me\\Documents\\report.docx")
// → { "sessionId": "word-a1b2c3d4e5f6g", "fileName": "report.docx", ... }text — содержимое
Действие | Назначение |
| Прочитать весь текст или диапазон символов ( |
| Добавить текст, при необходимости новым абзацем |
| Найти термин; возвращает позиции и окружающий контекст |
| Заменить вхождения ( |
| Применить |
Позиции символов получают из get и find и являются смещениями диапазонов Word.
paragraph — структура
Действие | Назначение |
| Перечислить абзацы с индексом, текстом, стилем, выравниванием и уровнем структуры |
| Добавить абзац, при необходимости со стилем |
| Вставить абзац перед указанным индексом |
| Удалить абзац по индексу |
| Применить стиль, например |
|
|
Индекс абзаца начинается с 1, как в Word.
table — таблицы
Действие | Назначение |
| Перечислить таблицы с размерами и стилем |
| Создать таблицу с параметрами |
| Прочитать все ячейки таблицы как матрицу строк и столбцов |
| Записать одну ячейку ( |
| Добавить строку |
| Удалить строку |
| Применить стиль таблицы, например |
document — метаданные и экспорт
Действие | Назначение |
| Количество слов, знаков, абзацев, страниц, таблицы и разделов |
| Заголовок, автор, тема, ключевые слова, комментарии, компания |
| Изменить эти встроенные свойства |
| Экспортировать в PDF, не затрагивая открытый документ |
| Сохранить копию в другом формате |
image — изображения
Действие | Назначение |
| Перечислить встроенные изображения с индексом, размером, alt-текстом и состоянием ссылки |
| Вставить изображение, опционально с |
| Изменить размер с помощью |
| Заменить изображение по индексу, сохраняя его размер по умолчанию |
| Удалить изображение по индексу |
| Установить альтернативный текст для доступности |
Тип — поля и оглавления
Действие | Назначение |
| Перечислить все поля с индексом, типом и кодом поля |
| Вставить оглавление ( |
| Пересчитать каждое оглавление |
| Обновить все поля, включая поля верхних и нижних колонтитулов |
| Добавить номер страницы в верхний или нижний колонтитул |
section — разделы и параметры страницы
Действие | Назначение |
| Перечислить все разделы с типом начала, полями, размером страницы и ориентацией |
| Вставить разрыв раздела ( |
| Задать поля, |
header-footer — верхние и нижние колонтитулы
Действие | Назначение |
| Прочитать верхний или нижний колонтитул одного раздела или всех разделов |
| Записать текст, возможно с |
| Очистить верхний или нижний колонтитул |
kind выбирает header или footer, а type — primary, first-page или even-pages.
style — стили
Действие | Назначение |
| Перечислить стили; по умолчанию те, что используются в документе |
| Создать новый стиль, возможно на основе существующего |
| Изменить шаблон и форматирование абзаца для стиля |
| Удалить пользовательский стиль |
style_type выбирает paragraph, character или table. Укажите in_use_only: false в list, чтобы получить полный набор, который в локализованном Word содержит более 370 записей.
style(action: "create", session_id: "...", name: "Callout", base_style: "Normal")
style(action: "modify", session_id: "...", name: "Callout",
font_size: 11, bold: true, color: "#C00000", space_after: 12)list — маркеры и нумерация
Действие | Назначение |
| Сообщить форматирование списка абзацев, включая обрабатываемый маркер или номер |
| Оформить диапазон абзацев как список: |
| Установить уровень списка для диапазона (1–9) |
| Начать нумерацию заново с абзаца |
| Снять форматирование списка |
Если end_index не указан, действие применяется только к start_index.
list(action: "apply", session_id: "...", start_index: 2, end_index: 5, list_type: "number")
list(action: "set-level", session_id: "...", start_index: 3, end_index: 4, level: 2)
list(action: "restart", session_id: "...", start_index: 6)comment — комментарии рецензента
Действие | Назначение |
| Перечислить комментарии с автором, датой, текстом и комментируемым текстом |
| Прикрепить комментарий к абзацу или фразе внутри него |
| Пометить комментарий как решённый или открыть его снова |
| Удалить комментарий |
Команда add примечает весь абзац, если anchor_text не указывает на фразу внутри. После delete индексы изменяются, поэтому перед удалением ещё одного комментария выведите свой список заново.
comment(action: "add", session_id: "...", paragraph_index: 4,
text: "Source?", anchor_text: "fifteen percent")
comment(action: "list", session_id: "...", unresolved_only: true)revision — отслеживание исправлений
Действие | Назначение |
| Перечислить отслеживаемые исправления и сообщить, включено ли отслеживание |
| Принять одно исправление или все |
| Отклонить одно исправление или все |
| Включить или выключить отслеживание изменений |
Если опустить index в accept/reject, действие применится ко всему документу, включая верхние и нижние колонтитулы.
revision(action: "set-tracking", session_id: "...", enabled: true)
revision(action: "accept", session_id: "...")bookmark — стабильные ссылки
Действие | Назначение |
| Закладки с именем, индексом абзаца и предпросмотром отмеченного текста |
| Создаёт закладку на абзац, диапазон абзацев или фразу внутри абзаца |
| Читает полный текст, сохранённый в закладке |
| Удаляет закладку; текст остаётся |
Имена должны начинаться с буквы и могут содержать только буквы, цифры и символы подчёркивания. Закладки переживают правки в других местах документа, поэтому остаются надёжным способом возвращаться к нужному фрагменту, когда индексы абзацев уже сместились.
bookmark(action: "add", session_id: "...", name: "Intro", paragraph_index: 2)
bookmark(action: "add", session_id: "...", name: "Growth",
paragraph_index: 4, anchor_text: "fifteen percent")
bookmark(action: "get-text", session_id: "...", name: "Intro")screenshot — посмотреть страницу
Действие | Назначение |
| Отрисовывает страницу в формате PNG |
Вопросы вёрстки — разрывы страниц, ширины таблиц, расположение изображений, положение колонтитулов — гораздо проще решать по отрисованной странице, чем по измерениям. PNG записывается в файл, и возвращается путь к нему; include_image: true дополнительно возвращает его встроенным как base64, что имеет смысл только когда на изображение собираются смотреть.
dpi по умолчанию равен 150. Используйте 96 для быстрой проверки вёрстки и 300 для результата, близкого к печати.
screenshot(action: "page", session_id: "...", page: 2)
screenshot(action: "page", session_id: "...", page: 1,
output_path: "C:/temp/page1.png", dpi: 300, include_image: true)Ответы
Каждый инструмент возвращает JSON. Ошибки сообщаются структурированными данными, а не транспортной ошибкой:
{
"success": false,
"isError": true,
"tool": "text",
"action": "Replace",
"errorType": "KeyNotFoundException",
"errorMessage": "Session 'word-unknown' not found."
}Известное поведение и подводные камни
document(save-as)также сохраняет исходный файл. У Word нет API для смены формата «сохранить копию». Для любого целевого формата, кроме PDF, сервер вызываетSaveAs2(target)и затемSaveAs2(original), из-за чего несохранённые изменения пишутся в исходный файл как побочный эффект. Используйтеexport-pdf, когда нужен экспорт без побочных эффектов.Цвета задаются в hex RGB (
#0078D4). Сервер преобразует их в BGR-значение, которое ожидает Word.Документы с защитой прав доступа (IRM/AIP) отклоняются ещё до запуска Word.
Открытый в Word документ блокирует сеанс — сначала закройте его.
Диалоговые окна Word останавливают автоматизацию. Если вызов завершился по таймауту, проверьте, нет ли на рабочем столе открытого диалогового окна. Верхняя наждак? Actually "An open dialog on the desktop": "на рабочем столе".
Имена стилей английские. Встроенные стили (
Heading 1,Title,Table Grid, …) преобразуются в независимые от языка идентификаторы стилей Word, поэтому работают в локализованных установках. Любое другое имя передаётся в Word как есть; так адресуются пользовательские и локализованные стили. Учтите, что Word выдаёт имена стилей под их локализованным названием (Überschrift 1в немецкой установке), поэтомуstyle(list)возвращает иname, иenglish_name— при наличииenglish_nameпередавайте в ответ именно его.Встроенные стили нельзя удалить.
style(delete)отклоняет запрос понятным сообщением, не пропуская общую COM-ошибку Word. Пользовательский стиль, который всё ещё применяется к абзацу, тоже нельзя удалить; сначала присвойте таким абзацам другой стиль.Новые документы записываются напрямую, а не через Word.
file(create)сам записывает пустой пакет.docx/.docm, а затем открывает его. Создание документов через Word на старых машинах, входящих в Microsoft 365, ненадёжно: AutoSave перехватывает новый документ для OneDrive и молча игнорирует запрошенный локальный путь.Объединённые ячейки таблицы возвращаются функцией
table(read)как пустые строки.Размеры изображений указываются в пунктах, а не в пикселях (72 пт = 1 дюйм).
image(insert)иimage(resize)сохраняют пропорции, еслиlock_aspect_ratioне установлен вfalse, поэтому при передаче толькоwidthвысота масштабируется пропорционально.imageподдерживает только встроенные рисунки. Плавающие фигуры, надписи и диаграммы не затрагиваются и не появляются вimage(list), поэтому их наличие не сдвигает индексы изображений.Оглавление перечисляет только абзацы‑заголовки. Для документа без стилей заголовков
field(insert-toc)возвращаетentry_count: 0— сначала применитеHeading 1/Heading 2черезparagraph(add|set-style), затем выполнитеfield(update-toc).field(update-all)также обходит верхние и нижние колонтитулы. ПолеDocument.Fieldsв Word охватывает только простой текст документа, поэтому иначе номера страниц никогда не обновлялись бы.image(insert)с подписью использует нумерацию подписей Word, поэтому подпись выглядит какFigure 1 <your text>(в неанглийских установках — локализованно) и участвует в списке иллюстраций.Все измерения задаются в пунктах, включая поля страницы (1 см = 28,35 пт; 1 дюйм = 72 пт).
section(page-setup)применяетpaper_sizeдо полей, потому что изменение размера бумаги сбрасывает их в Word. Безsection_indexнастройка применяется каждому разделу.Верхние и нижние колонтитулы наследуются между нами. Новый раздел показывает колонтитулы предыдущего, пока в него что‑нибудь не записано.
header-footer(set)сsection_indexразрывает эту связь автоматически, поэтому раздел сохраняет собственный текст.Колонтитулы первой и чётной страницы требуют переключения раздела.
header-footer(set)сам включаетDifferentFirstPageиDifferentOddEvenPagesсоответственно; без этого Word сохраняет текст, но никогда не выводит его.list(apply)по умолчанию начинает новый список.continue_previous_listотключён, потому что продолжать нумерацию постороннего более раннего списка почти никогда не нужно. Два нумерованных списка, разделённых обычными абзацами, остаются независимыми; используйтеlist(restart), если Word всё же объединяет их.Разные уровни отображают только списки со структурной нумерацией.
list(set-level)работает с любым списком, но обычныйbulletилиnumberпоказывает один и тот же маркер на всех уровне — абзацы просто получают отступ.comment(resolve)в Microsoft 365 часто не срабатывает. Современные комментарии Word считают каждый комментарий, добавленный через API, неопубликованным черновиком, а черновик нельзя отметить выполненным. Сервер сообщает об этом ясным сообщением; вместо этого удалите комментарий. На установках, где невозможно выяснить состояние вовсе,comment(list)возвращаетresolved: null.Индексы комментариев и ревизий сдвигаются. Удаление комментарияи принятие одной ревизии перенумеровывает всё после них, поэтому между двумя такими вызовами выполняйте
listснова, а не не используйте старые индексы.revision(accept|reject)без индекса также обходит колонтитулы. МетодDocument.AcceptAllRevisions()в Word охватывает только основную текст документа, так же как уAdd-rangeetc. Actually "same gap as with field(update-all)".Записанные изменения фиксируются только во время их записи. The same as "while tracking is on".
Имена закладок ограничены Wordом. They must start with a letter, may contain only letters, digits, underscores, length 40. Spaces, hyphens, dots, non-ASCII letters rejected before Word.
Закладки — стабильный способ обращения к фрагменту. Индексы абзацев сдвигаются от каждой вставки, закладки — нет. Создайте закладку один раз и впоследствии читайте текст через
bookmark(get-text).bookmark(add)на абзац не включает знак абзаца самого конца, поэтомуget-textвозвращает текст без финального переноса. Закладка на несколько абзацев сохраняет знаки между ними.screenshot(page)работает через PDF. У Word нет API, возвращающего страницу как изображение, поэтому сервер экспортирует одну страницу черезExportAsFixedFormatи растрирует её. Несохранённые изменения включаются, а временная PDF‑файл потом удаляется.Номера страниц берутся из свежей разбивки на страницы. Документ, редактированный только автоматизацией, показывает устаревшее число страниц, поэтому
screenshotсначала выполняет переразбивку. Это также значит, что количество страниц отражает текущий макет, а не состояние на момент открытия.
Сборка из исходного кода
git clone https://github.com/trsdn/mcp-server-word.git
cd mcp-server-word
dotnet build WordMcp.sln -c Release
dotnet test WordMcp.sln --filter "Category!=RequiresWord"Структура проекта
Проект | Назначение |
| Жизненный цикл COM Word: STA‑потоки, сеансы, фильтр сообщений OLE, проверка файлов |
| Интерфейсы команд, реализации команд и модели результатов |
| Исходные файлы, общие для генераторов; не самостоятельный проект |
| Исходный генератор Roslyn, создающий классы инструментов MCP |
| stdio MCP‑сервер, предоставляющий пятнадцать инструментов |
| Модульные тесты и интеграционные тесты с реальным Word |
| Модульные тесты слоя инструментов без Word |
Генерируемый слой инструментов
Четырнадцать из пятнадцати инструментов генерируются при сборке. Интерфейсы команд в src/WordMcp.Core/Commands — единственный источник правды для контракта передачи данных:
[ServiceCategory("section", "Section")]задаёт имя класса инструмента —WordSectionTool.[McpTool("section", Title = ..., Description = ...)]задаёт имя инструмента и подсказку, которую читает модель.[Action("page-setup")]на каждом методе становится значением генерируемого перечисленияWordSectionAction.XML-документация параметров интерфейса превращается в описания параметров MCP‑схемы.
Генератор объединяет параметры всех действий в один метод, поэтому параметр, используемый только некоторыми действия, добавляется как необязательный. Чтобы изменить API, правится интерфейс, а не сгенерированный код. file остаётся написанным вручную, потому что управляет параметрами на всех сессиях, а не работает с одним документом.
Сгенерированный код смотрите в src/WordMcp.Mcmcs/obj/generated. Тесты в GeneratedToolContractTests сверяют сгенерированную «поверхность» с интерфейсами, поэтому несоответствие приводит к поправке как проверки сборки, а не к ошибке у клиента.
Тесты, тем которым нужен установленный Word, помечены [Trait("Category", "RequiresWord")] и исключены из CI. После неудачных интеграционных прогонов могут остаться зависшие процессы WINWORD.EXE, которые замедляют или блокируют последующие запуски; очистите их командой Get-Process WINWORD | Stop-Process -Force перед повторным запуском.
Дополнительные материалы
Документ | Что описывает |
Слои, поток запросов и то, как генерируется слой инструментов | |
STA‑потоки, освобождение COM‑объектов и поведение Word, стоящее за пунктами выше | |
Сборка, тестрование, добавление инструмента, подготовка релиза | |
Ориентное агентом руководство оприменению инструментов в правильном порядке |
Устранение неполадок
Симптом | Причина и решение |
| Установите настольную версию Word; версия Store не поддерживает автоматизацию |
|
|
Операция истекла по времени | Диалог Word ожидает ввода; закройте его и повторите. |
| Закройте документ в окне Word. |
Участие в разработке
Сообщения об ошибках и запросы на новые функции проходят через шаблоны issue. Пул-реквесты приветствуются; в CONTRIBUTING.md описано, как выполнить сборку, как запустить обе части тестового набора и что нужно, чтобы добавить инструмент.
Пожалуйста, сначала прочитайте Кодекс поведения.
Не создавайте публичных issue о проблемах безопасности — сообщите о них в частном порядке, как описано в политике безопасности.
Лицензия
MIT — см. LICENSE.
This server cannot be installed
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
- -licenseBqualityNot gradedmaintenanceEnables AI assistants to create, read, and manipulate Microsoft Word documents with comprehensive formatting, table creation, content management, and document protection capabilities. Supports advanced operations like merging documents, PDF conversion, and rich text formatting through a standardized interface.32
- AlicenseBqualityDmaintenanceEnables AI assistants to create and manipulate Microsoft Word documents programmatically with support for rich text formatting, tables, lists, headings, and find-and-replace operations.1031MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to directly read, edit, and manipulate Word documents, supporting image and table operations, paragraph editing, and search/replace.202MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to create, edit, and extract data from Microsoft Word documents programmatically, supporting document creation, content editing, table manipulation, parameter extraction, and template generation.1MIT
Related MCP Connectors
Use your own Word templates to convert Markdown → DOCX/PDF/HTML from any MCP-compatible AI.
AI document editing for agents: draft, edit, export .docx/PDF. 37 MCP tools; agent self-signup.
Generate PDFs from templates via AI chat. Works with Claude, ChatGPT, Cursor, and any MCP client.
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/trsdn/mcp-server-word'
If you have feedback or need assistance with the MCP directory API, please join our Discord server