Skip to main content
Glama
trsdn

io.github.trsdn/mcp-server-word

by trsdn

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 — жизненный цикл сеанса

Действие

Назначение

open

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

create

Создать новый документ по пути path

save

Сохранить открытый документ

close

Сохранить (если нужно) и закрыть сеанс

list

Перечислить все активные сеансы

test

Проверить, можно ли автоматизировать Word на этом компьютере

file(action: "open", path: "C:\\Users\\me\\Documents\\report.docx")
// → { "sessionId": "word-a1b2c3d4e5f6g", "fileName": "report.docx", ... }

text — содержимое

Действие

Назначение

get

Прочитать весь текст или диапазон символов (start, end, max_length)

append

Добавить текст, при необходимости новым абзацем

find

Найти термин; возвращает позиции и окружающий контекст

replace

Заменить вхождения (match_case, match_whole_word, replace_all)

format

Применить bold, italic, underline, font_name, font_size, color к диапазону

Позиции символов получают из get и find и являются смещениями диапазонов Word.

paragraph — структура

Действие

Назначение

list

Перечислить абзацы с индексом, текстом, стилем, выравниванием и уровнем структуры

add

Добавить абзац, при необходимости со стилем style

insert

Вставить абзац перед указанным индексом

delete

Удалить абзац по индексу

set-style

Применить стиль, например Heading 1

set-alignment

left, center, right или justify

Индекс абзаца начинается с 1, как в Word.

table — таблицы

Действие

Назначение

list

Перечислить таблицы с размерами и стилем

create

Создать таблицу с параметрами rows × columns

read

Прочитать все ячейки таблицы как матрицу строк и столбцов

set-cell

Записать одну ячейку (row, column, text)

add-row

Добавить строку

delete-row

Удалить строку

set-style

Применить стиль таблицы, например Table Grid

document — метаданные и экспорт

Действие

Назначение

get-info

Количество слов, знаков, абзацев, страниц, таблицы и разделов

get-properties

Заголовок, автор, тема, ключевые слова, комментарии, компания

set-properties

Изменить эти встроенные свойства

export-pdf

Экспортировать в PDF, не затрагивая открытый документ

save-as

Сохранить копию в другом формате

image — изображения

Действие

Назначение

list

Перечислить встроенные изображения с индексом, размером, alt-текстом и состоянием ссылки

insert

Вставить изображение, опционально с width, height, caption и alt_text

resize

Изменить размер с помощью width/height или scale_percent

replace

Заменить изображение по индексу, сохраняя его размер по умолчанию

delete

Удалить изображение по индексу

set-alt-text

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

Тип — поля и оглавления

Действие

Назначение

list

Перечислить все поля с индексом, типом и кодом поля

insert-toc

Вставить оглавление (up_per_heading_level, lower_heading_level)

update-toc

Пересчитать каждое оглавление

update-all

Обновить все поля, включая поля верхних и нижних колонтитулов

insert-page-number

Добавить номер страницы в верхний или нижний колонтитул

section — разделы и параметры страницы

Действие

Назначение

list

Перечислить все разделы с типом начала, полями, размером страницы и ориентацией

add

Вставить разрыв раздела (start_type: next-page, continuous, even-page, odd-page)

page-setup

Задать поля, orientation и paper_size для одного раздела или всего документа

Действие

Назначение

get

Прочитать верхний или нижний колонтитул одного раздела или всех разделов

set

Записать текст, возможно с alignment

clear

Очистить верхний или нижний колонтитул

kind выбирает header или footer, а typeprimary, first-page или even-pages.

style — стили

Действие

Назначение

list

Перечислить стили; по умолчанию те, что используются в документе

create

Создать новый стиль, возможно на основе существующего

modify

Изменить шаблон и форматирование абзаца для стиля

delete

Удалить пользовательский стиль

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 — маркеры и нумерация

Действие

Назначение

get

Сообщить форматирование списка абзацев, включая обрабатываемый маркер или номер

apply

Оформить диапазон абзацев как список: bullet, number или outline-number

set-level

Установить уровень списка для диапазона (1–9)

restart

Начать нумерацию заново с абзаца

remove

Снять форматирование списка

Если 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 — комментарии рецензента

Действие

Назначение

list

Перечислить комментарии с автором, датой, текстом и комментируемым текстом

добавить

Прикрепить комментарий к абзацу или фразе внутри него

resolved

Пометить комментарий как решённый или открыть его снова

delete

Удалить комментарий

Команда 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 — отслеживание исправлений

Действие

Назначение

list

Перечислить отслеживаемые исправления и сообщить, включено ли отслеживание

accept

Принять одно исправление или все

reject

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

set-tracking

Включить или выключить отслеживание изменений

Если опустить index в accept/reject, действие применится ко всему документу, включая верхние и нижние колонтитулы.

revision(action: "set-tracking", session_id: "...", enabled: true)
revision(action: "accept", session_id: "...")

bookmark — стабильные ссылки

Действие

Назначение

list

Закладки с именем, индексом абзаца и предпросмотром отмеченного текста

add

Создаёт закладку на абзац, диапазон абзацев или фразу внутри абзаца

get-text

Читает полный текст, сохранённый в закладке

delete

Удаляет закладку; текст остаётся

Имена должны начинаться с буквы и могут содержать только буквы, цифры и символы подчёркивания. Закладки переживают правки в других местах документа, поэтому остаются надёжным способом возвращаться к нужному фрагменту, когда индексы абзацев уже сместились.

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 — посмотреть страницу

Действие

Назначение

page

Отрисовывает страницу в формате 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-range etc. 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"

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

Проект

Назначение

src/WordMcp.ComInterop

Жизненный цикл COM Word: STA‑потоки, сеансы, фильтр сообщений OLE, проверка файлов

src/WordMcp.Core

Интерфейсы команд, реализации команд и модели результатов

src/WordMcp.Generators.Shared

Исходные файлы, общие для генераторов; не самостоятельный проект

src/WordMcp.Generators.Mcp

Исходный генератор Roslyn, создающий классы инструментов MCP

src/WordMcp.McpServer

stdio MCP‑сервер, предоставляющий пятнадцать инструментов

tests/WordMcp.Core.Tests

Модульные тесты и интеграционные тесты с реальным Word

tests/WordMcp.McpServer.Tests

Модульные тесты слоя инструментов без 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 перед повторным запуском.

Дополнительные материалы

Документ

Что описывает

docs/architecture.md

Слои, поток запросов и то, как генерируется слой инструментов

docs/com-interop.md

STA‑потоки, освобождение COM‑объектов и поведение Word, стоящее за пунктами выше

CONTRIBUTING.md

Сборка, тестрование, добавление инструмента, подготовка релиза

skills/word-mcp/SKILL.md

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

Устранение неполадок

Симптом

Причина и решение

Word is not installed or not registered for COM

Установите настольную версию Word; версия Store не поддерживает автоматизацию

Could not load file or assembly 'office'

office.dll не найден в GAC — переустановите или восстановите Office

Операция истекла по времени

Диалог Word ожидает ввода; закройте его и повторите.

The file is already open in Word

Закройте документ в окне Word.

Участие в разработке

Сообщения об ошибках и запросы на новые функции проходят через шаблоны issue. Пул-реквесты приветствуются; в CONTRIBUTING.md описано, как выполнить сборку, как запустить обе части тестового набора и что нужно, чтобы добавить инструмент.

Пожалуйста, сначала прочитайте Кодекс поведения.

Не создавайте публичных issue о проблемах безопасности — сообщите о них в частном порядке, как описано в политике безопасности.

Лицензия

MIT — см. LICENSE.

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
1dResponse time
Release cycle
1Releases (12mo)
Commit activity

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

  • -
    license
    B
    quality
    Not graded
    maintenance
    Enables 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
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
    1
    MIT

View all related MCP servers

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.

View all MCP Connectors

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/trsdn/mcp-server-word'

If you have feedback or need assistance with the MCP directory API, please join our Discord server