mcp-meilisearch 1.4.1 → 1.4.4

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
@@ -63,14 +63,15 @@ pnpm add mcp-meilisearch
63
63
  - `aiProviderApiKey`: AI provider API key for AI inference
64
64
  - `llmModel`: AI model to use (Default: "gpt-3.5-turbo")
65
65
 
66
- ##### Using OpenRouter as AI Provider
66
+ Please be aware that not all models support function calling, which is required for proper AI inference in this package. Make sure to select a model that supports the tools parameter.
67
67
 
68
- When setting `aiProviderName` to "openrouter", please be aware that not all models support function calling, which is required for proper AI inference in this package. Make sure to select a model that supports the tools parameter.
68
+ | Provider | Supported Models |
69
+ | ----------- | -------------------------------------------------------------------------------------------------------- |
70
+ | OpenAI | [GPT-4, GPT-3.5-turbo and other compatible models](https://platform.openai.com/docs/models) |
71
+ | OpenRouter | [Models with tools parameter support](https://openrouter.ai/models?fmt=cards&supported_parameters=tools) |
72
+ | HuggingFace | [Models with function calling capability](https://huggingface.co/models?other=function+calling) |
69
73
 
70
- You can find a list of OpenRouter models that support function calling at:
71
- https://openrouter.ai/models?fmt=cards&supported_parameters=tools
72
-
73
- Example configuration with OpenRouter:
74
+ #### Example server setup
74
75
 
75
76
  ```typescript
76
77
  await mcpMeilisearchServer({
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,qBAAa,SAAS;IACpB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAS;IAE7B;;;OAGG;IACH,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC,EAAE,CAAM;IAET,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,oBAAoB,CAEZ;gBAEJ,UAAU,EAAE,MAAM;IAI9B;;;OAGG;IACH,sBAAsB,CACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,IAAI;IAKzE;;;;;OAKG;IACG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAOhE;;;;OAIG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAuBzC,SAAS;IA0BvB,OAAO,CAAC,kBAAkB;IAW1B;;;;;;;OAOG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IA2CF;;;;;;;;OAQG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAO,GAClE,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IA6CF,OAAO,CAAC,cAAc;IAKtB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,qBAAa,SAAS;IACpB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAS;IAE7B;;;OAGG;IACH,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC,EAAE,CAAM;IAET,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,oBAAoB,CAEZ;gBAEJ,UAAU,EAAE,MAAM;IAI9B;;;OAGG;IACH,sBAAsB,CACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,IAAI;IAKzE;;;;;OAKG;IACG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAOhE;;;;OAIG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAuBzC,SAAS;IA0BvB,OAAO,CAAC,kBAAkB;IAW1B;;;;;;;OAOG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IA2CF;;;;;;;;OAQG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAO,GAClE,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IAsCF,OAAO,CAAC,cAAc;IAKtB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}
package/dist/client.js CHANGED
@@ -160,12 +160,6 @@ export class MCPClient {
160
160
  if (!result.success)
161
161
  return result;
162
162
  const { toolName, parameters, reasoning } = result.data;
163
- if (!toolName) {
164
- return {
165
- success: false,
166
- error: "AI could not determine which tool to use for this query",
167
- };
168
- }
169
163
  if (justReasoning) {
170
164
  return {
171
165
  reasoning,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAO7B,OAAO,EAAyB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAU1E;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,aAA8B,GACtC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CA2HtB;AAuCD,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,EAAE,aAAa,EAAyB,MAAM,oBAAoB,CAAC;AAE1E;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,aAA8B,GACtC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAkEtB;AAwCD,eAAe,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,16 +1,7 @@
1
1
  import { createServer } from "node:http";
2
- import { parse as parseUrl } from "node:url";
3
2
  import { AIService } from "./utils/ai-handler.js";
4
- import { initServer } from "./server.js";
5
3
  import { configHandler } from "./utils/config-handler.js";
6
- import { createErrorResponse } from "./utils/error-handler.js";
7
- const defaultOptions = {
8
- aiProviderApiKey: "",
9
- meilisearchApiKey: "",
10
- llmModel: "gpt-3.5-turbo",
11
- aiProviderName: "openai",
12
- meilisearchHost: "http://localhost:7700",
13
- };
4
+ import { initServer, defaultOptions } from "./server.js";
14
5
  /**
15
6
  * Start a MCP server
16
7
  * @param options Configuration options for the MCP server
@@ -37,57 +28,13 @@ export async function mcpMeilisearchServer(options = defaultOptions) {
37
28
  let mcpServerInstance = null;
38
29
  const mcpEndpoint = options.mcpEndpoint || "/mcp";
39
30
  const server = createServer(async (req, res) => {
40
- res.setHeader("Access-Control-Allow-Origin", "*");
41
- res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
42
- res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, mcp-session-id");
43
- if (req.method === "OPTIONS") {
44
- res.statusCode = 200;
45
- res.end();
46
- return;
47
- }
48
- const parsedUrl = parseUrl(req.url || "/", true);
49
- const pathname = parsedUrl.pathname || "/";
50
- if (!pathname.startsWith(mcpEndpoint)) {
51
- res.statusCode = 404;
52
- res.end(JSON.stringify({ error: "Not found" }));
53
- return;
54
- }
55
31
  if (!mcpServerInstance) {
56
- console.error("MCP server not initialized yet");
57
32
  res.statusCode = 503;
58
33
  res.setHeader("Content-Type", "application/json");
59
- res.end(JSON.stringify(createErrorResponse("MCP server not initialized yet")));
34
+ res.end(JSON.stringify({ error: "MCP server not initialized yet" }));
60
35
  return;
61
36
  }
62
- if (req.method === "GET") {
63
- await mcpServerInstance.handleGetRequest(req, res);
64
- return;
65
- }
66
- if (req.method === "POST") {
67
- let body = "";
68
- req.on("data", (chunk) => {
69
- body += chunk.toString();
70
- });
71
- req.on("end", async () => {
72
- try {
73
- const jsonBody = JSON.parse(body);
74
- if (mcpServerInstance) {
75
- await mcpServerInstance.handlePostRequest(req, res, jsonBody);
76
- }
77
- else {
78
- res.statusCode = 503;
79
- res.end(JSON.stringify(createErrorResponse("MCP server not initialized yet")));
80
- }
81
- }
82
- catch {
83
- res.statusCode = 400;
84
- res.end(JSON.stringify(createErrorResponse("Invalid JSON body")));
85
- }
86
- });
87
- return;
88
- }
89
- res.statusCode = 405;
90
- res.end(JSON.stringify(createErrorResponse("Method not allowed")));
37
+ await mcpServerInstance.handleHttpRequest(req, res, mcpEndpoint);
91
38
  });
92
39
  await new Promise((resolve) => {
93
40
  server.listen(httpPort, () => {
@@ -141,6 +88,7 @@ if (import.meta.url === `file://${process.argv?.[1]}`) {
141
88
  break;
142
89
  case "aiApiKey":
143
90
  options.aiProviderApiKey = value;
91
+ break;
144
92
  case "aiProvider":
145
93
  options.aiProviderName = value;
146
94
  break;
package/dist/server.d.ts CHANGED
@@ -1,22 +1,13 @@
1
1
  import { IncomingMessage, ServerResponse } from "http";
2
+ import { ServerOptions } from "./types/options.js";
2
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
- /**
4
- * Configuration for the MCP server
5
- */
6
- interface ServerConfig {
7
- host: string;
8
- apiKey: string;
9
- httpPort: number;
10
- mcpEndpoint: string;
11
- sessionTimeout: number;
12
- sessionCleanupInterval: number;
13
- }
14
4
  /**
15
5
  * Return type for the initServer function
16
6
  */
17
7
  interface ServerInstance {
18
8
  mcpServer: MCPServer;
19
9
  }
10
+ export declare const defaultOptions: ServerOptions;
20
11
  /**
21
12
  * Implementation of an MCP server for Meilisearch
22
13
  */
@@ -32,7 +23,14 @@ export declare class MCPServer {
32
23
  * @param server The underlying MCP server implementation
33
24
  * @param config Configuration options
34
25
  */
35
- constructor(server: McpServer, config?: Partial<ServerConfig>);
26
+ constructor(server: McpServer, config?: Partial<ServerOptions>);
27
+ /**
28
+ * Handles an HTTP request and routes it to the appropriate handler
29
+ * @param req The HTTP request
30
+ * @param res The HTTP response
31
+ * @param mcpEndpoint The MCP endpoint path
32
+ */
33
+ handleHttpRequest(req: IncomingMessage, res: ServerResponse, mcpEndpoint: string): Promise<void>;
36
34
  /**
37
35
  * Handles an HTTP GET request
38
36
  * @param req The HTTP request
@@ -93,9 +91,10 @@ export declare class MCPServer {
93
91
  /**
94
92
  * Initialize the MCP server with the specified transport
95
93
  * @param transport The transport type to use ("stdio" or "http")
94
+ * @param config Configuration options for the server
96
95
  * @returns A promise that resolves to the server instances
97
96
  * @throws Error if the transport type is unsupported
98
97
  */
99
- export declare const initServer: (transport: "stdio" | "http", config?: Partial<ServerConfig>) => Promise<ServerInstance>;
98
+ export declare const initServer: (transport: "stdio" | "http", config?: Partial<ServerOptions>) => Promise<ServerInstance>;
100
99
  export {};
101
100
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAUvD,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUpE;;GAEG;AACH,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,UAAU,cAAc;IACtB,SAAS,EAAE,SAAS,CAAC;CACtB;AAmBD;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAoB;IAE3D,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,QAAQ,CAAuC;IAEvD;;;;OAIG;gBACS,MAAM,EAAE,SAAS,EAAE,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAOjE;;;;OAIG;IACG,gBAAgB,CACpB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;;;OAKG;IACG,iBAAiB,CACrB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,IAAI,CAAC;IA+BhB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAqBhB;;;;;OAKG;YACW,uBAAuB;IAuCrC;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAWvC;;OAEG;YACW,gBAAgB;IAmB9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAa3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;CA0B/B;AA+DD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,WAAW,OAAO,GAAG,MAAM,EAC3B,SAAS,OAAO,CAAC,YAAY,CAAC,KAC7B,OAAO,CAAC,cAAc,CAcxB,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAOvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUpE;;GAEG;AACH,UAAU,cAAc;IACtB,SAAS,EAAE,SAAS,CAAC;CACtB;AASD,eAAO,MAAM,cAAc,EAAE,aAO5B,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAoB;IAE3D,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,QAAQ,CAAuC;IAEvD;;;;OAIG;gBACS,MAAM,EAAE,SAAS,EAAE,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM;IAOlE;;;;;OAKG;IACG,iBAAiB,CACrB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IA+ChB;;;;OAIG;IACG,gBAAgB,CACpB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;;;OAKG;IACG,iBAAiB,CACrB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,IAAI,CAAC;IA+BhB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAqBhB;;;;;OAKG;YACW,uBAAuB;IAuCrC;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAWvC;;OAEG;YACW,gBAAgB;IAmB9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAa3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;CA2B/B;AA+DD;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GACrB,WAAW,OAAO,GAAG,MAAM,EAC3B,SAAS,OAAO,CAAC,aAAa,CAAC,KAC9B,OAAO,CAAC,cAAc,CAcxB,CAAC"}
package/dist/server.js CHANGED
@@ -12,13 +12,13 @@ import registerDocumentTools from "./tools/meilisearch/document-tools.js";
12
12
  import registerSettingsTools from "./tools/meilisearch/settings-tools.js";
13
13
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
14
14
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
15
- const defaultConfig = {
15
+ export const defaultOptions = {
16
16
  httpPort: 4995,
17
17
  mcpEndpoint: "/mcp",
18
18
  sessionTimeout: 3600000,
19
19
  sessionCleanupInterval: 60000,
20
- apiKey: process.env.MEILISEARCH_API_KEY || "",
21
- host: process.env.MEILISEARCH_HOST || "http://localhost:7700",
20
+ meilisearchApiKey: process.env.MEILISEARCH_API_KEY || "",
21
+ meilisearchHost: process.env.MEILISEARCH_HOST || "http://localhost:7700",
22
22
  };
23
23
  /**
24
24
  * Implementation of an MCP server for Meilisearch
@@ -37,9 +37,52 @@ export class MCPServer {
37
37
  */
38
38
  constructor(server, config = {}) {
39
39
  this.server = server;
40
- this.config = { ...defaultConfig, ...config };
40
+ this.config = { ...defaultOptions, ...config };
41
41
  this.startSessionCleanup();
42
42
  }
43
+ /**
44
+ * Handles an HTTP request and routes it to the appropriate handler
45
+ * @param req The HTTP request
46
+ * @param res The HTTP response
47
+ * @param mcpEndpoint The MCP endpoint path
48
+ */
49
+ async handleHttpRequest(req, res, mcpEndpoint) {
50
+ res.setHeader("Access-Control-Allow-Origin", "*");
51
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
52
+ res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, mcp-session-id");
53
+ if (req.method === "OPTIONS") {
54
+ res.statusCode = 200;
55
+ res.end();
56
+ return;
57
+ }
58
+ const parsedUrl = new URL(req.url || "/", `http://${req.headers.host}`);
59
+ const pathname = parsedUrl.pathname || "/";
60
+ if (!pathname.startsWith(mcpEndpoint)) {
61
+ this.sendErrorResponse(res, 404, "Not found");
62
+ return;
63
+ }
64
+ if (req.method === "GET") {
65
+ await this.handleGetRequest(req, res);
66
+ return;
67
+ }
68
+ if (req.method === "POST") {
69
+ let body = "";
70
+ req.on("data", (chunk) => {
71
+ body += chunk.toString();
72
+ });
73
+ req.on("end", async () => {
74
+ try {
75
+ const jsonBody = JSON.parse(body);
76
+ await this.handlePostRequest(req, res, jsonBody);
77
+ }
78
+ catch (error) {
79
+ this.sendErrorResponse(res, 400, "Invalid JSON body");
80
+ }
81
+ });
82
+ return;
83
+ }
84
+ this.sendErrorResponse(res, 405, "Method not allowed");
85
+ }
43
86
  /**
44
87
  * Handles an HTTP GET request
45
88
  * @param req The HTTP request
@@ -215,9 +258,10 @@ export class MCPServer {
215
258
  * Starts the session cleanup process
216
259
  */
217
260
  startSessionCleanup() {
261
+ const cleanupInterval = this.config.sessionCleanupInterval || 60000;
218
262
  this.cleanupInterval = setInterval(() => {
219
263
  this.cleanupExpiredSessions();
220
- }, this.config.sessionCleanupInterval);
264
+ }, cleanupInterval);
221
265
  }
222
266
  /**
223
267
  * Removes expired sessions
@@ -225,8 +269,9 @@ export class MCPServer {
225
269
  cleanupExpiredSessions() {
226
270
  const now = Date.now();
227
271
  const expiredIds = [];
272
+ const sessionTimeout = this.config.sessionTimeout || 3600000;
228
273
  for (const [sessionId, info] of this.sessions.entries()) {
229
- if (now - info.lastActivity > this.config.sessionTimeout) {
274
+ if (now - info.lastActivity > sessionTimeout) {
230
275
  expiredIds.push(sessionId);
231
276
  }
232
277
  }
@@ -248,7 +293,7 @@ export class MCPServer {
248
293
  }
249
294
  }
250
295
  /**
251
- * Initialize the MCP server with HTTP transport using Vite
296
+ * Initialize the MCP server with HTTP transport
252
297
  */
253
298
  const initServerHTTPTransport = async (customConfig) => {
254
299
  const serverInstance = new McpServer({
@@ -296,6 +341,7 @@ const initServerStdioTransport = async (customConfig) => {
296
341
  /**
297
342
  * Initialize the MCP server with the specified transport
298
343
  * @param transport The transport type to use ("stdio" or "http")
344
+ * @param config Configuration options for the server
299
345
  * @returns A promise that resolves to the server instances
300
346
  * @throws Error if the transport type is unsupported
301
347
  */
@@ -1 +1 @@
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;AAapE;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,SAAS,SAyEhD,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;AAapE;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,SAAS,SAoDhD,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
- import { AIService } from "../../utils/ai-handler.js";
3
2
  import { zodToJsonSchema } from "zod-to-json-schema";
3
+ import { AIService } from "../../utils/ai-handler.js";
4
4
  import { createErrorResponse } from "../../utils/error-handler.js";
5
5
  /**
6
6
  * Register AI tools with the MCP server
@@ -28,35 +28,16 @@ export const registerAITools = (server) => {
28
28
  });
29
29
  aiService.setAvailableTools(availableTools);
30
30
  const result = await aiService.processQuery(query, specificTools);
31
- if (!aiService.ensureInitialized()) {
32
- return {
33
- isError: true,
34
- content: [
35
- {
36
- type: "text",
37
- text: "AI service not initialized. Please provide an API key.",
38
- },
39
- ],
40
- };
41
- }
42
- if (!result) {
43
- return {
44
- content: [
45
- {
46
- type: "text",
47
- text: "AI couldn't determine an appropriate tool to use for this query.",
48
- },
49
- ],
50
- };
51
- }
31
+ if (result.error)
32
+ return createErrorResponse(result.error);
52
33
  return {
53
34
  content: [
54
35
  {
55
36
  type: "text",
56
37
  text: JSON.stringify({
57
38
  toolName: result.toolName,
39
+ reasoning: result.reasoning,
58
40
  parameters: result.parameters,
59
- reasoning: result.reasoning || "No explanation provided",
60
41
  }, null, 2),
61
42
  },
62
43
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/types/options.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC;AAE5E,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,cAAc,CAAC,EAAE,qBAAqB,CAAC;IAEvC;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/types/options.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC;AAE5E,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,cAAc,CAAC,EAAE,qBAAqB,CAAC;IAEvC;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -4,10 +4,18 @@ interface AITool {
4
4
  description: string;
5
5
  parameters: Record<string, any>;
6
6
  }
7
- interface AIToolResponse {
8
- toolName: string;
7
+ interface AIToolResponseBase {
9
8
  reasoning?: string | null;
10
- parameters: Record<string, any>;
9
+ }
10
+ interface AIToolSuccessResponse extends AIToolResponseBase {
11
+ error: null;
12
+ toolName: string;
13
+ parameters: Record<string, unknown>;
14
+ }
15
+ interface AIToolErrorResponse extends AIToolResponseBase {
16
+ error: string;
17
+ toolName?: string;
18
+ parameters?: Record<string, unknown>;
11
19
  }
12
20
  /**
13
21
  * AI Inference Service
@@ -16,7 +24,6 @@ interface AIToolResponse {
16
24
  * to use based on the user's query
17
25
  */
18
26
  export declare class AIService {
19
- private apiKey;
20
27
  private model;
21
28
  private static instance;
22
29
  private static serverInitialized;
@@ -41,7 +48,7 @@ export declare class AIService {
41
48
  * @param provider AI provider name (defaults to openai)
42
49
  * @param model Optional model to use (defaults to gpt-3.5-turbo)
43
50
  */
44
- initialize(apiKey: string, provider?: AiProviderNameOptions, model?: string, forceNewInit?: boolean): void;
51
+ initialize(apiKey: string, provider?: AiProviderNameOptions, model?: string): void;
45
52
  /**
46
53
  * Set the available tools that can be used by the AI
47
54
  * @param tools Array of tools with name, description, and parameters
@@ -66,7 +73,7 @@ export declare class AIService {
66
73
  * @param specificTools Optional array of specific tool names to consider
67
74
  * @returns Object containing the selected tool name and parameters
68
75
  */
69
- processQuery(query: string, specificTools?: string[]): Promise<AIToolResponse | null>;
76
+ processQuery(query: string, specificTools?: string[]): Promise<AIToolSuccessResponse | AIToolErrorResponse>;
70
77
  private processOpenAIQuery;
71
78
  private processHuggingFaceQuery;
72
79
  }
@@ -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;AAE5D,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACjC;AAiBD,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACjC;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAc;IAC5B,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,CAAyC;IACvD,OAAO,CAAC,cAAc,CAIb;IAET;;;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,EACd,YAAY,GAAE,OAAe,GAC5B,IAAI;IA6BP;;;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,GAAG,IAAI,CAAC;YAwBnB,kBAAkB;YAiClB,uBAAuB;CAiCtC"}
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,GAAG,CAAC,CAAC;CACjC;AAmBD,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,UAAU,qBAAsB,SAAQ,kBAAkB;IACxD,KAAK,EAAE,IAAI,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,UAAU,mBAAoB,SAAQ,kBAAkB;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IACpB,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;IAC9D,OAAO,CAAC,cAAc,CAIb;IAET;;;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,qBAAqB,GAAG,mBAAmB,CAAC;YA4BzC,kBAAkB;YAyClB,uBAAuB;CAqCtC"}
@@ -10,7 +10,6 @@ import { InferenceClient } from "@huggingface/inference";
10
10
  * to use based on the user's query
11
11
  */
12
12
  export class AIService {
13
- apiKey = "";
14
13
  model = "gpt-3.5-turbo";
15
14
  static instance = null;
16
15
  static serverInitialized = false;
@@ -40,27 +39,23 @@ export class AIService {
40
39
  * @param provider AI provider name (defaults to openai)
41
40
  * @param model Optional model to use (defaults to gpt-3.5-turbo)
42
41
  */
43
- initialize(apiKey, provider = "openai", model, forceNewInit = false) {
44
- if (AIService.serverInitialized && !forceNewInit) {
42
+ initialize(apiKey, provider = "openai", model) {
43
+ if (AIService.serverInitialized) {
45
44
  console.warn("AIService has already been initialized by the server.");
46
45
  return;
47
46
  }
48
- this.apiKey = apiKey;
49
47
  this.provider = provider;
50
48
  if (model)
51
49
  this.model = model;
52
50
  switch (this.provider) {
53
51
  case "openai":
54
- this.client = new OpenAI({ apiKey: this.apiKey });
55
- break;
56
- case "openrouter":
57
- this.client = new OpenAI({
58
- apiKey: this.apiKey,
59
- baseURL: OPEN_ROUTER_API.baseURL,
60
- });
52
+ this.client = new OpenAI({ apiKey });
61
53
  break;
62
54
  case "huggingface":
63
- this.client = new InferenceClient(this.apiKey);
55
+ this.client = new InferenceClient(apiKey);
56
+ break;
57
+ case "openrouter":
58
+ this.client = new OpenAI({ apiKey, baseURL: OPEN_ROUTER_API.baseURL });
64
59
  break;
65
60
  default:
66
61
  throw new Error(`Unsupported AI provider: ${this.provider}`);
@@ -118,8 +113,11 @@ export class AIService {
118
113
  * @returns Object containing the selected tool name and parameters
119
114
  */
120
115
  async processQuery(query, specificTools) {
121
- if (!this.ensureInitialized())
122
- return null;
116
+ if (!this.ensureInitialized()) {
117
+ return {
118
+ error: "AI service not initialized. Please provide an API key.",
119
+ };
120
+ }
123
121
  const mentionedTools = this.extractToolNames(query);
124
122
  const toolsToUse = specificTools || (mentionedTools.length ? mentionedTools : undefined);
125
123
  const tools = this.getToolDefinitions(toolsToUse);
@@ -134,54 +132,67 @@ export class AIService {
134
132
  return await this.processOpenAIQuery(tools, messages);
135
133
  }
136
134
  async processOpenAIQuery(tools, messages) {
137
- const client = this.client;
138
- const response = await client.chat.completions.create({
139
- tools,
140
- messages,
141
- model: this.model,
142
- });
143
- if ("error" in response) {
144
- console.error("Error in OpenAI API call:", response);
145
- return null;
135
+ try {
136
+ const client = this.client;
137
+ const response = await client.chat.completions.create({
138
+ tools,
139
+ messages,
140
+ model: this.model,
141
+ tool_choice: "required",
142
+ });
143
+ if (!response.choices?.length) {
144
+ return { error: "No choices returned from OpenAI" };
145
+ }
146
+ const message = response.choices[0].message;
147
+ if (message.content) {
148
+ const toolCall = markdownToJson(message.content);
149
+ if (!toolCall) {
150
+ return {
151
+ error: `Invalid tool call format in content: ${message.content}`,
152
+ };
153
+ }
154
+ return {
155
+ error: null,
156
+ toolName: toolCall.name,
157
+ parameters: toolCall.parameters,
158
+ reasoning: JSON.stringify(toolCall, null, 2),
159
+ };
160
+ }
161
+ return { error: "No tool call or content in OpenAI response" };
162
+ }
163
+ catch (error) {
164
+ return { error: `OpenAI API error: ${error}` };
146
165
  }
147
- if (!response?.choices.length)
148
- return null;
149
- const message = response.choices[0].message;
150
- if (!message.content)
151
- return null;
152
- const toolCall = markdownToJson(message.content);
153
- if (!toolCall)
154
- return null;
155
- return {
156
- toolName: toolCall.name,
157
- parameters: toolCall.parameters,
158
- reasoning: JSON.stringify(toolCall, null, 2),
159
- };
160
166
  }
161
167
  async processHuggingFaceQuery(tools, messages) {
162
- const client = this.client;
163
- const response = await client.chatCompletion({
164
- tools,
165
- messages,
166
- max_tokens: 512,
167
- model: this.model,
168
- });
169
- if ("error" in response) {
170
- console.error("Error in HugginFace call:", response);
171
- return null;
168
+ try {
169
+ const client = this.client;
170
+ const response = await client.chatCompletion({
171
+ tools,
172
+ messages,
173
+ model: this.model,
174
+ tool_choice: "required",
175
+ });
176
+ if (!response.choices?.length) {
177
+ return { error: "No choices in Hugging Face response" };
178
+ }
179
+ const message = response.choices[0].message;
180
+ if (message.content) {
181
+ const toolCall = markdownToJson(message.content);
182
+ if (!toolCall) {
183
+ return { error: `Invalid tool call format in content: ${response}` };
184
+ }
185
+ return {
186
+ error: null,
187
+ toolName: toolCall.name,
188
+ parameters: toolCall.parameters,
189
+ reasoning: JSON.stringify(toolCall, null, 2),
190
+ };
191
+ }
192
+ return { error: "No tool call or content in Hugging Face response" };
193
+ }
194
+ catch (error) {
195
+ return { error: `Hugging Face API error: ${error}` };
172
196
  }
173
- if (!response?.choices.length)
174
- return null;
175
- const message = response.choices[0].message;
176
- if (!message.content)
177
- return null;
178
- const toolCall = markdownToJson(message.content);
179
- if (!toolCall)
180
- return null;
181
- return {
182
- toolName: toolCall.name,
183
- parameters: toolCall.parameters,
184
- reasoning: JSON.stringify(toolCall, null, 2),
185
- };
186
197
  }
187
198
  }
@@ -1,6 +1,3 @@
1
- /**
2
- * Error handling utilities for Meilisearch API responses
3
- */
4
1
  /**
5
2
  * Formats Meilisearch API errors for consistent error messaging
6
3
  *
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,GAAG,KAAG,MAU3C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,GAAG;;;;;;CAK7C,CAAC;;4BAvBoC,GAAG,KAAG,MAAM;iCAkBP,GAAG;;;;;;;;AAO9C,wBAGE"}
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,GAAG,KAAG,MAU3C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,GAAG;;;;;;CAK7C,CAAC;;4BAvBoC,GAAG,KAAG,MAAM;iCAkBP,GAAG;;;;;;;;AAO9C,wBAGE"}
@@ -1,6 +1,3 @@
1
- /**
2
- * Error handling utilities for Meilisearch API responses
3
- */
4
1
  /**
5
2
  * Formats Meilisearch API errors for consistent error messaging
6
3
  *
@@ -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,CA6BtE"}
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"}
@@ -16,11 +16,19 @@ export function markdownToJson(markdownJsonString) {
16
16
  if (fenceMatch && fenceMatch[1]) {
17
17
  S = fenceMatch[1].trim();
18
18
  }
19
+ 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();
24
+ }
25
+ }
19
26
  if (S === "")
20
27
  return null;
21
28
  S = S.replace(/\/\/[^\r\n]*/g, "");
22
29
  S = S.replace(/\/\*[\s\S]*?\*\//g, "");
23
30
  S = S.replace(/,\s*([}\]])/g, "$1");
31
+ S = S.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":');
24
32
  try {
25
33
  const parsedJson = JSON.parse(S);
26
34
  return parseNestedJsonStrings(parsedJson);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-meilisearch",
3
- "version": "1.4.1",
3
+ "version": "1.4.4",
4
4
  "description": "Model Context Protocol (MCP) implementation for Meilisearch",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",