doc-control
PYPI · DOC-CONTROL
Edit Word documents by address: tracked changes, comments, anchors, with backups and undo.
Available components
Last scanned (6 hours ago)
Scores higher than 72% of PyPI servers
Category Documents and Files
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- Runs hatchling.build at install time, a recognised build step with no custom scripting around it. View diagnostics → Pass
- No production dependencies, so there is no dependency health to assess. View diagnostics → Pass
Provenance & Transparency97
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Cryptographically verified build provenance (signed, bound to nuncaeslupus/doc-control). View diagnostics → Pass
- Clear OSI-approved license (Apache-2.0).Pass
- Actively maintained (last published 0 days ago).Pass
- Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
Schema Quality & AI Usability38
- 0% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Fail
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 18106 tokens (~266/item across 68 items; 67 tools + 1 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management7
- Stability observed for 2 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- All 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- An AI judge read all 68 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
- Supports UI / widget rendering.Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 16 Oct 26 +16
- Tool safety: pass → unverified ▼ security
- Malware scan: unverified → pass ▲ security
- Stability: Stability not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet. security
- Capabilities: pass → unverified ▼ functional
- Schema quality: 0 → unverified ▼ functional
- Tool coverage: 100 → unverified ▼ functional
- Stability: unverified → 0.03 ▲ functional
- Package version: 0.8.1 → 0.8.3 functional
- 15 Oct 26 59
First indexed and scored.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 17 Oct 2026 · Analysed pypi/doc-control@0.8.3
Provenance Verified
A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.
| Result | Verified |
|---|---|
| Ecosystem | pypi |
| Reason | Verified |
| Discovered via | Registry attestation endpoint |
| Source repo | nuncaeslupus/doc-control |
| Certificate issuer | https://token.actions.githubusercontent.com |
| Certificate SAN | https://github.com/nuncaeslupus/doc-control/.github/workflows/release.yml@refs/heads/main |
| Rekor log index | 3281733764 |
| Predicate type | PyPI publish attestation https://docs.pypi.org/attestations/publish/v1 |
| Subject digest | sha256:478ab88818062751080dfdf2bb11e13f09948dc7d8c9a87e93d80ee0d595fc48 |
Background: How many MCP packages publish verified provenance →
Install scripts 1 script
| Hook | Tier | Command |
|---|---|---|
| build_backend | allowlisted | hatchling.build |
Background: Why install scripts are a supply-chain risk →
Dependencies 0 packages
| Packages resolved | 0 |
|---|---|
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
anchor_create ~239
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.
| Name | Type | Req | Description |
|---|---|---|---|
| at | string | yes | Range inside one paragraph, e.g. p142#a7b2a7b2:10-15, or a whole paragraph or sentence (p142#a7b2a7b2.s3). |
| context | integer | – | Characters of prefix and of suffix to keep. |
| doc | string | yes | Path to the .docx file. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
anchor_resolve ~405
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.
| Name | Type | Req | Description |
|---|---|---|---|
| anchor | object | yes | An anchor from anchor.create, or just {exact, prefix, suffix}. |
| doc | string | yes | Path to the .docx file. |
| match_level | – | – | How far the quote is folded when neither it nor its normalised text occurs. exact: today's rule (verbatim, then normalised, then fuzzy in mode best). default: then ignoring case, accents and punctuat… |
| mode | – | – | best: verbatim matches first, then fuzzy ones (match says which). exact: only places holding the quote verbatim or, when none does, in the normalised text (soft hyphens and zero-width characters igno… |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
caption_add ~298
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.
| Name | Type | Req | Description |
|---|---|---|---|
| at | string | yes | Address of the body paragraph the caption goes next to. |
| author | string | – | Revision author. |
| doc | string | yes | Path to the .docx. |
| dry_run | boolean | – | Preview only; write nothing. |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| label | – | yes | The caption label. |
| position | – | – | Default: above for a Table, below for a Figure or Equation. |
| tag | string | – | Appended to the author. |
| text | string | yes | Caption text after the number; may be empty. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
comment_add ~348
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.
| Name | Type | Req | Description |
|---|---|---|---|
| at | string | yes | Range to comment on: p3#fp, p3#fp:10-15 or across. |
| author | string | – | Revision author. |
| doc | string | yes | Path to the .docx (live: or the file name of one open in a live app). |
| dry_run | boolean | – | Preview only; write nothing. |
| engine | – | – | `live` edits the document open in Word or LibreOffice (see live.open). |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| tag | string | – | Appended to the author. |
| text | string | yes | Comment text; a newline starts a new paragraph. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
comment_list ~222
List the comments in thread order (each root comment, then its replies) with id, author, date, text (clipped at 1,000 characters), 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. 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`.
| Name | Type | Req | Description |
|---|---|---|---|
| author | string | – | Only this author. |
| cursor | string | – | The `next` value of the previous response, to continue the list. |
| doc | string | yes | Path to the .docx. |
| limit | integer | – | Most items to return; a response is also capped at about 8,000 bytes. |
| resolved | boolean | – | Only resolved (true) or open (false). |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
doc_batch ~833
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 <kind> gives each kind's fields.
| Name | Type | Req | Description |
|---|---|---|---|
| author | string | – | Revision author. |
| doc | string | yes | Path to the .docx (live: or the file name of one open in a live app). |
| dry_run | boolean | – | Preview only; write nothing. |
| engine | – | – | `live` edits the document open in Word or LibreOffice (see live.open). |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| ops | array | yes | Operations, applied together. Every address refers to the document as read; an operation placed relative to a paragraph another operation deletes or moves is a BATCH_CONFLICT. Kinds: text.replace ['a… |
| tag | string | – | Appended to the author. |
| tracked | boolean | – | true (default): edits are tracked changes. false: a plain write, for a change the writer already approved: built as the tracked edit, then this call's own revisions are accepted in the same verified… |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
doc_compare ~232
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.
| Name | Type | Req | Description |
|---|---|---|---|
| author | string | – | Revision author (default Claude). |
| date | string | – | Revision date, ISO 8601 with time zone. |
| new | string | yes | Path of the later version (.docx). |
| old | string | yes | Path of the earlier version (.docx). |
| output | string | yes | Path of the redline to create (must not exist). |
| tag | string | – | Appended to the author as `author (tag)`. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
doc_diff ~233
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).
| Name | Type | Req | Description |
|---|---|---|---|
| collapse_runs | boolean | – | List runs of shifted unchanged paragraphs as one record each. |
| cursor | string | – | The `next` value of the previous response, to continue the list. |
| limit | integer | – | Most items to return; a response is also capped at about 8,000 bytes. |
| new | string | yes | Path of the later version (.docx). |
| old | string | yes | Path of the earlier version (.docx). |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
doc_info ~135
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the .docx. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
doc_open ~132
Start a session on a document: back it up into its store (.doc-control/<file name>/ 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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the .docx. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
doc_outline ~270
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`.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | The `next` value of the previous response, to continue the list. |
| doc | string | yes | Path to the .docx. |
| limit | integer | – | Most items to return; a response is also capped at about 8,000 bytes. |
| max_level | integer | – | Only headings up to this level. |
| stories | array | – | Stories to read (default ["body"]): "notes" adds footnotes and endnotes, each after the paragraph holding its mark; "headers" adds headers and footers, after the body. Their addresses carry a prefix… |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
doc_segment ~359
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`.
| Name | Type | Req | Description |
|---|---|---|---|
| chapter | string | – | scenes only: the chapter id whose scenes to list. |
| cursor | string | – | The `next` value of the previous response, to continue the list. |
| doc | string | yes | Path to the .docx. |
| language | string | – | Sentence rules (default es). |
| limit | integer | – | Most items to return; a response is also capped at about 8,000 bytes. |
| overrides | array | – | Force or deny a chapter or scene at paragraphs by fingerprint. |
| profile | object | – | Detection settings for this document. |
| range | string | – | sentences and dialogue only: what to cover — a paragraph address or range, a run of whole paragraphs (p24#fp..p60#fp), or a chapter, scene or part id (ch-…, sc-…, pt-…; same profile and overrides). |
| unit | string | – | What to list (default chapters). |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
doc_stats ~191
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the .docx. |
| stories | array | – | Stories to read (default ["body"]): "notes" adds footnotes and endnotes, each after the paragraph holding its mark; "headers" adds headers and footers, after the body. Their addresses carry a prefix… |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
field_list ~189
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the .docx. |
| stories | array | – | Stories to read (default all): "body", "notes", "headers" and "comments". |
| type | string | – | Only fields of this type, e.g. "TOC" or "ADDIN ZOTERO_ITEM". |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
field_update ~269
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).
| Name | Type | Req | Description |
|---|---|---|---|
| author | string | – | Revision author. |
| doc | string | yes | Path to the .docx. |
| dry_run | boolean | – | Preview only; write nothing. |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| set_update_on_open | boolean | – | Only set w:updateFields in settings.xml (no LibreOffice). |
| tag | string | – | Appended to the author. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
history_adopt ~213
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the .docx. |
| dry_run | boolean | – | Say what would move; move nothing. |
| force | boolean | – | Adopt although the document's sha256 is not the store's last. |
| store | string | – | The orphan store to adopt (see doc.open's `adoptable` or history.orphans); needed when several match or the old folder is far away. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
history_list ~211
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`).
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | The `next` of the previous response. |
| doc | string | – | Path to the .docx. |
| kind | – | – | Only entries of this kind (batch: every logged edit). |
| limit | integer | – | Most entries per page (default 20). |
| store | string | – | A store folder (see history.orphans) to read instead of the document's own. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
history_orphans ~128
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.
| Name | Type | Req | Description |
|---|---|---|---|
| dir | string | – | Also scan this folder. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
history_purge ~211
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.
| Name | Type | Req | Description |
|---|---|---|---|
| all | boolean | – | Remove the whole log. |
| before | string | – | Remove entries older than this ISO date or time (UTC). |
| confirm | string | – | From the dry run. |
| doc | string | – | Path to the .docx. |
| dry_run | boolean | – | List what would go; returns confirm. |
| store | string | – | A store folder (see history.orphans) to read instead of the document's own. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
history_restore ~365
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.
| Name | Type | Req | Description |
|---|---|---|---|
| after | string | – | Insert after this paragraph address instead of the old place (needed when that place was edited, or the history comes from `store`). |
| author | string | – | Revision author. |
| change | integer | – | Index of one change of the op (history.list shows them). |
| doc | string | yes | Path to the .docx. |
| dry_run | boolean | – | Preview only; write nothing. |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| op_id | string | yes | The logged op the paragraph was changed by. |
| store | string | – | A store folder (see history.orphans) to read instead of the document's own. |
| tag | string | – | Appended to the author. |
| tracked | boolean | – | false: a plain write for a change the writer already approved: the paragraph comes back without revision marks (this call's own insertion accepted in the same verified write). |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
history_search ~430
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | – | Path to the .docx. |
| ignore_accents | boolean | – | Ignore accents: `maria` finds `María`. |
| ignore_case | boolean | – | Ignore case. |
| limit | integer | – | Most hits to return (default 20); `total` counts them all. |
| match_level | string | – | Fold the search as `text.find` does: `default` ignores case, accents and punctuation (symbols such as `$` still count), `loose` drops symbols too; `exact` keeps the flags. When passed, Word's Find co… |
| query | string | yes | Text to find. |
| store | string | – | A store folder (see history.orphans) to read instead of the document's own. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
history_undo ~243
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the .docx. |
| dry_run | boolean | – | Check and preview; write nothing. |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| op_id | string | – | The op to undo (default: the latest in effect). |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
index_insert ~257
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.
| Name | Type | Req | Description |
|---|---|---|---|
| after | string | yes | Address of the body paragraph it goes after. |
| author | string | – | Revision author. |
| doc | string | yes | Path to the .docx. |
| dry_run | boolean | – | Preview only; write nothing. |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| tag | string | – | Appended to the author. |
| title | string | – | Title paragraph above it (default "Index"); "" for none. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
index_mark ~266
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.
| Name | Type | Req | Description |
|---|---|---|---|
| at | string | yes | A range inside one paragraph; the mark goes after it. |
| author | string | – | Revision author. |
| doc | string | yes | Path to the .docx. |
| dry_run | boolean | – | Preview only; write nothing. |
| entry | string | yes | The index entry, e.g. "Term" or "Term:Sub". |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| tag | string | – | Appended to the author. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
layout_apply ~404
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.
| Name | Type | Req | Description |
|---|---|---|---|
| author | string | – | Revision author. |
| doc | string | yes | Path to the .docx. |
| dry_run | boolean | – | Preview only; write nothing. |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| plan | object | yes | The page plan, as layout.get returns it: version 1, two_sided, mirror_margins and sections, each with a `from` address; keys left out stay as they are, and numbering.shown is checked, not set. Every… |
| tag | string | – | Appended to the author. |
| untracked | boolean | – | Allow a change Word cannot track (LAYOUT D-L2). |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
layout_get ~119
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the .docx. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
live_close ~143
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.
| Name | Type | Req | Description |
|---|---|---|---|
| discard | boolean | – | Close and drop the unsaved changes. |
| doc | string | yes | Path to the document, or the file name of one open in a live app. |
| engine | – | – | Always the live engine; may be left out. |
| save | boolean | – | Save, then close. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
live_get_selection ~130
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the document, or the file name of one open in a live app. |
| engine | – | – | Always the live engine; may be left out. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
live_open ~200
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.
| Name | Type | Req | Description |
|---|---|---|---|
| app | string | – | `word` or `libreoffice`. |
| doc | string | yes | Path to the document, or the file name of one open in a live app. |
| engine | – | – | Always the live engine; may be left out. |
| front | boolean | – | Bring the app's window to the front (default true); the reply's `front` says whether it came. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
live_places ~223
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the document, or the file name of one open in a live app. |
| engine | – | – | Always the live engine; may be left out. |
| mode | – | – | What a click does: `cursor` (default) puts the cursor at the place's start; `select` selects its paragraph. |
| places | array | yes | The buttons, in order: a `label` and `at` or `find_phrase` each (with both, `find_phrase` is tried when `at` fails). |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
live_save ~115
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | yes | Path to the document, or the file name of one open in a live app. |
| engine | – | – | Always the live engine; may be left out. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
live_select ~478
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.
| Name | Type | Req | Description |
|---|---|---|---|
| at | string | – | Paragraph address, e.g. `p142#a7b2a7b2`. |
| doc | string | yes | Path to the document, or the file name of one open in a live app. |
| engine | – | – | Always the live engine; may be left out. |
| find_phrase | string | – | A phrase that occurs once in the document (`\r` for a paragraph mark), as `para.locate` gives it. |
| find_phrase_across | – | – | `para.locate`'s `find_phrase_across`, for a phrase spanning a mark. |
| front | boolean | – | Bring the app's window to the front (default true); the reply's `front` says whether it came. |
| match_level | – | – | How loosely `find_phrase` matches. `default` (the default) ignores case, accents and punctuation; `loose` symbols too. Either tries the levels from verbatim on and takes the first that matches, so on… |
| mode | – | – | `select` (default) selects the paragraph; `cursor` only puts the cursor at its start, so typing or Delete cannot replace it. |
| paragraphs_after | integer | – | Select the paragraph this many after the one named. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
live_status ~144
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.
| Name | Type | Req | Description |
|---|---|---|---|
| doc | string | – | Path to the document, or the file name of one open in a live app. |
| engine | – | – | Always the live engine; may be left out. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
note_add ~316
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#…).
| Name | Type | Req | Description |
|---|---|---|---|
| at | string | yes | Body point p3#fp:10-10 (the mark goes after the offset), a range inside one paragraph (after it) or a paragraph (at its end). |
| author | string | – | Revision author. |
| doc | string | yes | Path to the .docx. |
| dry_run | boolean | – | Preview only; write nothing. |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| kind | – | yes | footnote (bottom of the page) or endnote (end of the document). |
| tag | string | – | Appended to the author. |
| text | string | yes | The note text, one line. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
page_estimate ~224
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`.
| Name | Type | Req | Description |
|---|---|---|---|
| at | string | – | Only this paragraph, by address, e.g. p142#a7b2a7b2. |
| by | string | – | List one row per paragraph (default) or per page. |
| cursor | string | – | The `next` value of the previous response, to continue the list. |
| doc | string | yes | Path to the .docx. |
| limit | integer | – | Most items to return; a response is also capped at about 8,000 bytes. |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
para_delete ~467
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.
| Name | Type | Req | Description |
|---|---|---|---|
| at | string | yes | Paragraph p3#fp or run p3#fp..p5#fp. |
| author | string | – | Revision author. |
| doc | string | yes | Path to the .docx (live: or the file name of one open in a live app). |
| dry_run | boolean | – | Preview only; write nothing. |
| expect | object | – | Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK. |
| tag | string | – | Appended to the author. |
| tracked | boolean | – | true (default): edits are tracked changes. false: a plain write, for a change the writer already approved: built as the tracked edit, then this call's own revisions are accepted in the same verified… |
| Name | Type | Req | Description |
|---|---|---|---|
| api | string | yes | API version (1.0). |
| doc | object | – | The document read or written: path, sha256 and paragraph count. |
| next | string|null | yes | Cursor for the next page (pass as cursor), or null. |
| ok | boolean | yes | Always true on success. |
| op | string | yes | The operation that ran. |
| result | object | yes | What the operation returns. |
| warnings | array | yes | Things to know about the result. |
No examples provided.
How do I install the doc-control MCP server?
doc-control runs locally as a PyPI package, launched with uvx doc-control. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
pypi · doc-control
claude mcp add nuncaeslupus-doc-control -- uvx doc-control
What is the doc-control MCP server?
doc-control is an MCP server listed in the public MCP registry as io.github.nuncaeslupus/doc-control. Edit Word documents by address: tracked changes, comments, anchors, with backups and undo. This page covers its PyPI package (doc-control).
Is the doc-control MCP server safe to use?
doc-control scores 75 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 17 October 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the doc-control MCP server expose?
doc-control exposes 67 tools: anchor_create, anchor_resolve, caption_add, comment_add, comment_list, and 62 more. Their descriptions and schemas cost roughly 18,102 tokens of context every time the server is loaded.
Is the doc-control MCP server still maintained?
doc-control is still listed as active in the MCP registry. We last reached this channel on 17 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the doc-control MCP server under?
doc-control declares the Apache-2.0 licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.