mcp-meilisearch 1.4.7 → 1.4.8

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ai-tools.d.ts","sourceRoot":"","sources":["../../../src/tools/core/ai-tools.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAapE;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,SAAS,SAoDhD,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"ai-tools.d.ts","sourceRoot":"","sources":["../../../src/tools/core/ai-tools.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,SAAS,SAoDhD,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import { zodToJsonSchema } from "zod-to-json-schema";
3
3
  import { AIService } from "../../utils/ai-handler.js";
4
- import { cleanNullValues } from "../../utils/response-handler.js";
5
4
  import { createErrorResponse } from "../../utils/error-handler.js";
5
+ import { convertNullToUndefined } from "../../utils/response-handler.js";
6
6
  /**
7
7
  * Register AI tools with the MCP server
8
8
  * @param server - The MCP server instance
@@ -38,7 +38,7 @@ export const registerAITools = (server) => {
38
38
  text: JSON.stringify({
39
39
  toolName: result.toolName,
40
40
  reasoning: result.reasoning,
41
- parameters: cleanNullValues(result.parameters),
41
+ parameters: convertNullToUndefined(result.parameters),
42
42
  }, null, 2),
43
43
  },
44
44
  ],
@@ -5,9 +5,9 @@ interface AITool {
5
5
  parameters: Record<string, unknown>;
6
6
  }
7
7
  interface AIToolResponse {
8
+ error?: unknown;
8
9
  toolName?: string;
9
10
  reasoning?: string;
10
- error: string | null;
11
11
  parameters?: Record<string, unknown>;
12
12
  }
13
13
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ai-handler.d.ts","sourceRoot":"","sources":["../../src/utils/ai-handler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAmBD,UAAU,cAAc;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0B;IACjD,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwB;IACrD,OAAO,CAAC,MAAM,CAAgD;IAE9D;;;OAGG;IACH,OAAO;IAEP;;;OAGG;WACW,WAAW,IAAI,SAAS;IAOtC;;;;;;OAMG;IACH,UAAU,CACR,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,qBAAgC,EAC1C,KAAK,CAAC,EAAE,MAAM,GACb,IAAI;IAyBP;;;OAGG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAIxC,iBAAiB,IAAI,OAAO;IAI5B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;;OAKG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,cAAc,CAAC;YA4BZ,kBAAkB;YA+DlB,uBAAuB;CAyDtC"}
1
+ {"version":3,"file":"ai-handler.d.ts","sourceRoot":"","sources":["../../src/utils/ai-handler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAmBD,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0B;IACjD,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwB;IACrD,OAAO,CAAC,MAAM,CAAgD;IAE9D;;;OAGG;IACH,OAAO;IAEP;;;OAGG;WACW,WAAW,IAAI,SAAS;IAOtC;;;;;;OAMG;IACH,UAAU,CACR,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,qBAAgC,EAC1C,KAAK,CAAC,EAAE,MAAM,GACb,IAAI;IAyBP;;;OAGG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAIxC,iBAAiB,IAAI,OAAO;IAI5B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;;OAKG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,cAAc,CAAC;YA4BZ,kBAAkB;YA6DlB,uBAAuB;CAuDtC"}
@@ -154,7 +154,6 @@ export class AIService {
154
154
  parameters: JSON.parse(toolCall.arguments),
155
155
  };
156
156
  return {
157
- error: null,
158
157
  toolName: inferenceToolResponse.name,
159
158
  parameters: inferenceToolResponse.parameters,
160
159
  reasoning: JSON.stringify(inferenceToolResponse, null, 2),
@@ -168,7 +167,6 @@ export class AIService {
168
167
  };
169
168
  }
170
169
  return {
171
- error: null,
172
170
  toolName: toolCall.name,
173
171
  parameters: toolCall.parameters,
174
172
  reasoning: JSON.stringify(toolCall, null, 2),
@@ -177,7 +175,7 @@ export class AIService {
177
175
  return { error: "No tool call or content in OpenAI response" };
178
176
  }
179
177
  catch (error) {
180
- return { error: `OpenAI API error: ${error}` };
178
+ return { error };
181
179
  }
182
180
  }
183
181
  async processHuggingFaceQuery(tools, messages) {
@@ -203,7 +201,6 @@ export class AIService {
203
201
  parameters: JSON.parse(toolCall.arguments),
204
202
  };
205
203
  return {
206
- error: null,
207
204
  toolName: inferenceToolResponse.name,
208
205
  parameters: inferenceToolResponse.parameters,
209
206
  reasoning: JSON.stringify(inferenceToolResponse, null, 2),
@@ -214,7 +211,6 @@ export class AIService {
214
211
  if (!toolCall)
215
212
  return { error: "Invalid tool call format in content" };
216
213
  return {
217
- error: null,
218
214
  toolName: toolCall.name,
219
215
  parameters: toolCall.parameters,
220
216
  reasoning: JSON.stringify(toolCall, null, 2),
@@ -223,7 +219,7 @@ export class AIService {
223
219
  return { error: "No tool call or content in Hugging Face response" };
224
220
  }
225
221
  catch (error) {
226
- return { error: `Hugging Face API error: ${error}` };
222
+ return { error };
227
223
  }
228
224
  }
229
225
  }
@@ -12,7 +12,7 @@ export const handleApiError = (error) => {
12
12
  return `Meilisearch API error (${status}): ${JSON.stringify(data)}`;
13
13
  }
14
14
  // If it's a network error or other error
15
- return `MCP Server error: ${JSON.stringify(error)}`;
15
+ return JSON.stringify(error);
16
16
  };
17
17
  /**
18
18
  * Creates a standardized error response object for MCP tools
@@ -11,5 +11,5 @@ export declare function markdownToJson<T>(markdownJsonString: string): T | null;
11
11
  * Recursively removes null values from an object, replacing them with undefined
12
12
  * This ensures optional parameters are properly handled by JSON schema validation
13
13
  */
14
- export declare function cleanNullValues(obj?: Record<string, any>): Record<string, any>;
14
+ export declare function convertNullToUndefined(obj: unknown, seen?: WeakMap<object, unknown>): unknown;
15
15
  //# sourceMappingURL=response-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"response-handler.d.ts","sourceRoot":"","sources":["../../src/utils/response-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAoCtE;AAgCD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACxB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAwBrB"}
1
+ {"version":3,"file":"response-handler.d.ts","sourceRoot":"","sources":["../../src/utils/response-handler.ts"],"names":[],"mappings":"AA0CA;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAuDtE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,OAAO,EACZ,IAAI,GAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAiB,GAC7C,OAAO,CA6BT"}
@@ -1,3 +1,41 @@
1
+ function tryParseJsonString(str) {
2
+ if (typeof str === "string" &&
3
+ str.length >= 2 &&
4
+ ((str.startsWith("{") && str.endsWith("}")) ||
5
+ (str.startsWith("[") && str.endsWith("]")))) {
6
+ try {
7
+ return JSON.parse(str);
8
+ }
9
+ catch {
10
+ return str;
11
+ }
12
+ }
13
+ return str;
14
+ }
15
+ function parseNestedJsonStrings(obj) {
16
+ if (Array.isArray(obj)) {
17
+ return obj.map(parseNestedJsonStrings);
18
+ }
19
+ if (obj !== null && typeof obj === "object") {
20
+ const result = {};
21
+ for (const key in obj) {
22
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
23
+ result[key] = parseNestedJsonStrings(obj[key]);
24
+ }
25
+ }
26
+ return result;
27
+ }
28
+ if (typeof obj === "string") {
29
+ return tryParseJsonString(obj);
30
+ }
31
+ return obj;
32
+ }
33
+ const TRAILING_COMMA_REGEX = /,\s*([}\]])/g;
34
+ const SINGLE_LINE_COMMENT_REGEX = /\/\/[^\r\n]*/g;
35
+ const MULTI_LINE_COMMENT_REGEX = /\/\*[\s\S]*?\*\//g;
36
+ const FENCE_REGEX = /^```(?:json)?\s*([\s\S]*?)\s*```$/;
37
+ const JSON_TAG_REGEX = /<json>\s*([\s\S]*?)\s*<\/json>/;
38
+ const UNQUOTED_KEYS_REGEX = /([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g;
1
39
  /**
2
40
  * Transforms a string, potentially containing JSON embedded in Markdown
3
41
  * or with non-standard features like comments and trailing commas,
@@ -7,94 +45,87 @@
7
45
  * @returns A parsed JavaScript object/array, or null if parsing fails.
8
46
  */
9
47
  export function markdownToJson(markdownJsonString) {
10
- if (typeof markdownJsonString !== "string" || !markdownJsonString.trim()) {
48
+ if (typeof markdownJsonString !== "string")
11
49
  return null;
12
- }
13
- let S = markdownJsonString.trim();
14
- const fenceRegex = /^```(?:json)?\s*([\s\S]*?)\s*```$/;
15
- const fenceMatch = S.match(fenceRegex);
16
- if (fenceMatch && fenceMatch[1]) {
17
- S = fenceMatch[1].trim();
50
+ let jsonString = markdownJsonString.trim();
51
+ if (!jsonString)
52
+ return null;
53
+ const fenceMatch = jsonString.match(FENCE_REGEX);
54
+ if (fenceMatch && fenceMatch[1] !== undefined) {
55
+ jsonString = fenceMatch[1].trim();
18
56
  }
19
57
  else {
20
- const jsonTagRegex = /<json>\s*([\s\S]*?)\s*<\/json>/;
21
- const jsonTagMatch = S.match(jsonTagRegex);
22
- if (jsonTagMatch && jsonTagMatch[1]) {
23
- S = jsonTagMatch[1].trim();
58
+ const jsonTagMatch = jsonString.match(JSON_TAG_REGEX);
59
+ if (jsonTagMatch && jsonTagMatch[1] !== undefined) {
60
+ jsonString = jsonTagMatch[1].trim();
24
61
  }
25
62
  }
26
- if (S === "")
63
+ if (jsonString === "")
27
64
  return null;
28
- S = S.replace(/\/\/[^\r\n]*/g, "");
29
- S = S.replace(/\/\*[\s\S]*?\*\//g, "");
30
- S = S.replace(/,\s*([}\]])/g, "$1");
31
- S = S.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":');
65
+ let parsedJson;
66
+ try {
67
+ parsedJson = JSON.parse(jsonString);
68
+ }
69
+ catch {
70
+ let cleanedJson = jsonString;
71
+ cleanedJson = cleanedJson.replace(SINGLE_LINE_COMMENT_REGEX, "");
72
+ cleanedJson = cleanedJson.replace(MULTI_LINE_COMMENT_REGEX, "");
73
+ cleanedJson = cleanedJson.trim();
74
+ if (cleanedJson === "")
75
+ return null;
76
+ cleanedJson = cleanedJson.replace(TRAILING_COMMA_REGEX, "$1");
77
+ cleanedJson = cleanedJson.replace(UNQUOTED_KEYS_REGEX, '$1"$2":');
78
+ try {
79
+ parsedJson = JSON.parse(cleanedJson);
80
+ }
81
+ catch (error) {
82
+ console.error("Failed to parse JSON after transformations.");
83
+ console.error("Original string:", markdownJsonString);
84
+ console.error("String after extraction (before cleaning):", jsonString);
85
+ console.error("Processed string that failed parsing:", cleanedJson);
86
+ console.error("Error:", error);
87
+ return null;
88
+ }
89
+ }
32
90
  try {
33
- const parsedJson = JSON.parse(S);
34
91
  return parseNestedJsonStrings(parsedJson);
35
92
  }
36
93
  catch (error) {
37
- console.error("Failed to parse JSON after transformations.");
38
- console.error("Original string:", markdownJsonString);
39
- console.error("Processed string that failed:", S);
94
+ console.error("Error during nested JSON string parsing:");
95
+ console.error("Parsed object before nested parsing:", parsedJson);
40
96
  console.error("Error:", error);
41
97
  return null;
42
98
  }
43
99
  }
44
- function tryParseJsonString(str) {
45
- try {
46
- if (typeof str === "string" &&
47
- ((str.startsWith("[") && str.endsWith("]")) ||
48
- (str.startsWith("{") && str.endsWith("}")))) {
49
- return JSON.parse(str);
50
- }
51
- return str;
52
- }
53
- catch {
54
- return str;
55
- }
56
- }
57
- function parseNestedJsonStrings(obj) {
58
- if (Array.isArray(obj)) {
59
- return obj.map((item) => parseNestedJsonStrings(item));
60
- }
61
- else if (obj !== null && typeof obj === "object") {
62
- const result = {};
63
- for (const key of Object.keys(obj)) {
64
- result[key] = parseNestedJsonStrings(obj[key]);
65
- }
66
- return result;
67
- }
68
- else if (typeof obj === "string") {
69
- return tryParseJsonString(obj);
70
- }
71
- return obj;
72
- }
73
100
  /**
74
101
  * Recursively removes null values from an object, replacing them with undefined
75
102
  * This ensures optional parameters are properly handled by JSON schema validation
76
103
  */
77
- export function cleanNullValues(obj) {
78
- if (!obj || typeof obj !== "object")
79
- return obj ?? {};
80
- const result = {};
81
- for (const [key, value] of Object.entries(obj)) {
82
- if (value === null) {
83
- continue;
84
- }
85
- else if (typeof value === "object" && value !== null) {
86
- if (Array.isArray(value)) {
87
- result[key] = value.map((item) => typeof item === "object" && item !== null
88
- ? cleanNullValues(item)
89
- : item);
90
- }
91
- else {
92
- result[key] = cleanNullValues(value);
93
- }
94
- }
95
- else {
96
- result[key] = value;
104
+ export function convertNullToUndefined(obj, seen = new WeakMap()) {
105
+ if (obj === null)
106
+ return undefined;
107
+ if (obj === undefined || typeof obj !== "object")
108
+ return obj;
109
+ if (seen.has(obj))
110
+ return seen.get(obj);
111
+ if (obj instanceof Date)
112
+ return new Date(obj.getTime());
113
+ if (obj instanceof RegExp)
114
+ return new RegExp(obj.source, obj.flags);
115
+ if (Array.isArray(obj)) {
116
+ const result = [];
117
+ seen.set(obj, result);
118
+ for (const item of obj) {
119
+ result.push(convertNullToUndefined(item, seen));
97
120
  }
121
+ return result;
122
+ }
123
+ const result = {};
124
+ seen.set(obj, result);
125
+ const keys = Object.keys(obj);
126
+ for (const key of keys) {
127
+ const value = obj[key];
128
+ result[key] = convertNullToUndefined(value, seen);
98
129
  }
99
130
  return result;
100
131
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-meilisearch",
3
- "version": "1.4.7",
3
+ "version": "1.4.8",
4
4
  "description": "Model Context Protocol (MCP) implementation for Meilisearch",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",