Skip to main content
Glama
io.github.trsdn/mcp-server-word

io.github.trsdn/mcp-server-word

by trsdn

WordMcp — Microsoft Word MCP 服务器

一个 MCP 服务器,让 AI 助手可以通过 COM 自动化驱动 Microsoft Word for Windows:打开文档、读取和编辑文本、管理段落和表格、设置文档属性并导出为 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 运行它,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,并仅对该 SID 设置了 ACL,因此会话绝不会在不同账户之间共享。一旦在空闲超时时长内没有任何会话处于打开状态,它就会自行退出。

要使用它,请为 MCP服务器设置 WORDMCP_SERVICE_MODE=daemon。此后,每次工具调用都会被发送给守护进程,而不是在服务器自己的进程中运行。若不设置,服务器就会自己持有会话——这正是单一客户端所需:无需额外进程,也无需启动等待。


工具

十五个工具,每个都有 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

以 zip 格式另存一份副本

image — 图片

操作

说明

list

列出内嵌图片及索引、尺寸、alt 文本和链接状态

insert

插入图片,可选 width、height、caption 和 alt_text

resize

利用 width/height 或 scale_percent 调整大小

replace

替换指定索引图片,默认保持原大小

delete

按索引删除图片

set-alt-text

为无障助手设置替代文本

field — 域和状态更新

操作

说明

list

列出所有域,包括索引、类型和域代码

insert-toc

插入目录(upper_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,type 用于选择 primary、first-page 或 even-pages。

style — 样式

操作

说明

list

列出样式;默认仅列出文档中使用的样式

create

创建自定义样式,可选基于已有样式

modify

更改样式的字体和段落格式

delete

删除自定义样式

style_type 用于选择 paragraph、character、table 或 list。向 list 传入 in_use_only: false 可查看完整列表——在本地化 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

列出批注,包括作者、日期、批注文本和被定位到的文本

add

添加批注至段落或段内短语

resolve

将批注标记为“已解决”,或重新打开

delete

删除批注

除非 anchor_text 指定了段落内的某个短语,否则 add 默认批注整个段落。执行 delete 之后索引会移动,所以删除第二条批注前请先重新 list。

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

打开或关闭修订跟踪

在 accept/reject 中省略 index 时会处理整个文档,包括页眉、页脚。

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。

  • 颜色是十六进制 RGB(#0078D4)。服务器会将其转换为 Word 所期望的 BGR 值。

  • 受权限保护的文档(IRM/AIP)会在启动 Word 之前被拒绝。

  • 在 Word 中打开的文档会阻塞会话——请先关闭该文档。

  • Word 对话框会使自动化停滞。 如果调用超时,请检查桌面上是否有打开的对话框。

  • 样式名称是英文的。 内置样式(Heading 1、Title、Table Grid、…)会映射为 Word 的语言无关样式 ID,因此可在本地化安装上正常工作。任何其他名称都会原样传给 Word,这就是自定义和本地化样式的处理方式。请注意,Word 在显示样式名称时会使用本地化名称(德文安装上是 Überschrift 1),为此 style(list) 同时返回 name 和 english_name——存在时将 english_name 回传。

  • 无法删除内置样式。 style(delete) 会以清晰的错误信息拒绝它们,而不是透传 Word 的通用 COM 错误。仍应用于某个段落的自定义样式也无法删除;请先将这些段落设为其他样式。

  • 新文档是直接写入的,而非通过 Word 创建。 file(create) 自己写入一个空的 .docx/.docm 包,然后打开它。在已登录 Microsoft 365 的机器上,通过 Word 创建文档并不可靠,因为 AutoSave 会把新文档认领到 OneDrive 去,并静默忽略请求的本地路径。

  • 合并后的表格单元格会被 table(read) 返回为空字符串。

  • 图片大小以磅为单位,而非像素(72 磅 = 1 英寸)。image(insert) 和 image(resize) 会保持宽高比,除非 lock_aspect_ratio 设为 false,因此只传入 width 时高度会随之缩放。

  • image 只覆盖嵌入式图片。 浮动形状、文本框和图表不会被触碰,也不会出现在 image(list) 中,因此它们的存在不会移动图片索引。

  • 目录只列出标题段落。 对于没有标题样式的文档,field(insert-toc) 会返回 entry_count: 0——请先通过 paragraph(add|set-style) 应用 Heading 1/Heading 2,再运行 field(update-toc)。

  • field(update-all) 也会遍历页眉和页脚。 Word 的 Document.Fields 只覆盖正文,这正是否则页码无法刷新的原因。

  • 带标题的 image(insert) 使用 Word 的题注编号,因此题注会显示为 Figure 1 <your text>(在非英语安装上会本地化),并参与“图表目录”。

  • 所有度量均以磅为单位,包括页边距(1 厘米 = 28.35 磅,1 英寸 = 72 磅)。

  • section(page-setup) 会在设定边距之前先应用 paper_size,因为在 Word 中改变纸张大小会重置边距。section_index 不存在时,设置会应用于每一节。

  • 页眉和页脚会跨节继承。 新节会显示上一节的页眉,直到有内容写入该节为止。带上 section_index 的 header-footer(set) 会自动切断这个关联,因此第 1 节会保留自己的页眉文字。

  • “首页”和“偶数页”页眉需要节开关。 header-footer(set) 会为你打开 DifferentFirstPage(或 DifferentOddEvenPages);否则 Word 会保存文字但从不渲染它。

  • list(apply) 默认开始一个新列表。 continue_previous_list 默认关闭,因为延续一个不相关的前置列表并不是经常的想法。两个之间夹有条一段普通段落的编号列表仍保持独立;如果 Word 确实把它们合并了,可以使用 list(restart)。

  • 只有大纲风格的编号列表会渲染出不同层级。 list(set-level) 可用于任何列表,但普通的 bullet 或 number 列表在每一层都会显示相同的标记——这些段落只是被缩进了。

  • comment(resolve) 在 Microsoft 365 上经常失败。 Word 的新式批注里面,所有通过 API 添加的批注都被视为未发布的草稿,而不能将草稿标记为已完成。服务器会把这个情况作为明确信息报告出来;这种时候请删除该批注。在完全不公开批注状态的安装上,comment(list) 会返回 resolved: null。

  • 批注和修订的索引会偏移。 删除一条批注或接受一条修订后,其后的所有条目都会重新编号,因此在两次调用之间要重新运行一次 list,不要重复使用旧索引。

  • 不带索引的 revision(accept|reject) 也会遍历页眉和页脚。 Word 的 Document.AcceptAllRevisions() 只覆盖正文,与 field(update-all) 存在一样的空缺。

  • 修订只有在修订(tracked changes)开启时才会被记录。 revision(set-tracking) 不能回溯应用——请在要记录的编辑发生之前打开它。

  • Word 对书签名称有限制。 名称必须以字母开头,只能包含字母、数字和下划线,且长度不能超过 40 个字符。空格、连字符、点号和非 ASCII 字母会在调用到达 Word 之前就被拒绝,否则 Word 会报出通用的 COM 错误。

  • 书签是引用某段落的稳定方式。 段落索引会随每次插入而移动,书签不会。只需记住某一段一次,之后便可使用 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

Word COM 生命周期: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 = ...)] 提供工具名称和模型要读取的提示语。

  • 方法上的 [ServiceAction("page-setup")] 变成所生成 WordSectionAction 枚举中的一个值。

  • 接口参数上的 XML 文档注释会变成 MCP schema 中的参数描述。

生成器会把所有操作的参数合并到一个方法,因此只被某些操作使用的参数会被生成为可选参数。要修改 API,请编辑接口——不要编辑生成的代码。file 工具保持不变,因为它处理的是多个会话而不是单个会话。

可以在 src/WordMcp.McpServer/object/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/英文-skill.md

面向 agent 的指南,说明如何正确使用工具

故障排除

症状

原因与修复

Word is not installed or not registered for COM

请安装 Word 桌面版;Microsoft Store 版本无法进行自动化

Could not load file or assembly

在 GAC 中找不到 office.dll——请重新安装或修复 Office

操作超时

Word 对话框正在等待输入;关闭并重试

The file is already open in Word

请在 Word 界面中关闭该文档

贡献

错误报告和功能请求请通过 issue 模板 提交。 欢迎提交 Pull Request;CONTRIBUTING.md 介绍了如何构建、如何运行 测试套件的两个部分,以及添加一个工具需要做哪些事。

请先阅读 行为准则。

不要针对安全问题提交公开 issue — 请按照 安全策略中的说明私下提交。

许可证

MIT — 参见 LICENSE。

Related MCP Connectors

Related MCP Servers