@baruchiro/paperless-mcp 0.4.3 → 0.4.5
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/build/api/documentEnhancer.js +3 -4
- package/build/api/documentEnhancer.test.d.ts +1 -0
- package/build/api/documentEnhancer.test.js +80 -0
- package/build/test/mocks/paperlessApi.d.ts +4 -0
- package/build/test/mocks/paperlessApi.js +33 -0
- package/package.json +1 -1
- package/paperless-mcp.dxt +0 -0
|
@@ -24,14 +24,13 @@ exports.convertDocsWithNames = convertDocsWithNames;
|
|
|
24
24
|
function convertDocsWithNames(input, api) {
|
|
25
25
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26
26
|
if ("results" in input) {
|
|
27
|
-
const
|
|
27
|
+
const { all, results } = input, paginationMeta = __rest(input, ["all", "results"]);
|
|
28
|
+
const enhancedResults = yield enhanceDocumentsArray(results || [], api);
|
|
28
29
|
return {
|
|
29
30
|
content: [
|
|
30
31
|
{
|
|
31
32
|
type: "text",
|
|
32
|
-
text: (
|
|
33
|
-
? JSON.stringify(Object.assign(Object.assign({}, input), { results: enhancedResults }))
|
|
34
|
-
: "No documents found",
|
|
33
|
+
text: JSON.stringify(Object.assign(Object.assign({}, paginationMeta), { results: enhancedResults })),
|
|
35
34
|
},
|
|
36
35
|
],
|
|
37
36
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
16
|
+
const node_test_1 = require("node:test");
|
|
17
|
+
const documentEnhancer_1 = require("./documentEnhancer");
|
|
18
|
+
const paperlessApi_1 = require("../test/mocks/paperlessApi");
|
|
19
|
+
const LARGE_DOCUMENT_COUNT = 709;
|
|
20
|
+
const MAX_RESPONSE_SIZE_BYTES = 2000;
|
|
21
|
+
function getTextContent(result) {
|
|
22
|
+
var _a;
|
|
23
|
+
const item = (_a = result.content) === null || _a === void 0 ? void 0 : _a[0];
|
|
24
|
+
if (!item || item.type !== "text") {
|
|
25
|
+
throw new Error("Expected text content");
|
|
26
|
+
}
|
|
27
|
+
return item.text;
|
|
28
|
+
}
|
|
29
|
+
(0, node_test_1.test)("convertDocsWithNames omits `all` and keeps paginated JSON shape", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
const docsResponse = {
|
|
31
|
+
count: 2,
|
|
32
|
+
next: null,
|
|
33
|
+
previous: null,
|
|
34
|
+
all: [1, 2],
|
|
35
|
+
results: [(0, paperlessApi_1.createDocument)(), (0, paperlessApi_1.createDocument)({ id: 2, title: "Document 2" })],
|
|
36
|
+
};
|
|
37
|
+
const result = yield (0, documentEnhancer_1.convertDocsWithNames)(docsResponse, (0, paperlessApi_1.createPaperlessApiMock)());
|
|
38
|
+
const parsed = JSON.parse(getTextContent(result));
|
|
39
|
+
strict_1.default.ok(!("all" in parsed));
|
|
40
|
+
strict_1.default.deepEqual(parsed.results.map((doc) => doc.id), [1, 2]);
|
|
41
|
+
strict_1.default.ok(!("content" in parsed.results[0]));
|
|
42
|
+
}));
|
|
43
|
+
(0, node_test_1.test)("convertDocsWithNames keeps responses small when source has large `all` arrays", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
|
+
const docsResponse = {
|
|
45
|
+
count: LARGE_DOCUMENT_COUNT,
|
|
46
|
+
next: "http://localhost:8000/api/documents/?page=2",
|
|
47
|
+
previous: null,
|
|
48
|
+
all: Array.from({ length: LARGE_DOCUMENT_COUNT }, (_, index) => index + 1),
|
|
49
|
+
results: [
|
|
50
|
+
(0, paperlessApi_1.createDocument)({
|
|
51
|
+
id: 123,
|
|
52
|
+
title: "Large all payload case",
|
|
53
|
+
content: "x".repeat(2700),
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
const result = yield (0, documentEnhancer_1.convertDocsWithNames)(docsResponse, (0, paperlessApi_1.createPaperlessApiMock)());
|
|
58
|
+
const responseText = getTextContent(result);
|
|
59
|
+
strict_1.default.ok(responseText.length < MAX_RESPONSE_SIZE_BYTES);
|
|
60
|
+
const parsed = JSON.parse(responseText);
|
|
61
|
+
strict_1.default.ok(!("all" in parsed));
|
|
62
|
+
strict_1.default.ok(!("content" in parsed.results[0]));
|
|
63
|
+
}));
|
|
64
|
+
(0, node_test_1.test)("convertDocsWithNames returns paginated JSON for empty multi-document results", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
const docsResponse = {
|
|
66
|
+
count: 0,
|
|
67
|
+
next: null,
|
|
68
|
+
previous: null,
|
|
69
|
+
all: [],
|
|
70
|
+
results: [],
|
|
71
|
+
};
|
|
72
|
+
const result = yield (0, documentEnhancer_1.convertDocsWithNames)(docsResponse, (0, paperlessApi_1.createPaperlessApiMock)());
|
|
73
|
+
const parsed = JSON.parse(getTextContent(result));
|
|
74
|
+
strict_1.default.deepEqual(parsed, {
|
|
75
|
+
count: 0,
|
|
76
|
+
next: null,
|
|
77
|
+
previous: null,
|
|
78
|
+
results: [],
|
|
79
|
+
});
|
|
80
|
+
}));
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createPaperlessApiMock = createPaperlessApiMock;
|
|
13
|
+
exports.createDocument = createDocument;
|
|
14
|
+
function emptyPaginationResponse(results = []) {
|
|
15
|
+
return {
|
|
16
|
+
count: results.length,
|
|
17
|
+
next: null,
|
|
18
|
+
previous: null,
|
|
19
|
+
all: [],
|
|
20
|
+
results,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function createPaperlessApiMock() {
|
|
24
|
+
return {
|
|
25
|
+
getCorrespondents: () => __awaiter(this, void 0, void 0, function* () { return emptyPaginationResponse(); }),
|
|
26
|
+
getDocumentTypes: () => __awaiter(this, void 0, void 0, function* () { return emptyPaginationResponse(); }),
|
|
27
|
+
getTags: () => __awaiter(this, void 0, void 0, function* () { return emptyPaginationResponse(); }),
|
|
28
|
+
getCustomFields: () => __awaiter(this, void 0, void 0, function* () { return emptyPaginationResponse(); }),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function createDocument(overrides = {}) {
|
|
32
|
+
return Object.assign({ id: 1, correspondent: null, document_type: null, storage_path: null, title: "Document 1", content: "OCR content", tags: [], created: "2026-01-01T00:00:00.000Z", created_date: "2026-01-01", modified: "2026-01-01T00:00:00.000Z", added: "2026-01-01T00:00:00.000Z", deleted_at: null, archive_serial_number: null, original_file_name: "doc1.pdf", archived_file_name: "2026/doc1.pdf", owner: null, user_can_change: true, is_shared_by_requester: false, notes: [], custom_fields: [], page_count: 1, mime_type: "application/pdf" }, overrides);
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@baruchiro/paperless-mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
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
|