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.

71 lines (64 loc) 3.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createMcpServer = createMcpServer; exports.getBearerToken = getBearerToken; exports.sendUnauthorized = sendUnauthorized; const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); const PaperlessAPI_1 = require("./api/PaperlessAPI"); const documents_1 = require("./resources/documents"); const correspondents_1 = require("./tools/correspondents"); const customFields_1 = require("./tools/customFields"); const documents_2 = require("./tools/documents"); const documentTypes_1 = require("./tools/documentTypes"); const mail_1 = require("./tools/mail"); const notes_1 = require("./tools/notes"); const tags_1 = require("./tools/tags"); function createMcpServer({ baseUrl, token, version, publicUrl, }) { const api = new PaperlessAPI_1.PaperlessAPI(baseUrl, token); const server = new mcp_js_1.McpServer({ name: "paperless-ngx", version }, { instructions: buildInstructions(publicUrl) }); (0, documents_2.registerDocumentTools)(server, api); (0, documents_1.registerDocumentResources)(server, api); (0, notes_1.registerNoteTools)(server, api); (0, tags_1.registerTagTools)(server, api); (0, correspondents_1.registerCorrespondentTools)(server, api); (0, documentTypes_1.registerDocumentTypeTools)(server, api); (0, customFields_1.registerCustomFieldTools)(server, api); (0, mail_1.registerMailTools)(server, api); return server; } function getBearerToken(req, options) { const authHeader = req.headers["authorization"]; if (authHeader && authHeader.startsWith("Bearer ")) { return authHeader.slice(7); } if (options.allowAnonymous) { return options.fallbackToken || undefined; } return undefined; } function sendUnauthorized(res) { // Log operator-facing guidance server-side; keep the wire response minimal so // we don't echo configuration hints back to unauthenticated callers. console.error("[paperless-mcp] Rejected request with no 'Authorization: Bearer <paperless-ngx-api-token>' header. " + "As of v2.0.0, HTTP mode requires a per-request Bearer token and no longer falls back to the " + "server-configured token for unauthenticated requests. Have clients send their Paperless-NGX API " + "token as a Bearer token, or restart the server with --no-auth to use the server token for " + "unauthenticated requests (trusted/local networks only)."); res .status(401) .set("WWW-Authenticate", 'Bearer realm="paperless-mcp"') .json({ error: "unauthorized" }); } function buildInstructions(publicUrl) { return ` Paperless-NGX MCP Server Instructions ⚠️ CRITICAL: Always differentiate between operations on specific documents vs operations on the entire system: - REMOVE operations (e.g., remove_tag in bulk_edit_documents): Affect only the specified documents, items remain in the system - DELETE operations (e.g., delete_tag, delete_correspondent): Permanently delete items from the entire system, affecting ALL documents that use them When a user asks to "remove" something, prefer operations that affect specific documents. Only use DELETE operations when explicitly asked to delete from the system. To view documents in your Paperless-NGX web interface, construct URLs using this pattern: ${publicUrl}/documents/{document_id}/ Example: If your base URL is "http://localhost:8000", the web interface URL would be "http://localhost:8000/documents/123/" for document ID 123. The document tools return JSON data with document IDs that you can use to construct these URLs. `; }