Skip to main content
Glama

Seamless PDF Skill

Edit PDFs so nobody can tell, plus 67 document tools, for AI agents.

Seamless PDF lets an AI agent (or you) change what is written in an existing PDF: a date, an amount, a name, a typo. The new text is drawn with the document's own embedded font, at the original baseline, size, colour and spacing, and in its original place in the drawing order. Nothing else on the page moves, and a watermark stays behind the table drawn over it.

It also has 67 whole-document tools: merge, split, compress, convert to and from PDF, protect, redact, sign, OCR, compare, watermark, forms and e-invoices.

You can use it in three ways:

Way

For

Start with

Agent Skill

Claude Code and other agents that read SKILL.md and run shell commands

seamless-pdf install-skill

MCP server

Claude Desktop, Claude Code, Cursor, any MCP client

seamless-pdf-mcp

CLI / Python library

scripts, pipelines, your own agent

seamless-pdf --help, from seamless_pdf import Workspace

Everything runs locally. No API key is needed, and nothing is uploaded anywhere.


Contents


Related MCP server: pdf-toolbox-mcp

Features

Editing what is on the page

  • Text: replace, restyle (size, colour, bold, italic, font family), move, delete or insert text. Find-and-replace across the document. Right-aligned and centred columns stay aligned when the text gets longer or shorter.

  • Fonts: edits reuse the document's own font program, including subsetted TrueType, Type1 and Type0/CID fonts. A character the subset lacks falls back, for that character alone, to the closest standard font, then to an embedded DejaVu Sans subset (Latin, Greek, Cyrillic, ₹, →, ...).

  • Images: insert, replace, move, resize or delete images, without re-encoding them and with masks kept.

  • Annotations: highlight, underline, strikeout, squiggly, sticky note, free text, rectangle, circle and line, each with a real appearance stream so every viewer shows it.

  • Forms: list, fill, add, move and delete form fields; flatten forms.

  • Scanned pages: OCR them (Tesseract), then edit or move scanned words. The paper and ink colours are sampled so the patch blends in.

  • Undo/redo: every operation is atomic. A batch of steps is all-or-nothing.

  • Look before and after: render any page or zoomed area to PNG.

67 document tools

Category

Tools

Create

Create PDF from Markdown/HTML/text, cards (business, postcard, greeting, invitation, place card), photo collage, fillable PDF form, job application bundle, QR code

Edit

Watermark (text/image, tiled), page numbers, overlay/letterhead, crop, change page size, metadata, viewer preferences, flatten, make fillable (auto-detects blanks), bulk form fill, add QR code

Organize

Merge, assemble pages from several PDFs, split (every N, ranges, bookmarks), rearrange, remove, extract, rotate, insert blank pages, n-up, halve pages, bookmarks (incl. auto from headings), extract images, extract text/Markdown

Optimize

Compress (4 levels, grayscale), web optimize (linearize), OCR, repair, rasterize

Security

Protect (AES-256 + permissions), unlock, redact (terms, regex, presets for email/phone/IBAN/card/SSN/date/URL; the text is removed from the file), remove metadata, generate passwords, visual signature, digital signature (PAdES, your .p12 or self-signed), verify signatures

View & check

Compare PDFs (text diff + visual diff PDF), search across PDFs, basic PDF/A check, document info

Convert to PDF

Word, PowerPoint, Excel, Publisher, OpenDocument, RTF, images (JPG, PNG, WEBP, HEIC, TIFF, GIF, BMP, SVG), text, Markdown, HTML, EPUB, CBZ, web pages

Convert from PDF

Excel (tables), PowerPoint, ODS, ODP, EPUB, HTML, Markdown, text, PNG, JPG, TIFF, WEBP

Invoices

Create invoice, e-invoice (Factur-X/ZUGFeRD EN 16931, CII and UBL XML), PDF invoice to e-invoice, XML e-invoice to PDF, validate e-invoice

Every tool, with all options, is listed in reference/tools.md. PDF to Word and PDF/A conversion are not included, because every free converter of good quality for them is AGPL.


Install

Python 3.11 or newer.

pip install "seamless-pdf[mcp] @ git+https://github.com/nishantsirohi23/seamless-pdf-skill.git"
seamless-pdf --version

Leave out [mcp] if you only need the CLI and skill. To work on the code:

git clone https://github.com/nishantsirohi23/seamless-pdf-skill.git
cd seamless-pdf-skill
python -m venv .venv && .venv/bin/pip install -e ".[mcp]"

Optional system programs

The editor and most tools need nothing else. A few tools call these programs, and seamless-pdf tools marks a tool unavailable (with the reason) when its program is missing:

Program

Used for

macOS

Debian/Ubuntu

Tesseract

OCR of scanned pages

brew install tesseract

apt install tesseract-ocr

LibreOffice

Word/Excel/PowerPoint/OpenDocument to PDF, PDF to ODS/ODP

brew install --cask libreoffice

apt install libreoffice

Chrome or Chromium

HTML, Markdown, text, cards, invoices and web pages to PDF

Google Chrome

apt install chromium

pandoc

EPUB in and out

brew install pandoc

apt install pandoc


Use as an Agent Skill

The skill is a folder with a SKILL.md that teaches the agent the workflow, the conventions and the commands, plus generated reference files listing every operation and tool.

Claude Code: install it into your personal skills folder:

seamless-pdf install-skill            # copies to ~/.claude/skills/seamless-pdf

Use --dest .claude/skills to install it into one project instead. Claude then uses it whenever a task involves a PDF, for example "change the due date in invoice.pdf to 30 April and compress it for email".

Other agents: point them at src/seamless_pdf/skill/seamless-pdf/SKILL.md. It only assumes the agent can run shell commands and read JSON.


Use as an MCP server

The server speaks MCP over stdio. Documents are opened by local path, kept in memory while you edit, and written back with save_pdf.

Claude Code

claude mcp add seamless-pdf -s user -- seamless-pdf-mcp

Claude Desktop: add to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/), using the full path from which seamless-pdf-mcp:

{
  "mcpServers": {
    "seamless-pdf": { "command": "/full/path/to/seamless-pdf-mcp" }
  }
}

Any other MCP client: command seamless-pdf-mcp (or seamless-pdf mcp), transport stdio, no arguments, no environment variables.

MCP tools

Tool

What it does

open_pdf(path)

Open a PDF; returns doc_id and an overview

get_page_objects(doc_id, page, kinds?)

Text segments, images, annotations, fields with ids and boxes

find_text(doc_id, query, match_case?)

Segments containing a string, with ids

get_text(doc_id, pages?)

Plain text

list_form_fields(doc_id)

Fields with names, types and values

view_page(doc_id, page, clip?, scale?)

PNG of a page or a zoomed area

edit_pdf(doc_id, steps)

Apply editing operations atomically, as one undo step

list_operations()

Full JSON schemas of the editing operations

undo(doc_id) / redo(doc_id)

History

save_pdf(doc_id, path)

Write the current state to disk

list_pdf_tools(category?)

Catalog of the 67 document tools with option schemas

run_pdf_tool(tool, inputs?, options?, out_dir?)

Run a document tool on paths or ids

list_open_files()

Everything opened or produced in this session

A typical agent turn: open_pdf, find_text, edit_pdf, view_page to check, then save_pdf.


CLI guide

Every command prints JSON on stdout (render writes a PNG and prints its path). Errors are JSON on stderr with exit code 1, so agents can read them and retry.

Inspect

seamless-pdf info contract.pdf                       # pages, sizes, scanned pages, form
seamless-pdf text contract.pdf --pages 0,1           # plain text
seamless-pdf find contract.pdf "March 3"             # text segments + ids
seamless-pdf objects contract.pdf --page 0 --kinds text,image
seamless-pdf fields form.pdf                         # form fields
seamless-pdf render contract.pdf --page 0 --clip 60,80,320,120 -o zoom.png

find returns segments like:

{"id": "t:0:72.0:92.0", "kind": "text", "page": 0,
 "text": "Amount due: $4,120.50 by March 3",
 "bbox": [72.0, 83.26, 259.45, 94.53], "font": "ArialMT", "size": 12.0, "color": "#000000"}

Edit

One operation:

seamless-pdf edit contract.pdf --op edit_text --args '{"id": "t:0:72.0:92.0", "text": "Amount due: $4,120.50 by April 30"}' -o contract-v2.pdf

Several, as one batch (all-or-nothing; ids renamed by an earlier step are followed). Pass --script - to read the steps from stdin:

seamless-pdf edit contract.pdf --script steps.json -o contract-v2.pdf
[
  {"op": "replace_all", "args": {"find": "Acme GmbH", "replace": "Globex AG"}},
  {"op": "edit_text", "args": {"id": "t:0:446.6:192.0", "text": "$1,250.00", "color": "#cc0000"}},
  {"op": "insert_text", "args": {"page": 0, "x": 72, "y": 760, "text": "Approved 23 April 2026"}},
  {"op": "insert_image", "args": {"page": 0, "image_path": "stamp.png", "rect": [420, 700, 540, 780]}},
  {"op": "add_annotation", "args": {"page": 0, "kind": "highlight", "target_text": "$1,250.00"}}
]

seamless-pdf ops prints every operation with its JSON schema.

Document tools

seamless-pdf tools                                   # catalog
seamless-pdf tools --category Security
seamless-pdf tool-info redact_pdf                    # one tool's options
seamless-pdf run merge_pdfs a.pdf b.pdf c.pdf --out-dir out/
seamless-pdf run compress_pdf scan.pdf --opt level=high
seamless-pdf run protect_pdf report.pdf --opt user_password=s3cret --opt allow_print=false
seamless-pdf run redact_pdf hr.pdf --opt 'presets=["email","phone","iban"]' -o hr-redacted.pdf
seamless-pdf run ocr_pdf scan.pdf -o scan-searchable.pdf
seamless-pdf run convert_to_pdf letter.docx photo.heic notes.md --opt merge=true
seamless-pdf run pdf_to_excel statement.pdf
seamless-pdf run digital_sign_pdf contract.pdf --opt signer_name="Jane Doe" --opt visible=true
  • --opt key=value values are parsed as JSON when they can be (numbers, true/false, lists, objects) and are strings otherwise. --options '{...}' gives all options at once.

  • In-place tools (watermark, page numbers, redact, sign, OCR, rotate, ...) change the PDF and save it to -o (default <name>-<tool>.pdf).

  • The other tools create new files. With -o, a single result is saved there; several results (split, PDF to images) go into that file's folder under their own names. Without -o they go to --out-dir (default: next to the first input). The JSON lists every file with its real path, size and page count. Your input file is never overwritten unless you pass its own path to -o.


Python library

from seamless_pdf import Workspace

ws = Workspace()
doc = ws.add("invoice.pdf")                     # PDFs become editable documents

hit = ws.op(doc, "find_text", {"query": "March 3"})["result"]["matches"][0]
ws.op(doc, "edit_text", {"id": hit["id"], "text": "Amount due: $4,120.50 by April 30"})
ws.script(doc, [                                # several steps; renamed ids followed
    {"op": "add_annotation", "args": {"page": 0, "kind": "highlight", "target_text": "April 30"}},
])
ws.save(doc, "invoice-v2.pdf")

out = ws.run_tool("compress_pdf", ["invoice-v2.pdf"], {"level": "high"}, out_dir="out")
print(out["outputs"][0]["path"])

png = ws.doc(doc).render_page(0, scale=2.0)     # bytes of a PNG

PdfDoc (from seamless_pdf) is the engine itself, if you want to work at that level: PdfDoc(data).text_objects(0), .edit_text(id, text), .undo(), .to_bytes().


Editing operations

Operation

Purpose

get_document_info, get_page_objects, find_text, get_document_text, list_form_fields, view_page

Read (no changes)

edit_text

Replace and/or restyle one text segment in place

replace_all

Find and replace across the document

insert_text

New text at a point (matches nearby style)

delete_objects, move_objects, set_object_rect

Any object by id

insert_image, replace_image

Images (image_path or asset_id)

add_annotation, update_annotation

Markup, notes, shapes

set_field_value, add_form_field, flatten_forms

Forms

ocr_page

Make a scanned page editable

undo, redo

History

Arguments and types for each: reference/operations.md.


Document tools

See the features table above and the full generated reference, reference/tools.md, which lists every option, default and alias.


Conventions

  • Pages: editing commands and operations use 0-based indexes. Document tools use 1-based ranges (1-3,5, odd, even, last, all), like a print dialog.

  • Coordinates: PDF points (1/72 inch), origin at the top-left of the unrotated page, rects as [x0, y0, x1, y1].

  • Ids: t: text segment, i: image, a: annotation, w: form field. Ids are stable across runs for unchanged content; an edited segment may get a new id (the result's new_ids maps old to new).

  • Segments: a run of same-style text on one line; table cells are separate segments. edit_text replaces a whole segment's text.


How the seamless edit works

  1. Locate. A content-stream interpreter tracks the complete graphics and text state (CTM, text matrix, font, size, character and word spacing, horizontal scaling, rise, render mode, colour, transparency) through every page and form XObject. It records each glyph's position and its exact place in the stream. Glyph positions agree with PDFium's to within 0.13 pt in the tests (0.00 pt on most fonts).

  2. Erase exactly. The edited glyphs' bytes are replaced in their TJ arrays by spacing numbers equal to their advance. Nothing else moves, and nothing above or below is clipped, however tight the line spacing.

  3. Redraw with the same font. The new text uses the original font resource with the same matrix, size and spacing, and goes into the same content stream right after the original text object, so it keeps its place in the stacking order. Unicode is mapped to the font's codes through /ToUnicode or its encoding. For subset fonts only glyphs the document already contains are used. Anything else falls back per character, and the result reports font_matched: false.

  4. Keep the layout. Right-aligned and centred text keeps its edge or centre fixed.

Built only on permissively licensed libraries: pikepdf/qpdf (object model), PDFium via pypdfium2 (rendering), fontTools, ReportLab, pdfplumber and pyHanko.


Recipes

Update a date everywhere and sign

seamless-pdf edit agreement.pdf --op replace_all --args '{"find": "1 March 2026", "replace": "23 April 2026"}' -o a2.pdf
seamless-pdf run sign_pdf a2.pdf --opt name="Jane Doe" -o a2-signed.pdf

Make a scanned letter editable and fix a word

seamless-pdf run ocr_pdf letter-scan.pdf -o letter-ocr.pdf
seamless-pdf find letter-ocr.pdf "recieved"
seamless-pdf edit letter-ocr.pdf --op edit_text --args '{"id": "t:0:118.4:233.0", "text": "received"}' -o letter-fixed.pdf

Share a document safely

seamless-pdf run redact_pdf contract.pdf --opt 'presets=["email","phone"]' --opt 'terms=["Project Falcon"]' -o r.pdf
seamless-pdf run remove_metadata r.pdf -o r-clean.pdf
seamless-pdf run protect_pdf r-clean.pdf --opt user_password=open-me

Photos to one small PDF

seamless-pdf run images_to_pdf IMG_1.heic IMG_2.heic IMG_3.jpg --opt page_size=A4 --out-dir out/
seamless-pdf run compress_pdf out/images.pdf --opt level=high

Testing

.venv/bin/python tests/test_engine.py     # engine: pixel diffs, glyph positions, fonts, stacking order, OCR
.venv/bin/python tests/test_tools.py      # every document tool on real inputs
.venv/bin/python tests/test_package.py    # CLI + MCP server as subprocesses, skill docs vs code

The tests read outputs back with PDFium and pdfminer, never with the code under test. They check that an edited line changes no pixels outside itself, that unchanged glyphs keep their x positions in subset fonts, and that edited text stays behind content drawn over it. Every command in SKILL.md and this README must parse with the real CLI and name a real tool, and the reference files must match the code (python scripts/gen_reference.py --check). Adding a tool without a test fails the suite.


Limits

  • An edit redraws one segment; it does not reflow a paragraph. Longer text extends along the baseline.

  • Vector drawings (lines, shapes) are not selectable objects.

  • Scanned-word edits use Helvetica or Times, matched to the ink. There is no font in a scan to reuse, so unusual typefaces will not match exactly.

  • The Unicode fallback has no CJK or Indic glyphs; those characters show as ?.

  • Editing a digitally signed PDF invalidates its signature. That is how signatures are meant to work.

  • Not included: PDF to Word, PDF/A conversion, XPS/MOBI input.

Licence

MIT, see LICENSE. Bundled fonts and dependency licences are listed in THIRD_PARTY_NOTICES.md.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to perform comprehensive PDF operations locally, including compression, text extraction, PII redaction, page organization, splitting, merging, watermarking, creation, and form filling, all without cloud uploads.
    11 npm
    -
  • A
    license
    B
    quality
    A
    maintenance
    Enables AI agents to perform local-first PDF processing entirely on-device, including OCR write-back to make scans searchable, unlocking and re-encrypting PDFs, splitting/merging/rotating pages, and compressing files, with no cloud calls or file uploads.
    25
    1
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to inspect and work with PDF files entirely on the local machine, covering page counts, metadata, layout, encryption permissions, scan-vs-text detection, and page rendering. Generated results land in a temporary workspace as short artifact ids that can be chained between tools and exported to real folders on request.
    12
    51 PyPI
    1
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    It enables AI agents and MCP clients to read, fill, create, export, and reconstruct fillable PDF forms, plus extract, search, and edit text and layout blocks, entirely against local files over stdio.
    Apache 2.0