PDF Extractor MCP Server
A Model Context Protocol server that exposes the PDF Extractor API as tools so that LLM agents (Claude Desktop, Claude Code, Cursor, etc.) can extract images, tables, text blocks, formulas, and other elements from PDF documents.
Tools
| Tool | Description |
|---|---|
extract_elements |
Extract elements from a single PDF (path, URL, or base64). |
extract_elements_batch |
Extract elements from multiple PDFs (Business tier). |
list_extractions |
Paginate the authenticated user's past extraction jobs. |
get_extraction |
Fetch details and files for a specific extraction. |
delete_extraction |
Delete an extraction job. |
download_file |
Fetch (and optionally save) a presigned Files[].Url from an extraction. |
Install
Requires Python 3.10+. Pick whichever fits your workflow:
# Zero local setup — recommended for end users
uvx pdf-extractor-mcp
# Or a persistent install
pipx install pdf-extractor-mcp
# Or from source (for development)
cd mcp_server
python -m pip install -e ".[dev]"
Configure
Generate an API token at https://www.pdf-xtract.com/tokens and export it before running the server:
export PDF_EXTRACTOR_API_KEY=pxt_...
# Optional: point at a self-hosted deployment
# export PDF_EXTRACTOR_API_URL=https://pdf.example.com
Run
pdf-extractor-mcp
# or
python -m pdf_extractor_mcp
The server speaks MCP over stdio.
Claude Desktop / Claude Code config
Add this to claude_desktop_config.json (or your IDE's MCP settings). With
uvx the package is fetched and cached on first run, so users don't need a
prior pip install:
{
"mcpServers": {
"pdf-extractor": {
"command": "uvx",
"args": ["pdf-extractor-mcp"],
"env": {
"PDF_EXTRACTOR_API_KEY": "pxt_..."
}
}
}
}
If you installed via pipx, replace "command": "uvx", "args": [...] with
"command": "pdf-extractor-mcp".
Element categories
Caption, Footnote, Expression, Entry, Footer, Header, Image,
SectionTitle, Table, Text, Title. Defaults to ["Image"].
Example prompts
- "Extract all tables from
~/Downloads/report.pdfas PNG and summarize the first one." - "Pull every figure caption from pages 5-12 of
https://arxiv.org/pdf/2401.12345.pdf." - "List my extractions from the last week."
Testing the server
Three ways to exercise the server without a full IDE round-trip:
-
MCP Inspector (interactive UI):
npx @modelcontextprotocol/inspector pdf-extractor-mcp
Lists every tool, lets you fill in arguments, and shows the live response.
-
stdio smoke test — confirms the binary starts and registers tools:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \ | pdf-extractor-mcp
-
Unit tests (no network, no API key required):
cd mcp_server pip install -e ".[dev]" pytest -m "not integration"
An opt-in integration test exercises the live API; set a real key and run:
PDF_EXTRACTOR_API_KEY=pxt_... pytest -m integration
Releasing
The MCP server is published to PyPI as pdf-extractor-mcp from the
.github/workflows/mcp-server-release.yml workflow. To cut a release:
- Bump
versioninmcp_server/pyproject.toml. - Tag the commit:
git tag mcp-v0.1.0 && git push origin mcp-v0.1.0. - The workflow builds the sdist + wheel and publishes via PyPI Trusted Publishing (OIDC — no API token stored).
One-time PyPI setup (Trusted Publishing)
Before the first release, register a pending publisher on PyPI so it
will accept the OIDC token. Without this the publish step fails with
invalid-publisher: valid token, but no corresponding publisher.
-
Under "Add a new pending publisher", enter these values exactly (they must match the token claims the workflow produces):
Field Value PyPI Project Name pdf-extractor-mcpOwner BorisBeskyRepository name pdf-extractorWorkflow name mcp-server-release.ymlEnvironment name pypi -
Make sure a GitHub environment named
pypiexists (repo Settings → Environments). The release job declaresenvironment: pypi; the name is case-sensitive and must match the PyPI entry above. -
Re-run the release (re-push the tag, or trigger the workflow manually via "Run workflow").
Once the first publish succeeds, PyPI converts the pending publisher into a
normal trusted publisher automatically — no further setup for later mcp-v*
tags.
Notes
- Pass
store_file=true(the default) for large PDFs - the API returns presigned URLs instead of base64 blobs. Usedownload_fileto fetch them. - When
store_file=false, the server truncatesFileDatain its response summary and addsFileDataLength; the raw base64 stays available by calling the API directly if needed. - OCR (
ocr_mode=element|page) requires Starter or Business tier. - Batch extraction requires Business tier.
Metadata
Release files for pdf-extractor-mcp 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pdf_extractor_mcp-0.1.1.tar.gz | 19.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pdf_extractor_mcp-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.9 kB
Release files / pdf_extractor_mcp-0.1.1.tar.gz
| Download URL | pdf_extractor_mcp-0.1.1.tar.gz |
|---|---|
| Size | 19.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cb9813a37c5ec1264556a3338b6fd8f982aebf361efd2f364fa25de6cf47cfe9
|
|
BLAKE2b-256 checksum How to use checksums |
843adb731b7a7fdd372db0efa355813426b66603977e03a9df758b6307b7b37c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 25, 2026.
Transparency logRelease files / pdf_extractor_mcp-0.1.1-py3-none-any.whl
| Download URL | pdf_extractor_mcp-0.1.1-py3-none-any.whl |
|---|---|
| Size | 13.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9df5e51b50fea8e1d7d89ee97e038b779b940c5c4f8f73086c0432ea0d23fce3
|
|
BLAKE2b-256 checksum How to use checksums |
181d58c9833e594c06f53cae7d065609ced2c5cc03ecf13b9fcaeece2eaa2ff7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 25, 2026.
Transparency logSecurity for pdf-extractor-mcp 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pdf_extractor_mcp-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 25, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.