@kjanat/paperless-mcp 2.0.0 → 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 +158 -102
- package/dist/index.js +83 -81
- package/package.json +13 -14
- package/skills/paperless-ngx/SKILL.md +13 -13
- package/skills/paperless-ngx/references/query-syntax.md +5 -5
- package/skills/paperless-ngx/references/tools.md +28 -25
- package/skills/paperless-ngx/references/workflows.md +34 -14
- package/skills/paperless-ngx/scripts/test-connection.sh +4 -4
- package/src/index.ts +0 -144
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.
|
|
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
|
-
|
|
12
|
-
|
|
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
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
110
|
-
- method
|
|
111
|
-
- set_correspondent
|
|
112
|
-
- set_document_type
|
|
113
|
-
- set_storage_path
|
|
114
|
-
- add_tag
|
|
115
|
-
- remove_tag
|
|
116
|
-
- modify_tags
|
|
117
|
-
- delete
|
|
118
|
-
- reprocess
|
|
119
|
-
- set_permissions
|
|
120
|
-
- merge
|
|
121
|
-
- split
|
|
122
|
-
- rotate
|
|
123
|
-
- delete_pages
|
|
124
|
-
- Additional parameters based on method
|
|
125
|
-
- correspondent
|
|
126
|
-
- document_type
|
|
127
|
-
- storage_path
|
|
128
|
-
- tag
|
|
129
|
-
- add_tags
|
|
130
|
-
- remove_tags
|
|
131
|
-
- permissions
|
|
132
|
-
- metadata_document_id
|
|
133
|
-
- delete_originals
|
|
134
|
-
- pages
|
|
135
|
-
- degrees
|
|
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
|
|
185
|
-
- filename
|
|
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
|
|
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
|
|
245
|
-
- 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
|
|
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
|
|
279
|
-
- operation
|
|
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
|
|
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
|
|
326
|
-
- operation
|
|
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
|
|
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
|
|
373
|
-
- operation
|
|
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
|
-
|
|
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).
|
|
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 --
|
|
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-->
|