PDF To Text MCP
Deutsche Dokumentation
Changelog
A local MCP server that extracts text from PDF files. It starts with local
extraction and can upgrade an inadequate result once through the OpenAI API.
Package version: 0.7.0.
Requirements
- Node.js 22.13 or newer
- An MCP client that supports local stdio servers
- macOS for the optional local PDFKit and Vision OCR fallbacks; the normal
local extractor uses
pdfjs-dist on every supported Node.js platform
OPENAI_API_KEY only when AI fallback should be available
Set the required PDF_TO_TEXT_MCP_ROOT environment variable to an existing
directory. Tool paths are relative to that root, and the process still needs
matching runtime read or write permissions. The configured root is private to
the server and never appears in tool arguments or results.
Dependencies and limitations at a glance
| Embedded PDF text | Node.js ≥ 22.13; bundled pdfjs-dist | Linux, macOS, Windows | No OCR; damaged font encoding and PDF object order can produce garbled text or incorrect reading order. |
| Local PDFKit/Vision fallback | System swift, PDFKit, Apple Vision | macOS only | Unavailable on Linux and Windows; local OCR quality is therefore not platform-equivalent before 1.0.0. |
| AI extraction retry | OPENAI_API_KEY, network access | Any supported Node.js platform | At most one retry per attempt; generated output can be wrong and may incur provider costs. |
| Save extracted text | WRITE_TEXT=true, directory write permission, hard-link support | Filesystem-dependent | Existing targets are never overwritten; PDF_TO_TEXT_MCP_ROOT is required and paths are root-relative. Complete TOCTOU hardening remains a separate task. |
File access and request behavior
| Read source PDF | Yes; through a path relative to PDF_TO_TEXT_MCP_ROOT. The source remains unchanged. |
| Modify or delete source PDF | Never. |
| Write extracted text | Only with WRITE_TEXT=true; writes the exact returned text beside the source as document.pdf.txt. The actual root-relative path is returned as saved_text_path only after writing succeeds. |
| Overwrite existing output | Never; final publication also rejects a target created after the initial availability check. |
| Target name already exists | Fail with an error. No suffixed name is chosen; resolve the conflict outside the tool. |
Repeat without last_try_id | Start a new local extraction. With text saving enabled, an existing output blocks the call. |
| Repeat a completed AI attempt | Reuse the retained result for the same unchanged source and page scope, without another AI extraction. Output collision rules still apply. |
| Request while another extraction runs | Run within the concurrency limit or wait in the bounded FIFO queue; reject when full or expired. |
| Retain attempt results | In the AI-enabled profile, retain up to ten completed attempts in FIFO order. Evicted IDs fail explicitly. Any number of PDFs can be extracted sequentially. |
| Send PDF to an external provider | Only on an explicit AI continuation with OPENAI_API_KEY configured. The complete PDF is sent to OpenAI, even when page_range selects only part of its text. |
Install and connect
Run the server directly from npm:
npx -y @jim-panse/pdf-to-text-mcp
Or install its executable globally:
npm install --global @jim-panse/pdf-to-text-mcp
pdf-to-text-mcp
For example, register it with Codex using:
codex mcp add pdf-to-text -- npx -y @jim-panse/pdf-to-text-mcp
The server also needs PDF_TO_TEXT_MCP_ROOT in its MCP process environment.
The JSON example below shows that setting; configure the same variable in the
client's server environment when using the CLI registration.
Equivalent JSON-based MCP clients can use:
{
"mcpServers": {
"pdf-to-text": {
"command": "npx",
"args": ["-y", "@jim-panse/pdf-to-text-mcp"],
"env": { "PDF_TO_TEXT_MCP_ROOT": "/path/to/pdf-library" }
}
}
}
The server communicates through standard input/output. Diagnostic logs go to
standard error and do not interfere with MCP messages.
Call extraction-try with a root-relative PDF path:
{ "path": "document.pdf" }
The first call extracts locally. AI continuation is available only when configured
and explicitly requested. The complete PDF is sent on AI continuation even if
page_range limits the requested text. Sources and existing outputs are never
overwritten. Requests overlap asynchronously without a JavaScript worker pool.
A client timeout does not stop admitted work; avoid automatic retries.
Configuration at a glance
Set variables in the MCP server's environment:
PDF_TO_TEXT_MCP_ROOT | Required existing directory defining the root-relative filesystem namespace. The server does not fall back to its working directory. |
OPENAI_API_KEY | Enables the optional one-time AI fallback. Local extraction works without it. |
OPENAI_MODEL | Overrides the AI model. The default is gpt-5.4-mini. |
AI_MAX_OUTPUT_TOKENS | Upper limit for AI-generated output tokens. Must be an integer of at least 800; defaults to 32000. |
WRITE_TEXT | true saves each successful result beside the PDF; false or omission disables saving. |
MAX_PARALLEL_EXTRACTIONS | Integer from 1 to 32; defaults to min(os.availableParallelism(), 4). |
EXTRACTION_QUEUE_CAPACITY | Integer from 0 to 100; defaults to 10; 0 disables waiting. |
EXTRACTION_QUEUE_WAIT_MS | Integer from 1 to 2147483647; defaults to 60000 ms; applies only before execution. |
Detailed behavior, diagrams, queue examples, timeout consequences and
troubleshooting are in the user manual.
Calling models should follow Model interaction.
Support
No free support is provided for this free software. Paid support is available
on request: jim-panse-1@posteo.de.
Third-party directories
These independent directories may show outdated package metadata. For current
product and release information, use the included user manual
and the official npm package.
License: AGPL-3.0-only.