Metadata-Version: 2.4
Name: pdf-extractor-mcp
Version: 0.1.0
Summary: MCP server exposing the PDF Extractor API as tools.
Author: Boris Besky
License: Apache-2.0
Project-URL: Homepage, https://github.com/BorisBesky/pdf-extractor
Project-URL: Issues, https://github.com/BorisBesky/pdf-extractor/issues
Project-URL: Source, https://github.com/BorisBesky/pdf-extractor/tree/main/mcp_server
Keywords: mcp,model-context-protocol,pdf,pdf-extractor,claude,anthropic
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Text Processing :: General
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp>=1.2.0
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Dynamic: license-file

# PDF Extractor MCP Server

A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes
the [PDF Extractor](https://www.pdf-xtract.com) 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:

```bash
# 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/account/tokens> and export
it before running the server:

```bash
export PDF_EXTRACTOR_API_KEY=pxt_...
# Optional: point at a self-hosted deployment
# export PDF_EXTRACTOR_API_URL=https://pdf.example.com
```

## Run

```bash
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`:

```json
{
  "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.pdf` as 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:

1. **MCP Inspector** (interactive UI):

   ```bash
   npx @modelcontextprotocol/inspector pdf-extractor-mcp
   ```

   Lists every tool, lets you fill in arguments, and shows the live response.

2. **stdio smoke test** — confirms the binary starts and registers tools:

   ```bash
   echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
     | pdf-extractor-mcp
   ```

3. **Unit tests** (no network, no API key required):

   ```bash
   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:

   ```bash
   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:

1. Bump `version` in `mcp_server/pyproject.toml`.
2. Tag the commit: `git tag mcp-v0.1.0 && git push origin mcp-v0.1.0`.
3. The workflow builds the sdist + wheel and publishes via PyPI Trusted
   Publishing (OIDC — no API token stored). The PyPI project and GitHub OIDC
   binding need to be configured once by the project owner.

## Notes

- Pass `store_file=true` (the default) for large PDFs - the API returns
  presigned URLs instead of base64 blobs. Use `download_file` to fetch them.
- When `store_file=false`, the server truncates `FileData` in its response
  summary and adds `FileDataLength`; 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.
