UNPKG

@baruchiro/paperless-mcp

Version:

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.

213 lines (212 loc) 8.23 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const strict_1 = __importDefault(require("node:assert/strict")); const node_test_1 = require("node:test"); const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js"); const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); const mail_1 = require("./mail"); class TestTransport { start() { return __awaiter(this, void 0, void 0, function* () { }); } send(message) { return __awaiter(this, void 0, void 0, function* () { queueMicrotask(() => { var _a, _b; return (_b = (_a = this.peer) === null || _a === void 0 ? void 0 : _a.onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, message); }); }); } close() { return __awaiter(this, void 0, void 0, function* () { var _a; (_a = this.onclose) === null || _a === void 0 ? void 0 : _a.call(this); }); } } function createTransportPair() { const clientTransport = new TestTransport(); const serverTransport = new TestTransport(); clientTransport.peer = serverTransport; serverTransport.peer = clientTransport; return { clientTransport, serverTransport }; } function parseToolText(result) { var _a; const item = (_a = result.content) === null || _a === void 0 ? void 0 : _a[0]; if (!item || item.type !== "text") { throw new Error("Expected text tool response"); } return JSON.parse(item.text); } function withMailClient(api, run) { return __awaiter(this, void 0, void 0, function* () { const server = new mcp_js_1.McpServer({ name: "paperless-mail-test", version: "1.0.0" }); (0, mail_1.registerMailTools)(server, api); const client = new index_js_1.Client({ name: "paperless-mail-test-client", version: "1.0.0", }); const { clientTransport, serverTransport } = createTransportPair(); yield server.connect(serverTransport); yield client.connect(clientTransport); try { yield run(client); } finally { yield client.close(); yield server.close(); } }); } (0, node_test_1.test)("mail tools are registered", () => __awaiter(void 0, void 0, void 0, function* () { yield withMailClient({}, (client) => __awaiter(void 0, void 0, void 0, function* () { const result = yield client.listTools(); const names = result.tools.map((tool) => tool.name).sort(); strict_1.default.deepEqual(names, [ "create_mail_rule", "delete_mail_rule", "get_mail_account", "get_mail_rule", "list_mail_accounts", "list_mail_rules", "process_mail_account", "update_mail_rule", ]); })); })); (0, node_test_1.test)("list_mail_accounts redacts returned passwords", () => __awaiter(void 0, void 0, void 0, function* () { const api = { getMailAccounts: (queryString) => __awaiter(void 0, void 0, void 0, function* () { return ({ count: 1, next: null, previous: null, results: [ { id: 1, name: "Inbox", username: "paperless@example.test", password: "secret", queryString, }, ], }); }), }; yield withMailClient(api, (client) => __awaiter(void 0, void 0, void 0, function* () { const result = (yield client.callTool({ name: "list_mail_accounts", arguments: { page: 2, page_size: 10 }, })); const response = parseToolText(result); strict_1.default.equal(response.results[0].password, undefined); strict_1.default.equal(response.results[0].queryString, "page=2&page_size=10"); })); })); (0, node_test_1.test)("get_mail_account redacts returned password", () => __awaiter(void 0, void 0, void 0, function* () { const api = { getMailAccount: (id) => __awaiter(void 0, void 0, void 0, function* () { return ({ id, name: "Inbox", username: "paperless@example.test", password: "secret", }); }), }; yield withMailClient(api, (client) => __awaiter(void 0, void 0, void 0, function* () { const result = (yield client.callTool({ name: "get_mail_account", arguments: { id: 7 }, })); const account = parseToolText(result); strict_1.default.deepEqual(account, { id: 7, name: "Inbox", username: "paperless@example.test", }); })); })); (0, node_test_1.test)("process_mail_account reports success after processing", () => __awaiter(void 0, void 0, void 0, function* () { const calls = []; const api = { processMailAccount: (id) => __awaiter(void 0, void 0, void 0, function* () { calls.push(["process", id]); }), }; yield withMailClient(api, (client) => __awaiter(void 0, void 0, void 0, function* () { const result = (yield client.callTool({ name: "process_mail_account", arguments: { id: 5 }, })); const response = parseToolText(result); strict_1.default.deepEqual(response, { status: "processed" }); })); strict_1.default.deepEqual(calls, [["process", 5]]); })); (0, node_test_1.test)("mail rule write tools pass through payloads", () => __awaiter(void 0, void 0, void 0, function* () { const calls = []; const api = { createMailRule: (data) => __awaiter(void 0, void 0, void 0, function* () { calls.push(["create", data]); return Object.assign({ id: 3 }, data); }), updateMailRule: (id, data) => __awaiter(void 0, void 0, void 0, function* () { calls.push(["update", id, data]); return Object.assign({ id }, data); }), deleteMailRule: (id) => __awaiter(void 0, void 0, void 0, function* () { calls.push(["delete", id]); }), }; yield withMailClient(api, (client) => __awaiter(void 0, void 0, void 0, function* () { yield client.callTool({ name: "create_mail_rule", arguments: { name: "Invoices", account: 1, folder: "INBOX", filter_from: "billing@example.test", assign_tags: [3, 15], }, }); yield client.callTool({ name: "update_mail_rule", arguments: { id: 3, enabled: false, }, }); yield client.callTool({ name: "delete_mail_rule", arguments: { id: 3, confirm: true, }, }); })); strict_1.default.deepEqual(calls, [ [ "create", { name: "Invoices", account: 1, folder: "INBOX", filter_from: "billing@example.test", assign_tags: [3, 15], }, ], ["update", 3, { enabled: false }], ["delete", 3], ]); }));