Skip to main content
Glama

delete_footnote_from_document

Remove footnotes from Word documents by specifying the footnote ID or searching for nearby text. This tool helps clean up document formatting and eliminate unwanted references.

Instructions

Delete a footnote from a Word document. Identify the footnote either by ID (1, 2, 3, etc.) or by searching for text near it.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filenameYes
footnote_idNo
search_textNo
output_filenameNo

Implementation Reference

  • Registers the MCP tool 'delete_footnote_from_document' using FastMCP decorator and delegates to the implementation in footnote_tools.
    @mcp.tool() def delete_footnote_from_document(filename: str, footnote_id: int = None, search_text: str = None, output_filename: str = None): """Delete a footnote from a Word document. Identify the footnote either by ID (1, 2, 3, etc.) or by searching for text near it.""" return footnote_tools.delete_footnote_from_document( filename, footnote_id, search_text, output_filename )
  • Direct handler called by the registered tool. Performs file checks and invokes the core delete_footnote_robust implementation from core/footnotes.
    async def delete_footnote_from_document(filename: str, footnote_id: Optional[int] = None, search_text: Optional[str] = None, output_filename: Optional[str] = None) -> str: """Delete a footnote from a Word document. You can identify the footnote to delete either by: 1. footnote_id: The numeric ID of the footnote (1, 2, 3, etc.) 2. search_text: Text near the footnote reference to find and delete Args: filename: Path to the Word document footnote_id: Optional ID of the footnote to delete (1-based) search_text: Optional text to search near the footnote reference output_filename: Optional output filename (if None, modifies in place) """ filename = ensure_docx_extension(filename) if not os.path.exists(filename): return f"Document {filename} does not exist" # Check if file is writeable is_writeable, error_message = check_file_writeable(filename) if not is_writeable: return f"Cannot modify document: {error_message}. Consider creating a copy first." try: # Use robust implementation with orphan cleanup success, message, details = delete_footnote_robust( filename=filename, footnote_id=footnote_id, search_text=search_text, output_filename=output_filename, clean_orphans=True ) return message except Exception as e: return f"Failed to delete footnote: {str(e)}"
  • Core handler function that performs the actual deletion by parsing and modifying the DOCX XML parts (document.xml and footnotes.xml), removing references and content, and optionally cleaning orphan footnotes.
    def delete_footnote_robust( filename: str, footnote_id: Optional[int] = None, search_text: Optional[str] = None, output_filename: Optional[str] = None, clean_orphans: bool = True ) -> Tuple[bool, str, Optional[Dict[str, Any]]]: """Delete a footnote with comprehensive cleanup.""" if not footnote_id and not search_text: return False, "Must provide either footnote_id or search_text", None if not os.path.exists(filename): return False, f"File not found: {filename}", None # Set working file working_file = output_filename if output_filename else filename if output_filename and filename != output_filename: import shutil shutil.copy2(filename, output_filename) try: # Read document parts with zipfile.ZipFile(filename, 'r') as zin: doc_xml = zin.read('word/document.xml') if 'word/footnotes.xml' not in zin.namelist(): return False, "No footnotes in document", None footnotes_xml = zin.read('word/footnotes.xml') # Parse documents doc_root = etree.fromstring(doc_xml) footnotes_root = etree.fromstring(footnotes_xml) nsmap = {'w': W_NS} # Find footnote to delete if search_text: # Find footnote reference near text for para in doc_root.xpath('//w:p', namespaces=nsmap): para_text = ''.join(para.xpath('.//w:t/text()', namespaces=nsmap)) if search_text in para_text: # Look for footnote reference in this paragraph fn_refs = para.xpath('.//w:footnoteReference', namespaces=nsmap) if fn_refs: footnote_id = int(fn_refs[0].get(f'{{{W_NS}}}id')) break if not footnote_id: return False, f"No footnote found near text '{search_text}'", None # Remove footnote reference from document refs_removed = 0 for fn_ref in doc_root.xpath(f'//w:footnoteReference[@w:id="{footnote_id}"]', namespaces=nsmap): # Remove the entire run containing the reference run = fn_ref.getparent() if run is not None and run.tag == f'{{{W_NS}}}r': para = run.getparent() if para is not None: para.remove(run) refs_removed += 1 if refs_removed == 0: return False, f"Footnote {footnote_id} not found", None # Remove footnote content content_removed = 0 for fn in footnotes_root.xpath(f'//w:footnote[@w:id="{footnote_id}"]', namespaces=nsmap): footnotes_root.remove(fn) content_removed += 1 # Clean orphans if requested orphans_removed = [] if clean_orphans: # Find all referenced IDs referenced_ids = set() for ref in doc_root.xpath('//w:footnoteReference', namespaces=nsmap): ref_id = ref.get(f'{{{W_NS}}}id') if ref_id: referenced_ids.add(ref_id) # Remove unreferenced footnotes (except separators) for fn in footnotes_root.xpath('//w:footnote', namespaces=nsmap): fn_id = fn.get(f'{{{W_NS}}}id') if fn_id and fn_id not in referenced_ids and fn_id not in ['-1', '0']: footnotes_root.remove(fn) orphans_removed.append(fn_id) # Write modified document temp_file = working_file + '.tmp' with zipfile.ZipFile(temp_file, 'w', zipfile.ZIP_DEFLATED) as zout: with zipfile.ZipFile(filename, 'r') as zin: for item in zin.infolist(): if item.filename == 'word/document.xml': zout.writestr(item, etree.tostring(doc_root, encoding='UTF-8', xml_declaration=True, standalone="yes")) elif item.filename == 'word/footnotes.xml': zout.writestr(item, etree.tostring(footnotes_root, encoding='UTF-8', xml_declaration=True, standalone="yes")) else: zout.writestr(item, zin.read(item.filename)) os.replace(temp_file, working_file) details = { 'footnote_id': footnote_id, 'references_removed': refs_removed, 'content_removed': content_removed, 'orphans_removed': orphans_removed } message = f"Successfully deleted footnote {footnote_id}" if orphans_removed: message += f" and {len(orphans_removed)} orphaned footnotes" return True, message, details except Exception as e: return False, f"Error deleting footnote: {str(e)}", None

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