@baruchiro/paperless-mcp 2.0.0 → 2.0.1
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
|
@@ -66,7 +66,7 @@ Add these to your MCP config file:
|
|
|
66
66
|
| `PAPERLESS_URL` | Yes | — | Base URL of your Paperless-NGX instance |
|
|
67
67
|
| `PAPERLESS_API_KEY` | Yes | — | API token from your Paperless-NGX profile |
|
|
68
68
|
| `PAPERLESS_PUBLIC_URL` | No | `PAPERLESS_URL` | Public-facing URL for document links |
|
|
69
|
-
| `PAPERLESS_API_VERSION` | No | `
|
|
69
|
+
| `PAPERLESS_API_VERSION` | No | `9` | Paperless-ngx REST API version. `9` works on Paperless-ngx v2.x (recent) and v3.x. Paperless-ngx v3.0.0 dropped support for versions below `9`, so older defaults now return HTTP 406. If you see HTTP 406 errors, set this to a version your server supports. |
|
|
70
70
|
| `PAPERLESS_MCP_UPLOAD_PATHS` | No | — | Colon-separated list of allowed directories for `file_path` uploads. **Recommended for security.** Example: `/var/uploads:/tmp/scans` |
|
|
71
71
|
|
|
72
72
|
That's it! Now you can ask Claude to help you manage your Paperless-NGX documents.
|
|
@@ -22,7 +22,7 @@ class PaperlessAPI {
|
|
|
22
22
|
this.token = token;
|
|
23
23
|
this.baseUrl = baseUrl;
|
|
24
24
|
this.token = token;
|
|
25
|
-
this.apiVersion = process.env.PAPERLESS_API_VERSION || "
|
|
25
|
+
this.apiVersion = process.env.PAPERLESS_API_VERSION || "9";
|
|
26
26
|
}
|
|
27
27
|
request(path_1) {
|
|
28
28
|
return __awaiter(this, arguments, void 0, function* (path, options = {}) {
|
|
@@ -57,7 +57,7 @@ class PaperlessAPI {
|
|
|
57
57
|
catch (error) {
|
|
58
58
|
if (axios_1.default.isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 406) {
|
|
59
59
|
throw new Error(`HTTP 406: Paperless-ngx rejected API version ${this.apiVersion}. ` +
|
|
60
|
-
`Set the PAPERLESS_API_VERSION environment variable to
|
|
60
|
+
`Set the PAPERLESS_API_VERSION environment variable to a version your server supports (e.g., "9" or "10" for Paperless-ngx v3+, or a lower value for older servers).`);
|
|
61
61
|
}
|
|
62
62
|
console.error({
|
|
63
63
|
error: "Error executing request",
|
|
@@ -121,7 +121,7 @@ class PaperlessAPI {
|
|
|
121
121
|
catch (error) {
|
|
122
122
|
if (axios_1.default.isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 406) {
|
|
123
123
|
throw new Error(`HTTP 406: Paperless-ngx rejected API version ${this.apiVersion}. ` +
|
|
124
|
-
`Set the PAPERLESS_API_VERSION environment variable to
|
|
124
|
+
`Set the PAPERLESS_API_VERSION environment variable to a version your server supports (e.g., "9" or "10" for Paperless-ngx v3+, or a lower value for older servers).`);
|
|
125
125
|
}
|
|
126
126
|
throw error;
|
|
127
127
|
}
|
package/build/tools/documents.js
CHANGED
|
@@ -412,7 +412,7 @@ function registerDocumentTools(server, api) {
|
|
|
412
412
|
],
|
|
413
413
|
};
|
|
414
414
|
})));
|
|
415
|
-
server.tool("update_document", "Update a specific document with new values
|
|
415
|
+
server.tool("update_document", "Update a specific document with new values (title, correspondent, document type, storage path, tags, custom fields, and more). Top-level fields you omit are left unchanged. IMPORTANT: custom_fields is the exception — see its parameter description; it replaces the document's entire custom-field set.", {
|
|
416
416
|
id: zod_1.z.number().describe("The ID of the document to update"),
|
|
417
417
|
title: zod_1.z
|
|
418
418
|
.string()
|
|
@@ -469,13 +469,13 @@ function registerDocumentTools(server, api) {
|
|
|
469
469
|
.describe(descriptions_1.CUSTOM_FIELD_VALUE_DESCRIPTION),
|
|
470
470
|
}))
|
|
471
471
|
.optional()
|
|
472
|
-
.describe("
|
|
472
|
+
.describe("Custom field values for the document. ⚠️ REPLACES the document's entire custom-field set — any field not included here will be CLEARED. To update or add a single field without losing the others, first call get_document to read the existing custom_fields, then pass the full merged array. To add/set fields additively without fetching, use bulk_edit_documents with method 'modify_custom_fields' instead."),
|
|
473
473
|
}, (0, middlewares_1.withErrorHandling)((args, extra) => __awaiter(this, void 0, void 0, function* () {
|
|
474
474
|
if (!api)
|
|
475
475
|
throw new Error("Please configure API connection first");
|
|
476
476
|
const { id } = args, updateData = __rest(args, ["id"]);
|
|
477
477
|
(0, monetary_1.validateCustomFields)(updateData.custom_fields);
|
|
478
|
-
updateData.custom_fields = yield (0, selectFields_1.resolveSelectCustomFieldValues)(api, updateData.custom_fields, "
|
|
478
|
+
updateData.custom_fields = yield (0, selectFields_1.resolveSelectCustomFieldValues)(api, updateData.custom_fields, "stored");
|
|
479
479
|
const response = yield api.updateDocument(id, updateData);
|
|
480
480
|
return (0, documentEnhancer_1.convertDocsWithNames)(response, api);
|
|
481
481
|
})));
|
|
@@ -416,7 +416,7 @@ const OBJECT_SELECT_FIELD = {
|
|
|
416
416
|
const [, data] = calls.updateDocument[0];
|
|
417
417
|
strict_1.default.deepEqual(data.custom_fields, [{ field: 2, value: 0 }]);
|
|
418
418
|
}));
|
|
419
|
-
(0, node_test_1.test)("update_document
|
|
419
|
+
(0, node_test_1.test)("update_document sends the option id for 2.17+ select fields (stored form)", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
420
420
|
const { api, calls } = createDocumentApi([OBJECT_SELECT_FIELD]);
|
|
421
421
|
yield withDocumentClient(api, (client) => __awaiter(void 0, void 0, void 0, function* () {
|
|
422
422
|
var _a;
|
|
@@ -427,7 +427,7 @@ const OBJECT_SELECT_FIELD = {
|
|
|
427
427
|
strict_1.default.ok(!result.isError, (_a = parseToolText(result)) === null || _a === void 0 ? void 0 : _a.error);
|
|
428
428
|
}));
|
|
429
429
|
const [, data] = calls.updateDocument[0];
|
|
430
|
-
strict_1.default.deepEqual(data.custom_fields, [{ field: 3, value:
|
|
430
|
+
strict_1.default.deepEqual(data.custom_fields, [{ field: 3, value: "def456" }]);
|
|
431
431
|
}));
|
|
432
432
|
(0, node_test_1.test)("bulk_edit_documents translates a select label in add_custom_fields", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
433
433
|
const { api, calls } = createDocumentApi([LEGACY_SELECT_FIELD]);
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { PaperlessAPI } from "../../api/PaperlessAPI";
|
|
2
2
|
import { CustomField, CustomFieldInstanceRequest, CustomFieldValue } from "../../api/types";
|
|
3
3
|
/**
|
|
4
|
-
* Encoding Paperless expects for a select value
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Encoding Paperless expects for a select value. On the supported API versions
|
|
5
|
+
* (v9+) both `update_document` and `bulk_edit` take the option's stored form:
|
|
6
|
+
* the option id on 2.17+ fields, or the index on pre-2.17 string-option fields.
|
|
7
|
+
* The bare `index` form is retained for older API versions whose document
|
|
8
|
+
* endpoint accepted the option index directly.
|
|
7
9
|
*/
|
|
8
10
|
export type SelectValueEncoding = "index" | "stored";
|
|
9
11
|
/** Translates a select value (label, option id, or index) to the `encoding` Paperless expects; throws on no match. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@baruchiro/paperless-mcp",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server for interacting with Paperless-NGX document management system. Enables AI assistants to manage documents, tags, correspondents, and document types through the Paperless-NGX API.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"bin": {
|
package/paperless-mcp.dxt
CHANGED
|
Binary file
|