pdf_add_annotation
Add annotations to PDF documents by specifying page location, type, and content for marking up files with notes, highlights, or comments.
Instructions
Add an annotation to a PDF.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| pdf_path | Yes | ||
| page_number | Yes | ||
| annotation_type | Yes | ||
| x | Yes | ||
| y | Yes | ||
| width | Yes | ||
| height | Yes | ||
| content | Yes |
Implementation Reference
- The core handler function for the 'pdf_add_annotation' tool. It adds annotations of types 'text', 'highlight', 'underline', or 'strikeout' to a specified position on a PDF page using PyMuPDF (fitz). Includes validation, generates timestamped output file, and returns success/error message.async def pdf_add_annotation( pdf_path: str, page_number: int, annotation_type: str, x: float, y: float, width: float, height: float, content: str ) -> str: """Add an annotation to a PDF.""" if not os.path.exists(pdf_path): return f"Error: PDF file not found: {pdf_path}" if not validate_pdf_file(pdf_path): return f"Error: Invalid PDF file: {pdf_path}" try: # Open PDF document doc = fitz.open(pdf_path) # Validate page number if not validate_page_number(doc, page_number): doc.close() return f"Error: Invalid page number {page_number}. Document has {len(doc)} pages." # Get the page page = doc[page_number] # Create rectangle for annotation rect = fitz.Rect(x, y, x + width, y + height) # Add annotation based on type if annotation_type == "text": annot = page.add_text_annot(rect, content) elif annotation_type == "highlight": annot = page.add_highlight_annot(rect) annot.set_info(content=content) elif annotation_type == "underline": annot = page.add_underline_annot(rect) annot.set_info(content=content) elif annotation_type == "strikeout": annot = page.add_strikeout_annot(rect) annot.set_info(content=content) else: doc.close() return f"Error: Invalid annotation type: {annotation_type}" # Update annotation appearance annot.update() # Generate output filename output_path = generate_output_filename(pdf_path) # Save the modified PDF doc.save(output_path) doc.close() return f"Successfully added {annotation_type} annotation to PDF. Output saved to: {output_path}" except Exception as e: return f"Error adding annotation to PDF: {str(e)}"
- pdf_manipulation_mcp_server/pdf_server.py:268-268 (registration)The @mcp.tool() decorator registers the pdf_add_annotation function as an MCP tool in the FastMCP server instance.async def pdf_add_annotation(
- Utility function used by pdf_add_annotation (and others) to generate a timestamped output filename to prevent overwriting the original PDF.def generate_output_filename(input_path: str, suffix: str = "modified") -> str: """Generate a new filename with timestamp to avoid overwriting originals.""" path = Path(input_path) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") return str(path.parent / f"{path.stem}_{suffix}_{timestamp}{path.suffix}")
- Helper function called by pdf_add_annotation to validate the input PDF file.def validate_pdf_file(pdf_path: str) -> bool: """Validate that the file is a valid PDF.""" try: doc = fitz.open(pdf_path) doc.close() return True except Exception: return False
- Helper function called by pdf_add_annotation to check if the specified page number is valid.def validate_page_number(doc: fitz.Document, page_num: int) -> bool: """Validate that the page number exists in the document.""" return 0 <= page_num < len(doc)