Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

doc-control

PYPI · DOC-CONTROL

Edit Word documents by address: tracked changes, comments, anchors, with backups and undo.

Available components

75 Trust /100

Last scanned (7 hours ago)

Scores higher than 73% of PyPI servers

Category Documents and Files

Trust breakdown (7 categories)

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
Changelog

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.

Diagnostics

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 →

MCP tools · 67 exposed · ~18,102 tokens

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 →

Tool Tokens
para_get ~208

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.

NameTypeReqDescription
atstringyesParagraph address from a read result, e.g. p142#a7b2a7b2.
cursorstring–The `next` value of the previous response, to continue the list.
docstringyesPath to the .docx.
limitinteger–Most characters of text to return.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

para_insert ~495

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.

NameTypeReqDescription
afterstring–Insert after this paragraph (or before).
authorstring–Revision author.
beforestring–Insert before this paragraph (or after).
docstringyesPath to the .docx (live: or the file name of one open in a live app).
dry_runboolean–Preview only; write nothing.
engine––`live` edits the document open in Word or LibreOffice (see live.open).
expectobject–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.
tagstring–Appended to the author.
textstringyesText of the new paragraph.
trackedboolean–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…
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

para_list ~318

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`.

NameTypeReqDescription
cursorstring–The `next` value of the previous response, to continue the list.
docstringyesPath to the .docx.
limitinteger–Most items to return; a response is also capped at about 8,000 bytes.
normalizedboolean–Add `normalized`, the text as `text.normalize` gives it.
pagesboolean–Add the estimated `page` and `page_label` per paragraph, and `page_basis`, `rendered_marks` and `page_count` (see page.estimate).
storiesarray–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…
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

para_locate ~321

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`.

NameTypeReqDescription
atstring–Paragraph address or range (offsets ignored), e.g. p142#a7b2a7b2; default the whole document (empty paragraphs left out).
cursorstring–The `next` value of the previous response, to continue the list.
docstringyesPath to the .docx.
limitinteger–Most items to return; a response is also capped at about 8,000 bytes.
overridesarray–Force or deny a chapter or scene at paragraphs by fingerprint.
profileobject–Detection settings for this document.
structureboolean–false: skip chapter, part and scene detection (they come back null), for callers that keep their own structure; faster on a single paragraph. Default true.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

recipe_list ~62

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.

Input schema present but exposes no named parameters.

NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

recipe_run ~175

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. Refused for .txt/.md/.odt sources, which cannot be written.

NameTypeReqDescription
definitionobject–An inline declarative recipe (same schema as a stored one).
docstringyesPath to the .docx file.
dry_runboolean–Accepted for symmetry; recipe.run never writes.
recipestring–Name from recipe.list.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

revision_accept ~286

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.

NameTypeReqDescription
allboolean–true: every revision in the document.
atstring–Paragraph p3#fp or run p3#fp..p9#fp.
authorstring–Exact revision author.
docstringyesPath to the .docx (live: or the file name of one open in a live app).
dry_runboolean–Preview only; write nothing.
expectobject–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.
idsarray–Accept the revisions with these ids (from revision.list).
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

revision_list ~271

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). Filter by `author` or `type`; stories notes or headers adds their changes. Use the ids with revision.accept or revision.reject; doc.stats counts changes by type. Read-only; paged: about 8,000 bytes per reply (limit up to 1,000), continue with `cursor` set to the reply's `next`.

NameTypeReqDescription
authorstring–Only this author.
cursorstring–The `next` value of the previous response, to continue the list.
docstringyesPath to the .docx.
limitinteger–Most items to return; a response is also capped at about 8,000 bytes.
storiesarray–Stories to list (default ["body"]): "notes" adds footnotes and endnotes, "headers" headers and footers, after the body's revisions; their addresses carry a prefix (fn3/p1#…, hdr1.default/p1#…). Row a…
typestring–Only this type.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

revision_reject ~297

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.

NameTypeReqDescription
allboolean–true: every revision in the document.
atstring–Paragraph p3#fp or run p3#fp..p9#fp.
authorstring–Exact revision author.
docstringyesPath to the .docx (live: or the file name of one open in a live app).
dry_runboolean–Preview only; write nothing.
expectobject–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.
idsarray–Reject the revisions with these ids (from revision.list).
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

section_list ~112

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.

NameTypeReqDescription
docstringyesPath to the .docx.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

server_capabilities ~86

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.

Input schema present but exposes no named parameters.

NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

server_help ~133

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.

NameTypeReqDescription
opstring–Operation or batch operation kind.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

style_create ~419

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.

NameTypeReqDescription
based_onstring–Parent style id or name; '' for none.
customboolean–A user-defined (not built-in) style.
defaultboolean–The default style of its type.
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
idstring–Style id (default: from the name).
linkstring–Linked paragraph/character style; '' for none.
namestringyesDisplay name.
nextstring–Style of the next paragraph; '' for none.
paragraphobject–Paragraph formatting (twips): alignment, indent{left,right,first_line,hanging}, spacing{before,after,line,line_rule}, keep_next, keep_lines, page_break_before, outline_level; null removes a key.
quickboolean–Show in the quick-style gallery.
runobject–Character formatting: bold, italic, small_caps, strike, underline, font, size_pt, color, highlight, vertical_align; null removes a key.
type––Kind of style (default paragraph).
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

style_get ~122

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.

NameTypeReqDescription
docstringyesPath to the .docx.
stylestringyesStyle id or name.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

style_list ~197

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`.

NameTypeReqDescription
cursorstring–The `next` value of the previous response, to continue the list.
docstringyesPath to the .docx.
limitinteger–Most items to return; a response is also capped at about 8,000 bytes.
typestring–Only this kind of style.
used_onlyboolean–Only styles used at least once.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

style_merge ~221

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.

NameTypeReqDescription
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
from–yesStyle id or name, or a list of them (they are removed).
intostringyesStyle id or name.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

style_rename ~217

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.

NameTypeReqDescription
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
idstring–Style id (default: from the name).
namestring–Display name.
stylestringyesStyle id or name.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

style_update ~355

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.

NameTypeReqDescription
based_onstring–Parent style id or name; '' for none.
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
linkstring–Linked paragraph/character style; '' for none.
nextstring–Style of the next paragraph; '' for none.
paragraphobject–Paragraph formatting (twips): alignment, indent{left,right,first_line,hanging}, spacing{before,after,line,line_rule}, keep_next, keep_lines, page_break_before, outline_level; null removes a key.
quickboolean–Show in the quick-style gallery.
runobject–Character formatting: bold, italic, small_caps, strike, underline, font, size_pt, color, highlight, vertical_align; null removes a key.
stylestringyesStyle id or name.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

styleset_export ~143

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.

NameTypeReqDescription
custom_onlyboolean–Only user-defined styles.
docstringyesPath to the .docx.
namestring–Set name.
outstring–Also write the JSON here.
stylesarray–Only these styles (ids or names).
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

styleset_export_dotx ~158

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.

NameTypeReqDescription
custom_onlyboolean–Only user-defined styles.
docstringyesPath to the .docx.
namestring–Set name.
outstringyesNew .dotx to create.
stylesarray–Only these styles (ids or names).
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

styleset_import_dotx ~215

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.

NameTypeReqDescription
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
on_conflict––A style id already in the document (default replace).
pathstringyesThe .dotx to read.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

styleset_install ~238

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.

NameTypeReqDescription
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
on_conflict––A style id already in the document (default replace).
pathstring–Or a style set file.
stylesetobject–The style set (inline).
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

table_get ~239

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.

NameTypeReqDescription
atstring–Instead of `table`: any paragraph address in the table, in any story (`fn3/p1#…`, `hdr1.default/p1#…`); the reply's `table` is then numbered within that story.
docstringyesPath to the .docx.
tableinteger–Table number in the main story, 1-based in document order (the `cell.table` of a paragraph row); text-box and DrawingML tables are not counted. Tables of notes, headers and footers are reached with `…
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

table_row_delete ~250

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.

NameTypeReqDescription
authorstring–Revision author.
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
rowintegeryesThe row, 1-based.
tableintegeryesTable number as `table.get` numbers it: 1-based, in document order, main story only (a table in a note, header or footer cannot be named here).
tagstring–Appended to the author.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

table_row_insert ~310

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.

NameTypeReqDescription
after_rowintegeryesInsert after this row (1-based); 0 inserts before the first row.
authorstring–Revision author.
cellsarrayyesOne text per cell of the row it follows (the first row for after_row 0); a horizontally merged cell is one cell.
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
tableintegeryesTable number as `table.get` numbers it: 1-based, in document order, main story only (a table in a note, header or footer cannot be named here).
tagstring–Appended to the author.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

term_rename ~636

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.

NameTypeReqDescription
authorstring–Revision author.
case_sensitiveboolean–Exact spelling only; `to` is used as written.
docstringyesPath to the .docx.
dry_runboolean–Plan and preview only; write nothing.
expectobject–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.
fromstringyesTerm to rename.
ignore_accentsboolean–`Lucia` also matches `Lucía`.
inflectionsarray–Suffixes that follow the term: "s" renames Lucías to Elenas; {"from": "o", "to": "a"} renames Lucíao to Elenaa.
match_levelstring–Fold the search as `text.find` does: `default` ignores case, accents and punctuation (symbols such as `$` still count), `loose` drops symbols too; `exact` is the rename as without it. When passed, Wo…
preserve_caseboolean–LUCÍA becomes ELENA, lucía becomes elena, Lucía becomes Elena.
preview_limitinteger–Most changes echoed back in `preview`.
tagstring–Appended to the author.
tostringyesNew term.
trackedboolean–false: a plain write for a change the writer already approved: the same edits, with this call's own revisions accepted in the same verified write (no revision marks; undo works). Refused (UNSUPPORTED…
whole_wordboolean–Whole words only.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

text_find ~599

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`.

NameTypeReqDescription
contextinteger–Characters of surrounding text on each side of a match.
cursorstring–The `next` value of the previous page.
docstringyesPath to the .docx file.
ignore_accentsboolean–Ignore accents: `maria` finds `María`. A regex must be written without accents then.
ignore_caseboolean–Ignore case.
limitinteger–Most matches to return; more are reached with `cursor`.
match_levelstring–Fold a literal query: `default` ignores case, accents and punctuation (symbols such as `$` still count), `loose` drops symbols too; `exact` is the search as without it. When passed, Word's Find codes…
querystringyesText to find (at most 1000 characters), or a Python regex if `regex`.
regexboolean–Treat `query` as a regex.
storiesarray–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…
whole_wordboolean–Match only whole words (no letter, digit or mark on either side).
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

text_normalize ~238

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.

NameTypeReqDescription
atstring–Paragraph address or range, e.g. p142#a7b2a7b2:10-15.
cursorstring–The `next` value of the previous response, to continue the list.
docstring–Path to a .docx.
limitinteger–Most items to return; a response is also capped at about 8,000 bytes.
textstring–Text to normalise instead of `doc`.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

text_replace ~550

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.

NameTypeReqDescription
atstringyesRange p3#fp:10-15, p3#fp or p3#fp:10..p5#fp:2.
authorstring–Revision author.
docstringyesPath to the .docx (live: or the file name of one open in a live app).
dry_runboolean–Preview only; write nothing.
engine––`live` edits the document open in Word or LibreOffice (see live.open).
expectobject–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.
tagstring–Appended to the author.
textstringyesNew text; empty deletes the range.
trackedboolean–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…
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

toc_insert ~281

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.

NameTypeReqDescription
afterstringyesAddress of the body paragraph it goes after.
authorstring–Revision author.
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
levelsstring–Heading levels it lists, e.g. "1-3" (default) or "2".
tagstring–Appended to the author.
titlestring–Title paragraph above it (default "Contents"); "" for none.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

xref_add ~308

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.

NameTypeReqDescription
atstringyesInsertion point: p<n>#<fp>:<k>-<k>, or a paragraph address for its end.
authorstring–Revision author.
docstringyesPath to the .docx.
dry_runboolean–Preview only; write nothing.
expectobject–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.
show––number (default): a caption's label and number, or a paragraph's number; page: the page it is on; text: the caption or paragraph text.
tagstring–Appended to the author.
tostringyesAddress of the caption or heading it points at.
NameTypeReqDescription
apistringyesAPI version (1.0).
docobject–The document read or written: path, sha256 and paragraph count.
nextstring|nullyesCursor for the next page (pass as cursor), or null.
okbooleanyesAlways true on success.
opstringyesThe operation that ran.
resultobjectyesWhat the operation returns.
warningsarrayyesThings to know about the result.

No examples provided.

Install

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

# add to Claude Code
claude mcp add nuncaeslupus-doc-control -- uvx doc-control
Common questions

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.