@baruchiro/paperless-mcp 0.1.0 → 0.2.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
@@ -3,6 +3,7 @@
3
3
  # Paperless-NGX MCP Server
4
4
 
5
5
  [![smithery badge](https://smithery.ai/badge/@baruchiro/paperless-mcp)](https://smithery.ai/server/@baruchiro/paperless-mcp)
6
+ ![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/baruchiro/paperless-mcp?utm_source=oss&utm_medium=github&utm_campaign=baruchiro%2Fpaperless-mcp&labelColor=171717&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit+Reviews)
6
7
 
7
8
  An MCP (Model Context Protocol) server for interacting with a Paperless-NGX API server. This server provides tools for managing documents, tags, correspondents, and document types in your Paperless-NGX instance.
8
9
 
@@ -262,14 +263,21 @@ Parameters:
262
263
  - name: Tag name
263
264
  - color (optional): Hex color code (e.g. "#ff0000")
264
265
  - match (optional): Text pattern to match
265
- - matching_algorithm (optional): One of "any", "all", "exact", "regular expression", "fuzzy"
266
+ - matching_algorithm (optional): Number between 0 and 6:
267
+ 0 - None
268
+ 1 - Any word
269
+ 2 - All words
270
+ 3 - Exact match
271
+ 4 - Regular expression
272
+ 5 - Fuzzy word
273
+ 6 - Automatic
266
274
 
267
275
  ```typescript
268
276
  create_tag({
269
277
  name: "Invoice",
270
278
  color: "#ff0000",
271
279
  match: "invoice",
272
- matching_algorithm: "fuzzy"
280
+ matching_algorithm: 5
273
281
  })
274
282
  ```
275
283
 
@@ -288,13 +296,20 @@ Create a new correspondent.
288
296
  Parameters:
289
297
  - name: Correspondent name
290
298
  - match (optional): Text pattern to match
291
- - matching_algorithm (optional): One of "any", "all", "exact", "regular expression", "fuzzy"
299
+ - matching_algorithm (optional): Number between 0 and 6:
300
+ 0 - None
301
+ 1 - Any word
302
+ 2 - All words
303
+ 3 - Exact match
304
+ 4 - Regular expression
305
+ 5 - Fuzzy word
306
+ 6 - Automatic
292
307
 
293
308
  ```typescript
294
309
  create_correspondent({
295
310
  name: "ACME Corp",
296
311
  match: "ACME",
297
- matching_algorithm: "fuzzy"
312
+ matching_algorithm: 5
298
313
  })
299
314
  ```
300
315
 
@@ -313,13 +328,20 @@ Create a new document type.
313
328
  Parameters:
314
329
  - name: Document type name
315
330
  - match (optional): Text pattern to match
316
- - matching_algorithm (optional): One of "any", "all", "exact", "regular expression", "fuzzy"
331
+ - matching_algorithm (optional): Number between 0 and 6:
332
+ 0 - None
333
+ 1 - Any word
334
+ 2 - All words
335
+ 3 - Exact match
336
+ 4 - Regular expression
337
+ 5 - Fuzzy word
338
+ 6 - Automatic
317
339
 
318
340
  ```typescript
319
341
  create_document_type({
320
342
  name: "Invoice",
321
343
  match: "invoice total amount due",
322
- matching_algorithm: "any"
344
+ matching_algorithm: 1
323
345
  })
324
346
  ```
325
347
 
@@ -15,7 +15,8 @@ export declare class PaperlessAPI {
15
15
  createTag(data: Partial<Tag>): Promise<Tag>;
16
16
  updateTag(id: number, data: Partial<Tag>): Promise<Tag>;
17
17
  deleteTag(id: number): Promise<void>;
18
- getCorrespondents(): Promise<GetCorrespondentsResponse>;
18
+ getCorrespondents(queryString?: string): Promise<GetCorrespondentsResponse>;
19
+ getCorrespondent(id: number): Promise<Correspondent>;
19
20
  createCorrespondent(data: Partial<Correspondent>): Promise<Correspondent>;
20
21
  updateCorrespondent(id: number, data: Partial<Correspondent>): Promise<Correspondent>;
21
22
  deleteCorrespondent(id: number): Promise<void>;
@@ -178,9 +178,17 @@ class PaperlessAPI {
178
178
  });
179
179
  }
180
180
  // Correspondent operations
181
- getCorrespondents() {
181
+ getCorrespondents(queryString) {
182
182
  return __awaiter(this, void 0, void 0, function* () {
183
- return this.request("/correspondents/");
183
+ const url = queryString
184
+ ? `/correspondents/?${queryString}`
185
+ : "/correspondents/";
186
+ return this.request(url);
187
+ });
188
+ }
189
+ getCorrespondent(id) {
190
+ return __awaiter(this, void 0, void 0, function* () {
191
+ return this.request(`/correspondents/${id}/`);
184
192
  });
185
193
  }
186
194
  createCorrespondent(data) {
@@ -1,10 +1,7 @@
1
1
  import { CallToolResult } from "@modelcontextprotocol/sdk/types";
2
2
  import { PaperlessAPI } from "./PaperlessAPI";
3
3
  import { Document, DocumentsResponse } from "./types";
4
- interface NamedItem {
5
- id: number;
6
- name: string;
7
- }
4
+ import { NamedItem } from "./utils";
8
5
  interface CustomField {
9
6
  field: number;
10
7
  name: string;
@@ -1,3 +1,14 @@
1
+ export declare const MATCHING_ALGORITHM_OPTIONS: {
2
+ readonly 0: "None";
3
+ readonly 1: "Any word";
4
+ readonly 2: "All words";
5
+ readonly 3: "Exact match";
6
+ readonly 4: "Regular expression";
7
+ readonly 5: "Fuzzy word";
8
+ readonly 6: "Automatic";
9
+ };
10
+ export type MatchingAlgorithm = keyof typeof MATCHING_ALGORITHM_OPTIONS;
11
+ export declare const MATCHING_ALGORITHM_DESCRIPTION: string;
1
12
  export interface Tag {
2
13
  id: number;
3
14
  slug: string;
@@ -5,7 +16,7 @@ export interface Tag {
5
16
  color: string;
6
17
  text_color: string;
7
18
  match: string;
8
- matching_algorithm: number;
19
+ matching_algorithm: MatchingAlgorithm;
9
20
  is_insensitive: boolean;
10
21
  is_inbox_tag: boolean;
11
22
  document_count: number;
@@ -38,6 +49,18 @@ export interface GetTagsResponse extends PaginationResponse<Tag> {
38
49
  }
39
50
  export interface GetCustomFieldsResponse extends PaginationResponse<CustomField> {
40
51
  }
52
+ export interface BasicUser {
53
+ id: number;
54
+ username: string;
55
+ first_name?: string;
56
+ last_name?: string;
57
+ }
58
+ export interface Note {
59
+ id: number;
60
+ note: string;
61
+ created: string;
62
+ user: BasicUser;
63
+ }
41
64
  export interface DocumentsResponse extends PaginationResponse<Document> {
42
65
  }
43
66
  export interface Document {
@@ -59,7 +82,7 @@ export interface Document {
59
82
  owner: number | null;
60
83
  user_can_change: boolean;
61
84
  is_shared_by_requester: boolean;
62
- notes: any[];
85
+ notes: Note[];
63
86
  custom_fields: CustomFieldInstance[];
64
87
  page_count: number;
65
88
  mime_type: string;
@@ -76,12 +99,12 @@ export interface Correspondent {
76
99
  slug: string;
77
100
  name: string;
78
101
  match: string;
79
- matching_algorithm: number;
102
+ matching_algorithm: MatchingAlgorithm;
80
103
  is_insensitive: boolean;
81
104
  document_count: number;
82
105
  last_correspondence: string;
83
106
  owner: number | null;
84
- permissions: any;
107
+ permissions: Record<string, unknown>;
85
108
  user_can_change: boolean;
86
109
  }
87
110
  export interface GetCorrespondentsResponse extends PaginationResponse<Correspondent> {
@@ -91,12 +114,12 @@ export interface DocumentType {
91
114
  slug: string;
92
115
  name: string;
93
116
  match: string;
94
- matching_algorithm: number;
117
+ matching_algorithm: MatchingAlgorithm;
95
118
  is_insensitive: boolean;
96
119
  document_count: number;
97
120
  last_correspondence: string;
98
121
  owner: number | null;
99
- permissions: any;
122
+ permissions: Record<string, unknown>;
100
123
  user_can_change: boolean;
101
124
  }
102
125
  export interface GetDocumentTypesResponse extends PaginationResponse<DocumentType> {
@@ -1,2 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MATCHING_ALGORITHM_DESCRIPTION = exports.MATCHING_ALGORITHM_OPTIONS = void 0;
4
+ exports.MATCHING_ALGORITHM_OPTIONS = {
5
+ 0: "None",
6
+ 1: "Any word",
7
+ 2: "All words",
8
+ 3: "Exact match",
9
+ 4: "Regular expression",
10
+ 5: "Fuzzy word",
11
+ 6: "Automatic",
12
+ };
13
+ exports.MATCHING_ALGORITHM_DESCRIPTION = `Matching algorithm: ${Object.entries(exports.MATCHING_ALGORITHM_OPTIONS)
14
+ .map(([id, name]) => `${id}=${name}`)
15
+ .join(", ")}`;
@@ -1 +1,16 @@
1
+ import { MatchingAlgorithm } from "./types";
1
2
  export declare const headersToObject: (headers: any) => Record<string, string>;
3
+ export interface NamedItem {
4
+ id: number;
5
+ name: string;
6
+ }
7
+ export declare function enhanceMatchingAlgorithm<T extends {
8
+ matching_algorithm: MatchingAlgorithm;
9
+ }>(obj: T): T & {
10
+ matching_algorithm: NamedItem;
11
+ };
12
+ export declare function enhanceMatchingAlgorithmArray<T extends {
13
+ matching_algorithm: MatchingAlgorithm;
14
+ }>(objects: T[]): (T & {
15
+ matching_algorithm: NamedItem;
16
+ })[];
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.headersToObject = void 0;
4
+ exports.enhanceMatchingAlgorithm = enhanceMatchingAlgorithm;
5
+ exports.enhanceMatchingAlgorithmArray = enhanceMatchingAlgorithmArray;
6
+ const types_1 = require("./types");
4
7
  const headersToObject = (headers) => {
5
8
  if (!headers)
6
9
  return {};
@@ -14,3 +17,13 @@ const headersToObject = (headers) => {
14
17
  return headers;
15
18
  };
16
19
  exports.headersToObject = headersToObject;
20
+ function enhanceMatchingAlgorithm(obj) {
21
+ return Object.assign(Object.assign({}, obj), { matching_algorithm: {
22
+ id: obj.matching_algorithm,
23
+ name: types_1.MATCHING_ALGORITHM_OPTIONS[obj.matching_algorithm] ||
24
+ String(obj.matching_algorithm),
25
+ } });
26
+ }
27
+ function enhanceMatchingAlgorithmArray(objects) {
28
+ return objects.map((obj) => enhanceMatchingAlgorithm(obj));
29
+ }
@@ -1,2 +1,3 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp";
2
- export declare function registerCorrespondentTools(server: McpServer, api: any): void;
2
+ import { PaperlessAPI } from "../api/PaperlessAPI";
3
+ export declare function registerCorrespondentTools(server: McpServer, api: PaperlessAPI): void;
@@ -8,9 +8,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
11
22
  Object.defineProperty(exports, "__esModule", { value: true });
12
23
  exports.registerCorrespondentTools = registerCorrespondentTools;
13
24
  const zod_1 = require("zod");
25
+ const types_1 = require("../api/types");
26
+ const utils_1 = require("../api/utils");
14
27
  const middlewares_1 = require("./utils/middlewares");
15
28
  const queryString_1 = require("./utils/queryString");
16
29
  function registerCorrespondentTools(server, api) {
@@ -26,12 +39,13 @@ function registerCorrespondentTools(server, api) {
26
39
  if (!api)
27
40
  throw new Error("Please configure API connection first");
28
41
  const queryString = (0, queryString_1.buildQueryString)(args);
29
- const response = yield api.request(`/correspondents/${queryString ? `?${queryString}` : ""}`);
42
+ const response = yield api.getCorrespondents(queryString);
43
+ const enhancedResults = (0, utils_1.enhanceMatchingAlgorithmArray)(response.results || []);
30
44
  return {
31
45
  content: [
32
46
  {
33
47
  type: "text",
34
- text: JSON.stringify(response),
48
+ text: JSON.stringify(Object.assign(Object.assign({}, response), { results: enhancedResults })),
35
49
  },
36
50
  ],
37
51
  };
@@ -39,23 +53,33 @@ function registerCorrespondentTools(server, api) {
39
53
  server.tool("get_correspondent", { id: zod_1.z.number() }, (0, middlewares_1.withErrorHandling)((args, extra) => __awaiter(this, void 0, void 0, function* () {
40
54
  if (!api)
41
55
  throw new Error("Please configure API connection first");
42
- const response = yield api.request(`/correspondents/${args.id}/`);
56
+ const response = yield api.getCorrespondent(args.id);
57
+ const enhancedCorrespondent = (0, utils_1.enhanceMatchingAlgorithm)(response);
43
58
  return {
44
- content: [{ type: "text", text: JSON.stringify(response) }],
59
+ content: [
60
+ { type: "text", text: JSON.stringify(enhancedCorrespondent) },
61
+ ],
45
62
  };
46
63
  })));
47
64
  server.tool("create_correspondent", {
48
65
  name: zod_1.z.string(),
49
66
  match: zod_1.z.string().optional(),
50
67
  matching_algorithm: zod_1.z
51
- .enum(["any", "all", "exact", "regular expression", "fuzzy"])
52
- .optional(),
68
+ .number()
69
+ .int()
70
+ .min(0)
71
+ .max(6)
72
+ .optional()
73
+ .describe(types_1.MATCHING_ALGORITHM_DESCRIPTION),
53
74
  }, (0, middlewares_1.withErrorHandling)((args, extra) => __awaiter(this, void 0, void 0, function* () {
54
75
  if (!api)
55
76
  throw new Error("Please configure API connection first");
56
77
  const response = yield api.createCorrespondent(args);
78
+ const enhancedCorrespondent = (0, utils_1.enhanceMatchingAlgorithm)(response);
57
79
  return {
58
- content: [{ type: "text", text: JSON.stringify(response) }],
80
+ content: [
81
+ { type: "text", text: JSON.stringify(enhancedCorrespondent) },
82
+ ],
59
83
  };
60
84
  })));
61
85
  server.tool("update_correspondent", {
@@ -63,17 +87,22 @@ function registerCorrespondentTools(server, api) {
63
87
  name: zod_1.z.string(),
64
88
  match: zod_1.z.string().optional(),
65
89
  matching_algorithm: zod_1.z
66
- .enum(["any", "all", "exact", "regular expression", "fuzzy"])
67
- .optional(),
90
+ .number()
91
+ .int()
92
+ .min(0)
93
+ .max(6)
94
+ .optional()
95
+ .describe(types_1.MATCHING_ALGORITHM_DESCRIPTION),
68
96
  }, (0, middlewares_1.withErrorHandling)((args, extra) => __awaiter(this, void 0, void 0, function* () {
69
97
  if (!api)
70
98
  throw new Error("Please configure API connection first");
71
- const response = yield api.request(`/correspondents/${args.id}/`, {
72
- method: "PUT",
73
- body: JSON.stringify(args),
74
- });
99
+ const { id } = args, data = __rest(args, ["id"]);
100
+ const response = yield api.updateCorrespondent(id, data);
101
+ const enhancedCorrespondent = (0, utils_1.enhanceMatchingAlgorithm)(response);
75
102
  return {
76
- content: [{ type: "text", text: JSON.stringify(response) }],
103
+ content: [
104
+ { type: "text", text: JSON.stringify(enhancedCorrespondent) },
105
+ ],
77
106
  };
78
107
  })));
79
108
  server.tool("delete_correspondent", "⚠️ DESTRUCTIVE: Permanently delete a correspondent from the entire system. This will affect ALL documents that use this correspondent.", {
@@ -87,7 +116,7 @@ function registerCorrespondentTools(server, api) {
87
116
  if (!args.confirm) {
88
117
  throw new Error("Confirmation required for destructive operation. Set confirm: true to proceed.");
89
118
  }
90
- yield api.request(`/correspondents/${args.id}/`, { method: "DELETE" });
119
+ yield api.deleteCorrespondent(args.id);
91
120
  return {
92
121
  content: [
93
122
  { type: "text", text: JSON.stringify({ status: "deleted" }) },
@@ -1 +1,3 @@
1
- export declare function registerDocumentTypeTools(server: any, api: any): void;
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp";
2
+ import { PaperlessAPI } from "../api/PaperlessAPI";
3
+ export declare function registerDocumentTypeTools(server: McpServer, api: PaperlessAPI): void;
@@ -8,9 +8,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
11
22
  Object.defineProperty(exports, "__esModule", { value: true });
12
23
  exports.registerDocumentTypeTools = registerDocumentTypeTools;
13
24
  const zod_1 = require("zod");
25
+ const types_1 = require("../api/types");
26
+ const utils_1 = require("../api/utils");
14
27
  const middlewares_1 = require("./utils/middlewares");
15
28
  const queryString_1 = require("./utils/queryString");
16
29
  function registerDocumentTypeTools(server, api) {
@@ -27,11 +40,12 @@ function registerDocumentTypeTools(server, api) {
27
40
  throw new Error("Please configure API connection first");
28
41
  const queryString = (0, queryString_1.buildQueryString)(args);
29
42
  const response = yield api.request(`/document_types/${queryString ? `?${queryString}` : ""}`);
43
+ const enhancedResults = (0, utils_1.enhanceMatchingAlgorithmArray)(response.results || []);
30
44
  return {
31
45
  content: [
32
46
  {
33
47
  type: "text",
34
- text: JSON.stringify(response),
48
+ text: JSON.stringify(Object.assign(Object.assign({}, response), { results: enhancedResults })),
35
49
  },
36
50
  ],
37
51
  };
@@ -40,22 +54,28 @@ function registerDocumentTypeTools(server, api) {
40
54
  if (!api)
41
55
  throw new Error("Please configure API connection first");
42
56
  const response = yield api.request(`/document_types/${args.id}/`);
57
+ const enhancedDocumentType = (0, utils_1.enhanceMatchingAlgorithm)(response);
43
58
  return {
44
- content: [{ type: "text", text: JSON.stringify(response) }],
59
+ content: [{ type: "text", text: JSON.stringify(enhancedDocumentType) }],
45
60
  };
46
61
  })));
47
62
  server.tool("create_document_type", {
48
63
  name: zod_1.z.string(),
49
64
  match: zod_1.z.string().optional(),
50
65
  matching_algorithm: zod_1.z
51
- .enum(["any", "all", "exact", "regular expression", "fuzzy"])
52
- .optional(),
66
+ .number()
67
+ .int()
68
+ .min(0)
69
+ .max(6)
70
+ .optional()
71
+ .describe(types_1.MATCHING_ALGORITHM_DESCRIPTION),
53
72
  }, (0, middlewares_1.withErrorHandling)((args, extra) => __awaiter(this, void 0, void 0, function* () {
54
73
  if (!api)
55
74
  throw new Error("Please configure API connection first");
56
75
  const response = yield api.createDocumentType(args);
76
+ const enhancedDocumentType = (0, utils_1.enhanceMatchingAlgorithm)(response);
57
77
  return {
58
- content: [{ type: "text", text: JSON.stringify(response) }],
78
+ content: [{ type: "text", text: JSON.stringify(enhancedDocumentType) }],
59
79
  };
60
80
  })));
61
81
  server.tool("update_document_type", {
@@ -63,17 +83,20 @@ function registerDocumentTypeTools(server, api) {
63
83
  name: zod_1.z.string(),
64
84
  match: zod_1.z.string().optional(),
65
85
  matching_algorithm: zod_1.z
66
- .enum(["any", "all", "exact", "regular expression", "fuzzy"])
67
- .optional(),
86
+ .number()
87
+ .int()
88
+ .min(0)
89
+ .max(6)
90
+ .optional()
91
+ .describe(types_1.MATCHING_ALGORITHM_DESCRIPTION),
68
92
  }, (0, middlewares_1.withErrorHandling)((args, extra) => __awaiter(this, void 0, void 0, function* () {
69
93
  if (!api)
70
94
  throw new Error("Please configure API connection first");
71
- const response = yield api.request(`/document_types/${args.id}/`, {
72
- method: "PUT",
73
- body: JSON.stringify(args),
74
- });
95
+ const { id } = args, payloadWithoutId = __rest(args, ["id"]);
96
+ const response = yield api.updateDocumentType(id, payloadWithoutId);
97
+ const enhancedDocumentType = (0, utils_1.enhanceMatchingAlgorithm)(response);
75
98
  return {
76
- content: [{ type: "text", text: JSON.stringify(response) }],
99
+ content: [{ type: "text", text: JSON.stringify(enhancedDocumentType) }],
77
100
  };
78
101
  })));
79
102
  server.tool("delete_document_type", "⚠️ DESTRUCTIVE: Permanently delete a document type from the entire system. This will affect ALL documents that use this type.", {
@@ -87,7 +110,7 @@ function registerDocumentTypeTools(server, api) {
87
110
  if (!args.confirm) {
88
111
  throw new Error("Confirmation required for destructive operation. Set confirm: true to proceed.");
89
112
  }
90
- yield api.request(`/document_types/${args.id}/`, { method: "DELETE" });
113
+ yield api.deleteDocumentType(args.id);
91
114
  return {
92
115
  content: [
93
116
  { type: "text", text: JSON.stringify({ status: "deleted" }) },
@@ -11,6 +11,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.registerTagTools = registerTagTools;
13
13
  const zod_1 = require("zod");
14
+ const types_1 = require("../api/types");
15
+ const utils_1 = require("../api/utils");
14
16
  const middlewares_1 = require("./utils/middlewares");
15
17
  const queryString_1 = require("./utils/queryString");
16
18
  function registerTagTools(server, api) {
@@ -27,11 +29,12 @@ function registerTagTools(server, api) {
27
29
  throw new Error("Please configure API connection first");
28
30
  const queryString = (0, queryString_1.buildQueryString)(args);
29
31
  const tagsResponse = yield api.request(`/tags/${queryString ? `?${queryString}` : ""}`);
32
+ const enhancedResults = (0, utils_1.enhanceMatchingAlgorithmArray)(tagsResponse.results || []);
30
33
  return {
31
34
  content: [
32
35
  {
33
36
  type: "text",
34
- text: JSON.stringify(tagsResponse),
37
+ text: JSON.stringify(Object.assign(Object.assign({}, tagsResponse), { results: enhancedResults })),
35
38
  },
36
39
  ],
37
40
  };
@@ -43,16 +46,23 @@ function registerTagTools(server, api) {
43
46
  .regex(/^#[0-9A-Fa-f]{6}$/)
44
47
  .optional(),
45
48
  match: zod_1.z.string().optional(),
46
- matching_algorithm: zod_1.z.number().int().min(0).max(4).optional(),
49
+ matching_algorithm: zod_1.z
50
+ .number()
51
+ .int()
52
+ .min(0)
53
+ .max(6)
54
+ .optional()
55
+ .describe(types_1.MATCHING_ALGORITHM_DESCRIPTION),
47
56
  }, (0, middlewares_1.withErrorHandling)((args, extra) => __awaiter(this, void 0, void 0, function* () {
48
57
  if (!api)
49
58
  throw new Error("Please configure API connection first");
50
59
  const tag = yield api.createTag(args);
60
+ const enhancedTag = (0, utils_1.enhanceMatchingAlgorithm)(tag);
51
61
  return {
52
62
  content: [
53
63
  {
54
64
  type: "text",
55
- text: JSON.stringify(tag),
65
+ text: JSON.stringify(enhancedTag),
56
66
  },
57
67
  ],
58
68
  };
@@ -65,23 +75,32 @@ function registerTagTools(server, api) {
65
75
  .regex(/^#[0-9A-Fa-f]{6}$/)
66
76
  .optional(),
67
77
  match: zod_1.z.string().optional(),
68
- matching_algorithm: zod_1.z.number().int().min(0).max(4).optional(),
78
+ matching_algorithm: zod_1.z
79
+ .number()
80
+ .int()
81
+ .min(0)
82
+ .max(6)
83
+ .optional()
84
+ .describe(types_1.MATCHING_ALGORITHM_DESCRIPTION),
69
85
  }, (0, middlewares_1.withErrorHandling)((args, extra) => __awaiter(this, void 0, void 0, function* () {
70
86
  if (!api)
71
87
  throw new Error("Please configure API connection first");
72
88
  const tag = yield api.updateTag(args.id, args);
89
+ const enhancedTag = (0, utils_1.enhanceMatchingAlgorithm)(tag);
73
90
  return {
74
91
  content: [
75
92
  {
76
93
  type: "text",
77
- text: JSON.stringify(tag),
94
+ text: JSON.stringify(enhancedTag),
78
95
  },
79
96
  ],
80
97
  };
81
98
  })));
82
99
  server.tool("delete_tag", "⚠️ DESTRUCTIVE: Permanently delete a tag from the entire system. This will remove the tag from ALL documents that use it. Use with extreme caution.", {
83
100
  id: zod_1.z.number(),
84
- confirm: zod_1.z.boolean().describe("Must be true to confirm this destructive operation"),
101
+ confirm: zod_1.z
102
+ .boolean()
103
+ .describe("Must be true to confirm this destructive operation"),
85
104
  }, (0, middlewares_1.withErrorHandling)((args, extra) => __awaiter(this, void 0, void 0, function* () {
86
105
  if (!api)
87
106
  throw new Error("Please configure API connection first");
@@ -101,7 +120,10 @@ function registerTagTools(server, api) {
101
120
  server.tool("bulk_edit_tags", "Bulk edit tags. ⚠️ WARNING: 'delete' operation permanently removes tags from the entire system. Use with caution.", {
102
121
  tag_ids: zod_1.z.array(zod_1.z.number()),
103
122
  operation: zod_1.z.enum(["set_permissions", "delete"]),
104
- confirm: zod_1.z.boolean().optional().describe("Must be true when operation is 'delete' to confirm destructive operation"),
123
+ confirm: zod_1.z
124
+ .boolean()
125
+ .optional()
126
+ .describe("Must be true when operation is 'delete' to confirm destructive operation"),
105
127
  owner: zod_1.z.number().optional(),
106
128
  permissions: zod_1.z
107
129
  .object({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baruchiro/paperless-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.2.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