# How to Manipulate PDF Documents Using Claude Skills: Complete Technical Guide

> Learn to manipulate PDF documents with Claude Skills. Automate form detection, field extraction, and filling using Python CLI commands with this technical guide from ComposioHQ.

- Repository: [Composio/awesome-claude-skills](https://github.com/composiohq/awesome-claude-skills)
- Tags: how-to-guide
- Published: 2026-08-29

---

**Claude Skills provide a script-driven toolkit under `document-skills/pdf/` that enables automated form detection, field extraction, and annotation-based filling through simple Python CLI commands.**

The ComposioHQ/awesome-claude-skills repository delivers a complete Python-based solution for manipulating PDF documents using Claude Skills. Located in the `document-skills/pdf/` directory, this bundle provides atomic scripts that handle everything from fillable form detection to raster image conversion. By orchestrating these utilities, Claude can execute end-to-end PDF workflows without requiring users to write boilerplate automation code.

## Architecture of the PDF Skill Bundle

The PDF manipulation capability is organized into three distinct functional layers. Each layer exposes specific CLI scripts that Claude invokes with structured arguments.

### Detection and Introspection Layer

The **detection** component determines whether a target PDF contains fillable form fields. The script [`document-skills/pdf/scripts/check_fillable_fields.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/document-skills/pdf/scripts/check_fillable_fields.py) leverages the **pypdf** library to call `PdfReader.get_fields()`, returning a status message indicating fillability.

For form introspection, [`extract_form_field_info.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/extract_form_field_info.py) traverses the PDF object tree to build a JSON schema. This output includes field IDs, page numbers, bounding boxes (rect coordinates), and field types, providing Claude with a structured map of the document's interactive elements.

### Form Manipulation Layer

When working with **fillable PDFs**, the script [`fill_fillable_fields.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/fill_fillable_fields.py) reads a [`field_values.json`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/field_values.json) file, validates values against the detected field types, patches a known **pypdf** bug, and writes the completed output PDF.

For **non-fillable PDFs**, [`fill_pdf_form_with_annotations.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/fill_pdf_form_with_annotations.py) converts image-space bounding boxes into PDF coordinates and injects `FreeText` annotations using **pypdf**. This allows Claude to "fill" static forms by overlaying text annotations at precise coordinates.

### Image Processing Layer

The [`convert_pdf_to_images.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/convert_pdf_to_images.py) script uses **pdf2image** (`convert_from_path`) to render each PDF page to a PNG image. This enables visual analysis, manual bounding-box creation, and OCR preprocessing when dealing with scanned documents or flat PDFs.

## Working with Fillable PDF Forms

For PDFs that contain native AcroForm fields, Claude follows a three-step pipeline using specific scripts from the repository.

### Step 1: Detect Fillable Fields

Begin by determining if the target document contains interactive form fields. Execute the detection script to check for fillability:

```bash
python document-skills/pdf/scripts/check_fillable_fields.py sample.pdf

```

The script outputs a clear status message. If the PDF contains fields, proceed to extraction. If not, use the annotation-based workflow described later.

### Step 2: Extract Field Metadata

Extract the complete field schema to understand what data the form expects. This generates a JSON file containing field identifiers, types, and geometric coordinates:

```bash
python document-skills/pdf/scripts/extract_form_field_info.py sample.pdf field_info.json

```

The resulting [`field_info.json`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/field_info.json) follows this structure:

```json
[
  {"field_id":"name","page":1,"type":"text","rect":[100,200,300,220]},
  {"field_id":"agree","page":1,"type":"checkbox","checked_value":"/On","unchecked_value":"/Off","rect":[350,210,360,220]}
]

```

### Step 3: Populate and Save

Create a [`field_values.json`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/field_values.json) file matching the extracted field IDs to your desired values:

```json
[
  {"field_id":"name","page":1,"value":"Alice"},
  {"field_id":"agree","page":1,"value":"/On"}
]

```

Execute the filling script to generate the completed document:

```bash
python document-skills/pdf/scripts/fill_fillable_fields.py sample.pdf field_values.json filled.pdf

```

The script validates input types against field definitions and handles low-level PDF updates automatically.

## Handling Non-Fillable PDFs via Annotations

When [`check_fillable_fields.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/check_fillable_fields.py) reports no interactive fields, use the annotation workflow to overlay text onto static documents.

### Convert PDF Pages to PNG

First, render the document pages to images for visual analysis or coordinate mapping:

```bash
mkdir images
python document-skills/pdf/scripts/convert_pdf_to_images.py sample.pdf images

```

This creates `images/page_1.png`, `images/page_2.png`, and subsequent files based on the page count. The script supports optional rescaling parameters for high-resolution analysis.

### Define Bounding Box Geometry

Create a [`fields.json`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/fields.json) file that maps label and entry areas using image-space coordinates. The schema requires page dimensions and field definitions:

```json
{
  "pages": [
    {"page_number":1,"image_width":1240,"image_height":1754}
  ],
  "form_fields": [
    {
      "page_number":1,
      "description":"Customer name",
      "label_bounding_box":[30,125,95,142],
      "entry_bounding_box":[100,125,280,142],
      "entry_text":{"text":"Alice","font_size":14}
    }
  ]
}

```

The `entry_bounding_box` defines where the FreeText annotation will appear. Claude can validate this geometry using [`check_bounding_boxes.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/check_bounding_boxes.py) (documented in the repository) to ensure labels and entries do not intersect.

### Add FreeText Annotations

Finally, apply the annotations to create a filled PDF:

```bash
python document-skills/pdf/scripts/fill_pdf_form_with_annotations.py sample.pdf fields.json annotated.pdf

```

The script converts image coordinates to PDF space, creates `FreeText` annotations with the specified font sizes, and embeds them in the output document. Claude reports the count of annotations added upon completion.

## Advanced Libraries and Performance Optimization

The [`reference.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/reference.md) file in `document-skills/pdf/` documents additional utilities for specialized requirements:

- **pypdfium2**: Offers high-performance rendering and image extraction when `pdf2image` throughput is insufficient
- **pdf-lib**: JavaScript-based library for browser-side PDF manipulation
- **pdfjs-dist**: Mozilla's PDF.js for web-based rendering
- **poppler-utils** and **qpdf**: Command-line tools for PDF repair, linearization, and advanced object inspection

These tools extend the core Python scripts for scenarios requiring OCR, batch processing, or low-level PDF structural manipulation.

## Summary

- **Claude Skills for PDF manipulation** reside in `document-skills/pdf/` and provide Python CLI scripts for form handling
- **Fillable PDFs** use [`check_fillable_fields.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/check_fillable_fields.py), [`extract_form_field_info.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/extract_form_field_info.py), and [`fill_fillable_fields.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/fill_fillable_fields.py) for native form field workflows
- **Non-fillable PDFs** require conversion to images via [`convert_pdf_to_images.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/convert_pdf_to_images.py) and annotation injection via [`fill_pdf_form_with_annotations.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/fill_pdf_form_with_annotations.py)
- **Core dependencies** include **pypdf** for document structure, **pdf2image** for rasterization, and optional libraries like **pypdfium2** for performance-critical rendering

## Frequently Asked Questions

### What Python libraries does the Claude PDF skill use?

The primary implementation relies on **pypdf** for reading, updating, and writing PDF files, and **pdf2image** (which wraps `poppler-utils`) for converting pages to PNG images. For advanced use cases documented in [`reference.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/reference.md), the repository supports **pypdfium2**, **pdf-lib**, **pdfjs-dist**, and command-line utilities like **qpdf**.

### How do I handle PDFs that don't have fillable form fields?

Use the annotation-based workflow. First run [`convert_pdf_to_images.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/convert_pdf_to_images.py) to render pages as images, then define bounding boxes in a [`fields.json`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/fields.json) file specifying image coordinates and text content. Finally, execute [`fill_pdf_form_with_annotations.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/fill_pdf_form_with_annotations.py) to add FreeText annotations at the calculated PDF coordinates, effectively overlaying text onto static documents.

### Where are the PDF manipulation scripts located in the repository?

All PDF-specific scripts reside in the `document-skills/pdf/scripts/` directory within the ComposioHQ/awesome-claude-skills repository. Key files include [`check_fillable_fields.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/check_fillable_fields.py) for detection, [`extract_form_field_info.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/extract_form_field_info.py) for metadata extraction, and [`fill_fillable_fields.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/fill_fillable_fields.py) for data population.

### Can I validate bounding boxes before adding annotations?

Yes. The repository includes [`check_bounding_boxes.py`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/check_bounding_boxes.py) (referenced in the architecture documentation) which reads a [`fields.json`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/fields.json) file and verifies that label and entry boxes do not intersect and meet minimum size requirements. This validation step prevents overlapping text annotations in the final output.