From 51d4798597890e8bda0b183a1aca85ecb51382f0 Mon Sep 17 00:00:00 2001 From: Barry Walker Date: Tue, 13 Jan 2026 14:09:02 -0500 Subject: [PATCH] Refactor docs: slim README, separate API reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Condensed README to ~190 lines (was 870+) - Moved full API reference to docs/API_REFERENCE.md - Added tools summary table with link to full docs - Removed redundant nested README 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- PaperlessMCP/README.md | 341 ----------------- README.md | 843 ++++------------------------------------- docs/API_REFERENCE.md | 547 ++++++++++++++++++++++++++ 3 files changed, 626 insertions(+), 1105 deletions(-) delete mode 100644 PaperlessMCP/README.md create mode 100644 docs/API_REFERENCE.md diff --git a/PaperlessMCP/README.md b/PaperlessMCP/README.md deleted file mode 100644 index 30f6e80..0000000 --- a/PaperlessMCP/README.md +++ /dev/null @@ -1,341 +0,0 @@ -# PaperlessMCP - -A Model Context Protocol (MCP) server that provides AI-first tooling for managing [Paperless-ngx](https://docs.paperless-ngx.com/) instances via the official REST API. - -## Features - -- **Full Document Management**: Search, upload, download, update, and delete documents -- **Metadata Management**: CRUD operations for tags, correspondents, document types, storage paths, and custom fields -- **Bulk Operations**: Batch updates and deletions with dry-run support -- **Safety Guardrails**: Destructive operations require explicit confirmation -- **Dual Transport**: Supports both HTTP (for remote access) and stdio (for local Claude Desktop) -- **Structured Output**: All responses follow a consistent JSON envelope format - -## Requirements - -- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) (Preview) -- A running [Paperless-ngx](https://docs.paperless-ngx.com/) instance -- API token from your Paperless-ngx instance - -## Getting Started - -### Configuration - -Set the following environment variables: - -| Variable | Required | Default | Description | -|----------|----------|---------|-------------| -| `PAPERLESS_BASE_URL` | Yes | - | Base URL of your Paperless-ngx instance | -| `PAPERLESS_API_TOKEN` | Yes | - | API token for authentication | -| `MCP_LOG_LEVEL` | No | `Information` | Logging level | -| `MAX_PAGE_SIZE` | No | `100` | Maximum page size for paginated requests | -| `MCP_PORT` | No | `5000` | HTTP port for remote transport | - -### Getting an API Token - -1. Log into your Paperless-ngx instance -2. Go to Settings > Administration -3. Create a new API token or use an existing one - -### Running Locally (stdio transport) - -For use with Claude Desktop or other local MCP clients: - -```bash -# Clone and build -cd PaperlessMCP -dotnet build - -# Run with stdio transport -PAPERLESS_BASE_URL=https://your-instance.com \ -PAPERLESS_API_TOKEN=your-token \ -dotnet run -- --stdio -``` - -### Running as HTTP Server - -For remote access or containerized deployments: - -```bash -# Run with HTTP transport (default) -PAPERLESS_BASE_URL=https://your-instance.com \ -PAPERLESS_API_TOKEN=your-token \ -dotnet run -``` - -The MCP endpoint will be available at `http://localhost:5000/mcp` - -### Docker - -```bash -# Using docker-compose -echo "PAPERLESS_BASE_URL=https://your-instance.com" > .env -echo "PAPERLESS_API_TOKEN=your-token" >> .env -docker-compose up -d - -# Or build and run directly -docker build -t paperless-mcp . -docker run -p 5000:5000 \ - -e PAPERLESS_BASE_URL=https://your-instance.com \ - -e PAPERLESS_API_TOKEN=your-token \ - paperless-mcp -``` - -## Claude Desktop Configuration - -Add to your Claude Desktop MCP configuration (`~/.config/claude/claude_desktop_config.json` on macOS/Linux or `%APPDATA%\Claude\claude_desktop_config.json` on Windows): - -```json -{ - "mcpServers": { - "paperless": { - "command": "dotnet", - "args": ["run", "--project", "/path/to/PaperlessMCP", "--", "--stdio"], - "env": { - "PAPERLESS_BASE_URL": "https://your-paperless-instance.com", - "PAPERLESS_API_TOKEN": "your-api-token" - } - } - } -} -``` - -## Available Tools - -### Health & Capability - -| Tool | Description | -|------|-------------| -| `paperless.ping` | Verify connectivity and authentication | -| `paperless.capabilities` | List supported endpoints and features | - -### Documents - -| Tool | Description | -|------|-------------| -| `paperless.documents.search` | Full-text search with filters | -| `paperless.documents.get` | Get document by ID | -| `paperless.documents.download` | Get download URLs | -| `paperless.documents.preview` | Get preview URL | -| `paperless.documents.thumbnail` | Get thumbnail URL | -| `paperless.documents.upload` | Upload new document | -| `paperless.documents.update` | Update document metadata | -| `paperless.documents.delete` | Delete document (requires confirmation) | -| `paperless.documents.bulk_update` | Bulk operations (with dry-run) | -| `paperless.documents.reprocess` | Reprocess document OCR | - -### Tags - -| Tool | Description | -|------|-------------| -| `paperless.tags.list` | List all tags | -| `paperless.tags.get` | Get tag by ID | -| `paperless.tags.create` | Create new tag | -| `paperless.tags.update` | Update tag | -| `paperless.tags.delete` | Delete tag (requires confirmation) | -| `paperless.tags.bulk_delete` | Bulk delete tags | - -### Correspondents - -| Tool | Description | -|------|-------------| -| `paperless.correspondents.list` | List all correspondents | -| `paperless.correspondents.get` | Get correspondent by ID | -| `paperless.correspondents.create` | Create new correspondent | -| `paperless.correspondents.update` | Update correspondent | -| `paperless.correspondents.delete` | Delete correspondent (requires confirmation) | -| `paperless.correspondents.bulk_delete` | Bulk delete correspondents | - -### Document Types - -| Tool | Description | -|------|-------------| -| `paperless.document_types.list` | List all document types | -| `paperless.document_types.get` | Get document type by ID | -| `paperless.document_types.create` | Create new document type | -| `paperless.document_types.update` | Update document type | -| `paperless.document_types.delete` | Delete document type (requires confirmation) | -| `paperless.document_types.bulk_delete` | Bulk delete document types | - -### Storage Paths - -| Tool | Description | -|------|-------------| -| `paperless.storage_paths.list` | List all storage paths | -| `paperless.storage_paths.get` | Get storage path by ID | -| `paperless.storage_paths.create` | Create new storage path | -| `paperless.storage_paths.update` | Update storage path | -| `paperless.storage_paths.delete` | Delete storage path (requires confirmation) | -| `paperless.storage_paths.bulk_delete` | Bulk delete storage paths | - -### Custom Fields - -| Tool | Description | -|------|-------------| -| `paperless.custom_fields.list` | List all custom field definitions | -| `paperless.custom_fields.get` | Get custom field by ID | -| `paperless.custom_fields.create` | Create new custom field | -| `paperless.custom_fields.update` | Update custom field | -| `paperless.custom_fields.delete` | Delete custom field (requires confirmation) | -| `paperless.custom_fields.assign` | Assign field value to document | - -## Response Format - -All tools return responses in a consistent format: - -### Success Response - -```json -{ - "ok": true, - "result": { ... }, - "meta": { - "request_id": "uuid", - "page": 1, - "page_size": 25, - "total": 123, - "next": null, - "paperless_base_url": "https://your-instance.com" - }, - "warnings": [] -} -``` - -### Error Response - -```json -{ - "ok": false, - "error": { - "code": "NOT_FOUND", - "message": "Document with ID 123 not found", - "details": null - }, - "meta": { - "request_id": "uuid", - "paperless_base_url": "https://your-instance.com" - } -} -``` - -### Error Codes - -| Code | Description | -|------|-------------| -| `AUTH_FAILED` | Authentication failed | -| `NOT_FOUND` | Resource not found | -| `VALIDATION` | Invalid input | -| `UPSTREAM_ERROR` | Paperless API error | -| `RATE_LIMIT` | Rate limited | -| `CONFIRMATION_REQUIRED` | Destructive operation requires confirmation | -| `UNKNOWN` | Unknown error | - -## Example Tool Calls - -### Search for Documents - -```json -{ - "tool": "paperless.documents.search", - "arguments": { - "query": "invoice", - "tags": "1,2", - "correspondent": 5, - "page": 1, - "pageSize": 25 - } -} -``` - -### Upload a Document - -```json -{ - "tool": "paperless.documents.upload", - "arguments": { - "fileContent": "base64-encoded-content", - "fileName": "invoice.pdf", - "title": "January Invoice", - "tags": "1,3", - "correspondent": 5 - } -} -``` - -### Bulk Add Tag (Dry Run) - -```json -{ - "tool": "paperless.documents.bulk_update", - "arguments": { - "documentIds": "1,2,3,4,5", - "operation": "add_tag", - "value": 10, - "dryRun": true, - "confirm": false - } -} -``` - -### Bulk Add Tag (Execute) - -```json -{ - "tool": "paperless.documents.bulk_update", - "arguments": { - "documentIds": "1,2,3,4,5", - "operation": "add_tag", - "value": 10, - "dryRun": false, - "confirm": true - } -} -``` - -### Delete Document with Confirmation - -```json -{ - "tool": "paperless.documents.delete", - "arguments": { - "id": 123, - "confirm": true - } -} -``` - -## Testing with curl - -### Test HTTP endpoint - -```bash -# Check if server is running -curl http://localhost:5000/mcp - -# The MCP protocol uses JSON-RPC, so you'd typically -# connect using an MCP client rather than raw curl -``` - -## Development - -```bash -# Restore dependencies -dotnet restore - -# Build -dotnet build - -# Run tests (if any) -dotnet test - -# Run in development mode -dotnet run -``` - -## License - -MIT - -## Contributing - -Contributions are welcome! Please feel free to submit issues and pull requests. diff --git a/README.md b/README.md index 37a3cde..407e679 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,10 @@ [![.NET 10](https://img.shields.io/badge/.NET-10.0-512BD4?logo=dotnet)](https://dotnet.microsoft.com/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![MCP](https://img.shields.io/badge/MCP-0.2.0--preview.1-blue)](https://modelcontextprotocol.io/) -[![Build Status](https://img.shields.io/badge/build-passing-brightgreen)](https://github.com/) *Seamlessly integrate your Paperless-ngx document management system with Claude via the Model Context Protocol* -[Features](#-features) • [Installation](#-installation) • [Configuration](#-configuration) • [Usage](#-usage) • [API Reference](#-api-reference) • [Contributing](#-contributing) +[Features](#-features) • [Installation](#-installation) • [Configuration](#-configuration) • [API Reference](docs/API_REFERENCE.md) • [Contributing](#-contributing) @@ -19,7 +18,7 @@ ## 🎯 Overview -PaperlessMCP is a powerful Model Context Protocol (MCP) server that bridges [Paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) with AI assistants like Claude. It provides comprehensive document management capabilities through a modern, type-safe .NET implementation with built-in retry logic and error handling. +PaperlessMCP is a Model Context Protocol (MCP) server that bridges [Paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) with AI assistants like Claude. It provides comprehensive document management capabilities through a modern, type-safe .NET implementation. ### What is MCP? @@ -29,27 +28,16 @@ The [Model Context Protocol](https://modelcontextprotocol.io/) enables AI models ## ✨ Features -### 📚 Document Operations -- **Search & Discovery** - Full-text search with advanced filtering (tags, dates, correspondents, types) -- **Document Management** - Create, read, update, delete documents with metadata -- **Bulk Operations** - Process multiple documents at once (add/remove tags, set properties, reprocess) -- **File Uploads** - Support for base64 content or local file paths with automatic retries -- **Download URLs** - Get preview, thumbnail, and original file URLs +| Category | Capabilities | +|----------|-------------| +| **Documents** | Search, upload, download, update, delete, bulk operations, reprocess OCR | +| **Tags** | Create, manage, auto-tagging rules, bulk delete | +| **Correspondents** | Track document sources with auto-assignment | +| **Document Types** | Classify documents with custom types | +| **Storage Paths** | Organize files with template-based paths | +| **Custom Fields** | Define metadata fields (string, date, boolean, monetary, etc.) | -### 🏷️ Metadata Management -- **Tags** - Create, organize, and manage document tags with auto-tagging rules -- **Correspondents** - Track document sources and senders -- **Document Types** - Classify documents with custom types -- **Storage Paths** - Organize files with template-based storage paths -- **Custom Fields** - Define and assign custom metadata fields (string, date, boolean, monetary, etc.) - -### 🔧 Developer Features -- **Dual Transport** - Supports both stdio (Claude Desktop) and HTTP transports -- **Pagination** - Efficient handling of large datasets with configurable page sizes -- **Dry Run Mode** - Preview destructive operations before execution -- **Retry Logic** - Built-in exponential backoff for transient failures -- **Health Checks** - Verify connectivity and discover API capabilities -- **Comprehensive Tests** - Full test suite with 100% coverage +**Developer Features:** Dual transport (stdio/HTTP), pagination, dry-run mode, retry logic, comprehensive tests --- @@ -57,810 +45,137 @@ The [Model Context Protocol](https://modelcontextprotocol.io/) enables AI models ### Prerequisites -- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) (or later) +- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) - A running [Paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) instance - Paperless-ngx API token ([How to get one](https://docs.paperless-ngx.com/api/#authorization)) -### Method 1: Clone and Build +### Quick Start ```bash -# Clone the repository git clone https://github.com/barryw/PaperlessMCP.git cd PaperlessMCP - -# Build the project dotnet build - -# Run tests (optional) -dotnet test ``` -### Method 2: Docker +### Claude Desktop Integration -```bash -# Build the Docker image -docker build -t paperless-mcp ./PaperlessMCP - -# Run with environment variables -docker run -d \ - -e PAPERLESS_BASE_URL=https://your-paperless-instance.com \ - -e PAPERLESS_API_TOKEN=your-token-here \ - -p 5000:5000 \ - paperless-mcp -``` - -### Method 3: Claude Desktop Integration - -1. Build the project: - ```bash - cd PaperlessMCP - dotnet build -c Release - ``` - -2. Add to your Claude Desktop configuration (`claude_desktop_config.json`): - - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` - - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` - - ```json - { - "mcpServers": { - "paperless": { - "command": "dotnet", - "args": [ - "run", - "--project", - "/absolute/path/to/PaperlessMCP/PaperlessMCP", - "--", - "--stdio" - ], - "env": { - "PAPERLESS_BASE_URL": "https://your-paperless-instance.com", - "PAPERLESS_API_TOKEN": "your-token-here" - } - } - } - } - ``` - -3. Restart Claude Desktop - ---- - -## ⚙️ Configuration - -### Environment Variables - -PaperlessMCP supports multiple configuration methods. Environment variables take precedence over `appsettings.json`. - -| Variable | Aliases | Required | Default | Description | -|----------|---------|----------|---------|-------------| -| `PAPERLESS_BASE_URL` | `PAPERLESS_URL` | ✅ Yes | - | Base URL of your Paperless-ngx instance | -| `PAPERLESS_API_TOKEN` | `PAPERLESS_TOKEN` | ✅ Yes | - | API authentication token | -| `MAX_PAGE_SIZE` | - | ❌ No | `100` | Maximum items per page for paginated requests | -| `MCP_PORT` | - | ❌ No | `5000` | HTTP server port (HTTP mode only) | - -### appsettings.json - -Alternatively, configure via `appsettings.json`: +Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS): ```json { - "Paperless": { - "BaseUrl": "https://your-paperless-instance.com", - "ApiToken": "your-token-here", - "MaxPageSize": 100 - }, - "Mcp": { - "Port": 5000 - }, - "Logging": { - "LogLevel": { - "Default": "Information", - "ModelContextProtocol": "Debug" + "mcpServers": { + "paperless": { + "command": "dotnet", + "args": ["run", "--project", "/path/to/PaperlessMCP/PaperlessMCP", "--", "--stdio"], + "env": { + "PAPERLESS_BASE_URL": "https://your-paperless-instance.com", + "PAPERLESS_API_TOKEN": "your-token-here" + } } } } ``` -### Transport Modes +### Docker -- **stdio mode** (for Claude Desktop): `dotnet run -- --stdio` -- **HTTP mode** (for remote access): `dotnet run` (default) +```bash +docker build -t paperless-mcp ./PaperlessMCP +docker run -e PAPERLESS_BASE_URL=https://... -e PAPERLESS_API_TOKEN=... -p 5000:5000 paperless-mcp +``` + +--- + +## ⚙️ Configuration + +| Variable | Required | Default | Description | +|----------|----------|---------|-------------| +| `PAPERLESS_BASE_URL` | Yes | - | Base URL of your Paperless-ngx instance | +| `PAPERLESS_API_TOKEN` | Yes | - | API authentication token | +| `MAX_PAGE_SIZE` | No | 100 | Maximum items per page | +| `MCP_PORT` | No | 5000 | HTTP server port (HTTP mode only) | + +**Transport Modes:** +- `dotnet run -- --stdio` — For Claude Desktop +- `dotnet run` — HTTP mode at `http://localhost:5000/mcp` --- ## 💻 Usage -### With Claude Desktop - -Once configured, simply ask Claude to interact with your documents: +Once configured, ask Claude to interact with your documents: ``` "Search for all invoices from 2024" -"Upload this PDF to Paperless and tag it as 'Receipt'" -"Show me documents with the tag 'Important' that have no correspondent" +"Upload this PDF and tag it as 'Receipt'" +"Show me documents tagged 'Important' with no correspondent" "Create a new tag called 'Urgent' with a red color" ``` -### HTTP Endpoint - -When running in HTTP mode, the MCP endpoint is available at: - -``` -http://localhost:5000/mcp -``` - -### Running the Server - -```bash -# Stdio mode (Claude Desktop) -dotnet run --project PaperlessMCP/PaperlessMCP -- --stdio - -# HTTP mode (remote access) -dotnet run --project PaperlessMCP/PaperlessMCP - -# Docker -docker run -e PAPERLESS_BASE_URL=... -e PAPERLESS_API_TOKEN=... -p 5000:5000 paperless-mcp -``` - --- ## 📖 API Reference -### Health & Capabilities - -#### `paperless.ping` -Verify connectivity and authentication with Paperless-ngx. - -**Returns:** Connection status and server version - -#### `paperless.capabilities` -Return supported API endpoints and detected Paperless-ngx version information. - -**Returns:** Available endpoints, bulk operations, and server capabilities - ---- - -### Document Operations - -#### `paperless.documents.search` -Search for documents with full-text search and filters. - -**Parameters:** -- `query` (string, optional) - Full-text search query -- `tags` (string, optional) - Filter by tag IDs (comma-separated) -- `tagsExclude` (string, optional) - Exclude tag IDs (comma-separated) -- `correspondent` (int, optional) - Filter by correspondent ID -- `documentType` (int, optional) - Filter by document type ID -- `storagePath` (int, optional) - Filter by storage path ID -- `createdAfter` (string, optional) - Filter by creation date (YYYY-MM-DD) -- `createdBefore` (string, optional) - Filter by creation date (YYYY-MM-DD) -- `addedAfter` (string, optional) - Filter by added date (YYYY-MM-DD) -- `addedBefore` (string, optional) - Filter by added date (YYYY-MM-DD) -- `archiveSerialNumber` (int, optional) - Filter by archive serial number -- `page` (int, default: 1) - Page number -- `pageSize` (int, default: 25, max: 100) - Results per page -- `ordering` (string, optional) - Sort field (e.g., 'created', '-created', 'title') -- `includeContent` (bool, default: false) - Include document content in results -- `contentMaxLength` (int, default: 500) - Max content length when `includeContent=true` - -**Returns:** Paginated list of document summaries - -#### `paperless.documents.get` -Get a document by its ID. - -**Parameters:** -- `id` (int, required) - Document ID - -**Returns:** Complete document details including content - -#### `paperless.documents.download` -Get download URLs for a document's original file, preview, and thumbnail. - -**Parameters:** -- `id` (int, required) - Document ID - -**Returns:** Object with download URLs (`original_url`, `preview_url`, `thumbnail_url`) - -#### `paperless.documents.preview` -Get the preview URL for a document. - -**Parameters:** -- `id` (int, required) - Document ID - -**Returns:** Preview URL - -#### `paperless.documents.thumbnail` -Get the thumbnail URL for a document. - -**Parameters:** -- `id` (int, required) - Document ID - -**Returns:** Thumbnail URL - -#### `paperless.documents.upload` -Upload a new document to Paperless-ngx via base64-encoded content. - -**Parameters:** -- `fileContent` (string, required) - Base64-encoded file content -- `fileName` (string, required) - Original filename with extension -- `title` (string, optional) - Document title -- `correspondent` (int, optional) - Correspondent ID -- `documentType` (int, optional) - Document type ID -- `storagePath` (int, optional) - Storage path ID -- `tags` (string, optional) - Tag IDs (comma-separated) -- `archiveSerialNumber` (int, optional) - Archive serial number -- `created` (string, optional) - Created date (YYYY-MM-DD) - -**Returns:** Task ID and upload status - -**Note:** For large files, use `paperless.documents.upload_from_path` instead. - -#### `paperless.documents.upload_from_path` -Upload a document from a local file path. More reliable for large files. - -**Parameters:** -- `filePath` (string, required) - Absolute path to the file -- `title` (string, optional) - Document title (defaults to filename) -- `correspondent` (int, optional) - Correspondent ID -- `documentType` (int, optional) - Document type ID -- `storagePath` (int, optional) - Storage path ID -- `tags` (string, optional) - Tag IDs (comma-separated) -- `archiveSerialNumber` (int, optional) - Archive serial number -- `created` (string, optional) - Created date (YYYY-MM-DD) - -**Returns:** Task ID, upload status, and file information - -**Features:** Supports `~/` expansion, automatic retries, file validation - -#### `paperless.documents.update` -Update document metadata. - -**Parameters:** -- `id` (int, required) - Document ID -- `title` (string, optional) - New title -- `correspondent` (int, optional) - Correspondent ID (use -1 to clear) -- `documentType` (int, optional) - Document type ID (use -1 to clear) -- `storagePath` (int, optional) - Storage path ID (use -1 to clear) -- `tags` (string, optional) - Tag IDs to set (comma-separated) -- `archiveSerialNumber` (int, optional) - Archive serial number -- `created` (string, optional) - Created date (YYYY-MM-DD) - -**Returns:** Updated document - -#### `paperless.documents.delete` -Delete a document. Requires explicit confirmation. - -**Parameters:** -- `id` (int, required) - Document ID -- `confirm` (bool, default: false) - Must be true to confirm deletion - -**Returns:** Deletion status or dry-run preview - -**Safety:** Without `confirm=true`, returns a dry-run preview showing what would be deleted. - -#### `paperless.documents.bulk_update` -Perform bulk operations on multiple documents. - -**Parameters:** -- `documentIds` (string, required) - Document IDs (comma-separated) -- `operation` (string, required) - Operation: `add_tag`, `remove_tag`, `set_correspondent`, `set_document_type`, `set_storage_path`, `delete`, `reprocess` -- `value` (int, optional) - Parameter value (e.g., tag ID, correspondent ID) -- `dryRun` (bool, default: true) - Preview changes without applying -- `confirm` (bool, default: false) - Must be true to execute - -**Returns:** Affected document IDs and operation status - -**Safety:** Defaults to dry-run mode to prevent accidental changes. - -#### `paperless.documents.reprocess` -Reprocess a document's OCR and content extraction. - -**Parameters:** -- `id` (int, required) - Document ID -- `confirm` (bool, default: false) - Must be true to confirm reprocessing - -**Returns:** Processing status - ---- - -### Tag Operations - -#### `paperless.tags.list` -List all tags with pagination. - -**Parameters:** -- `page` (int, default: 1) - Page number -- `pageSize` (int, default: 25, max: 100) - Results per page -- `ordering` (string, optional) - Sort field (e.g., 'name', '-document_count') - -**Returns:** Paginated list of tags - -#### `paperless.tags.get` -Get a tag by its ID. - -**Parameters:** -- `id` (int, required) - Tag ID - -**Returns:** Tag details - -#### `paperless.tags.create` -Create a new tag. - -**Parameters:** -- `name` (string, required) - Tag name -- `color` (string, optional) - Hex color (e.g., '#ff0000') -- `match` (string, optional) - Match pattern for auto-tagging -- `matchingAlgorithm` (int, optional) - Matching algorithm (0=None, 1=Any, 2=All, 3=Literal, 4=Regex, 5=Fuzzy, 6=Auto) -- `isInboxTag` (bool, optional) - Mark as inbox tag - -**Returns:** Created tag - -#### `paperless.tags.update` -Update an existing tag. - -**Parameters:** -- `id` (int, required) - Tag ID -- `name` (string, optional) - New name -- `color` (string, optional) - Hex color -- `match` (string, optional) - Match pattern -- `matchingAlgorithm` (int, optional) - Matching algorithm -- `isInboxTag` (bool, optional) - Inbox tag status - -**Returns:** Updated tag - -#### `paperless.tags.delete` -Delete a tag. Requires explicit confirmation. - -**Parameters:** -- `id` (int, required) - Tag ID -- `confirm` (bool, default: false) - Must be true to confirm deletion - -**Returns:** Deletion status or dry-run preview - -#### `paperless.tags.bulk_delete` -Delete multiple tags. - -**Parameters:** -- `tagIds` (string, required) - Tag IDs (comma-separated) -- `dryRun` (bool, default: true) - Preview changes without applying -- `confirm` (bool, default: false) - Must be true to execute - -**Returns:** Affected tag IDs and operation status - ---- - -### Correspondent Operations - -#### `paperless.correspondents.list` -List all correspondents with pagination. - -**Parameters:** -- `page` (int, default: 1) - Page number -- `pageSize` (int, default: 25, max: 100) - Results per page -- `ordering` (string, optional) - Sort field (e.g., 'name', '-document_count', 'last_correspondence') - -**Returns:** Paginated list of correspondents - -#### `paperless.correspondents.get` -Get a correspondent by its ID. - -**Parameters:** -- `id` (int, required) - Correspondent ID - -**Returns:** Correspondent details - -#### `paperless.correspondents.create` -Create a new correspondent. - -**Parameters:** -- `name` (string, required) - Correspondent name -- `match` (string, optional) - Match pattern for auto-assignment -- `matchingAlgorithm` (int, optional) - Matching algorithm (0=None, 1=Any, 2=All, 3=Literal, 4=Regex, 5=Fuzzy, 6=Auto) - -**Returns:** Created correspondent - -#### `paperless.correspondents.update` -Update an existing correspondent. - -**Parameters:** -- `id` (int, required) - Correspondent ID -- `name` (string, optional) - New name -- `match` (string, optional) - Match pattern -- `matchingAlgorithm` (int, optional) - Matching algorithm - -**Returns:** Updated correspondent - -#### `paperless.correspondents.delete` -Delete a correspondent. Requires explicit confirmation. - -**Parameters:** -- `id` (int, required) - Correspondent ID -- `confirm` (bool, default: false) - Must be true to confirm deletion - -**Returns:** Deletion status or dry-run preview - -#### `paperless.correspondents.bulk_delete` -Delete multiple correspondents. - -**Parameters:** -- `correspondentIds` (string, required) - Correspondent IDs (comma-separated) -- `dryRun` (bool, default: true) - Preview changes without applying -- `confirm` (bool, default: false) - Must be true to execute - -**Returns:** Affected correspondent IDs and operation status - ---- - -### Document Type Operations - -#### `paperless.document_types.list` -List all document types with pagination. - -**Parameters:** -- `page` (int, default: 1) - Page number -- `pageSize` (int, default: 25, max: 100) - Results per page -- `ordering` (string, optional) - Sort field (e.g., 'name', '-document_count') - -**Returns:** Paginated list of document types - -#### `paperless.document_types.get` -Get a document type by its ID. - -**Parameters:** -- `id` (int, required) - Document type ID - -**Returns:** Document type details - -#### `paperless.document_types.create` -Create a new document type. - -**Parameters:** -- `name` (string, required) - Document type name -- `match` (string, optional) - Match pattern for auto-assignment -- `matchingAlgorithm` (int, optional) - Matching algorithm (0=None, 1=Any, 2=All, 3=Literal, 4=Regex, 5=Fuzzy, 6=Auto) - -**Returns:** Created document type - -#### `paperless.document_types.update` -Update an existing document type. - -**Parameters:** -- `id` (int, required) - Document type ID -- `name` (string, optional) - New name -- `match` (string, optional) - Match pattern -- `matchingAlgorithm` (int, optional) - Matching algorithm - -**Returns:** Updated document type - -#### `paperless.document_types.delete` -Delete a document type. Requires explicit confirmation. - -**Parameters:** -- `id` (int, required) - Document type ID -- `confirm` (bool, default: false) - Must be true to confirm deletion - -**Returns:** Deletion status or dry-run preview - -#### `paperless.document_types.bulk_delete` -Delete multiple document types. - -**Parameters:** -- `documentTypeIds` (string, required) - Document type IDs (comma-separated) -- `dryRun` (bool, default: true) - Preview changes without applying -- `confirm` (bool, default: false) - Must be true to execute - -**Returns:** Affected document type IDs and operation status - ---- - -### Storage Path Operations - -#### `paperless.storage_paths.list` -List all storage paths with pagination. - -**Parameters:** -- `page` (int, default: 1) - Page number -- `pageSize` (int, default: 25, max: 100) - Results per page -- `ordering` (string, optional) - Sort field (e.g., 'name', '-document_count') - -**Returns:** Paginated list of storage paths - -#### `paperless.storage_paths.get` -Get a storage path by its ID. - -**Parameters:** -- `id` (int, required) - Storage path ID - -**Returns:** Storage path details - -#### `paperless.storage_paths.create` -Create a new storage path. - -**Parameters:** -- `name` (string, required) - Storage path name -- `path` (string, required) - Path template (e.g., `{correspondent}/{document_type}`) -- `match` (string, optional) - Match pattern for auto-assignment -- `matchingAlgorithm` (int, optional) - Matching algorithm (0=None, 1=Any, 2=All, 3=Literal, 4=Regex, 5=Fuzzy, 6=Auto) - -**Returns:** Created storage path - -#### `paperless.storage_paths.update` -Update an existing storage path. - -**Parameters:** -- `id` (int, required) - Storage path ID -- `name` (string, optional) - New name -- `path` (string, optional) - Path template -- `match` (string, optional) - Match pattern -- `matchingAlgorithm` (int, optional) - Matching algorithm - -**Returns:** Updated storage path - -#### `paperless.storage_paths.delete` -Delete a storage path. Requires explicit confirmation. - -**Parameters:** -- `id` (int, required) - Storage path ID -- `confirm` (bool, default: false) - Must be true to confirm deletion - -**Returns:** Deletion status or dry-run preview - -#### `paperless.storage_paths.bulk_delete` -Delete multiple storage paths. - -**Parameters:** -- `storagePathIds` (string, required) - Storage path IDs (comma-separated) -- `dryRun` (bool, default: true) - Preview changes without applying -- `confirm` (bool, default: false) - Must be true to execute - -**Returns:** Affected storage path IDs and operation status - ---- - -### Custom Field Operations - -#### `paperless.custom_fields.list` -List all custom field definitions with pagination. - -**Parameters:** -- `page` (int, default: 1) - Page number -- `pageSize` (int, default: 25, max: 100) - Results per page - -**Returns:** Paginated list of custom field definitions - -#### `paperless.custom_fields.get` -Get a custom field definition by its ID. - -**Parameters:** -- `id` (int, required) - Custom field ID - -**Returns:** Custom field details - -#### `paperless.custom_fields.create` -Create a new custom field definition. - -**Parameters:** -- `name` (string, required) - Custom field name -- `dataType` (string, required) - Data type: `string`, `url`, `date`, `boolean`, `integer`, `float`, `monetary`, `documentlink`, `select` -- `selectOptions` (string, optional) - Select options (comma-separated, for 'select' type only) -- `defaultCurrency` (string, optional) - Default currency (for 'monetary' type only) - -**Returns:** Created custom field - -#### `paperless.custom_fields.update` -Update an existing custom field definition. - -**Parameters:** -- `id` (int, required) - Custom field ID -- `name` (string, optional) - New name -- `selectOptions` (string, optional) - Select options (comma-separated) -- `defaultCurrency` (string, optional) - Default currency - -**Returns:** Updated custom field - -#### `paperless.custom_fields.delete` -Delete a custom field definition. Requires explicit confirmation. - -**Parameters:** -- `id` (int, required) - Custom field ID -- `confirm` (bool, default: false) - Must be true to confirm deletion - -**Returns:** Deletion status or dry-run preview - -#### `paperless.custom_fields.assign` -Assign a custom field value to a document. - -**Parameters:** -- `documentId` (int, required) - Document ID -- `fieldId` (int, required) - Custom field ID -- `value` (string, required) - Value to assign (string, number, boolean, or date depending on field type) - -**Returns:** Assignment status and assigned value +PaperlessMCP provides **43+ MCP tools** across these categories: + +| Category | Tools | +|----------|-------| +| Health | `ping`, `capabilities` | +| Documents | `search`, `get`, `upload`, `upload_from_path`, `update`, `delete`, `bulk_update`, `download`, `preview`, `thumbnail`, `reprocess` | +| Tags | `list`, `get`, `create`, `update`, `delete`, `bulk_delete` | +| Correspondents | `list`, `get`, `create`, `update`, `delete`, `bulk_delete` | +| Document Types | `list`, `get`, `create`, `update`, `delete`, `bulk_delete` | +| Storage Paths | `list`, `get`, `create`, `update`, `delete`, `bulk_delete` | +| Custom Fields | `list`, `get`, `create`, `update`, `delete`, `assign` | + +**[📚 Full API Reference →](docs/API_REFERENCE.md)** --- ## 🛠️ Development -### Building from Source - ```bash -# Clone the repository -git clone https://github.com/barryw/PaperlessMCP.git -cd PaperlessMCP - -# Restore dependencies -dotnet restore - -# Build -dotnet build - -# Run tests -dotnet test - -# Build for release -dotnet build -c Release -``` - -### Running Tests - -```bash -# Run all tests -dotnet test - -# Run tests with coverage -dotnet test /p:CollectCoverage=true - -# Run specific test file -dotnet test --filter "FullyQualifiedName~DocumentToolsTests" +dotnet restore # Restore dependencies +dotnet build # Build +dotnet test # Run tests ``` ### Project Structure ``` PaperlessMCP/ -├── PaperlessMCP/ # Main application -│ ├── Client/ # Paperless API client -│ │ ├── PaperlessClient.cs # Main API client implementation -│ │ └── PaperlessAuthHandler.cs # Authentication handler -│ ├── Configuration/ # Configuration options -│ │ └── PaperlessOptions.cs # Connection configuration -│ ├── Models/ # Data models -│ │ ├── Common/ # Shared models -│ │ ├── Documents/ # Document models -│ │ ├── Tags/ # Tag models -│ │ ├── Correspondents/ # Correspondent models -│ │ ├── DocumentTypes/ # Document type models -│ │ ├── StoragePaths/ # Storage path models -│ │ └── CustomFields/ # Custom field models -│ ├── Tools/ # MCP tool implementations -│ │ ├── HealthTools.cs # Health checks -│ │ ├── DocumentTools.cs # Document operations -│ │ ├── TagTools.cs # Tag operations -│ │ ├── CorrespondentTools.cs # Correspondent operations -│ │ ├── DocumentTypeTools.cs # Document type operations -│ │ ├── StoragePathTools.cs # Storage path operations -│ │ └── CustomFieldTools.cs # Custom field operations -│ ├── Program.cs # Application entry point -│ ├── Dockerfile # Docker configuration -│ └── appsettings.json # Default configuration -├── PaperlessMCP.Tests/ # Test project -│ ├── Client/ # Client tests -│ ├── Tools/ # Tool tests -│ └── Fixtures/ # Test fixtures -└── PaperlessMCP.sln # Solution file +├── PaperlessMCP/ # Main application +│ ├── Client/ # Paperless API client +│ ├── Models/ # Data models +│ ├── Tools/ # MCP tool implementations +│ └── Program.cs # Entry point +├── PaperlessMCP.Tests/ # Test project +└── docs/ # Documentation ``` -### Technology Stack - -- **.NET 10** - Modern, cross-platform framework -- **ModelContextProtocol 0.2.0-preview.1** - MCP server implementation -- **Polly 8.5.2** - Resilience and transient fault handling -- **xUnit** - Testing framework - --- ## 🤝 Contributing -Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change. +Contributions welcome! Please: -### Guidelines - -1. **Fork the repository** and create your branch from `main` -2. **Write tests** for any new functionality -3. **Ensure all tests pass** with `dotnet test` -4. **Follow the existing code style** and conventions -5. **Update documentation** for any API changes -6. **Submit a pull request** with a clear description of changes - -### Development Setup - -```bash -# Fork and clone your fork -git clone https://github.com/YOUR-USERNAME/PaperlessMCP.git -cd PaperlessMCP - -# Create a feature branch -git checkout -b feature/your-feature-name - -# Make changes and test -dotnet test - -# Commit and push -git add . -git commit -m "Add your feature" -git push origin feature/your-feature-name -``` - ---- - -## 🐛 Troubleshooting - -### Common Issues - -#### Connection Errors - -**Problem:** "Failed to connect to Paperless instance" - -**Solution:** -- Verify `PAPERLESS_BASE_URL` is correct and accessible -- Ensure your Paperless-ngx instance is running -- Check network connectivity and firewall rules -- Verify API endpoint: `curl https://your-instance/api/` - -#### Authentication Errors - -**Problem:** "401 Unauthorized" - -**Solution:** -- Verify your `PAPERLESS_API_TOKEN` is correct -- Generate a new token in Paperless-ngx: Settings → API → Tokens -- Ensure the token has necessary permissions - -#### Upload Failures - -**Problem:** Document uploads timeout or fail - -**Solution:** -- For large files, use `paperless.documents.upload_from_path` instead of base64 upload -- Check file size limits in Paperless-ngx configuration -- Verify disk space on Paperless-ngx server -- Check Paperless-ngx logs for processing errors - -#### Claude Desktop Integration - -**Problem:** Server doesn't appear in Claude Desktop - -**Solution:** -- Verify JSON syntax in `claude_desktop_config.json` -- Use absolute paths (no relative paths or `~`) -- Restart Claude Desktop completely -- Check Claude Desktop logs for errors +1. Fork the repository +2. Create a feature branch +3. Write tests for new functionality +4. Submit a pull request --- ## 📄 License -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. +MIT License - see [LICENSE](LICENSE) for details. --- ## 🙏 Acknowledgments -- [Paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) - The excellent document management system -- [Model Context Protocol](https://modelcontextprotocol.io/) - For the MCP specification -- [Anthropic](https://www.anthropic.com/) - For Claude and the MCP implementation - ---- - -## 📞 Support - -- **Issues**: [GitHub Issues](https://github.com/barryw/PaperlessMCP/issues) -- **Discussions**: [GitHub Discussions](https://github.com/barryw/PaperlessMCP/discussions) -- **Paperless-ngx Docs**: [docs.paperless-ngx.com](https://docs.paperless-ngx.com/) -- **MCP Docs**: [modelcontextprotocol.io](https://modelcontextprotocol.io/) +- [Paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) +- [Model Context Protocol](https://modelcontextprotocol.io/) +- [Anthropic](https://www.anthropic.com/) --- @@ -868,6 +183,6 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file **[⬆ back to top](#-paperlessmcp)** -Made with ❤️ for the Paperless-ngx and MCP communities +Made with ❤️ for the Paperless-ngx community diff --git a/docs/API_REFERENCE.md b/docs/API_REFERENCE.md new file mode 100644 index 0000000..639fe8a --- /dev/null +++ b/docs/API_REFERENCE.md @@ -0,0 +1,547 @@ +# PaperlessMCP API Reference + +Complete reference for all MCP tools provided by PaperlessMCP. + +## Table of Contents + +- [Health & Capabilities](#health--capabilities) +- [Document Operations](#document-operations) +- [Tag Operations](#tag-operations) +- [Correspondent Operations](#correspondent-operations) +- [Document Type Operations](#document-type-operations) +- [Storage Path Operations](#storage-path-operations) +- [Custom Field Operations](#custom-field-operations) + +--- + +## Health & Capabilities + +### `paperless.ping` +Verify connectivity and authentication with Paperless-ngx. + +**Returns:** Connection status and server version + +### `paperless.capabilities` +Return supported API endpoints and detected Paperless-ngx version information. + +**Returns:** Available endpoints, bulk operations, and server capabilities + +--- + +## Document Operations + +### `paperless.documents.search` +Search for documents with full-text search and filters. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `query` | string | No | - | Full-text search query | +| `tags` | string | No | - | Filter by tag IDs (comma-separated) | +| `tagsExclude` | string | No | - | Exclude tag IDs (comma-separated) | +| `correspondent` | int | No | - | Filter by correspondent ID | +| `documentType` | int | No | - | Filter by document type ID | +| `storagePath` | int | No | - | Filter by storage path ID | +| `createdAfter` | string | No | - | Filter by creation date (YYYY-MM-DD) | +| `createdBefore` | string | No | - | Filter by creation date (YYYY-MM-DD) | +| `addedAfter` | string | No | - | Filter by added date (YYYY-MM-DD) | +| `addedBefore` | string | No | - | Filter by added date (YYYY-MM-DD) | +| `archiveSerialNumber` | int | No | - | Filter by archive serial number | +| `page` | int | No | 1 | Page number | +| `pageSize` | int | No | 25 | Results per page (max: 100) | +| `ordering` | string | No | - | Sort field (e.g., 'created', '-created', 'title') | +| `includeContent` | bool | No | false | Include document content in results | +| `contentMaxLength` | int | No | 500 | Max content length when `includeContent=true` | + +**Returns:** Paginated list of document summaries + +### `paperless.documents.get` +Get a document by its ID. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Document ID | + +**Returns:** Complete document details including content + +### `paperless.documents.download` +Get download URLs for a document's original file, preview, and thumbnail. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Document ID | + +**Returns:** Object with `original_url`, `preview_url`, `thumbnail_url` + +### `paperless.documents.preview` +Get the preview URL for a document. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Document ID | + +**Returns:** Preview URL + +### `paperless.documents.thumbnail` +Get the thumbnail URL for a document. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Document ID | + +**Returns:** Thumbnail URL + +### `paperless.documents.upload` +Upload a new document to Paperless-ngx via base64-encoded content. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `fileContent` | string | Yes | - | Base64-encoded file content | +| `fileName` | string | Yes | - | Original filename with extension | +| `title` | string | No | - | Document title | +| `correspondent` | int | No | - | Correspondent ID | +| `documentType` | int | No | - | Document type ID | +| `storagePath` | int | No | - | Storage path ID | +| `tags` | string | No | - | Tag IDs (comma-separated) | +| `archiveSerialNumber` | int | No | - | Archive serial number | +| `created` | string | No | - | Created date (YYYY-MM-DD) | + +**Returns:** Task ID and upload status + +> **Note:** For large files, use `paperless.documents.upload_from_path` instead. + +### `paperless.documents.upload_from_path` +Upload a document from a local file path. More reliable for large files. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `filePath` | string | Yes | - | Absolute path to the file | +| `title` | string | No | filename | Document title | +| `correspondent` | int | No | - | Correspondent ID | +| `documentType` | int | No | - | Document type ID | +| `storagePath` | int | No | - | Storage path ID | +| `tags` | string | No | - | Tag IDs (comma-separated) | +| `archiveSerialNumber` | int | No | - | Archive serial number | +| `created` | string | No | - | Created date (YYYY-MM-DD) | + +**Returns:** Task ID, upload status, and file information + +**Features:** Supports `~/` expansion, automatic retries, file validation + +### `paperless.documents.update` +Update document metadata. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `id` | int | Yes | - | Document ID | +| `title` | string | No | - | New title | +| `correspondent` | int | No | - | Correspondent ID (use -1 to clear) | +| `documentType` | int | No | - | Document type ID (use -1 to clear) | +| `storagePath` | int | No | - | Storage path ID (use -1 to clear) | +| `tags` | string | No | - | Tag IDs to set (comma-separated) | +| `archiveSerialNumber` | int | No | - | Archive serial number | +| `created` | string | No | - | Created date (YYYY-MM-DD) | + +**Returns:** Updated document + +### `paperless.documents.delete` +Delete a document. Requires explicit confirmation. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `id` | int | Yes | - | Document ID | +| `confirm` | bool | No | false | Must be true to confirm deletion | + +**Returns:** Deletion status or dry-run preview + +> **Safety:** Without `confirm=true`, returns a dry-run preview showing what would be deleted. + +### `paperless.documents.bulk_update` +Perform bulk operations on multiple documents. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `documentIds` | string | Yes | - | Document IDs (comma-separated) | +| `operation` | string | Yes | - | Operation: `add_tag`, `remove_tag`, `set_correspondent`, `set_document_type`, `set_storage_path`, `delete`, `reprocess` | +| `value` | int | No | - | Parameter value (e.g., tag ID, correspondent ID) | +| `dryRun` | bool | No | true | Preview changes without applying | +| `confirm` | bool | No | false | Must be true to execute | + +**Returns:** Affected document IDs and operation status + +> **Safety:** Defaults to dry-run mode to prevent accidental changes. + +### `paperless.documents.reprocess` +Reprocess a document's OCR and content extraction. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `id` | int | Yes | - | Document ID | +| `confirm` | bool | No | false | Must be true to confirm reprocessing | + +**Returns:** Processing status + +--- + +## Tag Operations + +### `paperless.tags.list` +List all tags with pagination. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `page` | int | No | 1 | Page number | +| `pageSize` | int | No | 25 | Results per page (max: 100) | +| `ordering` | string | No | - | Sort field (e.g., 'name', '-document_count') | + +**Returns:** Paginated list of tags + +### `paperless.tags.get` +Get a tag by its ID. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Tag ID | + +**Returns:** Tag details + +### `paperless.tags.create` +Create a new tag. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `name` | string | Yes | - | Tag name | +| `color` | string | No | - | Hex color (e.g., '#ff0000') | +| `match` | string | No | - | Match pattern for auto-tagging | +| `matchingAlgorithm` | int | No | 0 | Matching algorithm (see below) | +| `isInboxTag` | bool | No | false | Mark as inbox tag | + +**Matching Algorithms:** +- `0` - None +- `1` - Any word +- `2` - All words +- `3` - Literal match +- `4` - Regular expression +- `5` - Fuzzy match +- `6` - Auto + +**Returns:** Created tag + +### `paperless.tags.update` +Update an existing tag. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Tag ID | +| `name` | string | No | New name | +| `color` | string | No | Hex color | +| `match` | string | No | Match pattern | +| `matchingAlgorithm` | int | No | Matching algorithm | +| `isInboxTag` | bool | No | Inbox tag status | + +**Returns:** Updated tag + +### `paperless.tags.delete` +Delete a tag. Requires explicit confirmation. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `id` | int | Yes | - | Tag ID | +| `confirm` | bool | No | false | Must be true to confirm deletion | + +**Returns:** Deletion status or dry-run preview + +### `paperless.tags.bulk_delete` +Delete multiple tags. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `tagIds` | string | Yes | - | Tag IDs (comma-separated) | +| `dryRun` | bool | No | true | Preview changes without applying | +| `confirm` | bool | No | false | Must be true to execute | + +**Returns:** Affected tag IDs and operation status + +--- + +## Correspondent Operations + +### `paperless.correspondents.list` +List all correspondents with pagination. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `page` | int | No | 1 | Page number | +| `pageSize` | int | No | 25 | Results per page (max: 100) | +| `ordering` | string | No | - | Sort field (e.g., 'name', '-document_count', 'last_correspondence') | + +**Returns:** Paginated list of correspondents + +### `paperless.correspondents.get` +Get a correspondent by its ID. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Correspondent ID | + +**Returns:** Correspondent details + +### `paperless.correspondents.create` +Create a new correspondent. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `name` | string | Yes | - | Correspondent name | +| `match` | string | No | - | Match pattern for auto-assignment | +| `matchingAlgorithm` | int | No | 0 | Matching algorithm | + +**Returns:** Created correspondent + +### `paperless.correspondents.update` +Update an existing correspondent. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Correspondent ID | +| `name` | string | No | New name | +| `match` | string | No | Match pattern | +| `matchingAlgorithm` | int | No | Matching algorithm | + +**Returns:** Updated correspondent + +### `paperless.correspondents.delete` +Delete a correspondent. Requires explicit confirmation. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `id` | int | Yes | - | Correspondent ID | +| `confirm` | bool | No | false | Must be true to confirm deletion | + +**Returns:** Deletion status or dry-run preview + +### `paperless.correspondents.bulk_delete` +Delete multiple correspondents. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `correspondentIds` | string | Yes | - | Correspondent IDs (comma-separated) | +| `dryRun` | bool | No | true | Preview changes without applying | +| `confirm` | bool | No | false | Must be true to execute | + +**Returns:** Affected correspondent IDs and operation status + +--- + +## Document Type Operations + +### `paperless.document_types.list` +List all document types with pagination. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `page` | int | No | 1 | Page number | +| `pageSize` | int | No | 25 | Results per page (max: 100) | +| `ordering` | string | No | - | Sort field (e.g., 'name', '-document_count') | + +**Returns:** Paginated list of document types + +### `paperless.document_types.get` +Get a document type by its ID. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Document type ID | + +**Returns:** Document type details + +### `paperless.document_types.create` +Create a new document type. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `name` | string | Yes | - | Document type name | +| `match` | string | No | - | Match pattern for auto-assignment | +| `matchingAlgorithm` | int | No | 0 | Matching algorithm | + +**Returns:** Created document type + +### `paperless.document_types.update` +Update an existing document type. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Document type ID | +| `name` | string | No | New name | +| `match` | string | No | Match pattern | +| `matchingAlgorithm` | int | No | Matching algorithm | + +**Returns:** Updated document type + +### `paperless.document_types.delete` +Delete a document type. Requires explicit confirmation. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `id` | int | Yes | - | Document type ID | +| `confirm` | bool | No | false | Must be true to confirm deletion | + +**Returns:** Deletion status or dry-run preview + +### `paperless.document_types.bulk_delete` +Delete multiple document types. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `documentTypeIds` | string | Yes | - | Document type IDs (comma-separated) | +| `dryRun` | bool | No | true | Preview changes without applying | +| `confirm` | bool | No | false | Must be true to execute | + +**Returns:** Affected document type IDs and operation status + +--- + +## Storage Path Operations + +### `paperless.storage_paths.list` +List all storage paths with pagination. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `page` | int | No | 1 | Page number | +| `pageSize` | int | No | 25 | Results per page (max: 100) | +| `ordering` | string | No | - | Sort field (e.g., 'name', '-document_count') | + +**Returns:** Paginated list of storage paths + +### `paperless.storage_paths.get` +Get a storage path by its ID. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Storage path ID | + +**Returns:** Storage path details + +### `paperless.storage_paths.create` +Create a new storage path. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `name` | string | Yes | - | Storage path name | +| `path` | string | Yes | - | Path template (e.g., `{correspondent}/{document_type}`) | +| `match` | string | No | - | Match pattern for auto-assignment | +| `matchingAlgorithm` | int | No | 0 | Matching algorithm | + +**Returns:** Created storage path + +### `paperless.storage_paths.update` +Update an existing storage path. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Storage path ID | +| `name` | string | No | New name | +| `path` | string | No | Path template | +| `match` | string | No | Match pattern | +| `matchingAlgorithm` | int | No | Matching algorithm | + +**Returns:** Updated storage path + +### `paperless.storage_paths.delete` +Delete a storage path. Requires explicit confirmation. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `id` | int | Yes | - | Storage path ID | +| `confirm` | bool | No | false | Must be true to confirm deletion | + +**Returns:** Deletion status or dry-run preview + +### `paperless.storage_paths.bulk_delete` +Delete multiple storage paths. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `storagePathIds` | string | Yes | - | Storage path IDs (comma-separated) | +| `dryRun` | bool | No | true | Preview changes without applying | +| `confirm` | bool | No | false | Must be true to execute | + +**Returns:** Affected storage path IDs and operation status + +--- + +## Custom Field Operations + +### `paperless.custom_fields.list` +List all custom field definitions with pagination. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `page` | int | No | 1 | Page number | +| `pageSize` | int | No | 25 | Results per page (max: 100) | + +**Returns:** Paginated list of custom field definitions + +### `paperless.custom_fields.get` +Get a custom field definition by its ID. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Custom field ID | + +**Returns:** Custom field details + +### `paperless.custom_fields.create` +Create a new custom field definition. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `name` | string | Yes | - | Custom field name | +| `dataType` | string | Yes | - | Data type (see below) | +| `selectOptions` | string | No | - | Select options (comma-separated, for 'select' type) | +| `defaultCurrency` | string | No | - | Default currency (for 'monetary' type) | + +**Data Types:** +- `string` - Text value +- `url` - URL/link +- `date` - Date value +- `boolean` - True/false +- `integer` - Whole number +- `float` - Decimal number +- `monetary` - Currency amount +- `documentlink` - Link to another document +- `select` - Dropdown selection + +**Returns:** Created custom field + +### `paperless.custom_fields.update` +Update an existing custom field definition. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `id` | int | Yes | Custom field ID | +| `name` | string | No | New name | +| `selectOptions` | string | No | Select options (comma-separated) | +| `defaultCurrency` | string | No | Default currency | + +**Returns:** Updated custom field + +### `paperless.custom_fields.delete` +Delete a custom field definition. Requires explicit confirmation. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `id` | int | Yes | - | Custom field ID | +| `confirm` | bool | No | false | Must be true to confirm deletion | + +**Returns:** Deletion status or dry-run preview + +### `paperless.custom_fields.assign` +Assign a custom field value to a document. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `documentId` | int | Yes | Document ID | +| `fieldId` | int | Yes | Custom field ID | +| `value` | string | Yes | Value to assign (type depends on field) | + +**Returns:** Assignment status and assigned value