@kjanat/paperless-mcp 2.0.1 → 2.1.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/README.md CHANGED
@@ -6,13 +6,30 @@ An MCP (Model Context Protocol) server for interacting with a Paperless-ngx API
6
6
 
7
7
  ### Installation
8
8
 
9
- 1. Install the MCP server (optional):
9
+ 1. Get your API token:
10
+ 1. Log into your Paperless-ngx instance
11
+ 2. Click your username in the top right
12
+ 3. Select "My Profile"
13
+ 4. Click the circular arrow button to generate a new token
10
14
 
11
- ```bash
12
- bun install -g @kjanat/paperless-mcp
15
+ 1. Add it to your MCP client configuration (using env vars):
16
+
17
+ ```jsonc
18
+ {
19
+ "mcpServers": {
20
+ "paperless": {
21
+ "command": "bunx", // or npx
22
+ "args": ["@kjanat/paperless-mcp"],
23
+ "env": {
24
+ "PAPERLESS_URL": "http://your-paperless-instance:8000",
25
+ "PAPERLESS_API_KEY": "your-api-token",
26
+ },
27
+ },
28
+ },
29
+ }
13
30
  ```
14
31
 
15
- 1. Add it to your configuration:
32
+ Or pass them as positional arguments:
16
33
 
17
34
  ```jsonc
18
35
  {
@@ -29,17 +46,25 @@ An MCP (Model Context Protocol) server for interacting with a Paperless-ngx API
29
46
  }
30
47
  ```
31
48
 
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
49
+ CLI args take precedence over env vars when both are provided.
50
+
51
+ That's it!
52
+
53
+ ## Agent Skill
54
+
55
+ This package ships an [Agent Skill](https://agentskills.io/specification) in
56
+ `skills/paperless-ngx/` with decision trees, tool reference docs, query syntax
57
+ guide, and workflow templates for AI agents.
37
58
 
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
59
+ View the skill on the registry: https://skills.sh/kjanat/paperless-mcp/paperless-ngx
60
+
61
+ _Add using_:
62
+
63
+ ```bash
64
+ bunx skills add https://github.com/kjanat/paperless-mcp --skill paperless-ngx
65
+ ```
41
66
 
42
- That's it! Now you can ask Claude to help you manage your Paperless-ngx documents.
67
+ `# or npx -y skills...`
43
68
 
44
69
  ## Example Usage
45
70
 
@@ -54,15 +79,18 @@ Here are some things you can ask Claude to do:
54
79
 
55
80
  ## Available Tools
56
81
 
82
+ <details>
83
+ <summary>Document Operations</summary>
84
+
57
85
  ### Document Operations
58
86
 
59
- #### get_document
87
+ #### `get_document`
60
88
 
61
89
  Get a specific document by ID.
62
90
 
63
91
  Parameters:
64
92
 
65
- - id: Document ID
93
+ - `id`: Document ID
66
94
 
67
95
  ```typescript
68
96
  get_document({
@@ -70,13 +98,13 @@ get_document({
70
98
  });
71
99
  ```
72
100
 
73
- #### search_documents
101
+ #### `search_documents`
74
102
 
75
103
  Full-text search across documents.
76
104
 
77
105
  Parameters:
78
106
 
79
- - query: Search query string
107
+ - `query`: Search query string
80
108
 
81
109
  ```typescript
82
110
  search_documents({
@@ -84,14 +112,14 @@ search_documents({
84
112
  });
85
113
  ```
86
114
 
87
- #### download_document
115
+ #### `download_document`
88
116
 
89
117
  Download a document file by ID.
90
118
 
91
119
  Parameters:
92
120
 
93
- - id: Document ID
94
- - original (optional): If true, downloads original file instead of archived version
121
+ - `id`: Document ID
122
+ - `original` (optional): If true, downloads original file instead of archived version
95
123
 
96
124
  ```typescript
97
125
  download_document({
@@ -100,39 +128,39 @@ download_document({
100
128
  });
101
129
  ```
102
130
 
103
- #### bulk_edit_documents
131
+ #### `bulk_edit_documents`
104
132
 
105
133
  Perform bulk operations on multiple documents.
106
134
 
107
135
  Parameters:
108
136
 
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)
137
+ - `documents`: Array of document IDs
138
+ - `method`: One of:
139
+ - `set_correspondent`: Set correspondent for documents
140
+ - `set_document_type`: Set document type for documents
141
+ - `set_storage_path`: Set storage path for documents
142
+ - `add_tag`: Add a tag to documents
143
+ - `remove_tag`: Remove a tag from documents
144
+ - `modify_tags`: Add and/or remove multiple tags
145
+ - `delete`: Delete documents
146
+ - `reprocess`: Reprocess documents
147
+ - `set_permissions`: Set document permissions
148
+ - `merge`: Merge multiple documents
149
+ - `split`: Split a document into multiple documents
150
+ - `rotate`: Rotate document pages
151
+ - `delete_pages`: Delete specific pages from a document
152
+ - Additional parameters based on `method`:
153
+ - `correspondent`: ID for set_correspondent
154
+ - `document_type`: ID for set_document_type
155
+ - `storage_path`: ID for set_storage_path
156
+ - `tag`: ID for add_tag/remove_tag
157
+ - `add_tags`: Array of tag IDs for modify_tags
158
+ - `remove_tags`: Array of tag IDs for modify_tags
159
+ - `permissions`: Object for set_permissions with owner, permissions, merge flag
160
+ - `metadata_document_id`: ID for merge to specify metadata source
161
+ - `delete_originals`: Boolean for merge/split
162
+ - `pages`: String for split "[1,2-3,4,5-7]" or `delete_pages` "[2,3,4]"
163
+ - `degrees`: Number for rotate (90, 180, or 270)
136
164
 
137
165
  Examples:
138
166
 
@@ -175,22 +203,22 @@ bulk_edit_documents({
175
203
  });
176
204
  ```
177
205
 
178
- #### post_document
206
+ #### `post_document`
179
207
 
180
208
  Upload a new document to Paperless-ngx.
181
209
 
182
210
  Parameters:
183
211
 
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
212
+ - `file`: Base64 encoded file content
213
+ - `filename`: Name of the file
214
+ - `title` (optional): Title for the document
215
+ - `created` (optional): DateTime when the document was created (e.g. "2024-01-19" or "2024-01-19 06:15:00+02:00")
216
+ - `correspondent` (optional): ID of a correspondent
217
+ - `document_type` (optional): ID of a document type
218
+ - `storage_path` (optional): ID of a storage path
219
+ - `tags` (optional): Array of tag IDs
220
+ - `archive_serial_number` (optional): Archive serial number
221
+ - `custom_fields` (optional): Array of custom field IDs
194
222
 
195
223
  ```typescript
196
224
  post_document({
@@ -205,9 +233,13 @@ post_document({
205
233
  });
206
234
  ```
207
235
 
236
+ </details>
237
+ <details>
238
+ <summary>Tag Operations</summary>
239
+
208
240
  ### Tag Operations
209
241
 
210
- #### list_tags
242
+ #### `list_tags`
211
243
 
212
244
  Get all tags.
213
245
 
@@ -215,16 +247,16 @@ Get all tags.
215
247
  list_tags();
216
248
  ```
217
249
 
218
- #### create_tag
250
+ #### `create_tag`
219
251
 
220
252
  Create a new tag.
221
253
 
222
254
  Parameters:
223
255
 
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)
256
+ - `name`: Tag name
257
+ - `color` (optional): Hex color code (e.g. "#ff0000")
258
+ - `match` (optional): Text pattern to match
259
+ - `matching_algorithm` (optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
228
260
 
229
261
  ```typescript
230
262
  create_tag({
@@ -235,17 +267,17 @@ create_tag({
235
267
  });
236
268
  ```
237
269
 
238
- #### update_tag
270
+ #### `update_tag`
239
271
 
240
272
  Update an existing tag's name, color, or matching rules.
241
273
 
242
274
  Parameters:
243
275
 
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)
276
+ - `id`: Tag ID
277
+ - `name`: New tag name
278
+ - `color` (optional): Hex color code (e.g. "#ff0000")
279
+ - `match` (optional): Text pattern to match
280
+ - `matching_algorithm` (optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
249
281
 
250
282
  ```typescript
251
283
  update_tag({
@@ -255,13 +287,13 @@ update_tag({
255
287
  });
256
288
  ```
257
289
 
258
- #### delete_tag
290
+ #### `delete_tag`
259
291
 
260
292
  Permanently delete a tag. Removes it from all documents.
261
293
 
262
294
  Parameters:
263
295
 
264
- - id: Tag ID
296
+ - `id`: Tag ID
265
297
 
266
298
  ```typescript
267
299
  delete_tag({
@@ -275,11 +307,11 @@ Bulk set permissions or delete multiple tags.
275
307
 
276
308
  Parameters:
277
309
 
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)
310
+ - `tag_ids`: Array of tag IDs
311
+ - `operation`: "set_permissions" or "delete"
312
+ - `owner` (optional): User ID (for set_permissions)
313
+ - `permissions` (optional): Object with view/change user and group IDs
314
+ - `merge` (optional): Merge with existing permissions (default false)
283
315
 
284
316
  ```typescript
285
317
  bulk_edit_tags({
@@ -288,9 +320,13 @@ bulk_edit_tags({
288
320
  });
289
321
  ```
290
322
 
323
+ </details>
324
+ <details>
325
+ <summary>Correspondent Operations</summary>
326
+
291
327
  ### Correspondent Operations
292
328
 
293
- #### list_correspondents
329
+ #### `list_correspondents`
294
330
 
295
331
  Get all correspondents.
296
332
 
@@ -304,9 +340,9 @@ Create a new correspondent.
304
340
 
305
341
  Parameters:
306
342
 
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)
343
+ - `name`: Correspondent name
344
+ - `match` (optional): Text pattern to match
345
+ - `matching_algorithm` (optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
310
346
 
311
347
  ```typescript
312
348
  create_correspondent({
@@ -316,17 +352,17 @@ create_correspondent({
316
352
  });
317
353
  ```
318
354
 
319
- #### bulk_edit_correspondents
355
+ #### `bulk_edit_correspondents`
320
356
 
321
357
  Bulk set permissions or delete multiple correspondents.
322
358
 
323
359
  Parameters:
324
360
 
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)
361
+ - `correspondent_ids`: Array of correspondent IDs
362
+ - `operation`: "set_permissions" or "delete"
363
+ - `owner` (optional): User ID (for set_permissions)
364
+ - `permissions` (optional): Object with view/change user and group IDs
365
+ - `merge` (optional): Merge with existing permissions (default false)
330
366
 
331
367
  ```typescript
332
368
  bulk_edit_correspondents({
@@ -335,9 +371,13 @@ bulk_edit_correspondents({
335
371
  });
336
372
  ```
337
373
 
374
+ </details>
375
+ <details>
376
+ <summary>Document Type Operations</summary>
377
+
338
378
  ### Document Type Operations
339
379
 
340
- #### list_document_types
380
+ #### `list_document_types`
341
381
 
342
382
  Get all document types.
343
383
 
@@ -351,9 +391,9 @@ Create a new document type.
351
391
 
352
392
  Parameters:
353
393
 
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)
394
+ - `name`: Document type name
395
+ - `match` (optional): Text pattern to match
396
+ - `matching_algorithm` (optional): Integer 0-6 (0=none, 1=any, 2=all, 3=exact, 4=regex, 5=fuzzy, 6=auto)
357
397
 
358
398
  ```typescript
359
399
  create_document_type({
@@ -363,17 +403,17 @@ create_document_type({
363
403
  });
364
404
  ```
365
405
 
366
- #### bulk_edit_document_types
406
+ #### `bulk_edit_document_types`
367
407
 
368
408
  Bulk set permissions or delete multiple document types.
369
409
 
370
410
  Parameters:
371
411
 
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)
412
+ - `document_type_ids`: Array of document type IDs
413
+ - `operation`: "set_permissions" or "delete"
414
+ - `owner` (optional): User ID (for set_permissions)
415
+ - `permissions` (optional): Object with view/change user and group IDs
416
+ - `merge` (optional): Merge with existing permissions (default false)
377
417
 
378
418
  ```typescript
379
419
  bulk_edit_document_types({
@@ -382,6 +422,8 @@ bulk_edit_document_types({
382
422
  });
383
423
  ```
384
424
 
425
+ </details>
426
+
385
427
  ## Error Handling
386
428
 
387
429
  The server will show clear error messages if:
@@ -427,19 +469,33 @@ The MCP server can be run in two modes:
427
469
  This is the default mode. The server communicates over stdio, suitable for CLI and direct integrations.
428
470
 
429
471
  ```bash
430
- bun start -- <baseUrl> <token>
472
+ # via .env file (Bun loads .env automatically)
473
+ bun start
474
+
475
+ # via inline env vars
476
+ PAPERLESS_URL=http://localhost:8000 PAPERLESS_API_KEY=your-token bun start
477
+
478
+ # via positional args
479
+ bun start http://localhost:8000 your-token
431
480
  ```
432
481
 
482
+ > [!TIP]
483
+ > When using Bun, env vars in a `.env` file are loaded automatically —
484
+ > no extra setup needed. Just create a `.env` with `PAPERLESS_URL` and
485
+ > `PAPERLESS_API_KEY` and run `bun start`.
486
+
433
487
  ### 2. HTTP (Streamable HTTP Transport)
434
488
 
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).
489
+ To run the server as an HTTP service, use the `--http` flag. You can also specify the port with `--port` (default: 3000).
436
490
 
437
491
  ```bash
438
- bun start -- <baseUrl> <token> --http --port 3000
492
+ PAPERLESS_URL=http://localhost:8000 PAPERLESS_API_KEY=your-token bun start --http --port 3000
439
493
  ```
440
494
 
495
+ With a `.env` file, this simplifies to `bun start --http`.
496
+
441
497
  - The MCP API will be available at `POST /mcp` on the specified port.
442
498
  - Each request is handled statelessly, following the [StreamableHTTPServerTransport](https://github.com/modelcontextprotocol/typescript-sdk) pattern.
443
499
  - GET and DELETE requests to `/mcp` will return 405 Method Not Allowed.
444
500
 
445
- <!--markdownlint-disable-file no-hard-tabs-->
501
+ <!--markdownlint-disable-file no-hard-tabs no-inline-html no-bare-urls-->