@kjanat/paperless-mcp
v2.1.0
Published
MCP server for interacting with Paperless-ngx document management system.
Maintainers
Readme
Paperless-ngx MCP Server
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.
Quick Start
Installation
Get your API token:
- Log into your Paperless-ngx instance
- Click your username in the top right
- Select "My Profile"
- Click the circular arrow button to generate a new token
Add it to your MCP client configuration (using env vars):
{ "mcpServers": { "paperless": { "command": "bunx", // or npx "args": ["@kjanat/paperless-mcp"], "env": { "PAPERLESS_URL": "http://your-paperless-instance:8000", "PAPERLESS_API_KEY": "your-api-token", }, }, }, }Or pass them as positional arguments:
{ "mcpServers": { "paperless": { "command": "bunx", // or npx "args": [ "@kjanat/paperless-mcp", "http://your-paperless-instance:8000", "your-api-token", ], }, }, }CLI args take precedence over env vars when both are provided.
That's it!
Agent Skill
This package ships an Agent Skill in
skills/paperless-ngx/ with decision trees, tool reference docs, query syntax
guide, and workflow templates for AI agents.
View the skill on the registry: https://skills.sh/kjanat/paperless-mcp/paperless-ngx
Add using:
bunx skills add https://github.com/kjanat/paperless-mcp --skill paperless-ngx# or npx -y skills...
Example Usage
Here are some things you can ask Claude to do:
- "Show me all documents tagged as 'Invoice'"
- "Search for documents containing 'tax return'"
- "Create a new tag called 'Receipts' with color #FF0000"
- "Download document #123"
- "List all correspondents"
- "Create a new document type called 'Bank Statement'"
Available Tools
Document Operations
get_document
Get a specific document by ID.
Parameters:
id: Document ID
get_document({
id: 123,
});search_documents
Full-text search across documents.
Parameters:
query: Search query string
search_documents({
query: "invoice 2024",
});download_document
Download a document file by ID.
Parameters:
id: Document IDoriginal(optional): If true, downloads original file instead of archived version
download_document({
id: 123,
original: false,
});bulk_edit_documents
Perform bulk operations on multiple documents.
Parameters:
documents: Array of document IDsmethod: One of:set_correspondent: Set correspondent for documentsset_document_type: Set document type for documentsset_storage_path: Set storage path for documentsadd_tag: Add a tag to documentsremove_tag: Remove a tag from documentsmodify_tags: Add and/or remove multiple tagsdelete: Delete documentsreprocess: Reprocess documentsset_permissions: Set document permissionsmerge: Merge multiple documentssplit: Split a document into multiple documentsrotate: Rotate document pagesdelete_pages: Delete specific pages from a document
- Additional parameters based on
method:correspondent: ID for set_correspondentdocument_type: ID for set_document_typestorage_path: ID for set_storage_pathtag: ID for add_tag/remove_tagadd_tags: Array of tag IDs for modify_tagsremove_tags: Array of tag IDs for modify_tagspermissions: Object for set_permissions with owner, permissions, merge flagmetadata_document_id: ID for merge to specify metadata sourcedelete_originals: Boolean for merge/splitpages: String for split "[1,2-3,4,5-7]" ordelete_pages"[2,3,4]"degrees: Number for rotate (90, 180, or 270)
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],
});post_document
Upload a new document to Paperless-ngx.
Parameters:
file: Base64 encoded file contentfilename: Name of the filetitle(optional): Title for the documentcreated(optional): DateTime when the document was created (e.g. "2024-01-19" or "2024-01-19 06:15:00+02:00")correspondent(optional): ID of a correspondentdocument_type(optional): ID of a document typestorage_path(optional): ID of a storage pathtags(optional): Array of tag IDsarchive_serial_number(optional): Archive serial numbercustom_fields(optional): Array of custom field IDs
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",
});Tag Operations
list_tags
Get all tags.
list_tags();create_tag
Create a new tag.
Parameters:
name: Tag namecolor(optional): Hex color code (e.g. "#ff0000")match(optional): Text pattern to matchmatching_algorithm(optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
create_tag({
name: "Invoice",
color: "#ff0000",
match: "invoice",
matching_algorithm: 5,
});update_tag
Update an existing tag's name, color, or matching rules.
Parameters:
id: Tag IDname: New tag namecolor(optional): Hex color code (e.g. "#ff0000")match(optional): Text pattern to matchmatching_algorithm(optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
update_tag({
id: 5,
name: "Invoices",
color: "#00ff00",
});delete_tag
Permanently delete a tag. Removes it from all documents.
Parameters:
id: Tag ID
delete_tag({
id: 5,
});bulk_edit_tags
Bulk set permissions or delete multiple tags.
Parameters:
tag_ids: Array of tag IDsoperation: "set_permissions" or "delete"owner(optional): User ID (for set_permissions)permissions(optional): Object with view/change user and group IDsmerge(optional): Merge with existing permissions (default false)
bulk_edit_tags({
tag_ids: [1, 2, 3],
operation: "delete",
});Correspondent Operations
list_correspondents
Get all correspondents.
list_correspondents();create_correspondent
Create a new correspondent.
Parameters:
name: Correspondent namematch(optional): Text pattern to matchmatching_algorithm(optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
create_correspondent({
name: "ACME Corp",
match: "ACME",
matching_algorithm: 5,
});bulk_edit_correspondents
Bulk set permissions or delete multiple correspondents.
Parameters:
correspondent_ids: Array of correspondent IDsoperation: "set_permissions" or "delete"owner(optional): User ID (for set_permissions)permissions(optional): Object with view/change user and group IDsmerge(optional): Merge with existing permissions (default false)
bulk_edit_correspondents({
correspondent_ids: [1, 2],
operation: "delete",
});Document Type Operations
list_document_types
Get all document types.
list_document_types();create_document_type
Create a new document type.
Parameters:
name: Document type namematch(optional): Text pattern to matchmatching_algorithm(optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
create_document_type({
name: "Invoice",
match: "invoice total amount due",
matching_algorithm: 1,
});bulk_edit_document_types
Bulk set permissions or delete multiple document types.
Parameters:
document_type_ids: Array of document type IDsoperation: "set_permissions" or "delete"owner(optional): User ID (for set_permissions)permissions(optional): Object with view/change user and group IDsmerge(optional): Merge with existing permissions (default false)
bulk_edit_document_types({
document_type_ids: [1, 2],
operation: "delete",
});Error Handling
The server will show clear error messages if:
- The Paperless-ngx URL or API token is incorrect
- The Paperless-ngx server is unreachable
- The requested operation fails
- The provided parameters are invalid
Development
Want to contribute or modify the server? Here's what you need to know:
Clone the repository
Install dependencies:
bun installMake your changes in
src/(seesrc/tools/for MCP tools,src/api/for API client)Test locally:
bun src/index.ts http://localhost:8000 your-test-token
The server is built with:
- @modelcontextprotocol/sdk: Official TypeScript SDK for building MCP servers
- zod: TypeScript-first schema validation
API Documentation
This MCP server implements endpoints from the Paperless-ngx REST API. For more details about the underlying API, see the official documentation.
Running the MCP Server
The MCP server can be run in two modes:
1. stdio (default)
This is the default mode. The server communicates over stdio, suitable for CLI and direct integrations.
# via .env file (Bun loads .env automatically)
bun start
# via inline env vars
PAPERLESS_URL=http://localhost:8000 PAPERLESS_API_KEY=your-token bun start
# via positional args
bun start http://localhost:8000 your-token[!TIP] When using Bun, env vars in a
.envfile are loaded automatically — no extra setup needed. Just create a.envwithPAPERLESS_URLandPAPERLESS_API_KEYand runbun start.
2. HTTP (Streamable HTTP Transport)
To run the server as an HTTP service, use the --http flag. You can also specify the port with --port (default: 3000).
PAPERLESS_URL=http://localhost:8000 PAPERLESS_API_KEY=your-token bun start --http --port 3000With a .env file, this simplifies to bun start --http.
- The MCP API will be available at
POST /mcpon the specified port. - Each request is handled statelessly, following the StreamableHTTPServerTransport pattern.
- GET and DELETE requests to
/mcpwill return 405 Method Not Allowed.
