loading…
Search for a command to run...
loading…
Model Context Protocol (MCP) server for interacting with Paperless-NGX document management system. Enables AI assistants to manage documents, tags, corresponden
Model Context Protocol (MCP) server for interacting with Paperless-NGX document management system. Enables AI assistants to manage documents, tags, correspondents, and document types through the Paperless-NGX API.
An MCP (Model Context Protocol) server for interacting with a Paperless-NGX API server. This server provides tools for managing documents, tags, correspondents, and document types in your Paperless-NGX instance.
Add these to your MCP config file:
// STDIO mode (recommended for local or CLI use)
"paperless": {
"command": "npx",
"args": [
"-y",
"@baruchiro/paperless-mcp@latest",
],
"env": {
"PAPERLESS_URL": "http://your-paperless-instance:8000",
"PAPERLESS_API_KEY": "your-api-token",
"PAPERLESS_PUBLIC_URL": "https://your-public-domain.com"
}
}
// HTTP mode (recommended for Docker or remote use)
"paperless": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/baruchiro/paperless-mcp:latest",
],
"env": {
"PAPERLESS_URL": "http://your-paperless-instance:8000",
"PAPERLESS_API_KEY": "your-api-token",
"PAPERLESS_PUBLIC_URL": "https://your-public-domain.com"
}
}
Get your API token:
Replace the placeholders in your MCP config:
http://your-paperless-instance:8000 with your Paperless-NGX URLyour-api-token with the token you just generatedhttps://your-public-domain.com with your public Paperless-NGX URL (optional, falls back to PAPERLESS_URL)| Variable | Required | Default | Description |
|---|---|---|---|
PAPERLESS_URL |
Yes | — | Base URL of your Paperless-NGX instance |
PAPERLESS_API_KEY |
Yes | — | API token from your Paperless-NGX profile |
PAPERLESS_PUBLIC_URL |
No | PAPERLESS_URL |
Public-facing URL for document links |
PAPERLESS_API_VERSION |
No | 5 |
Paperless-ngx REST API version. Use 10 for Paperless-ngx v3+. If you see HTTP 406 errors, set this to 10. |
That's it! Now you can ask Claude to help you manage your Paperless-NGX documents.
Here are some things you can ask Claude to do:
Get a paginated list of all documents.
Parameters:
list_documents({
page: 1,
page_size: 25
})
Get a specific document by ID.
Parameters:
get_document({
id: 123
})
Full-text search across documents.
Parameters:
search_documents({
query: "invoice 2024"
})
Download a document file by ID.
Parameters:
download_document({
id: 123,
original: false
})
Get a document thumbnail (image preview) by ID. Returns the thumbnail as a base64-encoded WebP image resource.
Parameters:
get_document_thumbnail({
id: 123
})
Perform bulk operations on multiple documents.
Parameters:
Examples:
// Add a tag to multiple documents
bulk_edit_documents({
documents: [1, 2, 3],
method: "add_tag",
tag: 5
})
// Set correspondent and document type
bulk_edit_documents({
documents: [4, 5],
method: "set_correspondent",
correspondent: 2
})
// Merge documents
bulk_edit_documents({
documents: [6, 7, 8],
method: "merge",
metadata_document_id: 6,
delete_originals: true
})
// Split document into parts
bulk_edit_documents({
documents: [9],
method: "split",
pages: "[1-2,3-4,5]"
})
// Modify multiple tags at once
bulk_edit_documents({
documents: [10, 11],
method: "modify_tags",
add_tags: [1, 2],
remove_tags: [3, 4]
})
// Modify custom fields
bulk_edit_documents({
documents: [12, 13],
method: "modify_custom_fields",
add_custom_fields: [
{ field: 2, value: "year" }
],
remove_custom_fields: []
})
// Set an empty custom field value, e.g. a date field used as a pending marker
bulk_edit_documents({
documents: [14],
method: "modify_custom_fields",
add_custom_fields: [
{ field: 9, value: "" }
],
remove_custom_fields: []
})
Upload a new document to Paperless-NGX.
Parameters:
post_document({
file: "base64_encoded_content",
filename: "invoice.pdf",
title: "January Invoice",
created: "2024-01-19",
correspondent: 1,
document_type: 2,
tags: [1, 3],
archive_serial_number: "2024-001",
custom_fields: [1, 2]
})
Get all tags.
list_tags()
Create a new tag.
Parameters:
create_tag({
name: "Invoice",
color: "#ff0000",
match: "invoice",
matching_algorithm: 5
})
Get all correspondents.
list_correspondents()
Create a new correspondent.
Parameters:
create_correspondent({
name: "ACME Corp",
match: "ACME",
matching_algorithm: 5
})
Get all document types.
list_document_types()
Create a new document type.
Parameters:
create_document_type({
name: "Invoice",
match: "invoice total amount due",
matching_algorithm: 1
})
Get all custom fields.
list_custom_fields()
Get a specific custom field by ID.
Parameters:
get_custom_field({
id: 1
})
Create a new custom field.
Parameters:
create_custom_field({
name: "Invoice Number",
data_type: "string"
})
Update an existing custom field.
Parameters:
update_custom_field({
id: 1,
name: "Updated Invoice Number",
data_type: "string"
})
Delete a custom field.
Parameters:
delete_custom_field({
id: 1
})
Perform bulk operations on multiple custom fields.
Parameters:
bulk_edit_custom_fields({
custom_fields: [1, 2, 3],
operation: "delete"
})
The server will show clear error messages if:
Run the unit test suite (no external dependencies required):
npm test
The E2E suite boots an empty Paperless-ngx instance, runs the compiled MCP server, and drives a deterministic serial scenario through tools/call requests — creating a tag, correspondent, and document type, uploading a PDF, then exercising list / get / search / download / thumbnail / bulk-edit on the same document. No LLM and no Paperless REST client outside MCP.
Prerequisites: Docker, Docker Compose, and jq.
# 1. Build the MCP server
npm run build
# 2. Start Paperless-ngx
docker compose -f docker-compose.e2e.yml up -d
# 3. Wait for Paperless to be ready, then get a token
TOKEN=$(curl -s -X POST http://localhost:8000/api/token/ \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"admin123"}' | jq -r '.token')
# 4. Start the MCP server
node build/index.js --http --port 3001 \
--baseUrl http://localhost:8000 --token "$TOKEN" &
MCP_PID=$!
# 5. Run the E2E tests
MCP_URL=http://localhost:3001/mcp \
PAPERLESS_URL=http://localhost:8000 \
PAPERLESS_TOKEN="$TOKEN" \
npm run test:e2e
# 6. Cleanup
kill "$MCP_PID"
docker compose -f docker-compose.e2e.yml down -v
E2E tests also run automatically in CI on every pull request and push to main, covering both the build/index.js CLI and the published Docker image.
Want to contribute or modify the server? Here's what you need to know:
npm install
node server.js http://localhost:8000 your-test-token
The server is built with:
This MCP server implements endpoints from the Paperless-NGX REST API. For more details about the underlying API, see the official documentation.
The MCP server can be run in two modes:
This is the default mode. The server communicates over stdio, suitable for CLI and direct integrations.
npm run start -- <baseUrl> <token>
To run the server as an HTTP service, use the --http flag. You can also specify the port with --port (default: 3000). This mode requires Express to be installed (it is included as a dependency).
npm run start -- <baseUrl> <token> --http --port 3000
POST /mcp on the specified port./mcp will return 405 Method Not Allowed.In HTTP mode, clients can supply their own Paperless-NGX API token via the standard Authorization header instead of (or in addition to) the server-configured PAPERLESS_API_KEY. The client-supplied token takes precedence.
Authorization: Bearer <paperless-ngx-api-token>
| Scenario | Token used |
|---|---|
Client sends Authorization: Bearer <tok> |
<tok> (client-supplied, takes precedence) |
No header, PAPERLESS_API_KEY env var set |
PAPERLESS_API_KEY from env |
| No header, no env var | 401 Unauthorized |
This allows a single server instance to serve multiple users, each authenticating with their own Paperless-NGX token. The same behaviour applies to both /mcp and /sse endpoints.
The MCP server can be deployed using Docker and Docker Compose. The Docker image automatically runs in HTTP mode with SSE (Server-Sent Events) support on port 3000.
Create a docker-compose.yml file:
services:
paperless-mcp:
container_name: paperless-mcp
image: ghcr.io/baruchiro/paperless-mcp:latest
environment:
- PAPERLESS_URL=http://your-paperless-ngx-server:8000
- PAPERLESS_API_KEY=your-paperless-api-key
- PAPERLESS_PUBLIC_URL=https://paperless-ngx.yourpublicurl.com
ports:
- "3000:3000"
restart: unless-stopped
Then run:
docker-compose up -d
If you're using the Continue VS Code extension, you can configure it to use the Dockerized MCP server via SSE.
Create or edit .continue/mcpServers/paperless-mcp.yaml at your workspace root:
name: Paperless
version: 0.0.1
schema: v1
mcpServers:
- name: Paperless
type: sse
url: http://localhost:3000/sse
Notes:
localhost with your Docker host's IP address or hostname if running on a remote server/sse on the configured port (default: 3000)This project is a fork of nloui/paperless-mcp. Many thanks to the original author for their work. Contributions and improvements may be returned upstream.
To debug the MCP server in VS Code, use the following launch configuration:
{
"type": "node",
"request": "launch",
"name": "Debug Paperless MCP (HTTP, ts-node ESM)",
"program": "${workspaceFolder}/node_modules/ts-node/dist/bin.js",
"args": [
"--esm",
"src/index.ts",
"--http",
"--baseUrl",
"http://your-paperless-instance:8000",
"--token",
"your-api-token",
"--port",
"3002"
],
"env": {
"NODE_OPTIONS": "--loader ts-node/esm",
},
"console": "integratedTerminal",
"skipFiles": [
"<node_internals>/**"
]
}
Important: Before debugging, uncomment the following line in src/index.ts (around line 175):
// await new Promise((resolve) => setTimeout(resolve, 1000000));
This prevents the server from exiting immediately and allows you to set breakpoints and debug the code.
Выполни в терминале:
claude mcp add paperless-mcp --env MCP_PID="" --env MCP_URL="" --env PAPERLESS_API_KEY="" --env PAPERLESS_PUBLIC_URL="" --env PAPERLESS_TOKEN="" --env PAPERLESS_URL="" --env TOKEN="" -- npx -y @baruchiro/paperless-mcppro-tip
Поставил Paperless Mcp? Скажи Claude: «запомни почему я установил Paperless Mcp и что хочу попробовать» — попадёт в твой Vault.
как это работает →Безопасность
Проверь перед установкойЗапросит:
MCP_URLPAPERLESS_API_KEYPAPERLESS_PUBLIC_URLPAPERLESS_TOKENPAPERLESS_URLTOKENАвтоматическая эвристика по публичным данным — не гарантия безопасности.