Skip to main content
Glama

replace_block_between_manual_anchors

Automatically replace content between specified start and end anchor texts in Microsoft Word documents using defined paragraphs.

Instructions

Replace all content between start_anchor_text and end_anchor_text (or next logical header if not provided).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
end_anchor_textNo
filenameYes
match_fnNo
new_paragraph_styleNo
new_paragraphsYes
start_anchor_textYes

Implementation Reference

  • MCP tool registration with @mcp.tool() decorator. This is the entry point for the tool named 'replace_block_between_manual_anchors', which delegates to the async handler.
    @mcp.tool() def replace_block_between_manual_anchors(filename: str, start_anchor_text: str, new_paragraphs: list, end_anchor_text: str = None, match_fn=None, new_paragraph_style: str = None): """Replace all content between start_anchor_text and end_anchor_text (or next logical header if not provided).""" return replace_block_between_manual_anchors_tool(filename, start_anchor_text, new_paragraphs, end_anchor_text, match_fn, new_paragraph_style)
  • Async tool handler function that performs the core operation by calling the utility function in document_utils.
    async def replace_block_between_manual_anchors_tool(filename: str, start_anchor_text: str, new_paragraphs: list, end_anchor_text: str = None, match_fn=None, new_paragraph_style: str = None) -> str: """Replace all content between start_anchor_text and end_anchor_text (or next logical header if not provided).""" return replace_block_between_manual_anchors(filename, start_anchor_text, new_paragraphs, end_anchor_text, match_fn, new_paragraph_style)
  • Core implementation of the replace_block_between_manual_anchors functionality. This utility function handles the low-level XML manipulation to find anchors, remove content between them, and insert new paragraphs.
    def replace_block_between_manual_anchors( doc_path: str, start_anchor_text: str, new_paragraphs: list, end_anchor_text: str = None, match_fn=None, new_paragraph_style: str = None ) -> str: """ Replace all content (paragraphs, tables, etc.) between start_anchor_text and end_anchor_text (or next logical header if not provided). If end_anchor_text is None, deletes until next visually distinct paragraph (bold, all caps, or different font size), or end of document. Inserts new_paragraphs after the start anchor. """ from docx import Document import os if not os.path.exists(doc_path): return f"Document {doc_path} not found." doc = Document(doc_path) body = doc.element.body elements = list(body) start_idx = None end_idx = None # Find start anchor for i, el in enumerate(elements): if el.tag == CT_P.tag: p_text = "".join([node.text or '' for node in el.iter() if node.tag.endswith('}t')]).strip() if match_fn: if match_fn(p_text, el): start_idx = i break elif p_text == start_anchor_text.strip(): start_idx = i break if start_idx is None: return f"Start anchor '{start_anchor_text}' not found." # Find end anchor if end_anchor_text: for i in range(start_idx + 1, len(elements)): el = elements[i] if el.tag == CT_P.tag: p_text = "".join([node.text or '' for node in el.iter() if node.tag.endswith('}t')]).strip() if match_fn: if match_fn(p_text, el, is_end=True): end_idx = i break elif p_text == end_anchor_text.strip(): end_idx = i break else: # Heuristic: next visually distinct paragraph (bold, all caps, or different font size), or end of document for i in range(start_idx + 1, len(elements)): el = elements[i] if el.tag == CT_P.tag: # Check for bold, all caps, or font size runs = [node for node in el.iter() if node.tag.endswith('}r')] for run in runs: rpr = run.find(qn('w:rPr')) if rpr is not None: if rpr.find(qn('w:b')) is not None or rpr.find(qn('w:caps')) is not None or rpr.find(qn('w:sz')) is not None: end_idx = i break if end_idx is not None: break # Mark elements for removal to_remove = [] for i in range(start_idx + 1, end_idx if end_idx is not None else len(elements)): to_remove.append(elements[i]) for el in to_remove: body.remove(el) doc.save(doc_path) # Reload and find start anchor for insertion doc = Document(doc_path) paras = doc.paragraphs anchor_idx = None for i, para in enumerate(paras): if para.text.strip() == start_anchor_text.strip(): anchor_idx = i break if anchor_idx is None: return f"Start anchor '{start_anchor_text}' not found after deletion (unexpected)." anchor_para = paras[anchor_idx] style_to_use = new_paragraph_style or "Normal" for text in new_paragraphs: new_para = doc.add_paragraph(text, style=style_to_use) anchor_para._element.addnext(new_para._element) anchor_para = new_para doc.save(doc_path) return f"Replaced content between '{start_anchor_text}' and '{end_anchor_text or 'next logical header'}' with {len(new_paragraphs)} paragraph(s), style: {style_to_use}, removed {len(to_remove)} elements."

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/GongRzhe/Office-Word-MCP-Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server