grp-docx-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| open_documentA | Open a .docx file for reading and editing. Unpacks the DOCX archive, parses all XML parts, and caches them in memory under a handle. Multiple documents may be open concurrently, each under its own handle. Args:
path: Absolute path to the .docx file.
document_handle: Optional handle to store this document under. Empty
string uses the shared |
| close_documentB | Close a document and clean up temporary files. Args:
document_handle: Handle of the document to close. Empty = |
| create_documentA | Create a new blank .docx document (or from a .dotx template). The document is automatically opened for editing under the given handle. Use save_document to save changes, or start editing immediately with insert_text, add_table, etc. Args: output_path: Path for the new .docx file. template_path: Optional path to a .dotx template file. document_handle: Optional handle to store this document under. |
| create_from_markdownA | Create a new .docx document from markdown content. Supports full GitHub-Flavored Markdown: headings, bold/italic/strikethrough, links, images, bullet/numbered/nested lists, code blocks, blockquotes, tables, footnotes, and task lists. Smart typography (curly quotes, em/en dashes, ellipses) is applied automatically. Provide exactly one of md_path or markdown. The document is automatically opened for editing under the given handle. Args: output_path: Path for the new .docx file. md_path: Path to a .md file. Mutually exclusive with markdown. markdown: Raw markdown text. Mutually exclusive with md_path. template_path: Optional path to a .dotx template file. document_handle: Optional handle to store this document under. |
| get_document_infoA | Get overview stats: paragraph count, headings, footnotes, comments, images. |
| get_headingsB | Get the document heading structure with levels, text, and paraIds. Returns a list of headings in document order, each with:
|
| search_textA | Search for text across the document body, footnotes, and comments. Args: query: Text to search for (case-insensitive), or a regex pattern. regex: If true, treat query as a Python regular expression. Returns matching paragraphs with their paraId, source part, and context. |
| get_paragraphA | Get the full text and style of a specific paragraph by its paraId. Args: para_id: The 8-character hex paraId (e.g., "1A2B3C4D"). |
| get_tablesB | Get all tables with row/column counts and cell text content. |
| add_tableC | Insert a new table after a paragraph with tracked insertion. |
| modify_cellA | Modify a table cell. By default (tracked=True) the old content is marked as a deletion and the new content as an insertion — the human reviewer accepts/rejects in Word's Track Changes view. Pass tracked=False to overwrite the cell directly with no markup. Args: table_idx: Table index (0-based). row: Row index (0-based). col: Column index (0-based). text: New cell text. author: Author name shown in Word's review pane (tracked=True only). tracked: True (default) = tracked del+ins. False = direct overwrite, no markup. document_handle: Optional handle for concurrent session isolation. |
| add_table_rowB | Add a row to a table with tracked insertion. row_idx=-1 appends. |
| delete_table_rowC | Delete a table row with tracked changes. |
| merge_cellsC | Merge a rectangular range of cells. Horizontal: gridSpan. Vertical: vMerge. |
| set_header_rowC | Mark the first row as a repeating header row. |
| set_column_widthsA | Set column widths in cm. len(widths_cm) must match column count. |
| csv_to_tableC | Insert a table from CSV text. |
| table_to_csvB | Export a table as CSV string. |
| delete_tableA | Delete a table by index (0-based). Raises IndexError if out of range. |
| add_column_to_tableA | Add a new column to every row of a table. First row gets header_text. |
| delete_column_from_tableB | Delete a column (0-based) from every row of a table. |
| set_cell_widthB | Set the width of a table cell in millimetres (stored as DXA). |
| set_cell_vertical_alignmentC | Set vertical alignment of a table cell: top, center, or bottom. |
| set_row_heightB | Set row height in millimetres. rule: exact, atLeast, or auto. |
| set_table_alignmentC | Set table alignment: left, center, or right. |
| set_table_bordersC | Set borders on all six sides of a table (top, bottom, left, right, insideH, insideV). |
| set_cell_shadingC | Set background shading fill color on a table cell. |
| set_table_styleA | Apply a named table style (e.g. TableGrid, LightShading-Accent1) to a table. |
| add_listC | Apply list formatting to paragraphs (bullet or numbered). |
| get_stylesB | Get all defined styles with ID, name, type, and base style. |
| create_styleA | Create a new style in the document. Args: name: Style name (used as styleId after removing spaces). style_type: "paragraph", "character", "table", or "numbering". based_on: Optional styleId this style inherits from. next_style: Optional styleId applied to the next paragraph. |
| update_styleB | Update an existing style's basedOn and/or next properties. Args: name: Style name or styleId (case-insensitive). based_on: New basedOn styleId (replaces existing). next_style: New next styleId (replaces existing). |
| delete_styleA | Delete a style from the document. Args: name: Style name or styleId (case-insensitive). |
| get_styleA | Get details of a single style by name or styleId (case-insensitive). Args: name_or_id: Style name or styleId to look up. Returns: {"style_id": str, "name": str, "type": str, "base_style": str, "next_style": str} |
| copy_styleA | Deep-copy an existing style under a new name. Args: source_name_or_id: Name or styleId of the style to copy. new_name: Name for the new style (spaces stripped for styleId). Returns: {"style_id": str, "name": str, "type": str} |
| apply_style_to_rangeC | Apply a style to a list of paragraphs by their paraIds. Args: para_ids: List of paragraph paraIds to update. style_name_or_id: Style name or styleId to apply. Returns: {"applied": int, "style_id": str, "para_ids": list[str]} |
| get_headers_footersC | Get all headers and footers with their text content. |
| edit_header_footerA | Edit text in a header or footer. By default (tracked=True) the change is recorded as a deletion of the old text and an insertion of the new text — the human reviewer accepts/rejects in Word. Pass tracked=False to replace the text directly with no revision markup. Args: location: "header" or "footer" (matches the first found of that type). old_text: Text to find and replace. new_text: Replacement text. author: Author name shown in Word's review pane (tracked=True only). tracked: True (default) = tracked del+ins. False = direct replacement, no markup. document_handle: Optional handle for concurrent session isolation. |
| delete_headerA | Delete a header by location: default, first, or even. |
| delete_footerB | Delete a footer by location: default, first, or even. |
| get_propertiesB | Get core document properties (title, creator, subject, dates, revision). |
| set_propertiesB | Set core document properties. Empty string = unchanged. |
| get_custom_propertiesA | Get custom document properties from docProps/custom.xml. |
| set_custom_propertyC | Set (upsert) a custom document property. Args: name: Property name. value: Property value as a string. vt_type: VT type element name (lpwstr, i4, bool, etc.). |
| delete_custom_propertyC | Delete a custom document property by name. Args: name: Property name to delete. |
| get_imagesB | Get all embedded images with rId, filename, content type, and dimensions. |
| insert_imageC | Insert an image after a paragraph. Size in cm (preferred) or EMU; cm overrides EMU. align sets the image paragraph alignment (left/center/right). |
| insert_floating_imageC | Insert a floating (anchored) image. wrap: square|topbottom|none. |
| delete_imageA | Remove the drawing containing the image with the given rId from the document. Also removes the relationship entry from word/_rels/document.xml.rels. Args: rId: The relationship ID of the image to delete (e.g. 'rId5'). |
| update_imageA | Replace the binary for an existing image in-place. The image dimensions and position in the document are preserved. Args: rId: The relationship ID of the image to replace. new_image_path: Absolute path to the new image file on disk. |
| set_image_sizeA | Resize an embedded image by updating its EMU extent attributes. Args: rId: The relationship ID of the image to resize. width_cm: New width in centimetres. height_cm: New height in centimetres. |
| set_image_alt_textA | Set accessibility alt text and title on an embedded image. Args: rId: The relationship ID of the image. alt_text: Alt text (descr attribute on wp:docPr). title: Optional title attribute on wp:docPr. |
| set_image_borderA | Set or remove a border on an embedded image. Args: rId: The relationship ID of the image (e.g. 'rId6'). border_pt: Border width in points. Use 0 to remove the border. color: RGB hex color string without '#' (default '000000' = black). Returns: JSON with rId, border_pt, and color fields. |
| get_endnotesC | Get all endnotes with their ID and text content. |
| add_endnoteC | Add an endnote to a paragraph. |
| validate_endnotesC | Cross-reference endnote IDs between document.xml and endnotes.xml. |
| get_footnotesC | List all footnotes with their ID and text content. |
| add_footnoteC | Add a footnote to a paragraph. url, if provided, is rendered as a hotlink. |
| add_footnote_refA | Add a subsequent reference to an existing footnote without creating a new definition. Use when the same source must be cited again in a different paragraph. Inserts a hyperlink-wrapped footnoteReference that navigates to the same footnote as the original citation. Does not duplicate the footnote definition in footnotes.xml. |
| validate_footnotesC | Cross-reference footnote IDs between document.xml and footnotes.xml. |
| update_footnoteA | Update the text of an existing footnote. Args: footnote_id: The numeric ID of the footnote to update (must be >= 1). text: The new text content for the footnote. |
| delete_footnoteB | Delete a footnote and its in-body reference. Removes the footnote definition from footnotes.xml and removes the footnoteReference run from the document body. Args: footnote_id: The numeric ID of the footnote to delete. |
| update_endnoteA | Update the text of an existing endnote. Args: endnote_id: The numeric ID of the endnote to update (must be >= 1). text: The new text content for the endnote. |
| delete_endnoteA | Delete an endnote and its in-body reference. Removes the endnote definition from endnotes.xml and removes the endnoteReference run from the document body. Args: endnote_id: The numeric ID of the endnote to delete. |
| add_page_breakC | Insert a page break after a paragraph. |
| add_section_breakB | Add a section break at a paragraph. break_type: nextPage/continuous/evenPage/oddPage. |
| set_section_propertiesC | Modify section properties (page size, orientation, margins). 0/empty = unchanged. |
| set_page_sizeA | Set page size from millimetre values. Args: width_mm: Page width in mm (e.g. 210 for A4, 215.9 for Letter). height_mm: Page height in mm (e.g. 297 for A4, 279.4 for Letter). para_id: paraId of paragraph with section break. None = body section. |
| set_page_marginsA | Set page margins from millimetre values. Args: top_mm: Top margin in mm. None = unchanged. bottom_mm: Bottom margin in mm. None = unchanged. left_mm: Left margin in mm. None = unchanged. right_mm: Right margin in mm. None = unchanged. para_id: paraId of paragraph with section break. None = body section. |
| set_page_orientationA | Set page orientation, swapping width/height dimensions if needed. Args: orientation: "portrait" or "landscape". para_id: paraId of paragraph with section break. None = body section. |
| get_sectionsA | List all sections in the document with their properties. Returns a JSON array of section objects, each containing: index, break_type, page_width, page_height, orientation, columns, margin_top, margin_bottom (all sizes in twips/DXA). The final section always has break_type="". |
| set_section_columnsA | Set the number of columns in a section. Args: section_index: Zero-based section index (use get_sections to find it). num_columns: Number of text columns (1 = single column). equal_width: If True, all columns are equal width. Default True. |
| delete_section_breakA | Remove a section break from a paragraph. Removes the w:sectPr from the paragraph's w:pPr. After removal the paragraph's content flows into the next section rather than ending one. Args: para_id: paraId of the paragraph that holds the section break. Raises: ValueError: If the paragraph has no section break. |
| set_different_first_pageA | Enable or disable a different first-page header/footer for a section. When enabled, the section can have a unique header/footer on its first page, separate from the header/footer used on subsequent pages. Args: section_index: Zero-based section index (use get_sections to find it). enabled: True to enable different first page, False to disable. Returns: {"section_index": int, "different_first_page": bool} |
| set_odd_even_headersA | Enable or disable different odd/even page headers globally. This is a document-level setting stored in word/settings.xml. When enabled, even-numbered pages can use a different header/footer from odd-numbered pages. Args: enabled: True to enable different odd/even headers, False to disable. Returns: {"odd_even_headers": bool} |
| add_cross_referenceC | Add a cross-reference link from one paragraph to another. |
| set_document_protectionC | Set document protection. edit: trackedChanges/comments/readOnly/forms/none. |
| merge_documentsC | Merge another DOCX document's content into the current document. |
| validate_paraidsC | Check paraId uniqueness across all document parts. |
| insert_watermarkA | Insert a VML watermark into the document's default header. Places a <v:shape> with a <v:textpath> inside the default header, which is the standard Word watermark pattern. Args: text: Watermark text (e.g. "DRAFT", "CONFIDENTIAL"). diagonal: If True (default), diagonal orientation; if False, horizontal. document_handle: Optional handle for concurrent session isolation. |
| remove_watermarkB | Remove VML watermarks (e.g., DRAFT) from all document headers. |
| audit_documentC | Run a comprehensive structural audit of the document. |
| insert_textA | Insert text into a paragraph. By default (tracked=True) the insertion is marked as a proposed addition that appears underlined in Word's Track Changes view. The human reviewer must accept it in Word before it becomes permanent. Pass tracked=False to write the text directly with no revision markup. Args: para_id: paraId of the target paragraph. text: Text to insert. position: Where to insert — "start", "end", or a substring to insert after. author: Author name shown in Word's review pane (tracked=True only). context_before: Text immediately before the insertion point (for precise anchoring). context_after: Text immediately after the insertion point (for precise anchoring). ignore_case: If True, match context_before/context_after case-insensitively. tracked: True (default) = revision markup the human accepts/rejects in Word. False = text written directly, no markup. document_handle: Optional handle for concurrent session isolation. |
| delete_textA | Delete text from a paragraph. Finds the text within the paragraph (across run boundaries if needed). With tracked=True (default) the deleted text stays visible as red strikethrough in Word's Track Changes view — the human reviewer must accept the deletion to remove it permanently. With tracked=False the text is removed immediately. Provide context_before/context_after to disambiguate when the same text appears multiple times, or when it contains smart quotes / special whitespace. Args: para_id: paraId of the target paragraph. text: Text to delete (ASCII quotes/dashes/spaces match their Unicode equivalents). author: Author name shown in Word's review pane (tracked=True only). context_before: Text immediately before the target (for precise anchoring). context_after: Text immediately after the target (for precise anchoring). ignore_case: If True, match text and context case-insensitively. tracked: True (default) = red strikethrough the human accepts/rejects. False = text removed immediately, no markup. document_handle: Optional handle for concurrent session isolation. |
| replace_textA | Replace text in a paragraph. With tracked=True (default) the old text is shown as red strikethrough and the new text as an underlined insertion — the human reviewer accepts/rejects in Word. Only the actually-changed portion is marked; common leading/trailing text is left as plain runs. With tracked=False the replacement is applied immediately without any visible markup. Args: para_id: paraId of the target paragraph. find: Text to find and replace (may span run boundaries). replace: Replacement text. author: Author name shown in Word's review pane (tracked=True only). context_before: Text immediately before the target (for precise anchoring). context_after: Text immediately after the target (for precise anchoring). tracked: True (default) = strikethrough + underline the human accepts/rejects. False = replaced immediately, no markup. document_handle: Optional handle for concurrent session isolation. |
| get_body_textA | Return the full accepted-view text of the document. Accepted view: w:ins text included, w:del text excluded. Includes text inside w:hyperlink runs. Paragraphs are joined by newline. Footnote text is returned separately. Returns JSON: {"body": str, "footnotes": str} |
| get_tracked_changesC | Return all pending tracked changes (insertions and deletions) as a JSON list. Each entry contains: type, change_id, author, date, para_id, text. Changes are returned in document order. |
| accept_changesA | Accept tracked changes — keep insertions, remove deletions. Empty author = all. |
| reject_changesC | Reject tracked changes — remove insertions, restore deleted text. |
| accept_changeA | Accept a single tracked change by its change_id. For insertions: keeps the inserted text (unwraps w:ins). For deletions: discards the deleted text (removes w:del). Args: change_id: The integer id attribute of the w:ins or w:del element. |
| reject_changeA | Reject a single tracked change by its change_id. For insertions: discards the inserted text (removes w:ins). For deletions: keeps the deleted text (unwraps w:del, restoring text). Args: change_id: The integer id attribute of the w:ins or w:del element. |
| accept_all_changesA | Accept all tracked changes in document order. Returns a JSON object with the count of accepted changes: {"accepted": int}. |
| reject_all_changesA | Reject all tracked changes in document order. Returns a JSON object with the count of rejected changes: {"rejected": int}. |
| set_formattingC | Apply character formatting to text with tracked-change markup. |
| get_commentsC | List all comments with their ID, author, date, and text. |
| add_commentC | Add a comment anchored to a paragraph. |
| reply_to_commentC | Reply to an existing comment (creates a threaded reply). |
| update_commentC | Replace the text of an existing comment. Args: comment_id: ID of the comment to update. text: New comment text. |
| delete_commentB | Delete a comment and remove its range markers from the document. Args: comment_id: ID of the comment to delete. |
| resolve_commentA | Mark a comment as resolved (sets w15:done='1' in commentsExtended.xml). Args: comment_id: ID of the comment to resolve. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 227 tools
Numerous near-duplicate tools make selection treacherous: accept_change/accept_changes/accept_all_changes, generate_list_of_figures/generate_tof, generate_list_of_tables/generate_tot, get_headings/get_document_outline, compare_documents/diff_to_text, and set_image_alt_text/set_alt_text all perform essentially the same operations with minor parameter differences. The specialized insert_date_field/insert_page_number_field/insert_merge_field tools also duplicate what add_field already covers. An agent cannot reliably distinguish these without reading full argument lists.
The overwhelming majority of tools follow a consistent verb_noun snake_case pattern (get_, set_, add_, delete_, update_, insert_, create_), which is a strong convention across 227 tools. Minor outliers like xpath_query, bates_number, csv_to_table, and table_to_csv deviate slightly but are still readable and do not undermine the overall pattern.
227 tools is an extreme count, far beyond even the 50+ threshold the calibration identifies as a mismatch. Even for a broad domain like DOCX manipulation, this flat namespace is unmanageable and should be split into focused servers (e.g., tracked-changes, tables, formatting, templates) or namespaced submodules. The bloat directly causes the disambiguation failures.
The domain surface is exhaustively covered: full lifecycle tools for text, paragraphs, runs, tables, images, headers/footers, footnotes/endnotes, comments, tracked changes, styles, fields, bookmarks, hyperlinks, content controls, sections, properties, charts, and equations, plus redaction, sanitization, accessibility checking, PDF conversion, and document comparison. There are no obvious dead ends or missing CRUD operations—if anything, the surface over-covers due to redundancy.