Skip to main content
Glama

add_footnote

Add explanatory footnotes to DOCX documents by anchoring them to specific paragraphs. Insert references after designated text or at paragraph ends to provide citations and additional context while preserving document formatting.

Instructions

Add a footnote anchored to a paragraph. Optionally position the reference after specific text using after_text. Note: [^N] markers in read_file output are display-only and not part of the editable text used by replace_text.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
file_pathYesPath to the DOCX file.
target_paragraph_idYesParagraph ID to anchor the footnote to.
after_textNoText after which to insert the footnote reference. If omitted, appends at end of paragraph.
textYesFootnote body text.

Implementation Reference

  • The MCP tool handler for 'add_footnote', which validates input, resolves the document session, and calls the low-level docx-core addFootnote implementation.
    export async function addFootnote(
      manager: SessionManager,
      params: {
        file_path?: string;
        target_paragraph_id?: string;
        after_text?: string;
        text?: string;
      },
    ): Promise<ToolResponse> {
      const resolved = await resolveSessionForTool(manager, params, { toolName: 'add_footnote' });
      if (!resolved.ok) return resolved.response;
      const { session, metadata } = resolved;
    
      if (!params.target_paragraph_id) {
        return err('MISSING_PARAMETER', 'target_paragraph_id is required.', 'Provide the _bk_* ID of the paragraph to anchor the footnote to.');
      }
      if (!params.text) {
        return err('MISSING_PARAMETER', 'text is required.', 'Provide the footnote body text.');
      }
    
      const pid = params.target_paragraph_id;
      const pEl = session.doc.getParagraphElementById(pid);
      if (!pEl) {
        return err('ANCHOR_NOT_FOUND', `Paragraph ID ${pid} not found in document`, 'Use grep or read_file to find valid paragraph IDs.');
      }
    
      try {
        const result = await session.doc.addFootnote({
          paragraphId: pid,
          afterText: params.after_text,
          text: params.text,
        });
    
        manager.markEdited(session);
        return ok(mergeSessionResolutionMetadata({
          note_id: result.noteId,
          target_paragraph_id: pid,
          after_text: params.after_text ?? null,
          file_path: manager.normalizePath(session.originalPath),
        }, metadata));
      } catch (e: unknown) {
        const msg = errorMessage(e);
        if (msg.includes('not found in paragraph')) {
          return err('TEXT_NOT_FOUND', msg, 'Verify after_text is present in the target paragraph.');
        }
        if (msg.includes('found') && msg.includes('times')) {
          return err('MULTIPLE_MATCHES', msg, 'Provide more specific after_text for a unique match.');
        }
        return err('FOOTNOTE_ERROR', msg);
      }
    }
  • The core implementation of adding a footnote to a DOCX document, handling XML structure for footnotes.xml and updating document references.
    export async function addFootnote(
      documentXml: Document,
      zip: DocxZip,
      params: AddFootnoteParams,
    ): Promise<AddFootnoteResult> {
      const { paragraphEl, afterText, text } = params;
    
      // Load or bootstrap footnotes.xml
      const footnotesXml = await zip.readText('word/footnotes.xml');
      const footnotesDoc = parseXml(footnotesXml);
    
      // Allocate next ID
      const noteId = allocateNextFootnoteId(footnotesDoc);
    
      // Insert footnoteReference run in document body
      insertFootnoteReference(documentXml, paragraphEl, noteId, afterText);
    
      // Add footnote body to footnotes.xml
      addFootnoteElement(footnotesDoc, noteId, text);
      zip.writeText('word/footnotes.xml', serializeXml(footnotesDoc));
    
      return { noteId };
    }

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/UseJunior/safe-docx'

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