The local PDF workflow for Claude Desktop and MCP hosts: fill, sign, merge, split, extract, render, and analyze PDFs with local file operations.
Instead of just opening a PDF, PDF Tools lets Claude fetch PDF URLs to your machine, inspect documents visually, fill forms, save reusable profiles, add signature/date zones, merge and split files, reorganize pages visually, extract structured data, and return document content to your chosen MCP host for analysis.
This package targets Claude Desktop and other local MCP hosts today. It does not yet include a remote connector for Claude Cowork / web-hosted Claude.
.mcpb from Releases.mcpb file to install it in Claude DesktopThe extension is also available in the Claude Extensions directory.
Claude Desktop settings include an Allowed PDF Directories field. By default,
PDF Tools can access ~/Documents, ~/Downloads, and ~/Desktop. Add any other
folder you want Claude to use before asking it to read, fill, sign, merge, or save
PDFs there. Saved profiles and signatures live in the extension’s private local
store and do not need to be added manually.
{
"mcpServers": {
"pdf-tools": {
"command": "node",
"args": ["/full/path/to/PDF-Tools/server/index.js"]
}
}
}
A fresh Agent Plugin install uses a private PDF Tools workspace. There is no folder setup step: when the host is allowed to read a file, it can copy the file into that workspace for PDF Tools to process. PDF Tools itself still refuses direct paths outside the workspace.
This is a tool boundary, not a confidentiality boundary against the host. If
ChatGPT is set to Full Access, its broader filesystem permission governs what it
can import. Optional direct folder access can be configured separately in the
plugin’s config.json; a non-empty list replaces the private workspace.
Claude already knows how to read PDFs in limited ways. PDF Tools goes much further:
fill_pdf, read_pdf_fields, bulk_fill_from_csv, and reusable profilesText, images, and metadata returned by PDF Tools may be processed by Claude or another MCP host. Your host and model provider’s data terms apply to that content, so the complete workflow is not necessarily zero egress.
Lumin e-signing is an explicit external workflow. The rest of PDF Tools stays
local-first. PDF Tools contacts Lumin only when a Lumin tool is called. Sending
requires a provider-ready prepare_signing_packet receipt, a local preview, a
connected Lumin session, and the user’s fresh verbatim confirmation. The
prepared PDF plus listed names and email addresses then leave the device and are
handled by Lumin.
PDF Tools can validate the exact confirmation text and its freshness, but it cannot independently prove who typed it. The MCP host must present the destructive tool action, and the agent must pass only the user’s actual words and time. Agents must never fabricate either value.
This is currently a maintainer-configured integration, not a fully qualified one-click signup experience. An ordinary user should not need to create a developer app. If signing is not configured, ask the installation’s maintainer; creating a personal Lumin account alone does not enable the integration.
Once configured, ask PDF Tools to connect Lumin. Sign in and approve access in the browser, never by sharing passwords or callback URLs in chat. If you need an account, create it on Lumin’s website. If signup does not return to the connection before it expires, start the connection again. Connecting does not upload a PDF, send an invitation, or approve a signature. After reconnecting, check an existing request rather than sending it again.
For maintainers: configure a public OAuth client ID in the extension’s Lumin OAuth Client ID
setting. Other stdio hosts may set LUMIN_OAUTH_CLIENT_ID; Agent Plugin users
may set luminOAuthClientId in the plugin’s private config.json. Register the
exact redirect URI http://127.0.0.1/callback. The OAuth access token stays only
in the running PDF Tools process. It is not returned, logged, or written to
disk, and a restart requires connecting again.
The create call is one-shot and has no automatic retry. If the provider outcome is uncertain, PDF Tools preserves that uncertainty and will not create another request under the same authority. Status polling is the current desktop path. Lumin app webhooks require a private server app and are not part of this public PKCE workflow. The durable signing-operation store currently supports macOS and Linux. The public Lumin workflow fails closed on Windows until a reviewed ACL-aware state adapter exists.
Lumin also provides its own hosted MCP and an API-key-based local extension. These are separate connections, not automatically installed, authenticated, or invoked by PDF Tools. See Lumin onboarding and integration boundaries for the capability comparison, first-time-user limitations, and attribution proposal. No signup tracking or analytics reporting is enabled by this work.
See Verified extraction workspaces for the complete lifecycle, supported methods, privacy boundary, and current limits.
PDF Tools does not currently bundle an OCR engine. Text reads use the PDF.js
text layer. If the selected read_pdf_content result contains no text, the tool
may return a rendered image of page 1 for vision-capable host/model inspection.
Page and region rendering produces raster images, not recognized text. A mixed
text/raster PDF, or raster pages after page 1, may therefore contain content the
broad text read does not recognize. Optional local OCR remains a planned
improvement rather than a shipped capability.
get_pdf_info binds these observations to the exact race-aware source
SHA-256, keeps widget annotations separate from ordinary annotations, and
returns link or action targets only as inert values. Page and region renders
report page geometry, coordinate spaces, renderer policy, the PNG SHA-256,
and raw RGBA SHA-256 availability.
inspect_pdf_accessibility is a bounded structural-review screen for an
unencrypted local PDF. It does not run veraPDF, assess tag semantics or
assistive-technology behavior, or establish PDF/UA, WCAG, certification,
legal, or document-accessibility conclusions.
Region-render inputs are top-left PDF.js viewport points after CropBox, rotation, and UserUnit. They are not MediaBox-relative signing-zone coordinates. The macOS Quick Look fallback renders whole pages and regions in that same view and reports raw pixels unavailable.
This list is complete: it names every tool the server registers. One of them,
read_pdf_bytes, is available only to the in-app viewer and is not packed into
the .mcpb manifest that ordinary model workflows discover.
display_pdffetch_pdf_from_urllist_pdfsread_pdf_contentread_pdf_pagesread_pdf_layoutconvert_pdf_to_markdown (reconstructs evidence-backed tables and source-validated external http or https links; unsupported, ambiguous, internal, and action links stay escaped text reported as typed gaps)verify_table_proposal (checks a suggested table against the original PDF and returns it only when the text and layout match the document; unclear tables stay unconverted for review)render_pdf_pagerender_pdf_regionsearch_pdf_textget_pdf_resource_uriread_pdf_fieldsfill_pdfbulk_fill_from_csvsave_profileload_profilelist_profilesfill_with_profilevalidate_pdfdetect_signature_zonesadd_signature_fieldprepare_signing_packetstart_lumin_authorizationfinish_lumin_authorizationprepare_lumin_requestsend_lumin_requestcheck_lumin_statusdownload_lumin_artifactcreate_signaturelist_signaturesload_signatureapply_signatureapply_textmerge_pdfssplit_pdfrotate_pdf_pagesreorder_pdf_pagesapply_page_planextract_to_csvcompare_pdfsget_pdf_identityget_pdf_infoinspect_pdf_accessibilityget_page_analysiscreate_extraction_workspaceinspect_extraction_stateread_extraction_workspaceread_extraction_chunksubmit_extraction_proposalverify_extraction_proposaldelete_extraction_workspaceget_active_documentset_active_documentget_allowed_directoriesread_pdf_bytesreveal_in_findergit clone https://github.com/Open-Document-Alliance/PDF-Tools
cd PDF-Tools
npm ci
npm run build:mcpb
@modelcontextprotocol/sdkMIT
The MCPB and the share ZIP both carry a vendored QPDF WebAssembly runtime at
vendor/qpdf-wasm/runtime/. No tool loads it yet; it is packaged ahead of the
integration that will use it. qpdf is Apache-2.0, and the complete notice set
(qpdf, zlib, libjpeg-turbo, the Emscripten generated runtime, musl,
compiler-rt, libc++, libc++abi and libunwind) ships beside it in
vendor/qpdf-wasm/runtime/licenses/, bound to its SHA-256 hashes by
licenses/manifest.json. The npm dependencies keep their own licences inside
node_modules/, including the PDF.js, Foxit and Liberation font notices.