About pdfport
pdfport is a CLI and MCP server for working with local PDF files, including text extraction, metadata retrieval, file summaries, merging, and splitting. Its pure TypeScript engine handles a defined subset of PDFs and does not upload files.
Key features
- 01Extract text from PDF pages
- 02Read document metadata and file information
- 03Merge multiple PDFs
- 04Split a PDF into single-page files
- 05Process local files without uploading
Use cases
- 01Extract text from a supported PDF
- 02Inspect page count and document metadata
- 03Combine PDFs or separate pages into files
MCP support
The MCP server exposes tools to extract text, retrieve metadata and PDF information, merge PDFs, and split a PDF into page files.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
Tools
5Saved tool list · updated 2w ago
| Parameter | Type | Required | Description |
|---|---|---|---|
| file_path | string | Yes |
Details
From the project READMEpdfport
pdfport does the five PDF jobs that come up over and over: pull the text out of a file, read its document metadata, summarise it (pages, page sizes, file size, PDF version), merge several files into one, and split a file into one document per page. It works on local files only — nothing is uploaded anywhere.
The engine is a small, genuine PDF implementation written in pure TypeScript for this project. No PDF library is bundled and there are no runtime dependencies beyond the MCP SDK. The engine scans a document's indirect objects, follows the Catalog to its Pages tree, decodes plain and FlateDecode content streams, and recovers text from the standard text-showing operators. Merges renumber the source objects into one new object graph with a rebuilt page tree; splits emit one document per page the same way; both write a freshly computed cross-reference table.
Scope — what the engine does and does not handle
Supported: simple PDFs with a flat page tree (a Catalog whose Pages node lists Page objects directly — the shape common generators produce, and the shape pdfport's own merge/split write), uncompressed or FlateDecode streams, literal and hex strings in content and in the Info dictionary, and per-page MediaBox sizes (inherited from the Pages node when a page omits its own).
Not supported: encrypted files, object streams and compressed cross-reference streams (PDF 1.5+ compact files), nested page trees, embedded-font encodings that need a ToUnicode map to read, and form/annotation fidelity on merge or split. Files outside the subset fail with a plain error saying what was not found — pdfport never returns invented text or metadata.
Install
npx @reneturcios/pdfport get-pdf-info ./report.pdf
Or run the container image:
docker run -i ghcr.io/cloudcorprecords/pdfport
The container defaults to the MCP server (see below). Pass CLI arguments to use it as a CLI instead.
CLI
# Print the document's text
pdfport extract-text ./report.pdf
# Print the Info-dictionary metadata (plus page count) as JSON
pdfport get-metadata ./report.pdf
# Print page count, page sizes, file size and PDF version as JSON
pdfport get-pdf-info ./report.pdf
# Merge inputs, in order, into one output file
pdfport merge ./combined.pdf ./a.pdf ./b.pdf ./c.pdf
# Split into <name>-page-1.pdf, <name>-page-2.pdf, ... in a directory
pdfport split ./report.pdf ./report-pages
# Start the MCP server
pdfport mcp
pdfport --version
Exit codes: 0 on success, 1 when a file is missing or a document
cannot be processed (the error says which), 2 for usage errors.
MCP server
One bin serves both faces. The mcp subcommand starts a stdio MCP
server:
npx -y @reneturcios/pdfport mcp
MCP client configuration:
{
"mcpServers": {
"pdfport": {
"command": "npx",
"args": ["-y", "@reneturcios/pdfport", "mcp"]
}
}
}
Tools
| Tool | Input | What it returns |
|---|---|---|
extract_text | file_path (string, required) | The file's text: every page's shown text, pages joined with a newline. |
get_metadata | file_path (string, required) | The Info dictionary's title, author, subject, keywords, creator, producer and dates (only the fields the document carries), plus the page count. |
get_pdf_info | file_path (string, required) | Page count, each page's MediaBox size in points, the file size in bytes, and the PDF version from the header. |
merge_pdfs | input_files (array of strings, required), output_file (string, required) | Writes the merged document and reports the output path and total page count. The first input's metadata is kept. |
split_pdf | file_path (string, required), output_dir (string, required) | Writes one single-page file per page into the directory and reports the created file paths and page count. |
Development
npm install
npm run build # tsc -> dist/
npm test # node test runner over test/*.test.ts, no network
npm run dev # run the CLI from source via tsx
The test suite builds small PDFs from raw strings — plain and FlateDecode content streams — and drives the default engine end-to-end: extraction (including TJ arrays and literal-string escapes), metadata, info, merge and split are all asserted against the real implementation, then the file facade is exercised against real files in a temporary directory.
License
MIT — see LICENSE.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.