Skip to main content
Glama
andr3medeiros

PDF Manipulation MCP Server

pdf_add_image

Add images to PDF documents by specifying exact page positions and dimensions to enhance or annotate content.

Instructions

Add an image to a PDF.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pdf_pathYes
page_numberYes
image_pathYes
xYes
yYes
widthYes
heightYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The handler function for the 'pdf_add_image' tool. It validates the input PDF and image paths, opens the PDF using PyMuPDF (fitz), adds the image to the specified page at given coordinates and size, generates a timestamped output filename, saves the modified PDF, and returns the output path.
    @mcp.tool()
    async def pdf_add_image(
        pdf_path: str,
        page_number: int,
        image_path: str,
        x: float,
        y: float,
        width: float,
        height: float
    ) -> str:
        """Add an image 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}"
        
        if not os.path.exists(image_path):
            return f"Error: Image file not found: {image_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 image placement
            rect = fitz.Rect(x, y, x + width, y + height)
            
            # Add image to the page
            page.insert_image(rect, filename=image_path)
            
            # Generate output filename
            output_path = generate_output_filename(pdf_path)
            
            # Save the modified PDF
            doc.save(output_path)
            doc.close()
            
            return f"Successfully added image to PDF. Output saved to: {output_path}"
            
        except Exception as e:
            return f"Error adding image to PDF: {str(e)}"
  • Helper utility used by pdf_add_image (and other tools) 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 used by pdf_add_image to validate that the input file is a valid PDF.
    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 used by pdf_add_image 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)

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.0.0
    • addedInput schema / title
      Added value: +"pdf_add_imageArguments"
  2. First observed

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. 'Add an image' implies mutation, but it does not explain whether the PDF is modified in place, what coordinate system is used, or what the output will be. Critical behavioral context such as file overwriting, page number validity, or error handling is absent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single short sentence, which is efficient and free of fluff. However, it is under-specified, bordering on terse, as it omits essential details. It is not as extreme as a tautology, but it sacrifices clarity for brevity, resulting in a middling score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is complex with 7 required parameters, no annotations, and no schema parameter descriptions. The description 'Add an image to a PDF' is grossly inadequate to guide an agent on how to correctly invoke it. It does not cover positioning, page selection, image scaling, or any other necessary operational context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description adds no meaning to any of the 7 required parameters. It does not explain what x, y, width, height represent, how page_number is used, or what image formats are accepted. The tool has many parameters, and the description fails to compensate for the complete lack of schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Add an image to a PDF' clearly states the action (add) and resource (image to a PDF). It distinguishes from siblings like pdf_add_text and pdf_add_annotation by specifying 'image' rather than other content types. However, it lacks any detail about placement or constraints, so it is not fully specific.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives like pdf_add_text or pdf_add_annotation. The description provides no context about suitable scenarios, prerequisites, or when other tools should be preferred. It gives no usage directions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.