Skip to content

Documents Server

document_processing_server (doc_processing_std_tools.document_processing, MCP name document-processing-tools) gives an agent 13 tools to read PDFs, Word, Excel and PowerPoint files and images, to OCR scans, to render pages as images the model can look at, and to convert documents between formats.

from doc_processing_std_tools import document_processing_server

Writing documents from scratch is not part of this server: an agent creates them with code through the Code Execution server, and can then convert them with convert_document.

Install

Need Install
The readers, renderers and image tools the docs extra (pdfplumber, python-docx, openpyxl, python-pptx, Pillow, pymupdf)
ocr_pdf, ocr_image the ocr extra (llmwhisperer-client 2.x) and LLMWHISPERER_API_KEY
convert_document, and rendering Word, Excel, PowerPoint or OpenDocument files LibreOffice: on Debian or Ubuntu, apt-get install libreoffice-core libreoffice-writer libreoffice-calc libreoffice-impress. std-tools runs libreoffice, then soffice, from PATH, or the executable in DPTTOOLS_SOFFICE_BIN

PDFs render with pymupdf alone; LibreOffice is only needed to convert Office files.

Tools

Reading text

Tool Key parameters Returns
read_pdf path, pages="all", extract_tables=False Text with --- Page N --- headers; tables as |-separated rows. Says so, and suggests ocr_pdf, when no page has text
read_word path (.docx) Text: headings as Markdown # lines, then header and footer lines, tables, text boxes, and an embedded-image count when there are images
read_excel path (.xlsx), sheet (default: the active sheet), range (for example "A1:D10") JSON: sheet, headers (first row), rows, total_rows, merged_ranges, has_images, has_charts, has_media
read_powerpoint path (.pptx) JSON: slides (each with slide, text, speaker_notes, image_count, chart_count, has_media), slide_count, has_media
get_file_overview path JSON summary for the file type: PDF page count, sizes and text previews; Excel sheets, sizes and sample rows; Word headings and counts; PowerPoint slide titles; image size; or size, line count and first and last lines for any other file

OCR (LLMWhisperer)

Tool Key parameters Returns
ocr_pdf path (.pdf), pages="all" OCR text with --- Page N --- headers
ocr_image path (.png, .jpg, .jpeg, .webp, .tif, .tiff, .bmp) OCR text

Seeing pages and images

These return MCP image content, so the model sees the pixels. Every image is first brought within model-safe limits — see Image size limits below.

Tool Key parameters Returns
read_image path (PNG, JPEG, WEBP, GIF, BMP, TIFF) The image, with its format taken from the bytes rather than the extension; the file itself when it is within the limits
get_image_metadata path JSON: format, width, height, mode, file_size, file_size_bytes — no pixels
render_document_page path, page=1, scale=2.0 One page as a PNG
render_document_thumbnail path, max_pages=5 The first pages as PNGs at scale 1.0 (72 dpi)
read_document_pages_as_images path, pages="all", scale=2.0, max_pages=20 One PNG per requested page

The renderers accept PDF, DOCX, XLSX, PPTX, DOC, XLS, PPT, ODT, ODS and ODP, and reject image files (use read_image). scale multiplies 72 dpi, so the default 2.0 renders an A4 page at about 1190 × 1684 pixels.

Image size limits

New in 0.6.0. read_image, render_document_page, render_document_thumbnail and read_document_pages_as_images scale an image down when its long edge is over DPTTOOLS_IMAGE_MAX_EDGE_PX (default 1568 px) or its encoded size is over DPTTOOLS_IMAGE_MAX_MB (default 3 MB). Those defaults are accepted by every provider the toolkit supports. An image within both limits is sent unchanged, byte for byte; a scaled one may arrive as JPEG. An A4 page at the default scale=2.0 is 1684 px tall, so it is scaled to 1568 px. Images explains the rules.

Converting documents

New in 0.6.0.

Tool Key parameters Returns
convert_document path, to, outdir=None, page="all", overwrite=False JSON {"output_files": [...], "pages": ..., "engine": ...} — the files it wrote, not their content
  • Targets (to): pdf, docx, xlsx, pptx, odt, ods, odp, csv, html, txt, png, jpg (jpeg is accepted as jpg).
  • Sources: Office and OpenDocument files (DOCX, XLSX, PPTX, DOC, XLS, PPT, ODT, ODS, ODP, RTF and similar). A PDF can only become png or jpg; to get its text, use read_pdf.
  • png and jpg write one image per page, named <name>-p<N>.png (or .jpg), rendered at 144 dpi. The document is converted to PDF first, then each page is rendered with pymupdf; page picks the pages ("all", "1-3", "2,5"). For other targets page must be "all".
  • csv exports only the first sheet of a spreadsheet. txt and csv are written as UTF-8.
  • Other targets write one file, <name>.<to>.
  • Where: next to the source file, or into outdir, which must already exist. An existing output file is never replaced unless overwrite=True; otherwise the call fails and names the file.
  • pages in the result is the number of images written for png/jpg, the page count for pdf (when pymupdf is installed), and null otherwise. engine is libreoffice, libreoffice+pymupdf or pymupdf.

convert_document writes files and returns paths; it does not show anything to the model. To look at pages, use read_document_pages_as_images, or read_image on a converted page image.

LibreOffice runs

convert_document and the Office-to-PDF step of the three render tools run LibreOffice headless. Each run gets its own LibreOffice profile and output folder, which are removed afterwards, so concurrent conversions in one container do not collide (new in 0.6.0). A run is stopped after DPTTOOLS_CONVERT_TIMEOUT_S seconds (default 120).

Choosing a tool

The file is… Start with Then, if needed
Unknown get_file_overview the matching reader
A PDF with selectable text read_pdf read_document_pages_as_images for charts and diagrams
A scanned PDF ocr_pdf (needs a key; costs per page) or read_document_pages_as_images, which needs no key — the model reads the page images
A Word, Excel or PowerPoint file read_word, read_excel, read_powerpoint read_document_pages_as_images when the result is near-empty or reports media (has_media, the image count)
A photo or screenshot of text ocr_image or read_image
An image to inspect visually read_image get_image_metadata to check its size first
A file to deliver in another format convert_document read_document_pages_as_images to check the result

Environment variables

Variable Default Effect here
LLMWHISPERER_API_KEY none Required by ocr_pdf and ocr_image. Read on every call
DPTTOOLS_OCR_TIMEOUT 180 Deadline for one OCR call (upload plus waiting for the result), in seconds, clamped to 30–600. Read once per process; a value that is not a positive integer is an error naming the variable
DPTTOOLS_MAX_FILE_SIZE_MB 50 Every tool here refuses files larger than this
DPTTOOLS_IMAGE_MAX_EDGE_PX 1568 Long-edge limit for images returned to the model. New in 0.6.0
DPTTOOLS_IMAGE_MAX_MB 3 Encoded-size limit for images returned to the model. New in 0.6.0
DPTTOOLS_OUTPUT_TRUNCATION_LIMIT 50000 Text results are cut at this many characters. OCR output is cut on a page boundary
DPTTOOLS_SOFFICE_BIN none The LibreOffice executable (a path, or a command on PATH). When unset, libreoffice then soffice on PATH. A value that does not resolve is an error naming the variable. New in 0.6.0
DPTTOOLS_CONVERT_TIMEOUT_S 120 Timeout for one LibreOffice conversion, in seconds. New in 0.6.0

Examples

Tool calls are written as Python calls; the model sends the same arguments as JSON.

get_file_overview(path="statements/2026-09.pdf")
read_pdf(path="statements/2026-09.pdf", pages="1-3", extract_tables=True)
ocr_pdf(path="scans/contract.pdf", pages="1-3,7")
ocr_pdf(path="scans/contract.pdf", pages="21-")          # page 21 to the end
read_document_pages_as_images(path="deck.pptx", pages="1-5", max_pages=5)
convert_document(path="reports/q3.docx", to="pdf")
convert_document(path="deck.pptx", to="png", page="1-3", outdir="exports")

A convert_document result:

{
  "output_files": ["/workspace/exports/deck-p1.png", "/workspace/exports/deck-p2.png",
                   "/workspace/exports/deck-p3.png"],
  "pages": 3,
  "engine": "libreoffice+pymupdf"
}

Pitfalls

  • The pages syntax differs between tools. read_pdf and read_document_pages_as_images take "all", a page ("3"), a range ("1-5") or a comma list mixing both ("1-3,7"); a range that runs past the end is clipped, but a start page past the end is an error. ocr_pdf takes the same forms plus an open-ended range, "21-".
  • pages="all" can flood the context. read_document_pages_as_images returns one image per page, up to max_pages (20); pages past the cap are dropped without an error. Ask for a range.
  • A higher scale does not mean more detail for the model. Pages are scaled back to the long-edge limit, so beyond about scale=2.0 a larger value mostly costs time. To read small print, crop or zoom with Image Tools first, then read_image the result.
  • An image that cannot fit is an error. If an image would have to shrink below 256 px on its long edge to fit the byte limit, the tool returns an Error: suggesting a larger DPTTOOLS_IMAGE_MAX_MB or a crop.
  • Long OCR output is cut on a page boundary. The result then names the pages left out and the pages value to request them with. ocr_image has no pagination.
  • OCR prechecks the PDF. An empty file and a file without a PDF header are refused before anything is uploaded; so are a password-protected PDF and a PDF with no pages, when pymupdf is installed.
  • Excel values are strings, and formulas are not returned. read_excel reads the values saved with the workbook. A workbook generated by code and never opened in Excel may have no saved results for its formulas, which then read as empty strings. Only .xlsx workbooks are read; render an old .xls file with read_document_pages_as_images instead.
  • Old binary formats. read_word and read_powerpoint read .docx and .pptx only. .doc and .ppt files can still be rendered as images, through LibreOffice.
  • Office conversion needs LibreOffice. Without it, convert_document and rendering a Word, Excel or PowerPoint file return an error with the install command.
  • Fonts come from the machine. LibreOffice lays out pages with the fonts installed where it runs; install CJK fonts (for example fonts-noto-cjk) for Chinese, Japanese or Korean documents.
  • convert_document will not overwrite. Pass overwrite=True, or another outdir, when the output already exists. Converting a file to its own format is an error.
  • Large documents. A conversion that takes longer than DPTTOOLS_CONVERT_TIMEOUT_S is stopped; raise it for very long documents.
  • In-process image results need toolkit 0.5.1 or later. See Compatibility.

Upgrading from 0.5.0

DPTTOOLS_OCR_TIMEOUT used to be read on every call, and a non-integer value silently fell back to 180. It is now read once per process, and an invalid value is an error naming the variable; the composed launcher refuses to start. Values outside 30–600 are still clamped.

Skills that run LibreOffice by hand

Skill content that tells the model to write its own soffice commands through execute_command can be retired: convert_document handles the per-run profile, the timeout, cleanup and the "exit 0 but no output" case. Keep the policy — when to convert, naming and folders — in the skill, and have it call convert_document.

Recipes