doc-control
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| DOC_CONTROL_AUTHOR | No | The author name recorded for every tracked change made by the tool (default `Claude`). | Claude |
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 | {} |
| resources | {} |
| extensions | {
"io.modelcontextprotocol/ui": {
"mimeTypes": [
"text/html;profile=mcp-app"
]
}
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| anchor_createA | Make an anchor (quote with context) for a range, to find the passage again after edits. |
| anchor_resolveA | Find an anchor's passage now: its range, score and match kind (exact, normalized or fuzzy), or the ambiguous candidates. mode exact never returns a fuzzy match. match_level says how far the quote is folded when it is not found verbatim. |
| batchB | Apply text.replace, para.insert, para.delete, para.move, style.apply, format.apply, comment.add, comment.reply and comment.resolve together, all or nothing, or table.row.insert and table.row.delete (tracked table rows) together, or style.create/update/rename/merge together, or revision.accept and revision.reject to resolve revisions (by ids, author, address range or all); dry_run previews. |
| capabilitiesB | API version, engines, the build (frozen or not) and the list of operations. |
| caption_addA | Add a caption paragraph above or below a body paragraph, as tracked insertions: the label (Table, Figure or Equation), a SEQ field that numbers it, and the text, with a hidden bookmark around the label and number for cross-references. The number is refreshed by fields.update. Returns the address of the caption. |
| comments_listB | Comments in thread order (each root then its replies) with resolved state and location. |
| compareA | Write a new redline .docx from two versions: every difference a tracked change; the inputs are never modified. |
| diffB | Paragraph alignment between two versions of a document, with a cross-version address map. |
| fields_listA | Every field of the document, by story: its address, instruction code, type (PAGE, TOC, REF, ADDIN ZOTERO_ITEM, CITATION, ...), result text and whether the result is stale. Covers complex fields (also nested, or split across runs), simple fields and fields in text boxes. |
| fields_updateA | Recompute the results of the body's TOC, page, page-count, sequence and reference fields through headless LibreOffice and write only those result runs, as tracked changes (the old result is struck, the new one inserted). Without LibreOffice it refuses with ENGINE_UNAVAILABLE naming the stale fields; set_update_on_open sets w:updateFields instead, so Word updates the fields when it opens the file. Citation fields are never changed. SECTIONPAGES, SECTION and NOTEREF are not recomputed (LibreOffice keeps their cached results) and are listed under skipped. INDEX is never recomputed (LibreOffice ignores its switches and flattens sub-entries): every index is left as it is and listed under skipped; rebuild it in Word (F9). A REF that LibreOffice resolves to an error (a missing bookmark) or to nothing (a number of an unnumbered paragraph) keeps its result and is listed under skipped. Fields it could not pair with LibreOffice's are listed under skipped. |
| findA | Find text or a regex; matches come back as paragraph ranges, capped, with a cursor. The first page also gives |
| helpA | JSON Schema of one operation, or of all operations; also the kinds batch takes in |
| history_listB | The undo log, newest first: what each write changed, whether it was undone, and the deleted paragraphs |
| history_orphansA | List stores whose document is gone (app-data stores, and |
| history_purgeA | Remove undo history (all, or before a date) for privacy, leaving a tombstone. Run with dry_run first, then repeat with its |
| history_searchB | Find a quote in the undo log: in the requests, and in the text of every paragraph before and after each write. Exact unless |
| index_insertA | Insert an index (an INDEX field) after a body paragraph, as tracked insertions: an optional title, the field with a placeholder result and the paragraph that closes it. The field is marked dirty: Word builds the entries and page numbers from the index.mark marks (F9); fields.update leaves it alone. Returns the address of the field's paragraph. |
| index_markA | Mark an index entry: an XE field, as a tracked insertion, right after a range. The entry is "Term" or "Term:Sub" (up to three levels). index.insert puts the index, which Word builds from the marks. |
| infoC | File facts: size, hash, paragraph count, properties and which parts exist. |
| layout_applyA | Bring the document to a page plan (as layout.get returns it): where each section starts (from), its break (nextPage, oddPage for a right-hand start, evenPage, continuous), the page-number start and format, a different first page, the header and footer text per kind (default, first, even; {PAGE}, {NUMPAGES} and {chapter} become fields; null drops the section's own, so it inherits the previous section's; asking the text a section already prints changes nothing; a new part or a dropped reference that would change what a later section inheriting it prints is refused, as changing a header or footer that later sections inherit is not supported yet), two_sided (even and odd headers) and mirror_margins. Keys left out stay as they are; shown is checked, not set. Breaks, numbering and the text of a header or footer part are tracked changes; a part is rewritten only when every section using it asks the same text, else the section gets a new part. A new part, a dropped reference and two_sided or mirror_margins cannot be tracked and need untracked: true (LAYOUT D-L2). Sections already in the document must all be kept. A section that still holds an unaccepted tracked change of its setup (say from an earlier layout.apply) cannot take another, so a second apply that changes it is refused (UNSUPPORTED_CONTENT) until that change is accepted or rejected. A split-off section keeps the number format of the section it came from unless the plan states one. All or nothing: the plan read back from the result must equal the request, else nothing is written (UNSUPPORTED_CONTENT). dry_run lists the changes and the plan that would result. |
| layout_getA | The document's page plan: per section where it starts, its break, page numbering, title page, and the header and footer text per kind (default, first, even), with PAGE, NUMPAGES and chapter (STYLEREF) fields as {PAGE}, {NUMPAGES} and {chapter}. A kind the section does not define is null (inherited). The plan carries "version": 1. |
| live_closeA | Close the open document; with unsaved changes it needs |
| live_openB | Attach to the app window holding the document, or open it in a live app. |
| live_placesA | Show a list of places in the document as buttons; in a client that renders MCP Apps, a click calls |
| live_saveB | Save the open document in its app. |
| live_selectB | Select a paragraph in the app's window, by address ( |
| live_selectionB | The text selected in the app's window, and the paragraph the cursor is in. |
| live_statusB | Live apps (Word, LibreOffice) found and reachable, and the documents they have open; with |
| locateC | Chapter, scene, estimated page and the shortest unique first-and-last-words phrase of each paragraph, plus a phrase Word's Find meets once (one, a range, or the whole document, paged). |
| note_addA | Add a footnote or endnote at a body offset: the reference mark and the note text are both tracked insertions, so rejecting them removes the note. Creates the notes part when the document has none. Returns the note's id, displayed number and address. |
| openA | Back up the document into its store (retention applies) and note it in the history; call it when a session starts. The document is not changed. |
| outlineC | The headings of the document with level, style and address, in order. |
| page_estimateA | Estimated page of each paragraph (or of one): rendered page marks and explicit breaks first, a word-count model otherwise. Always |
| para_getB | One paragraph by address: text, style, direct formatting and formatted spans, and layout facts (heading_level is null for a body paragraph, 1-9 for a heading). |
| paragraphs_listA | Every paragraph with its address, text, style and layout facts (optionally the normalised text and the estimated page), in document order. heading_level is null for a body paragraph. |
| recipe_listA | List the bundled and user recipes, and any recipe files that are invalid. |
| recipe_runA | Run a recipe and return a batch proposal (repeated until stable); apply it with batch. |
| restoreA | Bring a logged paragraph back as a tracked insertion after the paragraph that holds its place now. Without |
| revisions_listB | Tracked changes in document order with author, date, type, text and paragraph address. |
| sections_listC | Each section's page setup: break type, title page, even/odd headers, page-number start and format, and the header and footer address per kind (default, first, even). |
| segmentC | Chapters and scenes with stable ids and detection signals, or sentences and dialogue lines. |
| statsA | Counts: paragraphs, words, headings, tables, comments, revisions, fonts and styles in use. |
| style_createC | Add a style. |
| style_getA | One style by id or name: its own formatting, inherited formatting and heading level. |
| style_mergeB | Re-point every use of the 'from' styles to 'into' and delete them. |
| style_renameB | Change a style's display name and/or id; references follow. |
| style_updateC | Change a style's parent, next/link styles, quick flag or formatting. |
| styles_listB | Styles defined in the document with how many times each is used. |
| styleset_exportB | The document's styles as a JSON style set; optionally also saved to a file. |
| styleset_export-dotxB | Write the document's styles as a new .dotx template; never touches the document. |
| styleset_import-dotxA | Install the styles of a .dotx template into the document: new styles are added, existing ones replaced (or skipped); dry_run previews. |
| styleset_installA | Install a JSON style set into the document: new styles are added, existing ones replaced (or skipped); dry_run previews. |
| table_getA | One table's grid: its rows of cells, each with its first grid column ( |
| table_row_deleteA | Delete a row of a body table as a tracked change (w:trPr/w:del, tracked deleted runs). Refused for a row with a vertical merge (w:vMerge) cell. |
| table_row_insertA | Insert a row into a body table as a tracked change (w:trPr/w:ins, tracked text), after row |
| term_renameB | Rename a term everywhere as one tracked batch: whole word, case, preserve case and inflections; dry_run previews with counts. Exact unless |
| text_normalizedA | Normalised text (NFC, soft hyphens and zero-width characters removed, whitespace collapsed) with a two-way offset map to the original code points, for a document (whole, or the paragraph/range |
| toc_insertA | Insert a table of contents (a TOC field) after a body paragraph, as tracked insertions: an optional title, the field with a placeholder result and the paragraph that closes it. The result text is filled by fields.update; until then fields.list shows the field as stale. Returns the address of the field's paragraph. |
| undoA | Take back a logged batch or restore (the latest one that is still in effect by default), returning its paragraphs to their prior state. Refused if they were edited since. |
| xref_addA | Insert a cross-reference field (REF, or PAGEREF for the page) at an insertion point, as a tracked insertion, pointing at a caption or another body paragraph. The target gets a hidden bookmark when it has none that fits. fields.update fills in the shown number, text or page. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| places |
TDQS
Scored across 60 tools
There is a large family of overlapping read/retrieval tools: find, locate, segment, anchor_resolve, history_search, text_normalized, plus para_get vs paragraphs_list vs outline all return content by position. The descriptions are unusually precise and do draw boundaries (regex vs unique phrase vs chapter/structure vs undo-log quote), so an agent can usually pick correctly, but the surface invites misselection. Style tools (styles_list vs styleset_export) and live_* tools are similarly adjacent.
A clear namespace_action snake_case convention dominates (para_get, table_row_delete, style_merge, fields_update, comments_list, anchor_resolve). Minor deviations exist: bare single-word verbs (find, locate, segment, restore, undo, compare, diff, info, open, outline, stats) and the hyphenated styleset_export-dotx / styleset_import-dotx, plus the adjective-style text_normalized. Still readable and largely predictable.
60 tools is very heavy and well past the point where an agent can hold the surface in mind; several coherent clusters (6 style ops, 4 style-set ops, 8 live_* ops, 4 history ops) could be consolidated. Each tool is narrowly scoped and arguably earns its place in a genuinely broad domain, but the count is excessive for practical selection.
Coverage is strong across reading, style/layout manipulation, tables, comments, revisions, fields, TOC/index/captions, history/undo, compare/diff and live editing. The main gap is that core write primitives (text.replace, para.insert/delete/move, comment.add/reply/resolve, revision accept/reject) are reachable only through batch rather than as first-class tools, which is workable but indirect. No document creation/export or comment-delete operations either.