Stop manually organizing your documents. Let AI do it.
You've got a Paperless-ngx instance. You've got hundreds (thousands?) of documents. You know you should tag them, set correspondents, organize them properly. But who has time for that?
PaperlessMCP connects your Paperless-ngx to any MCP-compatible AI. Now instead of clicking through the UI, you just ask:
"Find all my tax documents from 2023"
"Tag these 50 invoices as 'Business Expense' and set the correspondent to 'Acme Corp'"
"Upload this receipt and figure out what it is"
"What documents am I missing from my insurance folder?"
It's Paperless-ngx on LLM steroids. An interface designed specifically for AI to manage your documents while you do literally anything else.
Everything. Full CRUD on every entity type:
| You Say | AI Does |
|---|---|
| "Find receipts from Amazon over $100" | Searches documents with filters |
| "Tag all 2024 invoices as 'Tax Year 2024'" | Bulk updates dozens of docs at once |
| "Upload this PDF and file it appropriately" | Uploads, auto-tags, sets correspondent |
| "Delete all documents tagged 'Junk'" | Removes with confirmation (dry-run by default) |
| "Create a tag for medical records, make it red" | Creates tag with color |
| "Who sends me the most documents?" | Lists correspondents by document count |
| "Set up a storage path for legal documents" | Creates organized folder structure |
43 tools covering:
- Documents — search, upload, download, update, delete, bulk operations, OCR reprocessing
- Tags — full CRUD with colors and matching rules
- Correspondents — track who sends you stuff
- Document Types — classify invoices, receipts, contracts, whatever
- Storage Paths — organize files with smart templates
- Custom Fields — add your own metadata (dates, amounts, URLs, etc.)
All destructive operations require explicit confirmation and default to dry-run mode. AI can't nuke your archive by accident.
Yes, if:
- You run Paperless-ngx (self-hosted or cloud)
- You use any AI assistant that speaks MCP (Claude, or anything else supporting the protocol)
- You have a backlog of untagged documents and feel guilty about it
- You'd rather say "organize this" than click 47 buttons
- You want to query your documents in plain English
- You think computers should work for you, not the other way around
No, if:
- You don't use Paperless-ngx (this isn't a general document tool)
- You enjoy manually tagging documents (weirdo, but respect)
- You don't trust AI with your files (fair, but you can dry-run everything first)
The sweet spot: You've got Paperless running, you've got an MCP-compatible AI, and you want them to be friends.
-
A Paperless-ngx instance with an API token (Settings → Django Admin → Tokens → Create one for your user)
-
An MCP-compatible AI (Claude Desktop, or anything speaking the protocol)
The fastest path from zero to talking to your documents.
docker run -d \
--name paperless-mcp \
--restart unless-stopped \
-e PAPERLESS_BASE_URL=https://your-paperless.example.com \
-e PAPERLESS_API_TOKEN=your-token-here \
-p 5000:5000 \
ghcr.io/barryw/paperlessmcp:vX.Y.ZGrab the version from the badge above. We don't use
latestbecause you deserve reproducible deployments.
Connect your MCP client to http://localhost:5000/mcp and start talking to your documents.
Add to your config file:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
{
"mcpServers": {
"paperless": {
"command": "dotnet",
"args": ["run", "--project", "/path/to/PaperlessMCP/PaperlessMCP", "--", "--stdio"],
"env": {
"PAPERLESS_BASE_URL": "https://your-paperless.example.com",
"PAPERLESS_API_TOKEN": "your-token-here"
}
}
}
}Restart Claude Desktop. Look for the tools icon — Paperless should be there.
One command if you're already running the server somewhere:
# Connect to a running HTTP/SSE server
claude mcp add --transport sse paperless http://localhost:5000/mcpOr run from source with stdio:
claude mcp add --transport stdio paperless \
-e PAPERLESS_BASE_URL=https://your-paperless.example.com \
-e PAPERLESS_API_TOKEN=your-token-here \
-- dotnet run --project /path/to/PaperlessMCP/PaperlessMCP -- --stdioVerify it's there:
claude mcp listFor the homelabbers running k8s. We include ready-to-use manifests with Kustomize support.
# Clone and customize
git clone https://github.com/barryw/PaperlessMCP.git
cd PaperlessMCP/k8s
# Create your secrets
kubectl create secret generic paperless-mcp \
--from-literal=PAPERLESS_BASE_URL=https://your-paperless.example.com
kubectl create secret generic paperless-token \
--from-literal=token=your-api-token-here
# Deploy (edit the image tag first)
kubectl apply -k .Includes: Deployment, Service, Ingress, Kustomization. Tweak to taste.
For contributors and tinkerers:
git clone https://github.com/barryw/PaperlessMCP.git
cd PaperlessMCP
dotnet run --project PaperlessMCP # HTTP/SSE on :5000
dotnet run --project PaperlessMCP -- --stdio # stdio modeRequires .NET 10 SDK.
43 tools, organized by what they touch. Every entity supports full CRUD.
Documents — the main event
| Tool | What it does |
|---|---|
paperless.documents.search |
Find documents with full-text search and filters |
paperless.documents.get |
Get a document by ID with all metadata |
paperless.documents.upload |
Upload a document (base64) |
paperless.documents.upload_from_path |
Upload from a file path |
paperless.documents.update |
Update title, tags, correspondent, etc. |
paperless.documents.delete |
Delete a document (requires confirmation) |
paperless.documents.bulk_update |
Update multiple documents at once |
paperless.documents.download |
Get download URL for original file |
paperless.documents.preview |
Get preview URL |
paperless.documents.thumbnail |
Get thumbnail URL |
paperless.documents.reprocess |
Re-run OCR on a document |
Tags — organize everything
| Tool | What it does |
|---|---|
paperless.tags.list |
List all tags |
paperless.tags.get |
Get a tag by ID |
paperless.tags.create |
Create a tag with optional color and matching rules |
paperless.tags.update |
Update a tag |
paperless.tags.delete |
Delete a tag |
paperless.tags.bulk_delete |
Delete multiple tags |
Correspondents — who sends you stuff
| Tool | What it does |
|---|---|
paperless.correspondents.list |
List all correspondents |
paperless.correspondents.get |
Get a correspondent by ID |
paperless.correspondents.create |
Create with optional matching rules |
paperless.correspondents.update |
Update a correspondent |
paperless.correspondents.delete |
Delete a correspondent |
paperless.correspondents.bulk_delete |
Delete multiple correspondents |
Document Types — invoices, receipts, contracts...
| Tool | What it does |
|---|---|
paperless.document_types.list |
List all document types |
paperless.document_types.get |
Get a document type by ID |
paperless.document_types.create |
Create with optional matching rules |
paperless.document_types.update |
Update a document type |
paperless.document_types.delete |
Delete a document type |
paperless.document_types.bulk_delete |
Delete multiple document types |
Storage Paths — where things live
| Tool | What it does |
|---|---|
paperless.storage_paths.list |
List all storage paths |
paperless.storage_paths.get |
Get a storage path by ID |
paperless.storage_paths.create |
Create with path template |
paperless.storage_paths.update |
Update a storage path |
paperless.storage_paths.delete |
Delete a storage path |
paperless.storage_paths.bulk_delete |
Delete multiple storage paths |
Custom Fields — your own metadata
| Tool | What it does |
|---|---|
paperless.custom_fields.list |
List all custom field definitions |
paperless.custom_fields.get |
Get a custom field by ID |
paperless.custom_fields.create |
Create a field (string, date, number, monetary, etc.) |
paperless.custom_fields.update |
Update a field definition |
paperless.custom_fields.delete |
Delete a field |
paperless.custom_fields.assign |
Assign a field value to a document |
Health — is it alive?
| Tool | What it does |
|---|---|
paperless.ping |
Check connectivity and auth |
paperless.capabilities |
List supported features |
Environment variables. That's it. No config files to manage.
| Variable | Required | Default | Description |
|---|---|---|---|
PAPERLESS_BASE_URL |
Yes | — | Your Paperless-ngx URL |
PAPERLESS_API_TOKEN |
Yes | — | API token for authentication |
MCP_PORT |
5000 |
Port for HTTP/SSE mode | |
MAX_PAGE_SIZE |
100 |
Max items per paginated request |
Aliases supported: PAPERLESS_URL and PAPERLESS_TOKEN also work if that's your style.
If PaperlessMCP saves you time, consider supporting development:
Every bit helps keep the lights on and the commits flowing.
Yes please. We use trunk-based development with conventional commits.
git clone https://github.com/barryw/PaperlessMCP.git
cd PaperlessMCP
dotnet build
dotnet testThe rules:
- Conventional commits (
feat:,fix:,docs:, etc.) — versions bump automatically - Tests pass or it doesn't merge
- Destructive operations need
confirm=trueand dry-run by default
See CONTRIBUTING.md for the full rundown.
MIT — do whatever you want, just don't blame me.
- Paperless-ngx — the document system that makes this worth building
- Model Context Protocol — the glue between AI and everything else
- Everyone who's ever felt guilty about their untagged documents