insert_numbered_list_near_text
Add bulleted or numbered lists before or after specific paragraphs in Word documents by text or index position.
Instructions
Insert a bulleted or numbered list before or after the target paragraph. Specify by text or paragraph index. Args: filename (str), target_text (str, optional), list_items (list of str), position ('before' or 'after'), target_paragraph_index (int, optional), bullet_type ('bullet' for bullets or 'number' for numbered lists, default: 'bullet').
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| target_text | No | ||
| list_items | No | ||
| position | No | after | |
| target_paragraph_index | No | ||
| bullet_type | No | bullet |
Implementation Reference
- word_document_server/main.py:141-144 (registration)MCP tool registration using @mcp.tool() decorator. Delegates to the content_tools handler.@mcp.tool() def insert_numbered_list_near_text(filename: str, target_text: str = None, list_items: list = None, position: str = 'after', target_paragraph_index: int = None, bullet_type: str = 'bullet'): """Insert a bulleted or numbered list before or after the target paragraph. Specify by text or paragraph index. Args: filename (str), target_text (str, optional), list_items (list of str), position ('before' or 'after'), target_paragraph_index (int, optional), bullet_type ('bullet' for bullets or 'number' for numbered lists, default: 'bullet').""" return content_tools.insert_numbered_list_near_text_tool(filename, target_text, list_items, position, target_paragraph_index, bullet_type)
- Async handler function in content_tools that invokes the core implementation from document_utils.async def insert_numbered_list_near_text_tool(filename: str, target_text: str = None, list_items: list = None, position: str = 'after', target_paragraph_index: int = None, bullet_type: str = 'bullet') -> str: """Insert a bulleted or numbered list before or after the target paragraph. Specify by text or paragraph index.""" return insert_numbered_list_near_text(filename, target_text, list_items, position, target_paragraph_index, bullet_type)
- Core implementation of the tool logic: finds target paragraph, creates list paragraphs, applies bullet/numbering via XML manipulation, inserts near target.def insert_numbered_list_near_text(doc_path: str, target_text: str = None, list_items: list = None, position: str = 'after', target_paragraph_index: int = None, bullet_type: str = 'bullet') -> str: """ Insert a bulleted or numbered list before or after the target paragraph. Specify by text or paragraph index. Skips TOC paragraphs in text search. Args: doc_path: Path to the Word document target_text: Text to search for in paragraphs (optional if using index) list_items: List of strings, each as a list item position: 'before' or 'after' (default: 'after') target_paragraph_index: Optional paragraph index to use as anchor bullet_type: 'bullet' for bullets (•), 'number' for numbers (1,2,3) (default: 'bullet') Returns: Status message """ import os from docx import Document if not os.path.exists(doc_path): return f"Document {doc_path} does not exist" try: doc = Document(doc_path) found = False para = None if target_paragraph_index is not None: if target_paragraph_index < 0 or target_paragraph_index >= len(doc.paragraphs): return f"Invalid target_paragraph_index: {target_paragraph_index}. Document has {len(doc.paragraphs)} paragraphs." para = doc.paragraphs[target_paragraph_index] found = True else: for i, p in enumerate(doc.paragraphs): # Skip TOC paragraphs if p.style and p.style.name.lower().startswith("toc"): continue if target_text and target_text in p.text: para = p found = True break if not found or para is None: return f"Target paragraph not found (by index or text). (TOC paragraphs are skipped in text search)" # Save anchor index before insertion if target_paragraph_index is not None: anchor_index = target_paragraph_index else: anchor_index = None for i, p in enumerate(doc.paragraphs): if p is para: anchor_index = i break # Determine numbering ID based on bullet_type num_id = 1 if bullet_type == 'bullet' else 2 # Use ListParagraph style for proper list formatting style_name = None for candidate in ['List Paragraph', 'ListParagraph', 'Normal']: try: _ = doc.styles[candidate] style_name = candidate break except KeyError: continue if not style_name: style_name = None # fallback to default new_paras = [] for item in (list_items or []): p = doc.add_paragraph(item, style=style_name) # Add bullet numbering XML - this is the fix! add_bullet_numbering(p, num_id=num_id, level=0) new_paras.append(p) # Move the new paragraphs to the correct position for p in reversed(new_paras): if position == 'before': para._element.addprevious(p._element) else: para._element.addnext(p._element) doc.save(doc_path) list_type = "bulleted" if bullet_type == 'bullet' else "numbered" if anchor_index is not None: return f"{list_type.capitalize()} list with {len(new_paras)} items inserted {position} paragraph (index {anchor_index})." else: return f"{list_type.capitalize()} list with {len(new_paras)} items inserted {position} the target paragraph." except Exception as e: return f"Failed to insert numbered list: {str(e)}"
- Helper function to add bullet or numbering formatting to paragraphs using direct XML manipulation.def add_bullet_numbering(paragraph, num_id=1, level=0): """ Add bullet/numbering XML to a paragraph. Args: paragraph: python-docx Paragraph object num_id: Numbering definition ID (1=bullets, 2=numbers, etc.) level: Indentation level (0=first level, 1=second level, etc.) Returns: The modified paragraph """ # Get or create paragraph properties pPr = paragraph._element.get_or_add_pPr() # Remove existing numPr if any (to avoid duplicates) existing_numPr = pPr.find(qn('w:numPr')) if existing_numPr is not None: pPr.remove(existing_numPr) # Create numbering properties element numPr = OxmlElement('w:numPr') # Set indentation level ilvl = OxmlElement('w:ilvl') ilvl.set(qn('w:val'), str(level)) numPr.append(ilvl) # Set numbering definition ID numId = OxmlElement('w:numId') numId.set(qn('w:val'), str(num_id)) numPr.append(numId) # Add to paragraph properties pPr.append(numPr) return paragraph