@kjanat/paperless-mcp 1.0.1-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kaj Kowalski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,445 @@
1
+ # Paperless-ngx MCP Server
2
+
3
+ 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.
4
+
5
+ ## Quick Start
6
+
7
+ ### Installation
8
+
9
+ 1. Install the MCP server (optional):
10
+
11
+ ```bash
12
+ bun install -g @kjanat/paperless-mcp
13
+ ```
14
+
15
+ 1. Add it to your configuration:
16
+
17
+ ```jsonc
18
+ {
19
+ "mcpServers": {
20
+ "paperless": {
21
+ "command": "bunx", // or npx
22
+ "args": [
23
+ "@kjanat/paperless-mcp",
24
+ "http://your-paperless-instance:8000",
25
+ "your-api-token",
26
+ ],
27
+ },
28
+ },
29
+ }
30
+ ```
31
+
32
+ 1. Get your API token:
33
+ 1. Log into your Paperless-ngx instance
34
+ 2. Click your username in the top right
35
+ 3. Select "My Profile"
36
+ 4. Click the circular arrow button to generate a new token
37
+
38
+ 1. Replace the placeholders in your MCP config:
39
+ - `http://your-paperless-instance:8000` with your Paperless-ngx URL
40
+ - `your-api-token` with the token you just generated
41
+
42
+ That's it! Now you can ask Claude to help you manage your Paperless-ngx documents.
43
+
44
+ ## Example Usage
45
+
46
+ Here are some things you can ask Claude to do:
47
+
48
+ - "Show me all documents tagged as 'Invoice'"
49
+ - "Search for documents containing 'tax return'"
50
+ - "Create a new tag called 'Receipts' with color #FF0000"
51
+ - "Download document #123"
52
+ - "List all correspondents"
53
+ - "Create a new document type called 'Bank Statement'"
54
+
55
+ ## Available Tools
56
+
57
+ ### Document Operations
58
+
59
+ #### get_document
60
+
61
+ Get a specific document by ID.
62
+
63
+ Parameters:
64
+
65
+ - id: Document ID
66
+
67
+ ```typescript
68
+ get_document({
69
+ id: 123,
70
+ });
71
+ ```
72
+
73
+ #### search_documents
74
+
75
+ Full-text search across documents.
76
+
77
+ Parameters:
78
+
79
+ - query: Search query string
80
+
81
+ ```typescript
82
+ search_documents({
83
+ query: 'invoice 2024',
84
+ });
85
+ ```
86
+
87
+ #### download_document
88
+
89
+ Download a document file by ID.
90
+
91
+ Parameters:
92
+
93
+ - id: Document ID
94
+ - original (optional): If true, downloads original file instead of archived version
95
+
96
+ ```typescript
97
+ download_document({
98
+ id: 123,
99
+ original: false,
100
+ });
101
+ ```
102
+
103
+ #### bulk_edit_documents
104
+
105
+ Perform bulk operations on multiple documents.
106
+
107
+ Parameters:
108
+
109
+ - documents: Array of document IDs
110
+ - method: One of:
111
+ - set_correspondent: Set correspondent for documents
112
+ - set_document_type: Set document type for documents
113
+ - set_storage_path: Set storage path for documents
114
+ - add_tag: Add a tag to documents
115
+ - remove_tag: Remove a tag from documents
116
+ - modify_tags: Add and/or remove multiple tags
117
+ - delete: Delete documents
118
+ - reprocess: Reprocess documents
119
+ - set_permissions: Set document permissions
120
+ - merge: Merge multiple documents
121
+ - split: Split a document into multiple documents
122
+ - rotate: Rotate document pages
123
+ - delete_pages: Delete specific pages from a document
124
+ - Additional parameters based on method:
125
+ - correspondent: ID for set_correspondent
126
+ - document_type: ID for set_document_type
127
+ - storage_path: ID for set_storage_path
128
+ - tag: ID for add_tag/remove_tag
129
+ - add_tags: Array of tag IDs for modify_tags
130
+ - remove_tags: Array of tag IDs for modify_tags
131
+ - permissions: Object for set_permissions with owner, permissions, merge flag
132
+ - metadata_document_id: ID for merge to specify metadata source
133
+ - delete_originals: Boolean for merge/split
134
+ - pages: String for split "[1,2-3,4,5-7]" or delete_pages "[2,3,4]"
135
+ - degrees: Number for rotate (90, 180, or 270)
136
+
137
+ Examples:
138
+
139
+ ```typescript
140
+ // Add a tag to multiple documents
141
+ bulk_edit_documents({
142
+ documents: [1, 2, 3],
143
+ method: 'add_tag',
144
+ tag: 5,
145
+ });
146
+
147
+ // Set correspondent and document type
148
+ bulk_edit_documents({
149
+ documents: [4, 5],
150
+ method: 'set_correspondent',
151
+ correspondent: 2,
152
+ });
153
+
154
+ // Merge documents
155
+ bulk_edit_documents({
156
+ documents: [6, 7, 8],
157
+ method: 'merge',
158
+ metadata_document_id: 6,
159
+ delete_originals: true,
160
+ });
161
+
162
+ // Split document into parts
163
+ bulk_edit_documents({
164
+ documents: [9],
165
+ method: 'split',
166
+ pages: '[1-2,3-4,5]',
167
+ });
168
+
169
+ // Modify multiple tags at once
170
+ bulk_edit_documents({
171
+ documents: [10, 11],
172
+ method: 'modify_tags',
173
+ add_tags: [1, 2],
174
+ remove_tags: [3, 4],
175
+ });
176
+ ```
177
+
178
+ #### post_document
179
+
180
+ Upload a new document to Paperless-ngx.
181
+
182
+ Parameters:
183
+
184
+ - file: Base64 encoded file content
185
+ - filename: Name of the file
186
+ - title (optional): Title for the document
187
+ - created (optional): DateTime when the document was created (e.g. "2024-01-19" or "2024-01-19 06:15:00+02:00")
188
+ - correspondent (optional): ID of a correspondent
189
+ - document_type (optional): ID of a document type
190
+ - storage_path (optional): ID of a storage path
191
+ - tags (optional): Array of tag IDs
192
+ - archive_serial_number (optional): Archive serial number
193
+ - custom_fields (optional): Array of custom field IDs
194
+
195
+ ```typescript
196
+ post_document({
197
+ file: 'base64_encoded_content',
198
+ filename: 'invoice.pdf',
199
+ title: 'January Invoice',
200
+ created: '2024-01-19',
201
+ correspondent: 1,
202
+ document_type: 2,
203
+ tags: [1, 3],
204
+ archive_serial_number: '2024-001',
205
+ });
206
+ ```
207
+
208
+ ### Tag Operations
209
+
210
+ #### list_tags
211
+
212
+ Get all tags.
213
+
214
+ ```typescript
215
+ list_tags();
216
+ ```
217
+
218
+ #### create_tag
219
+
220
+ Create a new tag.
221
+
222
+ Parameters:
223
+
224
+ - name: Tag name
225
+ - color (optional): Hex color code (e.g. "#ff0000")
226
+ - match (optional): Text pattern to match
227
+ - matching_algorithm (optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
228
+
229
+ ```typescript
230
+ create_tag({
231
+ name: 'Invoice',
232
+ color: '#ff0000',
233
+ match: 'invoice',
234
+ matching_algorithm: 5,
235
+ });
236
+ ```
237
+
238
+ #### update_tag
239
+
240
+ Update an existing tag's name, color, or matching rules.
241
+
242
+ Parameters:
243
+
244
+ - id: Tag ID
245
+ - name: New tag name
246
+ - color (optional): Hex color code (e.g. "#ff0000")
247
+ - match (optional): Text pattern to match
248
+ - matching_algorithm (optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
249
+
250
+ ```typescript
251
+ update_tag({
252
+ id: 5,
253
+ name: 'Invoices',
254
+ color: '#00ff00',
255
+ });
256
+ ```
257
+
258
+ #### delete_tag
259
+
260
+ Permanently delete a tag. Removes it from all documents.
261
+
262
+ Parameters:
263
+
264
+ - id: Tag ID
265
+
266
+ ```typescript
267
+ delete_tag({
268
+ id: 5,
269
+ });
270
+ ```
271
+
272
+ #### bulk_edit_tags
273
+
274
+ Bulk set permissions or delete multiple tags.
275
+
276
+ Parameters:
277
+
278
+ - tag_ids: Array of tag IDs
279
+ - operation: "set_permissions" or "delete"
280
+ - owner (optional): User ID (for set_permissions)
281
+ - permissions (optional): Object with view/change user and group IDs
282
+ - merge (optional): Merge with existing permissions (default false)
283
+
284
+ ```typescript
285
+ bulk_edit_tags({
286
+ tag_ids: [1, 2, 3],
287
+ operation: 'delete',
288
+ });
289
+ ```
290
+
291
+ ### Correspondent Operations
292
+
293
+ #### list_correspondents
294
+
295
+ Get all correspondents.
296
+
297
+ ```typescript
298
+ list_correspondents();
299
+ ```
300
+
301
+ #### create_correspondent
302
+
303
+ Create a new correspondent.
304
+
305
+ Parameters:
306
+
307
+ - name: Correspondent name
308
+ - match (optional): Text pattern to match
309
+ - matching_algorithm (optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
310
+
311
+ ```typescript
312
+ create_correspondent({
313
+ name: 'ACME Corp',
314
+ match: 'ACME',
315
+ matching_algorithm: 5,
316
+ });
317
+ ```
318
+
319
+ #### bulk_edit_correspondents
320
+
321
+ Bulk set permissions or delete multiple correspondents.
322
+
323
+ Parameters:
324
+
325
+ - correspondent_ids: Array of correspondent IDs
326
+ - operation: "set_permissions" or "delete"
327
+ - owner (optional): User ID (for set_permissions)
328
+ - permissions (optional): Object with view/change user and group IDs
329
+ - merge (optional): Merge with existing permissions (default false)
330
+
331
+ ```typescript
332
+ bulk_edit_correspondents({
333
+ correspondent_ids: [1, 2],
334
+ operation: 'delete',
335
+ });
336
+ ```
337
+
338
+ ### Document Type Operations
339
+
340
+ #### list_document_types
341
+
342
+ Get all document types.
343
+
344
+ ```typescript
345
+ list_document_types();
346
+ ```
347
+
348
+ #### create_document_type
349
+
350
+ Create a new document type.
351
+
352
+ Parameters:
353
+
354
+ - name: Document type name
355
+ - match (optional): Text pattern to match
356
+ - matching_algorithm (optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
357
+
358
+ ```typescript
359
+ create_document_type({
360
+ name: 'Invoice',
361
+ match: 'invoice total amount due',
362
+ matching_algorithm: 1,
363
+ });
364
+ ```
365
+
366
+ #### bulk_edit_document_types
367
+
368
+ Bulk set permissions or delete multiple document types.
369
+
370
+ Parameters:
371
+
372
+ - document_type_ids: Array of document type IDs
373
+ - operation: "set_permissions" or "delete"
374
+ - owner (optional): User ID (for set_permissions)
375
+ - permissions (optional): Object with view/change user and group IDs
376
+ - merge (optional): Merge with existing permissions (default false)
377
+
378
+ ```typescript
379
+ bulk_edit_document_types({
380
+ document_type_ids: [1, 2],
381
+ operation: 'delete',
382
+ });
383
+ ```
384
+
385
+ ## Error Handling
386
+
387
+ The server will show clear error messages if:
388
+
389
+ - The Paperless-ngx URL or API token is incorrect
390
+ - The Paperless-ngx server is unreachable
391
+ - The requested operation fails
392
+ - The provided parameters are invalid
393
+
394
+ ## Development
395
+
396
+ Want to contribute or modify the server? Here's what you need to know:
397
+
398
+ 1. Clone the repository
399
+ 2. Install dependencies:
400
+
401
+ ```bash
402
+ bun install
403
+ ```
404
+
405
+ 3. Make your changes in `src/` (see `src/tools/` for MCP tools, `src/api/` for API client)
406
+ 4. Test locally:
407
+
408
+ ```bash
409
+ bun src/index.ts http://localhost:8000 your-test-token
410
+ ```
411
+
412
+ The server is built with:
413
+
414
+ - [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk): Official TypeScript SDK for building MCP servers
415
+ - [zod](https://github.com/colinhacks/zod): TypeScript-first schema validation
416
+
417
+ ## API Documentation
418
+
419
+ This MCP server implements endpoints from the Paperless-ngx REST API. For more details about the underlying API, see the [official documentation](https://docs.paperless-ngx.com/api/).
420
+
421
+ ## Running the MCP Server
422
+
423
+ The MCP server can be run in two modes:
424
+
425
+ ### 1. stdio (default)
426
+
427
+ This is the default mode. The server communicates over stdio, suitable for CLI and direct integrations.
428
+
429
+ ```bash
430
+ bun start -- <baseUrl> <token>
431
+ ```
432
+
433
+ ### 2. HTTP (Streamable HTTP Transport)
434
+
435
+ 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](https://expressjs.com/) to be installed (it is included as a dependency).
436
+
437
+ ```bash
438
+ bun start -- <baseUrl> <token> --http --port 3000
439
+ ```
440
+
441
+ - The MCP API will be available at `POST /mcp` on the specified port.
442
+ - Each request is handled statelessly, following the [StreamableHTTPServerTransport](https://github.com/modelcontextprotocol/typescript-sdk) pattern.
443
+ - GET and DELETE requests to `/mcp` will return 405 Method Not Allowed.
444
+
445
+ <!--markdownlint-disable-file no-hard-tabs-->