Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
DOC_CONTROL_AUTHORNoThe 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

CapabilityDetails
tools
{}
resources
{}
extensions
{
  "io.modelcontextprotocol/ui": {
    "mimeTypes": [
      "text/html;profile=mcp-app"
    ]
  }
}

Tools

Functions exposed to the LLM to take actions

NameDescription
anchor_createA

Make an anchor for a passage so it can be found again after edits shift or change addresses: the quoted text, context characters before and after (default 32, max 200), and the paragraph's number and fingerprint then. at is a range in one paragraph (p142#a7b2a7b2:10-15), a whole paragraph (p142#a7b2a7b2) or a sentence (p142#a7b2a7b2.s3). Use it to bookmark passages you will come back to; find them later with anchor.resolve (text.find searches for any text instead). Read-only; STALE_ADDRESS when at is outdated, SCHEMA_INVALID for a range across paragraphs.

anchor_resolveA

Find an anchor's passage in the document as it is now: its current range, a 0-1 score and the match kind (exact, normalized or fuzzy). Pass the anchor object anchor.create returned, or just {exact, prefix, suffix}. mode best (default) falls back to a fuzzy match scoring at least 0.80; mode exact accepts only verbatim, normalised or folded (match_level, default default: case, accents, punctuation) matches. Fails with ANCHOR_NOT_FOUND, or ANCHOR_AMBIGUOUS listing up to 5 tied candidates. Use it to re-address a passage after edits; doc.diff maps addresses between two files instead. Read-only.

caption_addA

Add a numbered caption next to a body paragraph (a table, figure or equation), as tracked insertions: label, a SEQ field with the number, and text (e.g. label Table, text "Results" gives "Table 3 Results"). position defaults to above for Table, below for Figure and Equation. A hidden bookmark wraps label and number so xref.add can point at it; field.update renumbers after later inserts. Backed up and undoable (history.undo); dry_run previews; expect.sha256 refuses a changed file. Returns the caption's address; UNSUPPORTED_CONTENT for a paragraph in a text box.

comment_addA

Add one comment on a range: at is a paragraph (p3#a1b2c3d4), part of one (p3#a1b2c3d4:10-15) or a span across paragraphs (p3#a1b2c3d4:10..p5#e5f6a7b8:2); a newline in text starts a new comment paragraph. Author defaults to DOC_CONTROL_AUTHOR. File engine: backed up first, dry_run previews, expect.sha256 refuses a file changed since, logged for history.undo. engine live adds it in the open Word/LibreOffice window (after live.open). Use doc.batch to add several, or with comment.reply/comment.resolve, all or nothing. Returns the new comment id.

comment_listA

List the comments in thread order (each root comment, then its replies) with id, author, date, text (clipped at 1,000 characters), quote (the text the comment covers, clipped at 200), resolved state and the address where each starts, including comments in notes and headers. Filter with resolved (true or false) and author (exact). Use the ids to reply or resolve with doc.batch (comment.reply, comment.resolve); use revision.list for tracked changes instead, review.list for comments and changes together by paragraph. Read-only; paged: a reply is capped at about 8,000 bytes (limit up to 1,000), continue with cursor set to the reply's next.

doc_batchA

The main editing tool: apply several edits in one verified write, as tracked changes, all or nothing. One family per batch: text.replace, para.insert, para.delete, para.move, style.apply, format.apply, comment.add/reply/resolve; or table.row.insert/delete; or style.create/update/rename/merge; or revision.accept/reject. Example ops: [{"op": "text.replace", "at": "p3#a1b2c3d4:10-15", "text": "new"}]. Every address is as read; overlapping edits are BATCH_CONFLICT, outdated ones STALE_ADDRESS. File engine: backed up first, dry_run previews, expect.sha256 refuses a changed file, history.undo takes the batch back. tracked: false writes approved text plainly, on either engine. engine live edits the open app (comment.add, text.replace, para.insert only; no dry_run or rollback). server.help gives each kind's fields.

doc_compareA

Write a redline: a new .docx at output (which must not exist) holding the new version with every difference from old as a tracked change (author default Claude, date ISO 8601 with time zone, default now), so a writer reviews and accepts or rejects them in Word. The input files are never modified; the redline is verified (accepting every change gives the new text) or removed (VERIFY_FAILED_RESTORED). Use doc.diff for the alignment as data without writing a file. Returns the output path and hash, per-kind paragraph counts and the revision count.

doc_diffA

Align the paragraphs of two versions (old, new; .docx, or .txt/.md/.odt): which are unchanged, modified, moved, split, merged, inserted or deleted, with a map from old addresses to new ones (null for deleted). Use it to carry addresses read from an older version over to the current one, or to see what changed; doc.compare writes the same differences as a redline .docx instead. collapse_runs folds runs of shifted unchanged paragraphs into one record. Read-only; paged at about 8,000 bytes with limit and cursor (the next of the previous reply).

doc_infoA

Cheap first look at a file: size, sha256 (pass it as expect.sha256 to a later write so it is refused if the file changed meanwhile), core properties (title, author, dates), whether Track Changes is on, whether Word holds it open (a ~$ lock file) and which parts exist (comments, notes, headers). The envelope's doc gives the paragraph count. Use doc.stats for word, heading and revision counts, doc.outline for the headings. Read-only; DOC_NOT_FOUND or NOT_A_DOCX for a bad path.

doc_openA

Start a session on a document: back it up into its store (.doc-control// next to it; the newest 20 backups or 30 days are kept) and note it in the undo log if it changed since the last logged write. Call it once before editing; the document itself is not changed. If the document has no history yet, adoptable lists orphaned stores (it was moved or renamed) that history.adopt can re-attach. Returns the backup path, the log entry and the store folder.

doc_outlineA

List the headings (levels 1-9, by style or outline level) in document order, each with its address, level, style and text: the table-of-contents view. max_level 2 keeps levels 1-2; stories ["body", "notes"] adds headings in notes. Use doc.segment for chapters that are not styled as headings, para.list for every paragraph, para.get to read one heading in full. Read-only; paged: about 8,000 bytes per reply (limit up to 1,000), continue with cursor set to the reply's next.

doc_segmentA

Split a manuscript into units with stable ids: unit chapters (default), parts or scenes (detected from headings, numerals, centring, scene markers; signals say which), or sentences or dialogue lines within range (an address, p24#a1b2c3d4..p60#e5f6a7b8, or a unit id such as ch-d5a3930d). chapter limits scenes to one chapter; language (default es) sets sentence rules; profile and overrides tune detection. Use it to work chapter by chapter or to get sentence addresses (p142#a7b2a7b2.s3); doc.outline lists only styled headings. Read-only; paged at about 8,000 bytes with cursor.

doc_statsA

Count what the body holds: paragraphs (and empty ones), words, characters, headings, tables, comments, footnotes, tracked changes by type, styles in use and the 20 most used fonts. stories ["notes", "headers"] adds separate counts for notes and for headers/footers (the body counts stay the body's). Use it to size a document or check for leftover revisions; doc.info gives file facts and the hash, revision.list the changes themselves. Read-only; one reply, not paged.

field_listA

List every field (PAGE, TOC, REF, SEQ, XE, citations such as ADDIN ZOTERO_ITEM...) with its address, story, code, type, shown result and whether it is stale (needs updating). stories defaults to all: body, notes, headers and comments; type keeps one type ("TOC"). Covers nested, split and simple fields and fields in text boxes. Use it before field.update to see what is stale, or to find citations; it never changes anything. Read-only; one reply, not paged.

field_updateA

Recompute the body's TOC, PAGE, NUMPAGES, SEQ and REF/PAGEREF results with headless LibreOffice and write only those result runs, as tracked changes (old result struck, new inserted). Needs LibreOffice (soffice): without it, ENGINE_UNAVAILABLE names the stale fields; set_update_on_open instead sets w:updateFields so Word updates them on opening. Citations are never changed; INDEX, SECTIONPAGES, SECTION, NOTEREF and unresolvable REFs are left and listed under skipped. Run after toc.insert, caption.add or xref.add. Backed up and undoable; dry_run previews; slow (seconds).

history_adoptA

Re-attach a moved or renamed document to its old undo history, so history.undo and history.restore work again. It finds the orphaned store whose last recorded state is this file's sha256 (doc.open lists them as adoptable, history.orphans lists all) and moves it, backups and log, to where this document's store lives now. Pass store when several match (the reply lists candidates); force adopts a file edited since; a document that already has history is never overwritten (BATCH_CONFLICT). dry_run moves nothing.

history_listA

List the document's undo log, newest first: each write's op_id, kind, time, author, the operations it ran, whether it was undone, and the deleted paragraphs history.restore can bring back (change numbers). Filter with kind (batch, restore, undo, open, purge, adopt); store reads an orphaned store instead. Use it to find the op_id for history.undo or history.restore; history.search finds a quote in the log. Read-only; paged with limit (default 20) and cursor (the reply's next).

history_orphansA

List undo stores whose document is gone (moved, renamed or deleted): the app-data stores, plus dir/.doc-control when dir is given, each with its folder, last document path, entry count and last time; unknown holds stores that name no document. Their history is never deleted automatically. Use history.adopt to re-attach one to a moved document, history.list or history.restore with store to read from it, history.purge with store to delete it. Read-only.

history_purgeA

Delete undo history for privacy: the whole log (all) or entries before a date (before, ISO 8601, UTC), of the document or of an orphaned store. Two steps: run with dry_run to see what would go and get a confirm token, then repeat with confirm; a log that changed in between is refused. Leaves a tombstone entry; backups are not removed by it. Destructive: purged entries can no longer be undone or restored. Use history.list first to check what you remove.

history_restoreA

Bring back paragraphs a logged write deleted or changed, as a tracked insertion (tracked: false: plainly, for a change the writer approved). Give the op_id (from history.list or history.search); without change, every paragraph that op deleted comes back after the paragraph now holding its old place; change picks one (also an edited one) and after (p12#a1b2c3d4) places it when that place was edited (BATCH_CONFLICT otherwise). Use history.undo to revert a whole write instead. Backed up, logged, undoable; dry_run previews.

history_searchA

Search the undo log for a quote: in each logged request and in the text of every paragraph before and after each write, newest first. Use it to find when a passage was changed or deleted, and the op_id for history.undo or history.restore; text.find searches the current document instead. Exact by default (ignore_case, ignore_accents loosen it); match_level default or loose folds case, accents and punctuation and returns each hit's offsets and level. Works on an orphaned store too. Read-only; limit (default 20) caps hits, total counts all.

history_undoA

Take back one logged write (doc.batch, text.replace and the other direct writes, comment and style writes, styleset.install, term.rename, field and note inserts, layout.apply, history.restore), returning its paragraphs and parts to their state before it: by default the latest one still in effect, or the op_id from history.list. Refused with BATCH_CONFLICT if a paragraph or part it changed was edited since (undo the later write first). Use history.restore to bring back single deleted paragraphs, revision.reject to drop tracked changes by author or id. The undo is itself logged; dry_run checks without writing; expect.sha256 refuses a changed file.

index_insertA

Insert an index (an INDEX field) after a body paragraph after (p40#a1b2c3d4), as tracked insertions: a title (default "Index", "" for none), the field with a placeholder result, and a closing paragraph. Mark entries first with index.mark; Word builds the entries and page numbers when the field is updated there (F9), since field.update leaves indexes alone. Backed up and undoable (history.undo); dry_run previews; expect.sha256 refuses a changed file. Returns the field paragraph's address.

index_markA

Mark an index entry: insert an XE field, as a tracked insertion, right after a range (p8#a1b2c3d4:10-15) so that word or phrase is indexed on its page. entry is "Term", or "Term:Sub" / "Term:Sub:Detail" for sub-entries. Mark every occurrence you want listed, then insert the index once with index.insert. Backed up and undoable (history.undo); dry_run previews; expect.sha256 refuses a changed file. Returns the paragraph address and field code.

layout_applyA

Bring the document to a page plan, the shape layout.get returns: per section its start (from address), break, page-number start and format, first-page difference, and header/footer text per kind ({PAGE}, {NUMPAGES}, {chapter} become fields; null inherits). Keys left out stay as they are. Edit the layout.get result and send it back. Breaks, numbering and header text are tracked changes; a new header part, a dropped reference, two_sided or mirror_margins need untracked: true. All or nothing: UNSUPPORTED_CONTENT if the result would differ from the plan or a section has a pending setup change. dry_run lists the changes.

layout_getA

Read the page plan: per section where it starts (from address), its break, page numbering (shown, start, format), first-page difference, and header/footer text per kind (default, first, even) with fields as {PAGE}, {NUMPAGES} and {chapter}; null means inherited from the previous section. Edit it and pass it to layout.apply to change the layout; section.list gives the same setup with header/footer part names instead of text. Read-only.

live_closeA

Close the document in its Word or LibreOffice window (attached with live.open). With unsaved changes it is refused (UNSAVED_CHANGES) unless save (save, then close) or discard (drop them) is given; nothing unsaved is ever lost silently. Use live.save to keep the window open. Returns whether it saved.

live_get_selectionA

Read what the user has selected in Word or LibreOffice right now, and the paragraph the selection starts in with its address (p12#a1b2c3d4), to edit with doc.batch or text.replace. Use it when the user points at text ("this paragraph", "here"); live.select moves the selection instead. The document must be attached with live.open (ENGINE_UNAVAILABLE otherwise). Read-only.

live_openA

Attach to Word or LibreOffice for live editing: find the window already holding the document, or open it in app (word or libreoffice; default the one reachable, see live.status) and bring it to the front (front: false keeps it behind). Call it before live.select, live.get_selection, live.save, live.close and doc.batch with engine live. Opens or focuses a window; never changes the document. ENGINE_UNAVAILABLE when no app can be driven, DOC_AMBIGUOUS when a file name matches several open documents.

live_placesA

Show the user a list of places as clickable buttons: in a client that renders MCP Apps, a click moves Word's or LibreOffice's cursor there (mode cursor) or selects the paragraph (mode select) by calling live.select, with no assistant turn. Each place has a label and an at address and/or a find_phrase from para.locate. Use it to walk a writer through findings; live.select jumps to one place directly. Other clients just get the list back. Read-only.

live_saveA

Save the document open in Word or LibreOffice (attached with live.open) to its file, from inside the app. Call it after live edits (doc.batch with engine live) to keep them; live.close with save: true saves and closes in one call. Overwrites the file on disk with the app's version; no backup is taken.

live_selectA

Show the user a place in Word or LibreOffice: select a paragraph, or with mode cursor only put the cursor at its start, by address (at, p142#a7b2a7b2) or by a find_phrase from para.locate (matched loosely per match_level). paragraphs_after moves on that many paragraphs. Use it to point at a passage you are discussing; live.places offers several as buttons. Changes only the selection; needs live.open. STALE_ADDRESS when at no longer matches, ANCHOR_NOT_FOUND or ANCHOR_AMBIGUOUS for a phrase.

live_statusA

Check the live apps: which of Word and LibreOffice are installed and reachable, and which documents they have open; with doc, which app holds it, whether that app is driven by this server or only a lock file says so, its full path and whether it has unsaved changes. Call it before live.open, or to decide between live editing and the file engine (a file open in Word should be edited live or closed first). Read-only; never fails for a missing app.

note_addA

Add a footnote or endnote: the reference mark goes at a body point (p3#a1b2c3d4:10-10, after offset 10), after a range, or at the end of a paragraph (p3#a1b2c3d4); text is the note's one line. Mark and note are tracked insertions, so rejecting them removes the note; the notes part is created when missing. Backed up and undoable (history.undo); dry_run previews; expect.sha256 refuses a changed file. Returns the note's id, displayed number and address (fn5/p1#…).

page_estimateA

Estimate the page each paragraph starts on (and ends on when it spans pages): from Word's rendered page marks and explicit breaks where present, else a words-per-page model; always flagged estimated. at (p142#a7b2a7b2) gives one paragraph; by "page" lists pages with their first and last paragraph instead. Use it to tell a user roughly where text is; para.locate adds chapter, scene and a find phrase. Read-only; paged at about 8,000 bytes with cursor.

para_deleteA

Delete a paragraph (p3#a1b2c3d4) or a run of paragraphs (p3#a1b2c3d4..p5#e5f6a7b8), as a tracked deletion the writer can reject. File engine: backed up first, logged for history.undo, dry_run previews, expect.sha256 refuses a file changed since; tracked: false deletes plainly (a change the writer approved). STALE_ADDRESS if the paragraph changed since it was read. Use text.replace to delete part of a paragraph, doc.batch for several edits all or nothing. Returns the address_map of shifted paragraphs.

para_getA

Read one paragraph in full by address (p142#a7b2a7b2, or fn3/p1#… in a note): text, style, direct paragraph formatting, character-formatted spans (bold, italic, font...) and layout facts (heading_level is null for a body paragraph, 1-9 for a heading). Use it before editing a paragraph or to check its formatting; para.list reads many paragraphs, style.get a style. Read-only; a very long text is paged (limit characters, cursor from the reply's next). STALE_ADDRESS if it changed since read.

para_insertA

Insert one new paragraph with text after or before an existing one (give after or before, e.g. p3#a1b2c3d4), as a tracked insertion (style it with style.apply in doc.batch). File engine: backed up first, logged for history.undo, dry_run previews, expect.sha256 refuses a changed file. tracked: false inserts plainly, on either engine. engine live inserts in the open Word/LibreOffice window (after live.open). Use doc.batch for several edits all or nothing. Returns the address_map of shifted paragraphs.

para_listA

List every paragraph in document order with its address, text, style, heading level and layout facts (centred, page break before, blank paragraphs before, empty, table cell); heading_level is null for a body paragraph. normalized adds normalised text, pages the estimated page, stories notes or headers. Use it to index or scan a whole document; para.get reads one paragraph with formatting, doc.outline only headings, text.find searches. Read-only; paged: about 8,000 bytes per reply (limit up to 1,000), continue with cursor set to the reply's next.

para_locateA

Say where paragraphs are, in terms a person can follow: for one paragraph, a range (p40#a1b2c3d4:0..p45#e5f6a7b8:0, offsets ignored) or the whole document, each one's chapter, scene, estimated page, shortest unique first … last words phrase, and a phrase Word's Find meets exactly once (for Ctrl+F or live.select). A phrase can be null with a reason (empty, duplicate). structure: false skips chapter detection for speed. Use it to tell a writer where a passage is; page.estimate gives only pages. Read-only; paged at about 8,000 bytes with cursor.

recipe_listA

List the cleanup recipes recipe.run can apply: the bundled ones and the user's own, each with name, version, description and source, plus any recipe files that failed validation and why. Call it to pick a recipe before recipe.run. Read-only; needs no document.

recipe_runA

Run a cleanup recipe (a name from recipe.list, or an inline definition) over the document and return the edits it proposes as a ready doc.batch request (batch, guarded by expect.sha256), repeating until the text is stable. Writes nothing itself: review the proposal, then apply it with doc.batch (dry_run there to preview). RECIPE_INVALID for an unknown or invalid recipe; edits that would touch unsupported content are listed under skipped. engine live reads the document open in the app (text-only recipes) and returns a live batch without expect, plus the text of each paragraph it edits. Refused for .txt/.md/.odt sources, which cannot be written.

review_listA

Read a reviewed document in one go: the body's comments and tracked insertions and deletions grouped by paragraph, in document order. Each paragraph gives its address, its text as it reads now, its comment threads (id, author, date, text, quote: the text the comment covers, resolved, replies) and its changes: a deletion and an insertion by one author right next to each other are one replace with old, new and both ids, others a lone insert or delete. totals counts them by kind and by author. author keeps that author's changes and the threads they wrote in. Use the ids with revision.accept / revision.reject (both of a replace) and doc.batch comment.reply / comment.resolve; revision.list adds formatting, moves, table changes and notes. Read-only; paged: about 8,000 bytes per reply (limit up to 1,000 paragraphs), continue with cursor set to the reply's next.

revision_acceptA

Accept tracked changes, making them plain text: by ids (from revision.list), by revision author, in a paragraph or run (at, p3#a1b2c3d4..p9#e5f6a7b8), or all. Not itself a tracked change: on the file engine the file is backed up first and the write is logged for history.undo; dry_run previews counts; expect.sha256 refuses a changed file. Use revision.reject to drop changes instead, doc.batch to accept and reject in one write. Returns counts and the revisions resolved.

revision_listA

List the tracked changes (insertions, deletions, moves, formatting, table rows and cells) in document order, each with id, type, author, date, paragraph address and text (clipped at 200 characters). A deletion and an insertion by one author right next to each other are one replacement: the insertion names the deletion in replaces, the deletion the insertion in replaced_by. Filter by author or type; stories notes or headers adds their changes. Use the ids with revision.accept or revision.reject (both halves to resolve a replacement); doc.stats counts changes by type, review.list groups changes and comments by paragraph. Read-only; paged: about 8,000 bytes per reply (limit up to 1,000), continue with cursor set to the reply's next.

revision_rejectA

Reject tracked changes, undoing them in the text (insertions removed, deletions restored): by ids (from revision.list), by revision author, in a paragraph or run (at, p3#a1b2c3d4..p9#e5f6a7b8), or all. Not itself a tracked change: on the file engine the file is backed up first and the write is logged for history.undo; dry_run previews counts; expect.sha256 refuses a changed file. Use revision.accept to keep changes instead, doc.batch to accept and reject in one write. Returns counts and the revisions resolved.

section_listA

List each section's page setup: break type, title page, even/odd headers, page-number start and format, and which header and footer story (hdr1.default, ftr2.first...) it uses per kind; null means inherited. Use the story keys to read header text with para.list (stories headers) or para.get; layout.get gives the same setup with the header and footer text, in the form layout.apply takes. Read-only.

server_capabilitiesA

Describe this doc-control server: API and package version, engines (file, live), which live apps are reachable, feature support per engine, every operation with its kind and summary, every error code, and whether it is a frozen build. Call it once at the start of a session; server.help gives one operation's full request and result schemas. Read-only; needs no document.

server_helpA

Get the JSON Schemas of one operation (op, e.g. "para.get": its request schema and its result's output_schema), or of every operation when op is left out. A doc.batch kind ("comment.reply", "para.move"...) gives the fields it takes inside ops, under batch_operations; a name that is both gets both. Old names (before 0.7.0) give the renamed operation. Call it before using an operation whose fields you are unsure of; server.capabilities lists the operations. Read-only.

style_createA

Add a new paragraph, character, table or numbering style with its parent (based_on), next and linked styles and run and paragraph formatting (e.g. run {"bold": true, "size_pt": 14}; paragraph in twips). id defaults from name. Refused (STYLE_CONFLICT) when the id or name exists: use style.update to change a style, style.rename to rename one, styleset.install to add many. Not a tracked change, but history.undo takes it back: the file is backed up first (backup); dry_run previews.

style_getA

Read one style by id or name ("Heading1" or "heading 1"): its type, parent chain, next and linked styles, how often it is used, heading level, the formatting it sets itself and its effective formatting after inheritance. Use it before style.update, or to see why text looks as it does; style.list lists all styles, para.get a paragraph's direct formatting. Read-only; STYLE_NOT_FOUND for an unknown style.

style_listA

List the styles defined in the document with id, name, type, parent and how many times each is used in the body. type keeps one kind (paragraph, character, table, numbering); used_only drops unused ones. Use it to find styles to clean up or reuse; style.get gives one style's full and inherited formatting. Read-only; paged: about 8,000 bytes per reply (limit up to 1,000), continue with cursor set to the reply's next.

style_mergeA

Merge styles: re-point every use of the from style or styles (ids or names) to into in the body, notes, headers and other styles, then delete the from styles. Use it to clean up duplicate styles; style.rename only renames, style.update changes formatting. Not a tracked change, but history.undo takes it back; it removes style definitions, so the file is backed up first (backup); check with dry_run first. STYLE_NOT_FOUND for an unknown style.

style_renameA

Rename a style's display name and/or id (id defaults from the name); every reference follows: paragraphs, runs, headers, notes, numbering, and based_on, next and link in other styles. STYLE_CONFLICT if the new name or id is taken. Use style.merge to fold one style into another instead. Not a tracked change, but history.undo takes it back: the file is backed up first (backup); dry_run previews.

style_updateA

Change an existing style: its parent (based_on), next or linked style, quick-gallery flag, or run and paragraph formatting (e.g. run {"italic": true, "font": "Garamond"}; null removes a key; other keys stay). Every paragraph using the style changes with it; to format one paragraph use format.apply in doc.batch. Not a tracked change, but history.undo takes it back: the file is backed up first (backup); dry_run previews. STYLE_NOT_FOUND for an unknown style.

styleset_exportA

Export the document's style definitions (all, the styles named, or custom_only) as a JSON style set, returned and also written to out when given (never overwrites an existing file). Feed it to styleset.install on another document to copy the look; styleset.export_dotx writes a Word template instead. The document is not changed.

styleset_export_dotxA

Write the document's style definitions (all, the styles named, or custom_only) to a new .dotx Word template at out (must not exist), for Word users to attach or base documents on. The document itself is never changed. styleset.import_dotx brings a template's styles into a document; styleset.export gives a JSON style set instead. Returns the path, style count and size.

styleset_import_dotxA

Install the styles of a .dotx Word template (path) into the document: new styles are added, existing ids replaced (on_conflict replace, default), kept (skip) or refused (error: STYLE_CONFLICT). Use it to apply a house template; styleset.install takes a JSON style set, style.create adds one style. Not a tracked change, but history.undo takes it back: the file is backed up first (backup); dry_run previews.

styleset_installA

Install a JSON style set (inline styleset, or a file at path, as styleset.export writes it) into the document: new styles are added, existing ids replaced (on_conflict replace, default), kept (skip) or refused (error: STYLE_CONFLICT). Use it to copy styles between documents; styleset.import_dotx reads a Word template, style.create adds one style. Not a tracked change, but history.undo takes it back: the file is backed up first (backup); dry_run previews.

table_getA

Read one table's grid: rows of cells, each with its first grid column, span, vertical merge (null, restart, continue) and the addresses of its paragraphs (read their text with para.get or para.list). Name it by table (1-based, body only, the cell.table para.list shows) or by at, any paragraph address in it, also in notes and headers. Use it before table.row.insert/delete or to edit cells with text.replace. Read-only; ANCHOR_NOT_FOUND for no such table.

table_row_deleteA

Delete one row of a body table (table as table.get numbers it, row 1-based) as a tracked change the writer can reject. Refused (UNSUPPORTED_CONTENT) for a row with a vertically merged cell. Backed up and logged for history.undo; dry_run previews; expect.sha256 refuses a changed file. Use doc.batch to change several rows at once, para.delete for paragraphs outside tables.

table_row_insertA

Insert a row into a body table as a tracked change: after row after_row (0: before the first), with one text per cell in cells (e.g. ["2024", "12.5"]), matching the row it follows (SCHEMA_INVALID otherwise). Refused (UNSUPPORTED_CONTENT) between two rows a vertical merge spans. Backed up and logged for history.undo; dry_run previews; expect.sha256 refuses a changed file. Use doc.batch for several rows at once.

term_renameA

Rename a term or a character's name everywhere (Lucía to Elena) as one tracked batch: whole words by default, case-insensitive with case preserved (LUCÍA becomes ELENA), with optional inflections (["s"] also renames Lucías) and ignore_accents. match_level default/loose folds case, accents and punctuation. Matches inside fields or links are left and counted. Run dry_run first to check counts and the preview, then the same request without it. Use it instead of many text.replace edits. Backed up, undoable; tracked: false writes plainly.

text_findA

Find text or a Python regex (regex) in the document; each match comes back as a range (p8#b72009e4:0-8) with context, ready for text.replace or anchor.create. ignore_case, ignore_accents (maria finds María), whole_word and match_level (default: also ignores punctuation) loosen it; stories adds notes or headers. The first page gives total, and query_word, the query as typed in Word's Find box. Use para.locate to describe where a paragraph is, history.search for removed text. Read-only; limit (default 20) per page, cursor continues; stops after 10 s with more.

text_normalizeA

Normalise text (NFC, soft hyphens and zero-width characters removed, whitespace collapsed) and return a two-way offset map to the original code points, for the whole document, one paragraph or range (at, p142#a7b2a7b2:10-15), or a text string (give doc or text). Use it to compare or search text robustly and map found offsets back to addresses for text.replace; para.list normalized adds just the text. Read-only; paged at about 8,000 bytes with cursor; a very long paragraph comes in parts.

text_replaceA

Replace one range with new text, as a tracked change: part of a paragraph (p3#a1b2c3d4:10-15, code-point offsets), a whole paragraph (p3#a1b2c3d4) or a span across paragraphs (p3#a1b2c3d4:10..p5#e5f6a7b8:2); empty text deletes it. Get ranges from text.find or para.get. File engine: backed up first, logged for history.undo, dry_run previews, expect.sha256 refuses a changed file. tracked: false writes plainly, on either engine. engine live edits the open app. STALE_ADDRESS if the paragraph changed since read. Use term.rename for a name everywhere, doc.batch for several edits.

toc_insertA

Insert a table of contents (a TOC field) after a body paragraph after (p1#a1b2c3d4), as tracked insertions: a title (default "Contents", "" for none), the field listing heading levels levels (default "1-3") with a placeholder result, and a closing paragraph. Run field.update next to fill in the entries and page numbers (until then field.list shows it stale). Backed up and undoable (history.undo); dry_run previews. Returns the field paragraph's address.

xref_addA

Insert a cross-reference field at an insertion point (at: p14#a1b2c3d4:20-20, or a paragraph address for its end), pointing to a caption or another body paragraph. show number (default: "Table 3" for a caption), page (a PAGEREF) or text. The target gets a hidden bookmark when it has none; run field.update afterwards to fill in the shown value. A tracked insertion; backed up and undoable (history.undo); dry_run previews. Add captions with caption.add first.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription
places

TDQS

A4.1/5.0

Scored across 68 tools

Disambiguation2/5

The 68-tool surface contains several clusters whose boundaries blur in practice: layout.get vs section.list, review.list vs comment.list/revision.list, doc.info vs doc.stats vs para.list/doc.outline, and history.list vs history.search. Descriptions do distinguish them, but an agent must read carefully to pick correctly, and multiple read tools target overlapping views of the same document.

Naming Consistency4/5

Most tools follow a predictable resource_verb pattern (para_get, style_update, history_undo, text_replace, table_row_insert), and names are consistently snake_case. Minor deviations like doc_batch (itself referred to as doc.batch), live_get_selection vs live_select, and styleset_export_dotx keep it from perfect consistency.

Tool Count2/5

68 tools is far too many for a single document-control server, even one covering editing, styles, revisions, fields, layout, live editing, and history. The surface could be consolidated substantially without losing capability.

Completeness5/5

Coverage is unusually thorough: paragraphs, tables, styles, comments, tracked revisions, fields, TOC/index entries, notes, layout, live app control, undo/restore history, recipes, and cross-references. No obvious lifecycle gap for a Word-document control server.

Maintenance

ActivityMaintained
ResponsivenessResponsive