accept_changes
Accept all tracked changes in a DOCX document to remove revision markup and produce a clean final version with acceptance statistics.
Instructions
Accept all tracked changes in the document body, producing a clean document with no revision markup. Returns acceptance stats.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | Yes | Path to the DOCX file. |
Implementation Reference
- MCP tool handler that calls doc.acceptChanges() and marks the session as edited.
export async function acceptChanges( manager: SessionManager, params: { file_path?: string }, ): Promise<ToolResponse> { const resolved = await resolveSessionForTool(manager, params, { toolName: 'accept_changes' }); if (!resolved.ok) return resolved.response; const { session, metadata } = resolved; try { const stats = session.doc.acceptChanges(); manager.markEdited(session); return ok(mergeSessionResolutionMetadata({ ...stats, file_path: manager.normalizePath(session.originalPath), }, metadata)); } catch (e: unknown) { return err('ACCEPT_CHANGES_ERROR', errorMessage(e)); } } - Core implementation of acceptChanges, which traverses the XML DOM to remove/unwrap revision-related elements.
export function acceptChanges(doc: Document): AcceptChangesResult { const body = doc.getElementsByTagNameNS(W_NS, 'body').item(0); if (!body) { return { insertionsAccepted: 0, deletionsAccepted: 0, movesResolved: 0, propertyChangesResolved: 0 }; } // Phase A — Identify paragraphs to remove const paragraphsToRemove = new Set<Element>(); const allParagraphs = collectByLocalName(body, 'p'); for (const p of allParagraphs) { // Paragraph-level deletion marker: w:p > w:pPr > w:rPr > w:del if (paragraphHasParaMarker(p, 'del')) { paragraphsToRemove.add(p); continue; } // Paragraphs whose only content is inside w:del or w:moveFrom if (paragraphHasOnlyRemovedContent(p)) { paragraphsToRemove.add(p); } } // Phase B — Remove deletions and move sources const deletionsAccepted = removeAllByLocalName(body, 'del'); const moveFromRemoved = removeAllByLocalName(body, 'moveFrom'); removeAllByLocalName(body, 'moveFromRangeStart'); removeAllByLocalName(body, 'moveFromRangeEnd'); removeAllByLocalName(body, 'moveToRangeStart'); removeAllByLocalName(body, 'moveToRangeEnd'); // Phase C — Unwrap insertions and move destinations (depth-sorted) const insertionsAccepted = unwrapAllByLocalName(body, 'ins'); const moveToUnwrapped = unwrapAllByLocalName(body, 'moveTo'); // Phase D — Remove property change records let propertyChangesResolved = 0; for (const localName of PR_CHANGE_LOCALS) { propertyChangesResolved += removeAllByLocalName(body, localName); } // Phase E — Cleanup // Strip paragraph-level revision markers from w:pPr/w:rPr for (const p of collectByLocalName(body, 'p')) { for (let i = 0; i < p.childNodes.length; i++) { const child = p.childNodes[i]!; if (!isW(child, 'pPr')) continue; for (let j = 0; j < child.childNodes.length; j++) { const pPrChild = child.childNodes[j]!; if (!isW(pPrChild, 'rPr')) continue; // Remove w:ins and w:del marker elements inside pPr > rPr const toRemove: Element[] = []; for (let k = 0; k < pPrChild.childNodes.length; k++) { const rPrChild = pPrChild.childNodes[k]!; if (isW(rPrChild, 'ins') || isW(rPrChild, 'del')) { toRemove.push(rPrChild as Element); } } for (const el of toRemove) { pPrChild.removeChild(el); } } } } // Remove paragraphs collected in Phase A (check parentNode still exists) for (const p of paragraphsToRemove) { if (p.parentNode) { p.parentNode.removeChild(p); } } // Strip w:rsidDel attributes on remaining elements const allElements = body.getElementsByTagNameNS(W_NS, '*'); for (let i = 0; i < allElements.length; i++) { const el = allElements[i]!; if (el.hasAttributeNS(W_NS, 'rsidDel')) { el.removeAttributeNS(W_NS, 'rsidDel'); } // Also check prefixed form if (el.hasAttribute('w:rsidDel')) { el.removeAttribute('w:rsidDel'); } } return { insertionsAccepted, deletionsAccepted, movesResolved: moveFromRemoved + moveToUnwrapped, propertyChangesResolved, }; } - packages/docx-mcp/src/tool_catalog.ts:206-206 (registration)Registration of the 'accept_changes' tool in the tool catalog.
name: 'accept_changes',