Skip to main content
Glama
trsdn

io.github.trsdn/mcp-server-word

by trsdn

WordMcp — Servidor MCP para Microsoft Word

Un servidor MCP que permite a los asistentes de IA controlar Microsoft Word para Windows mediante automatización de COM: abrir documentos, leer y editar texto, gestionar párrafos y tablas, establecer propiedades del documento y exportar a PDF.

Solo Windows. Se requiere una instalación local de Microsoft Word: este servidor automatiza la aplicación real, no analiza archivos .docx.


Requisitos

OS

Windows 10/11

Runtime

.NET 9 SDK o runtime

Office

Microsoft Word 2016 o posterior (versión de escritorio, no la versión de Microsoft Store)

Related MCP server: Word Document MCP Server

Instalación

dotnet tool install --global WordMcp.McpServer

A partir de ahí, la herramienta queda disponible como mcp-word.

mcp-word --version
mcp-word --help

Para actualizarla o eliminarla más adelante:

dotnet tool update --global WordMcp.McpServer
dotnet tool uninstall --global WordMcp.McpServer

Para ejecutar en su lugar una compilación no lanzada, empaqueta la localmente y la instala desde la carpeta de salida:

dotnet pack src\WordMcp.McpServer\WordMcp.McpServer.csproj -c Release -o artifacts
dotnet tool install --global --add-source .\artifacts WordMcp.McpServer

Sin instalación

El servidor figurado en el registro de MCP como io.github.trsdn/mcp-server-word. Los clientes que resuelven sus paquetes por sí mismos pueden ejecutarlo a través de dnx, que consulta la versión bajo demanda en lugar de mantener una herramienta global:

{
  "servers": {
    "word": {
      "type": "stdio",
      "command": "dnx",
      "args": ["WordMcp.McpServer@0.1.0", "--yes"]
    }
  }
}

Configuración del cliente

El servidor se comunica mediante 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

Conceptos

Cada operación se ejecuta dentro de una sesión. Una sesión posee un instancia residencial de Word y un documento abierto, identificada por un session_id como word-a1b2c3d4e5f6g.

file(open|create) ──► session_id ──► text / paragraph / table / document ──► file(save) ──► file(close)

Para realizar operaciones, ten en cuenta lo siguiente:

  • Las rutas deben ser absolutas (C:\Users\me\Documents\report.docx).

  • Formatos de entrada admitidos: .docx, .docm, .doc, .dotx, .dotm, .rtf.

  • El documento no debe estar ya abierto en Word: WordMcp necesita acceso exclusivo.

  • Word se ejecuta en segundo plano de forma invisible y se finaliza al cerrar la sesión.

El servicio de sesiones

Las sesiones normalmente viven dentro del proceso del servidor MCP y desaparecen con él. WordMcp.Service.exe es un demonio en segundo plano opcional que las conserva en su lugar, de modo que una sesión sobrevive a un cliente reiniciado y puede ser compartida por varios de ellos:

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

Iniciarlo manualmente rara vez es necesario: un cliente configurado para usarlo lo inicia bajo demanda. El pipe en el que escucha lleva su SID y su ACL está limitada a él, de modo que las sesiones nunca se comparten entre cuentas. El servicio finaliza por sí mismo cuando no ha habido ninguna sesión abierta durante el tiempo de espera de inactividad.

Para usarlo, configure WORDMCP_SERVICE_MODE=daemon en el servidor MCP. Cada llamada de herramientas viaja entonces al demonio en lugar de ejecutarse en el propio proceso del servidor. Sin esto, el servidor mantiene las sesiones para sí mismo, que es lo que quiere un único cliente: sin segundo proceso ni espera de inicio.


Herramientas

Quince herramientas, cada una con un parámetro action.

file — ciclo de vida de la sesión

Acción

Propósito

open

Abre un documento existente e inicia una sesión

create

Crea un nuevo documento en path

save

Guarda el documento abierto

close

Guarda (opcionalmente) y cierra la sesión

list

Muestra todas las sesiones activas

test

Comprueba si se puede automatizar Word en este equipo

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

text — contenido

Acción

Propósito

get

Lee todo el texto o un rango de caracteres (start, end, max_length)

append

Añade texto, opcionalmente como un nuevo párrafo

find

Busca un término; devuelve posiciones y contexto circundante

replace

Reemplaza coincidencias (match_case, match_whole_word, replace_all)

format

Aplica bold, italic, underline, font_name, font_size, color a un rango

Las posiciones de caracteres provienen de get y find y son desplazamientos (offsets) de rango de Word.

paragraph — estructura

Acción

Propósito

list

Lista los párrafos con índice, texto, estilo, alineación y nivel de esquema

add

Añade un párrafo, opcionalmente con style

insert

Inserta un párrafo antes del índice dado

delete

Elimina un párrafo por su índice

set-style

Aplica un estilo como Heading 1

set-alignment

left, center, right o justify

Las índices de párrafo son basados en 1, igual que Word.

table — tablas

Acción

Propósito

list

Lista las tablas con sus dimensiones y estilo

create

Crea una tabla de rows × columns

read

Lee todas las celdas de una tabla como una matriz de filas/columnas

set-cell

Escribe una celda individual (row, column, text))

add-row

Inserta una fila

delete-row

Elimina una fila

set-style

Aplica un estilo de tabla como Table Grid

document — metadatos y exportación

Acción

Propósito

get-info

Obtiene el recuento de palabras, caracteres, párrafos, páginas, tablas y secciones

get-properties

Título, autor, asunto libr>, keywords, comentarios y compañía

set-properties

Actualiza esas propiedades integradas

export-pdf

Exporta a PDF sin modificar el documento abierto

save-as

Guarda una copia en otro formato

image — imágenes

Acción

Propósito

list

Lista las imágenes insertadas con índice, tamaño, texto alternativo y estado de vínculo

insert

Inserta una imagen, opcionalmente con width, height, caption y alt_text

resize

Cambia el tamaño mediante width/height o scale_percent

replace

Reemplaza la imagen de un índice, conservando por defecto su tamaño

delete

Elimina una imagen por índice

set-alt-text

Define el texto alternativo para la accesibilidad

field — campos y tablas de contenido

Acción

Propósito

list

Lista todos los campos con índice, tipo y código de campo

insert-toc

Inserta una tabla de contenido (upper_heading_level, lower_heading_level)

update-toc

Recalcula cualquier tabla de contenido

update-all

Actualiza todos los campos, incluidos los de encabezados y pies de página

insert-page-number

Añade un número de página al encabezado o al pie

section — secciones y configuración de página

Acción

Propósito

list

Lista todas las secciones con el tipo de inicio, los márgenes, el tamaño y la orientación de página

add

Inserta un salto de sección (start_type: next-page, continuous, even-page, odd-page)

page-setup

Configura los márgenes, orientation y paper_size para una sección o para todo el documento

Acción

Propósito

get

Lee el encabezado o el pie de una sección o de todas ellas

set

Escribe texto, opcionalmente con una alignment

clear

Vacía el encabezado o el pie

kind selecciona header o footer, type selecciona primary, first-page o even-pages.

style — estilos

Acción

Propósito

list

Lista los estilos; por defecto, solo los que usa el documento

create

Crea un estilo personalizado, opcionalmente basado en uno existente

modify

Cambia la general y el formato de los párrafos de un estilo

delete

Elimina un estilo personalizado

style_type selecciona paragraph, character, table o list. Pasa in_use_only: false a list para obtener el conjunto completo, que supera las 370 entradas en un Word localizado.

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 — viñetas y numeración

Acción

Propósito

get

Notifica el formato de lista de los párrafos, incluida la viñeta o el número representado

apply

Aplica a un rango de párrafos una lista bullet, number o outline-number

set-level

Establece el nivel de lista de un rango de párrafos (1–9)

restart

Reinicia la numeración en un párrafo

remove

Elimina el formato de lista

Si se omite end_index, la acción se aplica solo a 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 — comentarios de revisión

Acción

Propósito

list

Lista los comentarios con autor, fecha, texto y el texto comentado

add

Adjunta un comentario a un párrafo o a una frase dentro de él

resolve

Marca un comentario como resuelt o revierte su estado

delete

Elimina un comentario

add comenta todo el párrafo salvo que anchor_text indique una frase dentro de él. Los índices cambian después de delete, por lo que debe volver a listar antes de eliminar un segundo comentario.

comment(action: "add", session_id: "...", paragraph_index: 4,
        text: "Source?", anchor_text: "fifteen percent")
comment(action: "list", session_id: "...", unresolved_only: true)

revision — control de cambios

Acción

Propósito

list

Lista los cambios del control de cambios e indica si el seguimiento está activado

accept

Acepta una revisión o todas ellas

reject

Rechaza una revisión o todas ellas

set-tracking

Activa o desactiva el control de cambios

Si se omite index en accept/reject, se procesa todo el documento, incluidos los encabezados y pies de página.

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

bookmark — referencias estables

Acción

Propósito

list

Marcadores con nombre, índice de párrafo y una vista previa del texto marcado

add

Marcar un párrafo, un rango de párrafos o una frase dentro de un párrafo

get-text

Leer el texto completo marcado

delete

Eliminar un marcador; el texto se conserva

Los nombres deben empezar por una letra y solo pueden contener letras, dígitos y guiones bajos. Los marcadores sobreviven a las ediciones en otras partes del documento, lo que los convierte en la forma fiable de volver a referirse a un pasaje una vez que los índices de párrafo han cambiado.

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 — ver la página

Acción

Propósito

page

Renderizar una página como PNG

Las cuestiones de maquetación —saltos de página, anchos de tabla, colocación de imágenes, posiciones de encabezados— son mucho más fáciles de resolver desde la página renderizada que a partir de mediciones. El PNG se escribe en un archivo y se devuelve la ruta; include_image: true además lo devuelve en línea como base64, lo que solo merece la pena en cuanto al contexto cuando se va a mirar la imagen.

dpi tiene un valor predeterminado de 150. Usa 96 para una comprobación rápida del diseño y 300 para algo parecido a impresión.

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)

Respuestas

Toda herramienta devuelve JSON. Los fallos se notifican como payload estructurados, nunca como error de transporte:

{
  "success": false,
  "isError": true,
  "tool": "text",
  "action": "Replace",
  "errorType": "KeyNotFoundException",
  "errorMessage": "Session 'word-unknown' not found."
}

Comportamiento conocido y dificultades

  • document(save-as) también guarda el original. Word no tiene una API de “guardar una copia” que cambie el formato. Para cualquier destino distinto de PDF, el servidor llama a SaveAs2(target) y luego a SaveAs2(original), lo que persiste los cambios pendientes en el archivo original como efecto secundario. Usa export-pdf cuando necesites una exportación sin efectos secundarios.

  • Los colores son RGB hexadecimal (#0078D4). El servidor convierte al valor BGR que Word espera.

  • Los documentos protegidos por derechos (IRM/AIP) se rechazan antes de que Word se inicie.

  • Un documento abierto en Word bloquea la sesión — ciérralo primero.

  • Los diálogos de Word bloquean la automatización. Si una llamada agota el tiempo de espera, comprueba si hay algún diálogo abierto en el escritorio.

  • Los nombres de estilo están en inglés. Los estilos integrados (Heading 1, Title, Table Grid, …) se convierten a los identificadores de estilo independientes del idioma de Word, por lo que funcionan en instalaciones localizadas. Cualquier otro nombre se pasa a Word tal cual, que es como se accede a los estilos personalizados y localizados. Ten en cuenta que Word notifica los estilos con su nombre localizado (Überschrift 1 en una instalación alemana), por eso style(list) devuelve tanto name como english_name — envía english_name de vuelta cuando esté presente.

  • Los estilos integrados no se pueden eliminar. style(delete) los rechaza con un mensaje claro en lugar de transmitir el error COM genérico de Word. Un estilo personalizado que sigue aplicado a un párrafo tampoco se puede eliminar; primero asigna esos párrafos a otro estilo.

  • Los documentos nuevos se escriben directamente, no a través de Word. file(create) escribe un paquete .docx/.docm vacío y luego lo abre. Crear documentos a través de Word no es fiable en máquinas con sesión iniciada en Microsoft 365, porque AutoSave reclama el documento nuevo para OneDrive e ignora silenciosamente la ruta local solicitada.

  • Las celdas de tabla combinadas se devuelven como cadenas vacías mediante table(read).

  • Los tamaños de imagen están en puntos, no en píxeles (72 pt = 1 pulgada). image(insert) y image(resize) mantienen la relación de aspecto a menos que lock_aspect_ratio se establezca en false, por lo que pasar solo width escala también la altura.

  • image solo cubre imágenes en línea. Las formas flotantes, los cuadros de texto y los gráficos se dejan intactos y no aparecen en image(list), por lo que su presencia no desplaza los índices de imagen.

  • Un índice solo lista los párrafos de título. field(insert-toc) devuelve entry_count: 0 en un documento sin estilos de título — aplica Heading 1/Heading 2 mediante paragraph(add|set-style) primero y luego ejecuta field(update-toc).

  • field(update-all) también recorre encabezados y pies de página. El Document.Fields de Word cubre solo el cuerpo, por lo que, de otro modo, los números de página nunca se actualizarían.

  • image(insert) con un título usa la numeración de títulos de Word, por lo que el título aparece como Figure 1 <your text> (localizado en instalaciones que no están en inglés) y participa en una tabla de figuras.

  • Todas las tarjetas están en puntos, incluidos los márgenes de página (1 cm = 28.35 pt, 1 pulgada = pt).

  • section(page-setup) aplica paper_size antes que los márgenes, porque cambiar el tamaño de papel los restablece en Word. Sin section_index, la configuración se aplica a cada sección.

  • Los encabezados y pies de página se heredan entre secciones. Una sección nueva muestra el encabezado de la sección anterior hasta que se escribe algo en ella. header-footer(set) con section_index rompe ese vínculo automáticamente, así la sección 1 conserva su propio texto.

  • Los encabezados de first-page y even-pages necesitan un cambio de sección. header-footer(set) activa DifferentFirstPage y DifferentOddEvenPages por ti; sin ellos, Word almacena el texto pero nunca lo renderiza.

  • list(apply) inicia una lista nueva por defecto. continue_previous_list está desactivado, porque continuar la numeración de una lista anterior no relacionada rara vez es lo que se quiere decir. Dos listas numeradas separadas por párrafos normales siguen siendo independientes; usa list(restart) cuando Word las fusione igualmente.

  • Solo las listas con numeración por esquema muestran niveles distintos. list(set-level) funciona en cualquier lista, pero una lista normal de bullet o number muestra el mismo marcador en todos los niveles — los párrafos solo se sangran.

  • comment(resolve) suele fallar en Microsoft 365. Los comentarios modernos de Word tratan todo comentario añadido a través de la API como un borrador sin publicar, y no se puede marcar como hecho. El servidor lo notifica claramente; elimina el comentario. comment(list) devuelve resolved: null en instalaciones que no exponen el estado en absoluto.

  • Los índices de comentarios y revisiones cambian. Al eliminar un comentario o aceptar una sola revisión, se renumeran todos los posteriores; por lo tanto, ejecuta list de nuevo entre dos llamadas de este tipo en lugar de reutilizar los índices antiguos.

  • revision(accept|reject) sin índice también recorre encabezados y pies de página. El Document.AcceptAllRevisions() de Word cubre solo el cuerpo, la misma deficiencia que con field(update-all).

  • Los cambios controlados solo se registran mientras el control de cambios está activado. revision(set-tracking) no se aplica retroactivamente: actívalo antes de los cambios que quieras grabar.

  • Los nombres de marcadores están restringidos por Word. Deben comenzar con una letra, solo pueden contener letras, dígitos y guiones bajos, y tener como máximo 40 caracteres. Los espacios, guiones, puntos y letras no ASCII se rechazan antes de que la llamada llegue a Word, porque de lo contrario daría un error COM genérico.

  • Los marcadores son el modo estable de referirse a un pasaje. Los índices de párrafo cambian con cada inserción; los marcadores, no. Marca un pasaje una vez y luego usa bookmark(get-text) para volver a leerlo.

  • bookmark(add) en un párrafo excluye la marca física de párrafo, así que get-text devuelve el texto sin una nueva línea final. Un marcador que abarca varios párrafos conserva las marcas intermedias.

  • screenshot(page) renderiza a través de un PDF. Word no tiene una API que devuelva una página como imagen, así que el servidor exporta la página única con ExportAsFixedFormat y la rasteriza. Los cambios no guardados se incluyen, y el PDF temporal se elimina después.

  • *Los números de página provienen de un nuevo cálculo. ** Los documentos que solo se han editado mediante la automatización muestran un recuento de páginas anticoi, por ello screenshot lo recalcula primero. Eso también implica que el recuento refleja el diseño actual, no el que había al abrir el documento.


Compilación desde el código fuente

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"

Estructura del proyecto

Proyecto

Propósito

src/WordMcp.ComInterop

Ciclo de vida de la COM de Word: subprocesos STA, sesiones, filtro de mensajes OLE, validación de archivos

src/WordMcp.Core

Interfaces de comandos, implementaciones de comandos y modelos de resultado

src/WordMcp.Generators.Shared

Archivos de código fuente compartidos por los generadores; no es un proyecto propio

src/WordMcp.Generators.Mcp

Generador de código fuente de Roslyn que genera las clases de herramientas MCP

src/WordMcp.McpServer

Servidor MCP stdio que expone las quince herramientas

tests/WordMcp.Core.Tests

Pruebas unitarias y pruebas de integración contra un Word real

tests/WordMcp.McpServer.Tests

Pruebas unitarias de la capa de herramientas, sin necesidad de Word

Capa de herramientas generada

Catorce de las quince herramientas se generan en tiempo de compilación. Las interfaces de comandos en src/WordMcp.Core/Commands son la única fuente de verdad para el contrato de la interfaz:

  • [ServiceCategory("section", "Section")] nombra la clase de herramienta, WordSectionTool.

  • [McpTool("section", Title = ..., Description = ...)] proporciona el nombre de la herramienta y el prompt que lee el modelo.

  • [ServiceAction("page-setup")] en cada método se convierte en un valor de la enumeración generada WordSectionAction.

  • La documentación XML en los parámetros de la interfaz se convierte en las descripciones de los parámetros en el esquema MCP.

El generador combina los parámetros de todas las acciones en un único método, por lo que un parámetro usado solo por algunas acciones se emite como opcional. Para cambiar la API, edita la interfaz; nunca el código generado. file se mantiene escrito a mano porque gestiona sesiones en lugar de operar sobre una.

Inspecciona el código emitido en src/WordMcp.McpServer/obj/generated. Las pruebas en GeneratedToolContractTests comparan la superficie generada contra las interfaces, de modo que un desajuste falla en la compilación y no llega al cliente.

Las pruebas que necesitan una instalación real de Word están marcadas con [Trait("Category", "RequiresWord")] y se excluyen en CI. Las ejecuciones de integración con errores pueden dejar procesos huérfanos de WINWORD.EXE, que ralentizan o bloquean ejecuciones posteriores; limpíalos con Get-Process WINWORD | Stop-Process -Force antes de volver a ejecutar.

Lecturas adicionales

Documento

Contenido

docs/architecture.md

Las capas, el flujo de solicitudes y cómo se genera la capa de herramientas

docs/com-interop.md

Threading STA, liberación de objetos COM y el comportamiento de Word que explica los inconvenientes anteriores

CONTRIBUTING.md

Compilar, probar, añadir una herramienta, publicar una versión

skills/word-mcp/SKILL.md

Guía orientada a agentes para usar las herramientas en el orden correcto

Solución de problemas

Síntoma

Causa y corrección

Word is not installed or not registered for COM

Instala Word de escritorio; la versión de Microsoft Store no se puede automatizar

Could not load file or assembly 'office'

No se encontró office.dll en la GAC — reinstala o repara Office

Operation times out

Un cuadro de diálogo de Word espera entrada; ciérralo y reinténtalo

The file is already open in Word

Cierra el documento predeterminado en la interfaz de Word

Contribución

Sugerire dirte, editar y colaborar.

Los informes de errores y las solicitudes de nuevas funcionalidades se tramitan a través de las plantillas de incidencias. Las pull requests son bienvenidas; CONTRIBUTING.md cubre cómo compilar, cómo ejecutar las dos mitades del conjunto de pruebas y qué se necesita para añadir una herramienta.

Por favor, lea primero el Código de conducta.

No utilice una incidencia pública para informar de un problema de seguridad — comuníquelo de forma privada según se describe en la política de seguridad.

Licencia

MIT — consulte 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