Skip to main content

pdf-mcp

Python MCP License

Let your AI agent pull text and tables out of PDFs. An MCP server for invoices, reports, and statements, where the data lives in tables the model can't read from a pasted blob.

When you paste a PDF into a prompt, the columns collapse and the table turns to mush, so the model guesses at the numbers. This extracts the actual table structure with deterministic code, so the agent gets clean rows and never invents a cell.

What it turns a PDF into

A PDF invoice table like this:

Item     Qty   Price
Widget    3    12.50
Gadget    1    40.00
Bolt     10     0.25

comes back as structured rows (or CSV), not a flattened line of text:

[["Item","Qty","Price"],["Widget","3","12.50"],["Gadget","1","40.00"],["Bolt","10","0.25"]]

The tools it gives an agent

Tool What it does
page_count(path) How many pages the PDF has
extract_text(path, page) Text per page (one page, or the whole doc)
extract_tables(path, page, merge_multipage) Tables as rows of cells, each with an honest assessment (looks_clean, warnings) flagging ragged or mostly-empty extractions
table_to_csv(path, page, index) One table as clean CSV text

Getting started (Claude Desktop)

The fastest way to use this is with an MCP client like Claude Desktop. Three steps:

1. Install it

pip install "pdf-agent-mcp[mcp]"

2. Add it to your client's config

Claude Desktop's config lives here:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add the server:

{
  "mcpServers": {
    "pdf": { "command": "pdf-agent-mcp" }
  }
}

3. Restart Claude Desktop. You'll see a tools icon appear, meaning the server is connected.

That's it. Now ask about any .pdf on your machine:

You:  Pull the line items out of /Users/me/invoices/2024-001.pdf

Agent (calls extract_tables):
  Item     Qty   Price
  Widget    3    12.50
  Gadget    1    40.00
  Bolt     10     0.25
  (the table extracted cleanly)

The agent reads the real table structure instead of a flattened blob, so nothing is misaligned.

Restricting file access: to stop the agent reading anything outside one folder, set PDF_MCP_ALLOWED_DIR. See SECURITY.md.

Use it with other MCP clients

The same server works in any MCP client, only the config differs. Use pdf-agent-mcp as the command.

Cursor~/.cursor/mcp.json (global) or .cursor/mcp.json (per project). Same shape as Claude Desktop, and it hot-reloads (no restart):

{ "mcpServers": { "pdf": { "command": "pdf-agent-mcp" } } }

VS Code / GitHub Copilot.vscode/mcp.json. Note the different key (servers, not mcpServers) and the required type. Tools only run in Copilot Agent mode:

{ "servers": { "pdf": { "type": "stdio", "command": "pdf-agent-mcp" } } }

Windsurf~/.codeium/windsurf/mcp_config.json (create it if missing). Same shape as Claude Desktop:

{ "mcpServers": { "pdf": { "command": "pdf-agent-mcp" } } }

Cline — add it from the extension's MCP settings panel in VS Code (command: pdf-agent-mcp).

Understanding the output

extract_tables returns the rows, plus an honest assessment of how reliable each table looks, so you can trust a clean table and double-check a shaky one:

{
  "page": 1,
  "rows": [ ... ],
  "n_rows": 4,
  "looks_clean": true,
  "column_count": 3,
  "empty_ratio": 0.0,
  "warnings": []
}
  • looks_cleantrue if the table extracted without red flags.
  • column_count — the number of columns, if every row agrees on it (null if rows disagree).
  • empty_ratio — fraction of blank cells. A high value often means a bad extraction.
  • warnings — plain-language flags, e.g. "ragged: rows have [2, 3, 4] columns (grid may be misdetected)" or "66% of cells are empty". PDF tables are genuinely hard (nested/merged cells, multi-page), so instead of pretending, the tool tells you when a result is suspect.

Also usable from plain Python

from pdf_mcp import extractor

extractor.extract_tables("invoice.pdf")      # {'tables': [{'rows': [...], 'looks_clean': True, ...}]}
extractor.table_to_csv("invoice.pdf")        # clean CSV of the first table
extractor.extract_text("report.pdf", page=1)

Tests

python -m unittest discover -s tests     # builds its own test PDF, runs anywhere

License

MIT

Release files for pdf-agent-mcp 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pdf-agent-mcp 0.1.3
File Size Uploaded
pdf_agent_mcp-0.1.3.tar.gz 8.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pdf-agent-mcp 0.1.3
File Interpreter ABI Platform
pdf_agent_mcp-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 16.9 kB

Release files / pdf_agent_mcp-0.1.3.tar.gz

Download URL pdf_agent_mcp-0.1.3.tar.gz
Size 8.5 kB
Tags Source
SHA-256 checksum
How to use checksums
4b46d18fb32473069d367d715feb9bef5bb560e22c739e1c646217a35a02576e
BLAKE2b-256 checksum
How to use checksums
c9fe37101e12c9031ca3b88305fe95e16ecd9419f5cf334a575b64c86c6e6dc9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / pdf_agent_mcp-0.1.3-py3-none-any.whl

Download URL pdf_agent_mcp-0.1.3-py3-none-any.whl
Size 8.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a83520e2d4b527ee05e041778f5ec6920daa2dc296ef2a42258049a5b6940f2f
BLAKE2b-256 checksum
How to use checksums
4533f224b82ff3af8c3f52ea933dbc5ffe64298fb4e442dd71d4e6c646781585
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page