Pdfops MCP

Operações rápidas em arquivos PDF

Documentação

pdfops

Ferramentas PDF rápidas para agentes de IA.
Um único binário, 31 ferramentas, JSON na entrada e na saída. Funciona como CLI, servidor MCP e biblioteca Rust.

CI crates.io npm release MIT license

$ pdfops tables invoice.pdf --format markdown        # tables as tables, not as a blob of text
$ pdfops redact contract.pdf --text "Jan Kowalski" -o safe.pdf   # removed from the file, then verified
$ pdfops text scan.pdf --ocr --ocr-lang pol+eng      # OCR only where there is no text layer
$ pdfops stamp offer.pdf --image signature.png --x 380 --y 690 -o signed.pdf

Por que pdfops

  • Feito para agentes. Cada comando retorna um documento JSON, erros indicam o que fazer em seguida, e o texto pode ser lido sob um orçamento de caracteres com um ponto de retomada.
  • Tudo em um só lugar. Leitura, layout, tabelas, OCR, renderização, cirurgia de páginas, carimbo, redação, anotações, assinaturas, formulários, criptografia, inspeção e criação: 31 ferramentas em um único esquema.
  • Nada para configurar. Um único binário sem bibliotecas PDF, sem Python e sem runtime. Apenas OCR precisa de um programa extra, e o pdfops pode baixar os dados de idioma por conta própria.
  • Rápido. Arquivos abrem em milissegundos, independentemente do tamanho, e o trabalho em páginas roda em todos os núcleos. Veja os benchmarks.
  • Redação confiável. O conteúdo é excluído da página, não coberto, e o resultado é verificado por um segundo interpretador antes de qualquer gravação.
  • Seguro em arquivos que você não criou. Cada comando roda sob um limite de memória e um limite de tempo, o servidor MCP executa cada chamada em um processo próprio e pode ser confinado a um diretório, e cada comando é testado contra um corpus de 988 PDFs hostis e malformados no CI.
  • Sabe o que um arquivo está fazendo. scan relata scripts, ações que disparam sozinhas, programas anexados, nomes disfarçados e texto extraído que não pode ser visto, o vetor de injeção de prompt. sanitize remove o conteúdo ativo e prova isso escaneando o resultado.

Início rápido

Como servidor MCP, sem nada instalado previamente:

{
  "mcpServers": {
    "pdfops": { "command": "npx", "args": ["-y", "pdfops-cli", "mcp"] }
  }
}

Para Claude Code: claude mcp add pdfops -- npx -y pdfops-cli mcp.

As ferramentas são nomeadas pdf_info, pdf_text, pdf_redact e assim por diante, e aceitam os mesmos argumentos da CLI. Caminhos relativos são resolvidos em relação ao diretório de trabalho do servidor.

Para manter um agente dentro de uma pasta, adicione --root: todo caminho fora dela é recusado, incluindo caminhos que chegam dentro de um documento, e caminhos relativos são resolvidos em relação a ela.

{ "command": "npx", "args": ["-y", "pdfops-cli", "mcp", "--root", "/home/me/documents"] }

Instalação

MétodoComandoNecessita
npmnpm install -g pdfops-cli ou npx pdfops-cliNode 18+
Pré-compilado, via cargocargo binstall pdfopscargo-binstall
A partir do código-fontecargo install pdfopsRust 1.92+
Dockerdocker run --rm -i -v "$PWD:/work" ghcr.io/kayzedd/pdfops mcp --root /workDocker
Manualbaixe um arquivo e coloque pdfops no seu PATHnada

O pacote npm é chamado pdfops-cli e instala o comando pdfops. É um pequeno lançador: na primeira execução, ele baixa o binário para sua plataforma do release do GitHub, verifica-o contra a soma SHA-256 publicada e o armazena em cache. Os binários pré-compilados cobrem Linux (glibc e musl) e macOS em x86-64 e ARM64, e Windows em x86-64. A imagem Docker é Alpine com pdfops e tesseract com inglês; adicione -v para a pasta de trabalho.

OCR adicionalmente precisa do programa tesseract; nada mais precisa. Os dados de idioma são baixados sob solicitação, sem direitos de administrador:

pdfops ocr-langs                     # is tesseract there, which languages can be used
pdfops ocr-install --lang pol+eng    # download language data into the user's data directory
pdfops ocr-install --engine          # install tesseract itself where that needs no password

Ferramentas

ComandoO que faz
LeiturainfoContagem de páginas, tamanho da página, metadados, criptografia, sumário e resumo de formulários
textTexto página por página, com orçamento de caracteres e fallback opcional de OCR
searchEncontra texto ou uma regex, retorna páginas e trechos
layoutCaixa delimitadora, fonte e tamanho de cada linha ou palavra
tablesTabelas como linhas de células, Markdown ou CSV
outlineMarcadores com páginas de destino
annotationsRealces, comentários, links e outras marcações, com posições
signaturesAssinaturas digitais: quem assinou e se o documento mudou desde então
renderPáginas para PNG, para visualizar gráficos, digitalizações e layout
imagesAs imagens desenhadas nas páginas, como arquivos
ocrTexto reconhecido de páginas digitalizadas, opcionalmente gravado em uma cópia pesquisável
scanScripts, ações automáticas, anexos, conteúdo disfarçado e texto oculto, por gravidade
ConstruçãocreateUm novo PDF a partir de Markdown
mergeVários PDFs em um só
pagesManter, reordenar, duplicar ou excluir páginas
splitDividir por contagem de páginas ou por intervalos
EdiçãorotateGirar páginas em múltiplos de 90 graus
stampMarca d'água, cabeçalho, rodapé, números de página, uma imagem como assinatura ou um código QR
annotateAdicionar um realce, sublinhado, tachado, caixa, nota ou link
replaceSubstituir texto no lugar, na fonte do próprio documento quando possível
redactRemover texto, imagens e desenhos em áreas ou texto correspondente, depois verificar
set-metaTítulo, autor, assunto, palavras-chave, criador
compressReduzir: sem perdas por padrão, opcionalmente re-encodificando e reduzindo a escala de imagens
FormuláriosformsCampos com seus tipos, valores e opções
fillPreencher campos por nome
ProteçãoencryptSenhas e permissões AES-256
decryptRemover proteção por senha
signAssinar digitalmente com um certificado, mantendo assinaturas anteriores válidas
sanitizeRemover scripts, ações arriscadas, anexos, XFA e mídia, depois verificar por escaneamento
Configuraçãoocr-langsSe o tesseract está instalado e quais idiomas são utilizáveis
ocr-installBaixar dados de idioma para OCR, opcionalmente instalar tesseract

Execute pdfops <command> --help para as opções de cada um.

Exemplos

$ pdfops info manual.pdf
{"encrypted":false,"file":"manual.pdf","form_fields":0,
 "metadata":{"created":"2026-06-30T09:07:46+00:00","producer":"GPL Ghostscript 10.07.1"},
 "outline_entries":645,"page_size_pt":{"height":792.0,"width":595.0},"pages":357,"pdf_version":"1.3",
 "size_bytes":1386723,"uniform_page_size":true}

$ pdfops search manual.pdf "calling convention" --max-results 1 --context 40
{"file":"manual.pdf","matches":[{"match":"Calling Convention","page":12,
 "snippet":"... 10.5.1 The Pascal Calling Convention ..."}],"query":"calling convention",
 "total_matches":17,"unreadable_pages":[]}

Leitura:

pdfops text manual.pdf --pages 12- --max-chars 4000     # resume_at_page says where to continue
pdfops text scan.pdf --ocr --ocr-lang pol+eng           # OCR only the pages that have no text
pdfops tables report.pdf --pages 4 --format markdown
pdfops layout report.pdf --pages 4 --level words        # bbox, font and size per word
pdfops render report.pdf --pages 1-3 --dpi 150 -o out/  # look at charts and layout
pdfops --stream ocr scan.pdf --lang pol                 # a line per page as it finishes
pdfops ocr scan.pdf --lang pol -o searchable.pdf        # the same file, with text to search
pdfops images report.pdf -o images/

Construção e trabalho em páginas:

pdfops create notes.md -o notes.pdf
pdfops merge a.pdf b.pdf -o merged.pdf
pdfops pages in.pdf --keep "3,1,5-" -o out.pdf
pdfops split in.pdf --every 10 -o parts/

Edição:

pdfops stamp in.pdf --text "Poufne · {page}/{pages}" --position footer -o out.pdf
pdfops stamp in.pdf --image signature.png --x 380 --y 690 --width 140 --pages last -o out.pdf
pdfops stamp in.pdf --qr "https://example.com/doc/42" --anchor bottom-right -o out.pdf
pdfops redact in.pdf --text "Jan Kowalski" --text "\d{11}" --regex -o redacted.pdf
pdfops redact in.pdf --rect "2:100,200,300,220" -o redacted.pdf
pdfops replace in.pdf --find "2025" --with "2026" -o out.pdf
pdfops replace in.pdf --find "2025" --with "2026" --dry-run -o out.pdf   # the plan, nothing written
pdfops compress in.pdf --max-image-edge 1600 --image-quality 70 -o small.pdf

Formulários e proteção:

pdfops forms form.pdf
pdfops fill form.pdf --set name="Ada Lovelace" --set agree=true -o filled.pdf
pdfops encrypt in.pdf --owner-password secret --deny-copy -o locked.pdf
pdfops sign in.pdf --p12 identity.p12 --p12-password secret --reason "Approved" -o signed.pdf
pdfops sign in.pdf --cert me.crt --key me.key --visible "1:360,700,560,760" -o signed.pdf
pdfops signatures signed.pdf                            # valid, unchanged, who and when
pdfops signatures signed.pdf --trust company-root.pem   # and whether the signer is one of yours
pdfops sign in.pdf --p12 identity.p12 --tsa http://timestamp.digicert.com -o signed.pdf
pdfops scan inbox/offer.pdf                             # what is in it, before reading it
pdfops sanitize inbox/offer.pdf -o offer-clean.pdf      # scripts, actions, attachments removed

Marcação:

pdfops annotate in.pdf --text "liability" --comment "check with legal" -o marked.pdf
pdfops annotate in.pdf --kind link --rect "1:72,50,300,70" --url https://example.com -o out.pdf
pdfops annotations marked.pdf

Convenções

  • Saída. Cada comando imprime um documento JSON no stdout. Erros vão para o stderr como {"error": "..."} com status de saída 1. Adicione --pretty para indentar.
  • Progresso. Com --stream, ocr, text --ocr, render, images, split, redact e replace imprimem uma linha de JSON por página ou arquivo concluído, {"event":"progress","step":"render","done":7,"total":20,"page":12,...}, e o resultado usual como a última linha. As páginas são trabalhadas em paralelo, então os eventos chegam na ordem em que o trabalho termina; cada um nomeia sua página e done aumenta em um por linha. Via MCP, os mesmos eventos chegam como notifications/progress quando a chamada carrega um token de progresso.
  • Gravação. Comandos que gravam aceitam -o. Pode ser o arquivo de entrada: a saída passa por um arquivo temporário.
  • Páginas são baseadas em 1 e separadas por vírgula: 3, 2-5, 7- (até o final), -4 (desde o início), 5-2 (decrescente), last, odd, even, all.
  • Posições são em pontos com a origem no canto superior esquerdo da página como exibida, y crescendo para baixo. layout as relata, stamp --x/--y e redact --rect as aceitam, e um pixel de render --dpi 72 é exatamente um ponto.

Como se compara

pdfopsPyMuPDFpypdfpdfplumberqpdfpoppler-utils
Extração de texto✓✓✓✓–✓
Posições e fontes de palavras✓✓–✓–posições
Tabelas✓✓–✓––
Renderizar páginas✓✓–✓–✓
OCR✓✓––––
Mesclar, dividir, reordenar, girar✓✓✓–✓parcialmente
Carimbos de texto, imagem e QR✓✓por sobreposição–por sobreposição–
Redação que remove conteúdo✓✓––––
Redação verificada antes de gravar✓–––––
Substituir texto no lugar✓–––––
Preencher formulários✓✓✓–––
Criptografar e descriptografar✓✓✓–✓–
Adicionar e listar anotações✓✓✓listar––
Assinar digitalmente✓–––––
Verificar assinaturas✓––––✓
Inspecionar conteúdo ativo e texto oculto✓–––––
Remover conteúdo ativo✓✓––––
Limites de memória e tempo por chamada✓–––––
Criar a partir de Markdown✓de HTML––––
Servidor MCP integrado e esquemas de ferramentas✓–––––
JSON de cada comando✓bibliotecabibliotecabibliotecaparcialmente–
Runtime necessárionenhumPythonPythonPythonnenhumnenhum
LicençaMITAGPL ou comercialBSDMITApache-2.0GPL

PyMuPDF é o mais próximo em escopo e é uma biblioteca excelente; é escrito em C, precisa de Python, e sua licença AGPL importa se você o distribuir. pdfops troca alguma amplitude por um único binário licenciado sob MIT cujas ferramentas um agente pode chamar diretamente.

Benchmarks

Melhor de 3 execuções de processo inteiro, incluindo inicialização, já que é isso que uma chamada de ferramenta custa a um agente. Documento: o manual do NASM 2.16, 308 páginas e 1,2 MB; images em um livro de 352 páginas e 2,6 MB com imagens; formulários em um formulário de uma página. Máquina: AMD Ryzen 7 9800X3D de 8 núcleos, Windows 11. Versões: poppler 25.07, qpdf 12.4, PyMuPDF 1.28, pypdf 6.19, pdfplumber 0.11, pyHanko 0.37 (CLI 0.5), tesseract 5.5. A entrada mais rápida de cada linha está em negrito; n/a marca uma ferramenta que foi instalada e não concluiu a tarefa. A entrada do PyMuPDF para sanitize é seu scrub.

Tarefapdfopsferramenta de linha de comandoPyMuPDFpypdfpdfplumber
info7 mspdfinfo 12 ms129 ms203 ms222 ms
text, todas as páginas53 mspdftotext 540 ms297 ms1273 ms11,3 s
search, todas as páginas53 ms-326 ms--
layout, cada palavra com sua caixa194 ms-346 ms-10,9 s
tables, 50 páginas20 ms-1558 ms-1629 ms
outline15 ms-128 ms221 ms-
render, 20 páginas a 150 dpi41 mspdftoppm 2677 ms593 ms--
ocr, uma página1087 mstesseract 759 ms---
images, todas as imagens incorporadas230 mspdfimages 5621 ms1297 ms1553 ms-
create, 100 seções de Markdown12 ms----
merge, três cópias57 msqpdf 204 ms401 ms2037 ms-
pages, manter 1017 msqpdf 138 ms138 ms285 ms-
split, um arquivo por página156 mspdfseparate 46,0 s437 ms2513 ms-
rotate, todas as páginas20 msqpdf 144 ms147 ms769 ms-
stamp, texto em todas as páginas21 ms-279 ms--
stamp, código QR em todas as páginas121 ms----
annotations, lista18 ms-227 ms-309 ms
annotate, destacar uma palavra em todas as páginas291 ms-700 ms--
redact, uma palavra em todas as páginas564 ms-1926 ms--
replace, uma palavra em todas as páginas575 ms----
scan, estrutura e texto oculto232 ms----
scan, apenas estrutura16 ms----
sanitize32 ms-2072 ms--
set-meta19 ms-140 ms771 ms-
compress31 msqpdf 179 ms378 ms--
encrypt, AES-25625 msqpdf 174 ms150 ms825 ms-
decrypt38 msqpdf 170 ms158 ms875 ms-
sign, RSA-204823 mspyhanko 615 ms---
signatures, verificar16 mspdfsig n/d---
forms, listar campos7 ms-121 ms169 ms-
fill, um campo9 ms-130 ms198 ms-

Reproduza com scripts/bench.py em qualquer documento.

Por que é rápido: info, layout, tables, render, images e ocr leem objetos sob demanda, então abrir um arquivo custa alguns milissegundos, independentemente do tamanho. Extração de texto, layout, tabelas, renderização, divisão, exportação de imagens e OCR são executados em todos os núcleos. Operações de página copiam apenas os objetos que as páginas selecionadas alcançam, então o tamanho da saída e o tempo seguem a seleção, não a origem.

Usando sem MCP

pdfops tools imprime [{"name", "description", "inputSchema"}] para cada comando. Passe-os para qualquer função que chame a API e execute a chamada via CLI ou biblioteca.

let result = pdfops::tools::call(
    "pdf_text",
    serde_json::json!({"input": "report.pdf", "pages": "1-3"}),
)?;

Pontos de entrada tipados estão em pdfops::ops, por exemplo pdfops::ops::read::text(TextArgs { .. }).

Comportamento que vale a pena conhecer

A versão curta. pdfops <command> --help tem o detalhe para cada comando.

  • Qualquer script. Texto que stamp, fill, replace, create e ocr -o desenham é moldado e incorporado como subconjuntos de fonte; onde nenhuma fonte única tem todos os caracteres, várias compartilham o texto. Hebraico e árabe são dispostos da direita para a esquerda e lidos de volta na ordem em que são lidos, então uma palavra é encontrada digitando-a. Alguns agrupamentos indianos e tailandeses que o próprio pdfops escreveu são lidos de volta com seus caracteres reagrupados.
  • Redação remove, não cobre. Glifos, pixels de imagem em qualquer codificação, desenhos e anotações sob uma área são excluídos, um texto a redigir também é removido de metadados e marcadores, e o resultado é lido de volta por um segundo interpretador antes que qualquer coisa seja escrita.
  • Substituir escreve na fonte do próprio documento onde ela tem os glifos e move o resto da linha adiante; valores de campos de texto e comentários de anotações também são alterados. Uma linha que cresce além de sua coluna passa suas últimas palavras para a próxima linha, e o parágrafo ganha uma linha a mais se houver espaço abaixo. Onde o parágrafo não pode ser determinado com certeza, a linha é deixada como está e overflow_pt diz em quanto ela ultrapassa; --dry-run mostra primeiro.
  • Execução de teste. redact, replace, annotate e stamp aceitam --dry-run: todo o trabalho, nada é escrito.
  • Verificação relata scripts, ações, anexos, conteúdo disfarçado e texto oculto por gravidade. Não é um scanner de vírus e nunca chama um arquivo de seguro. Saneamento remove o conteúdo ativo e verifica o resultado antes de escrevê-lo.
  • Tabelas com linhas de grade são lidas célula por célula. Tabelas sem são inferidas a partir do alinhamento (detected_by: alignment) e merecem uma olhada.
  • OCR é do tesseract. ocr -o escreve o texto reconhecido em uma cópia como uma camada invisível.
  • Assinaturas. sign anexa, então assinaturas anteriores permanecem válidas. Pode mostrar a assinatura em uma página (--visible) e incorporar a declaração de tempo de uma autoridade de carimbo de tempo (--tsa). signatures verifica se os bytes não foram alterados e quem assinou; com --trust verifica a cadeia do assinante contra certificados que você nomeia, e com --revocation suas listas de revogação. Qualquer outra alteração em um PDF assinado invalida suas assinaturas, como deve ser.
  • Mesclagem e trabalho de página mantêm marcadores e links que levam a páginas na saída, e renomeiam os campos de formulário de entradas posteriores doc2.<name> para que nomes iguais não compartilhem um valor.
  • Arquivos danificados são reparados para leitura e reconstruídos para escrita; o resultado então carrega repaired_inputs. Um arquivo danificado que também está criptografado não é reconstruído. Arquivos protegidos permanecem protegidos quando editados; apenas decrypt remove a proteção.
  • Limites. 4 GiB e 300 segundos por comando por padrão: --max-memory, --timeout, ou PDFOPS_MAX_MEMORY e PDFOPS_TIMEOUT; 0 remove um limite. Rasters são limitados a 64 megapixels.
  • Criar aceita Markdown, e o HTML nele pelo que diz: títulos, ênfase, links, listas, tabelas. Como deve parecer não é lido: não há CSS.

Desenvolvimento

cargo test                                # under a second; fixtures are generated in memory
cargo test -- --ignored                   # OCR test, needs tesseract with a language pack
cargo clippy --all-targets -- -D warnings
cargo fmt --check
scripts/bench.py --help                   # regenerate the benchmark table

Construído sobre lopdf (modelo de objetos), hayro (texto, renderização, posições e decodificação de imagens), rustybuzz (modelagem de texto), subsetter (incorporação de fontes) e pulldown-cmark (Markdown).

Licença

MIT