mcp-meilisearch 1.3.0 → 1.3.2

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
@@ -11,10 +11,9 @@ A Model Context Protocol (MCP) server implementation that provides a bridge betw
11
11
  ## Key Features
12
12
 
13
13
  - **Multiple Transport Options**: Supports both STDIO and StreamableHTTP transports.
14
- - **Real-time Communication**: Enables seamless interaction between clients and the server.
15
14
  - **Meilisearch API Support**: Full access to Meilisearch functionalities.
16
- - **Web Client Demo**: Updated interface for demonstrating search capabilities.
17
- - **AI Inference**: Uses OpenAI to intelligently select the most appropriate tool based on user queries.
15
+ - **Web Client Demo**: Updated interface showcasing search capabilities and features.
16
+ - **AI Inference**: Leverages LLMs from providers such as OpenAI, Hugging Face or Anthropic to intelligently determine and utilize the most suitable tool for user queries.
18
17
 
19
18
  ## Getting Started
20
19
 
@@ -23,7 +22,7 @@ A Model Context Protocol (MCP) server implementation that provides a bridge betw
23
22
  - Node.js v20 or higher.
24
23
  - A running Meilisearch instance (local or remote).
25
24
  - API key for Meilisearch (if required).
26
- - OpenAI API key (if using AI inference).
25
+ - AI provider API key (if using AI inference).
27
26
 
28
27
  ### Installation
29
28
 
@@ -60,7 +59,8 @@ pnpm add mcp-meilisearch
60
59
 
61
60
  #### AI Inference Options
62
61
 
63
- - `openaiApiKey`: OpenAI API key for AI inference
62
+ - `aiProviderName`: Name of the AI provider ("openai" | "anthropic" | "huggingface") (Default: "openai")
63
+ - `aiProviderApiKey`: AI provider API key for AI inference
64
64
  - `llmModel`: AI model to use (Default: "gpt-3.5-turbo")
65
65
 
66
66
  ### Using the MCPClient
@@ -79,8 +79,6 @@ const result = await client.callTool("search-across-all-indexes", {
79
79
  });
80
80
 
81
81
  // Use AI inference to choose the most appropriate tool
82
- // First enable AI inference
83
- client.setUseAI(true);
84
82
 
85
83
  const result = await client.callToolWithAI("Find articles about cucumber");
86
84
  console.log(`Tool used: ${result.toolUsed}`);
@@ -90,7 +88,6 @@ console.log(`Results: ${JSON.stringify(result.data)}`);
90
88
 
91
89
  #### AI Inference Client Methods
92
90
 
93
- - `setUseAI(use: boolean)`: Enable or disable AI inference.
94
91
  - `callToolWithAI(query: string, specificTools?: string[])`: Process a user query with AI inference, optionally limiting to specific tools.
95
92
 
96
93
  ### Starting the Server
@@ -102,9 +99,10 @@ import mcpMeilisearchServer from "mcp-meilisearch";
102
99
 
103
100
  await mcpMeilisearchServer({
104
101
  meilisearchHost: "http://localhost:7700",
105
- meilisearchApiKey: "your_api_key",
106
- openaiApiKey: "your_openai_api_key", // Required for AI inference
107
- llmModel: "gpt-4", // Optional, defaults to gpt-3.5-turbo
102
+ meilisearchApiKey: "your_meilisearch_api_key",
103
+ aiProviderName: "openai",
104
+ aiProviderApiKey: "your_ai_provider_api_key", // Required for AI inference
105
+ llmModel: "gpt-4",
108
106
  });
109
107
  ```
110
108
 
package/dist/client.d.ts CHANGED
@@ -1,9 +1,4 @@
1
1
  export declare class MCPClient {
2
- /**
3
- * Flag to enable/disable AI inference
4
- * When enabled, user queries are processed by an AI to determine which tool to use
5
- */
6
- useAI: boolean;
7
2
  /**
8
3
  * Indicates whether the client is connected to the MCP server
9
4
  * Used to track the connection state and control async operations
@@ -23,11 +18,6 @@ export declare class MCPClient {
23
18
  private transport;
24
19
  private toolsUpdatedCallback;
25
20
  constructor(serverName: string);
26
- /**
27
- * Set whether to use AI inference for tool selection
28
- * @param use Whether to use AI inference
29
- */
30
- setUseAI(use: boolean): void;
31
21
  /**
32
22
  * Registers a callback to be called when the list of available tools changes
33
23
  * @param callback The function to call when tools are updated
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,qBAAa,SAAS;IACpB;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAS;IAEvB;;;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,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAI5B;;;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;IAwBvB,OAAO,CAAC,kBAAkB;IAW1B;;;;;;OAMG;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;;;;;OAKG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,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;IAmCF,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;IAwBvB,OAAO,CAAC,kBAAkB;IAW1B;;;;;;OAMG;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;;;;;OAKG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,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;IAmCF,OAAO,CAAC,cAAc;IAKtB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}
package/dist/client.js CHANGED
@@ -2,11 +2,6 @@ import { TextContentSchema, LoggingMessageNotificationSchema, ToolListChangedNot
2
2
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
3
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4
4
  export class MCPClient {
5
- /**
6
- * Flag to enable/disable AI inference
7
- * When enabled, user queries are processed by an AI to determine which tool to use
8
- */
9
- useAI = false;
10
5
  /**
11
6
  * Indicates whether the client is connected to the MCP server
12
7
  * Used to track the connection state and control async operations
@@ -24,13 +19,6 @@ export class MCPClient {
24
19
  constructor(serverName) {
25
20
  this.client = new Client({ name: serverName, version: "1.0.0" });
26
21
  }
27
- /**
28
- * Set whether to use AI inference for tool selection
29
- * @param use Whether to use AI inference
30
- */
31
- setUseAI(use) {
32
- this.useAI = use;
33
- }
34
22
  /**
35
23
  * Registers a callback to be called when the list of available tools changes
36
24
  * @param callback The function to call when tools are updated
@@ -65,11 +53,11 @@ export class MCPClient {
65
53
  await this.listTools();
66
54
  this.isConnected = true;
67
55
  }
68
- catch (e) {
56
+ catch (error) {
69
57
  this.tries++;
70
58
  if (this.tries > 5) {
71
59
  this.isConnected = false;
72
- throw e;
60
+ throw error;
73
61
  }
74
62
  await new Promise((resolve) => setTimeout(resolve, this.tries * 1000));
75
63
  await this.connectToServer(serverUrl);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKnD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,aAGR,GACA,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAwHtB;AAwCD,eAAe,oBAAoB,CAAC"}
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"}
package/dist/index.js CHANGED
@@ -4,26 +4,33 @@ import { AIService } from "./utils/ai-handler.js";
4
4
  import { initServer } from "./server.js";
5
5
  import { configHandler } from "./utils/config-handler.js";
6
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
+ };
7
14
  /**
8
15
  * Start a MCP server
9
16
  * @param options Configuration options for the MCP server
10
17
  * @returns A promise that resolves to the HTTP server instance
11
18
  */
12
- export async function mcpMeilisearchServer(options = {
13
- meilisearchHost: "http://localhost:7700",
14
- meilisearchApiKey: "",
15
- }) {
19
+ export async function mcpMeilisearchServer(options = defaultOptions) {
16
20
  configHandler.setLlmModel(options.llmModel);
17
- configHandler.setOpenaiApiKey(options.openaiApiKey);
21
+ configHandler.setAiProviderName(options.aiProviderName);
18
22
  configHandler.setMeilisearchHost(options.meilisearchHost);
23
+ configHandler.setAiProviderApiKey(options.aiProviderApiKey);
19
24
  configHandler.setMeilisearchApiKey(options.meilisearchApiKey);
20
25
  const aiService = AIService.getInstance();
21
- const apiKey = configHandler.getOpenaiApiKey();
26
+ const apiKey = configHandler.getAiProviderApiKey();
22
27
  if (apiKey) {
23
- aiService.initialize(apiKey);
28
+ const llmModel = configHandler.getLlmModel();
29
+ const aiProviderName = configHandler.getAiProviderName();
30
+ aiService.initialize(apiKey, aiProviderName, llmModel);
24
31
  }
25
32
  else {
26
- console.warn("OpenAI API key not found. AI will not be available");
33
+ console.warn("AI provider API key not found. AI will not be available");
27
34
  }
28
35
  const httpPort = options.httpPort || 4995;
29
36
  const transport = options.transport || "http";
@@ -84,7 +91,7 @@ export async function mcpMeilisearchServer(options = {
84
91
  });
85
92
  await new Promise((resolve) => {
86
93
  server.listen(httpPort, () => {
87
- console.log(`MCP server listening on port ${httpPort}`);
94
+ console.info(`MCP server listening on port ${httpPort}`);
88
95
  resolve();
89
96
  });
90
97
  });
@@ -98,7 +105,7 @@ export async function mcpMeilisearchServer(options = {
98
105
  throw error;
99
106
  }
100
107
  const shutdownHandler = () => {
101
- console.log("Shutting down MCP server...");
108
+ console.info("Shutting down MCP server...");
102
109
  if (mcpServerInstance && typeof mcpServerInstance.shutdown === "function") {
103
110
  try {
104
111
  mcpServerInstance.shutdown();
@@ -115,10 +122,7 @@ export async function mcpMeilisearchServer(options = {
115
122
  }
116
123
  if (import.meta.url === `file://${process.argv?.[1]}`) {
117
124
  const args = process.argv.slice(2);
118
- const options = {
119
- meilisearchHost: "http://localhost:7700",
120
- meilisearchApiKey: "",
121
- };
125
+ const options = defaultOptions;
122
126
  for (let i = 0; i < args.length; i += 2) {
123
127
  const key = args[i].replace("--", "");
124
128
  const value = args[i + 1];
@@ -135,8 +139,10 @@ if (import.meta.url === `file://${process.argv?.[1]}`) {
135
139
  case "apiKey":
136
140
  options.meilisearchApiKey = value;
137
141
  break;
138
- case "openaiApiKey":
139
- options.openaiApiKey = value;
142
+ case "aiApiKey":
143
+ options.aiProviderApiKey = value;
144
+ case "aiProvider":
145
+ options.aiProviderName = value;
140
146
  break;
141
147
  case "llmModel":
142
148
  options.llmModel = value;
@@ -144,7 +150,7 @@ if (import.meta.url === `file://${process.argv?.[1]}`) {
144
150
  }
145
151
  }
146
152
  mcpMeilisearchServer(options)
147
- .then(() => console.log("MCP server running"))
153
+ .then(() => console.info("MCP server running"))
148
154
  .catch((err) => {
149
155
  console.error("Failed to start server:", err);
150
156
  process.exit(1);
package/dist/server.d.ts CHANGED
@@ -4,6 +4,8 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
4
  * Configuration for the MCP server
5
5
  */
6
6
  interface ServerConfig {
7
+ host: string;
8
+ apiKey: string;
7
9
  httpPort: number;
8
10
  mcpEndpoint: string;
9
11
  sessionTimeout: number;
@@ -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;AAgBvD,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE;;GAEG;AACH,UAAU,YAAY;IACpB,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;AAiBD;;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;AAwED;;;;;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;AAgBvD,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE;;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"}
package/dist/server.js CHANGED
@@ -12,11 +12,13 @@ import { createErrorResponse } from "./utils/error-handler.js";
12
12
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
13
13
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
14
14
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
15
- const DEFAULT_CONFIG = {
15
+ const defaultConfig = {
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
22
  };
21
23
  /**
22
24
  * Implementation of an MCP server for Meilisearch
@@ -35,7 +37,7 @@ export class MCPServer {
35
37
  */
36
38
  constructor(server, config = {}) {
37
39
  this.server = server;
38
- this.config = { ...DEFAULT_CONFIG, ...config };
40
+ this.config = { ...defaultConfig, ...config };
39
41
  this.startSessionCleanup();
40
42
  }
41
43
  /**
@@ -44,14 +46,14 @@ export class MCPServer {
44
46
  * @param res The HTTP response
45
47
  */
46
48
  async handleGetRequest(req, res) {
47
- console.log("GET request received");
49
+ console.info("GET request received");
48
50
  const sessionId = this.extractSessionId(req);
49
51
  if (!sessionId || !this.sessions.has(sessionId)) {
50
52
  console.error(`Invalid session ID: ${sessionId}`);
51
53
  this.sendErrorResponse(res, 400, "Bad Request: invalid session ID");
52
54
  return;
53
55
  }
54
- console.log(`Establishing HTTP stream for session ${sessionId}`);
56
+ console.info(`Establishing HTTP stream for session ${sessionId}`);
55
57
  const sessionInfo = this.sessions.get(sessionId);
56
58
  const transport = sessionInfo.transport;
57
59
  try {
@@ -77,7 +79,7 @@ export class MCPServer {
77
79
  const sessionId = this.extractSessionId(req);
78
80
  try {
79
81
  if (sessionId && this.sessions.has(sessionId)) {
80
- console.log(`POST request for existing session ${sessionId}`);
82
+ console.info(`POST request for existing session ${sessionId}`);
81
83
  const sessionInfo = this.sessions.get(sessionId);
82
84
  await sessionInfo.transport.handleRequest(req, res, body);
83
85
  this.updateSessionActivity(sessionId);
@@ -99,14 +101,14 @@ export class MCPServer {
99
101
  * Clean up and release server resources
100
102
  */
101
103
  shutdown() {
102
- console.log("Shutting down MCP server...");
104
+ console.info("Shutting down MCP server...");
103
105
  if (this.cleanupInterval) {
104
106
  clearInterval(this.cleanupInterval);
105
107
  this.cleanupInterval = null;
106
108
  }
107
109
  for (const [sessionId, sessionInfo] of this.sessions.entries()) {
108
110
  try {
109
- console.log(`Closing session ${sessionId}`);
111
+ console.info(`Closing session ${sessionId}`);
110
112
  sessionInfo.transport.close();
111
113
  }
112
114
  catch (error) {
@@ -114,7 +116,7 @@ export class MCPServer {
114
116
  }
115
117
  }
116
118
  this.sessions.clear();
117
- console.log("MCP server shutdown complete");
119
+ console.info("MCP server shutdown complete");
118
120
  }
119
121
  /**
120
122
  * Handles the initial connection request
@@ -138,7 +140,7 @@ export class MCPServer {
138
140
  lastActivity: Date.now(),
139
141
  });
140
142
  this.sendToolListChangedNotification(transport);
141
- console.log(`New session established: ${newSessionId}`);
143
+ console.info(`New session established: ${newSessionId}`);
142
144
  }
143
145
  catch (error) {
144
146
  console.error("Error handling initialize request:", error);
@@ -166,7 +168,7 @@ export class MCPServer {
166
168
  jsonrpc: this.JSON_RPC,
167
169
  };
168
170
  await transport.send(rpcNotification);
169
- console.log(`Sent notification: ${notification.method}`);
171
+ console.info(`Sent notification: ${notification.method}`);
170
172
  }
171
173
  catch (error) {
172
174
  console.error(`Failed to send notification ${notification.method}:`, error);
@@ -229,7 +231,7 @@ export class MCPServer {
229
231
  }
230
232
  }
231
233
  if (expiredIds.length) {
232
- console.log(`Cleaning up ${expiredIds.length} expired sessions`);
234
+ console.info(`Cleaning up ${expiredIds.length} expired sessions`);
233
235
  for (const sessionId of expiredIds) {
234
236
  try {
235
237
  const info = this.sessions.get(sessionId);
@@ -249,10 +251,6 @@ export class MCPServer {
249
251
  * Initialize the MCP server with HTTP transport using Vite
250
252
  */
251
253
  const initServerHTTPTransport = async (customConfig) => {
252
- const config = {
253
- ...DEFAULT_CONFIG,
254
- ...customConfig,
255
- };
256
254
  const serverInstance = new McpServer({
257
255
  version: "1.0.0",
258
256
  name: "mcp-meilisearch",
@@ -265,19 +263,14 @@ const initServerHTTPTransport = async (customConfig) => {
265
263
  registerSystemTools(serverInstance);
266
264
  registerTaskTools(serverInstance);
267
265
  registerAITools(serverInstance);
268
- const server = new MCPServer(serverInstance, config);
266
+ const server = new MCPServer(serverInstance, customConfig);
269
267
  return { mcpServer: server };
270
268
  };
271
269
  /**
272
270
  * Initialize the MCP server with stdio transport
273
271
  * @returns MCP server instance
274
272
  */
275
- const initServerStdioTransport = async () => {
276
- const config = {
277
- ...DEFAULT_CONFIG,
278
- host: process.env.MEILISEARCH_HOST,
279
- apiKey: process.env.MEILISEARCH_API_KEY,
280
- };
273
+ const initServerStdioTransport = async (customConfig) => {
281
274
  const serverInstance = new McpServer({
282
275
  version: "1.0.0",
283
276
  name: "mcp-meilisearch",
@@ -290,12 +283,12 @@ const initServerStdioTransport = async () => {
290
283
  registerSystemTools(serverInstance);
291
284
  registerTaskTools(serverInstance);
292
285
  registerAITools(serverInstance);
293
- const server = new MCPServer(serverInstance, config);
286
+ const server = new MCPServer(serverInstance, customConfig);
294
287
  const transport = new StdioServerTransport();
295
288
  await serverInstance.connect(transport);
296
- console.log("Meilisearch MCP Server is running on stdio transport");
289
+ console.info("Meilisearch MCP Server is running on stdio transport");
297
290
  process.on("SIGINT", () => {
298
- console.log("Shutting down stdio server...");
291
+ console.info("Shutting down stdio server...");
299
292
  process.exit(0);
300
293
  });
301
294
  return { mcpServer: server };
@@ -310,7 +303,7 @@ export const initServer = async (transport, config) => {
310
303
  try {
311
304
  switch (transport) {
312
305
  case "stdio":
313
- return await initServerStdioTransport();
306
+ return await initServerStdioTransport(config);
314
307
  case "http":
315
308
  return await initServerHTTPTransport(config);
316
309
  default:
package/dist/stdio.js CHANGED
@@ -2,5 +2,4 @@ import { mcpMeilisearchServer } from "./index.js";
2
2
  mcpMeilisearchServer({
3
3
  transport: "stdio",
4
4
  meilisearchHost: process.env.MEILISEARCH_HOST,
5
- meilisearchApiKey: process.env.MEILISEARCH_API_KEY,
6
5
  });
@@ -24,7 +24,7 @@ export const registerAITools = (server) => {
24
24
  }));
25
25
  aiService.setAvailableTools(availableTools);
26
26
  const result = await aiService.processQuery(query, specificTools);
27
- if (!aiService.client) {
27
+ if (!aiService.ensureInitialized()) {
28
28
  return {
29
29
  isError: true,
30
30
  content: [
@@ -1,15 +1,14 @@
1
+ export type AiProviderNameOptions = "openai" | "huggingface" | "anthropic";
1
2
  export interface ServerOptions {
2
3
  /**
3
4
  * The URL of the Meilisearch instance
4
- * @required
5
- * @example "http://localhost:7700"
5
+ * @default "http://localhost:7700"
6
6
  */
7
- meilisearchHost: string;
7
+ meilisearchHost?: string;
8
8
  /**
9
9
  * The API key for authenticating with Meilisearch
10
- * @required
11
10
  */
12
- meilisearchApiKey: string;
11
+ meilisearchApiKey?: string;
13
12
  /**
14
13
  * Transport type for MCP server ("http" | "stdio")
15
14
  * @default "http"
@@ -36,9 +35,14 @@ export interface ServerOptions {
36
35
  */
37
36
  sessionCleanupInterval?: number;
38
37
  /**
39
- * OpenAI API key for AI inference
38
+ * AI inference provider name
39
+ * @default "openai"
40
40
  */
41
- openaiApiKey?: string;
41
+ aiProviderName?: AiProviderNameOptions;
42
+ /**
43
+ * AI provider API key for AI inference
44
+ */
45
+ aiProviderApiKey?: string;
42
46
  /**
43
47
  * AI model to use for inference
44
48
  * @default "gpt-3.5-turbo"
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/types/options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;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;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;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,WAAW,CAAC;AAE3E,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,4 +1,4 @@
1
- import { OpenAI } from "openai";
1
+ import { AiProviderNameOptions } from "../types/options.js";
2
2
  /**
3
3
  * AI Inference Service
4
4
  *
@@ -6,12 +6,13 @@ import { OpenAI } from "openai";
6
6
  * to use based on the user's query
7
7
  */
8
8
  export declare class AIService {
9
- client: OpenAI | null;
10
- private static instance;
11
- private availableTools;
12
9
  private model;
13
10
  private systemPrompt;
11
+ private static instance;
14
12
  private static serverInitialized;
13
+ private provider;
14
+ private client;
15
+ private availableTools;
15
16
  /**
16
17
  * Private constructor to prevent direct instantiation
17
18
  * Use getInstance() method instead
@@ -25,10 +26,11 @@ export declare class AIService {
25
26
  /**
26
27
  * Initialize the AI service with an API key and optionally set the model
27
28
  * This should ONLY be called from the server side
28
- * @param apiKey OpenAI API key (required)
29
+ * @param apiKey AI provider API key (required)
30
+ * @param provider AI provider name (defaults to openai)
29
31
  * @param model Optional model to use (defaults to gpt-3.5-turbo)
30
32
  */
31
- initialize(apiKey: string, model?: string): void;
33
+ initialize(apiKey: string, provider?: AiProviderNameOptions, model?: string): void;
32
34
  /**
33
35
  * Set the available tools that can be used by the AI
34
36
  * @param tools Array of tools with name, description, and parameters
@@ -38,8 +40,9 @@ export declare class AIService {
38
40
  description: string;
39
41
  parameters: Record<string, any>;
40
42
  }[]): void;
43
+ ensureInitialized(): boolean;
41
44
  /**
42
- * Get tool definitions for the AI in the format expected by OpenAI
45
+ * Get tool definitions for the AI from the available tools
43
46
  * @param toolNames Optional array of tool names to filter by (if not provided, all tools will be included)
44
47
  * @returns Array of tool definitions
45
48
  */
@@ -61,6 +64,9 @@ export declare class AIService {
61
64
  parameters: Record<string, any>;
62
65
  reasoning?: string;
63
66
  } | null>;
67
+ private processHuggingFaceQuery;
68
+ private processAnthropicQuery;
69
+ private processOpenAIQuery;
64
70
  private setSystemPrompt;
65
71
  }
66
72
  //# sourceMappingURL=ai-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-handler.d.ts","sourceRoot":"","sources":["../../src/utils/ai-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAYhC;;;;;GAKG;AACH,qBAAa,SAAS;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0B;IACjD,OAAO,CAAC,cAAc,CAIb;IACT,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAkB;IAElD;;;OAGG;IACH,OAAO;IAEP;;;OAGG;WACW,WAAW,IAAI,SAAS;IAOtC;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAYhD;;;OAGG;IACH,iBAAiB,CACf,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC,EAAE,GACF,IAAI;IAUP;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;;OAKG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;IAwCT,OAAO,CAAC,eAAe;CAGxB"}
1
+ {"version":3,"file":"ai-handler.d.ts","sourceRoot":"","sources":["../../src/utils/ai-handler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAsB5D;;;;;GAKG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0B;IACjD,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,MAAM,CAAqD;IACnE,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,CACf,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC,EAAE,GACF,IAAI;IAUP,iBAAiB,IAAI,OAAO;IAI5B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;;OAKG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;YAgCK,uBAAuB;YA2BvB,qBAAqB;YAmCrB,kBAAkB;IA2BhC,OAAO,CAAC,eAAe;CAGxB"}
@@ -1,5 +1,7 @@
1
1
  import { OpenAI } from "openai";
2
+ import Anthropic from "@anthropic-ai/sdk";
2
3
  import generalPrompt from "../prompts/general.js";
4
+ import { InferenceClient } from "@huggingface/inference";
3
5
  /**
4
6
  * AI Inference Service
5
7
  *
@@ -7,12 +9,13 @@ import generalPrompt from "../prompts/general.js";
7
9
  * to use based on the user's query
8
10
  */
9
11
  export class AIService {
10
- client = null;
11
- static instance = null;
12
- availableTools = [];
13
12
  model = "gpt-3.5-turbo";
14
13
  systemPrompt = generalPrompt;
14
+ static instance = null;
15
15
  static serverInitialized = false;
16
+ provider = "openai";
17
+ client = null;
18
+ availableTools = [];
16
19
  /**
17
20
  * Private constructor to prevent direct instantiation
18
21
  * Use getInstance() method instead
@@ -31,17 +34,31 @@ export class AIService {
31
34
  /**
32
35
  * Initialize the AI service with an API key and optionally set the model
33
36
  * This should ONLY be called from the server side
34
- * @param apiKey OpenAI API key (required)
37
+ * @param apiKey AI provider API key (required)
38
+ * @param provider AI provider name (defaults to openai)
35
39
  * @param model Optional model to use (defaults to gpt-3.5-turbo)
36
40
  */
37
- initialize(apiKey, model) {
41
+ initialize(apiKey, provider = "openai", model) {
38
42
  if (AIService.serverInitialized) {
39
43
  console.warn("AIService has already been initialized by the server.");
40
44
  return;
41
45
  }
42
- this.client = new OpenAI({ apiKey });
46
+ this.provider = provider;
43
47
  if (model)
44
48
  this.model = model;
49
+ switch (this.provider) {
50
+ case "openai":
51
+ this.client = new OpenAI({ apiKey });
52
+ break;
53
+ case "anthropic":
54
+ this.client = new Anthropic({ apiKey });
55
+ break;
56
+ case "huggingface":
57
+ this.client = new InferenceClient(apiKey);
58
+ break;
59
+ default:
60
+ throw new Error(`Unsupported AI provider: ${this.provider}`);
61
+ }
45
62
  AIService.serverInitialized = true;
46
63
  }
47
64
  /**
@@ -52,8 +69,11 @@ export class AIService {
52
69
  this.availableTools = tools;
53
70
  this.setSystemPrompt(this.systemPrompt.replace("MCP_TOOLS", JSON.stringify(this.availableTools, null, 2)));
54
71
  }
72
+ ensureInitialized() {
73
+ return this.client !== null;
74
+ }
55
75
  /**
56
- * Get tool definitions for the AI in the format expected by OpenAI
76
+ * Get tool definitions for the AI from the available tools
57
77
  * @param toolNames Optional array of tool names to filter by (if not provided, all tools will be included)
58
78
  * @returns Array of tool definitions
59
79
  */
@@ -101,38 +121,97 @@ export class AIService {
101
121
  * @returns Object containing the selected tool name and parameters
102
122
  */
103
123
  async processQuery(query, specificTools) {
124
+ if (!this.ensureInitialized())
125
+ return null;
104
126
  try {
105
- if (!this.client)
106
- return null;
107
127
  const mentionedTools = this.extractToolNames(query);
108
128
  const toolsToUse = specificTools || (mentionedTools.length ? mentionedTools : undefined);
109
129
  const tools = this.getToolDefinitions(toolsToUse);
110
130
  const messages = [
111
- { role: "user", content: query },
112
131
  { role: "system", content: this.systemPrompt },
132
+ { role: "user", content: query },
113
133
  ];
114
- const response = await this.client.chat.completions.create({
115
- tools,
116
- messages,
117
- model: this.model,
118
- tool_choice: "auto",
119
- });
120
- const message = response.choices[0].message;
121
- if (message.tool_calls?.length) {
122
- const toolCall = message.tool_calls[0];
123
- return {
124
- toolName: toolCall.function.name,
125
- reasoning: message.content || undefined,
126
- parameters: JSON.parse(toolCall.function.arguments),
127
- };
134
+ if (this.provider === "openai") {
135
+ return this.processOpenAIQuery(tools, messages);
136
+ }
137
+ if (this.provider === "anthropic") {
138
+ return this.processAnthropicQuery(tools, messages);
139
+ }
140
+ if (this.provider === "huggingface") {
141
+ return this.processHuggingFaceQuery(tools, messages);
128
142
  }
129
143
  return null;
130
144
  }
131
145
  catch (error) {
132
- console.error("Error in AI inference:", error);
146
+ if (error instanceof Error) {
147
+ throw new Error(error.message);
148
+ }
133
149
  throw error;
134
150
  }
135
151
  }
152
+ async processHuggingFaceQuery(tools, messages) {
153
+ const response = await this.client.chatCompletion({
154
+ tools,
155
+ messages,
156
+ max_tokens: 512,
157
+ model: this.model,
158
+ });
159
+ if (!response.choices?.length)
160
+ return null;
161
+ const message = response.choices[0].message;
162
+ if (message.tool_calls?.length) {
163
+ const toolCall = message.tool_calls[0];
164
+ return {
165
+ toolName: toolCall.function.name,
166
+ reasoning: message.content || undefined,
167
+ parameters: JSON.parse(toolCall.function.arguments),
168
+ };
169
+ }
170
+ return null;
171
+ }
172
+ async processAnthropicQuery(tools, messages) {
173
+ const response = await this.client.messages.create({
174
+ tools,
175
+ messages,
176
+ max_tokens: 1024,
177
+ model: this.model,
178
+ });
179
+ const content = response.content;
180
+ if (Array.isArray(content) && content.length) {
181
+ const toolCallItem = content.find((item) => item.type === "tool_call");
182
+ if (toolCallItem?.tool_call) {
183
+ const textItems = content.filter((item) => item.type === "text" &&
184
+ content.indexOf(item) < content.indexOf(toolCallItem));
185
+ const reasoning = textItems.map((item) => item.text).join(" ");
186
+ return {
187
+ reasoning: reasoning || undefined,
188
+ toolName: toolCallItem.tool_call.name,
189
+ parameters: JSON.parse(toolCallItem.tool_call.input),
190
+ };
191
+ }
192
+ }
193
+ return null;
194
+ }
195
+ async processOpenAIQuery(tools, messages) {
196
+ const response = await this.client.chat.completions.create({
197
+ model: this.model,
198
+ messages,
199
+ tools,
200
+ tool_choice: "auto",
201
+ });
202
+ if (!response.choices?.length)
203
+ return null;
204
+ const message = response.choices[0].message;
205
+ if (message.tool_calls?.length) {
206
+ const toolCall = message.tool_calls[0];
207
+ return {
208
+ toolName: toolCall.function.name,
209
+ reasoning: message.content || undefined,
210
+ parameters: JSON.parse(toolCall.function.arguments),
211
+ };
212
+ }
213
+ return null;
214
+ }
136
215
  setSystemPrompt(prompt) {
137
216
  this.systemPrompt = prompt;
138
217
  }
@@ -1,16 +1,18 @@
1
+ import { AiProviderNameOptions } from "../types/options.js";
1
2
  /**
2
3
  * Configuration service to store and retrieve Meilisearch configuration
3
4
  */
4
5
  declare class ConfigHandler {
6
+ private _llmModel;
7
+ private _aiProviderName;
5
8
  private _meilisearchHost;
9
+ private _aiProviderApiKey;
6
10
  private _meilisearchApiKey;
7
- private _openaiApiKey;
8
- private _llmModel;
9
11
  /**
10
12
  * Set the Meilisearch host URL
11
13
  * @param host The URL of the Meilisearch instance
12
14
  */
13
- setMeilisearchHost(host: string): void;
15
+ setMeilisearchHost(host?: string): void;
14
16
  /**
15
17
  * Set the Meilisearch API key
16
18
  * @param apiKey The API key for Meilisearch
@@ -27,15 +29,25 @@ declare class ConfigHandler {
27
29
  */
28
30
  getMeilisearchApiKey(): string;
29
31
  /**
30
- * Set the OpenAI API key
31
- * @param apiKey The API key for OpenAI
32
+ * Set the provider for AI inference
33
+ * @param provider The provider name: openai, huggingface.
34
+ */
35
+ setAiProviderName(provider?: AiProviderNameOptions): void;
36
+ /**
37
+ * Get the current provider for AI inference
38
+ * @returns The provider name
39
+ */
40
+ getAiProviderName(): AiProviderNameOptions;
41
+ /**
42
+ * Set the provider API key
43
+ * @param apiKey The API key for provider
32
44
  */
33
- setOpenaiApiKey(apiKey?: string): void;
45
+ setAiProviderApiKey(apiKey?: string): void;
34
46
  /**
35
- * Get the current OpenAI API key
36
- * @returns The API key for OpenAI
47
+ * Get the current provider API key
48
+ * @returns The API key for provider
37
49
  */
38
- getOpenaiApiKey(): string;
50
+ getAiProviderApiKey(): string;
39
51
  /**
40
52
  * Set the AI model to use
41
53
  * @param model The model name (e.g., gpt-3.5-turbo, gpt-4)
@@ -1 +1 @@
1
- {"version":3,"file":"config-handler.d.ts","sourceRoot":"","sources":["../../src/utils/config-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,SAAS,CAAmB;IAEpC;;;OAGG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAItC;;;OAGG;IACH,oBAAoB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAI3C;;;OAGG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;;OAGG;IACH,oBAAoB,IAAI,MAAM;IAI9B;;;OAGG;IACH,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAItC;;;OAGG;IACH,eAAe,IAAI,MAAM;IAIzB;;;OAGG;IACH,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAIjC;;;OAGG;IACH,WAAW,IAAI,MAAM;CAGtB;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC;AAEjD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"config-handler.d.ts","sourceRoot":"","sources":["../../src/utils/config-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;GAEG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,kBAAkB,CAAM;IAEhC;;;OAGG;IACH,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAIvC;;;OAGG;IACH,oBAAoB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAI3C;;;OAGG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;;OAGG;IACH,oBAAoB,IAAI,MAAM;IAI9B;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,CAAC,EAAE,qBAAqB,GAAG,IAAI;IAIzD;;;OAGG;IACH,iBAAiB,IACgB,qBAAqB;IAGtD;;;OAGG;IACH,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAI1C;;;OAGG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;;OAGG;IACH,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAIjC;;;OAGG;IACH,WAAW,IAAI,MAAM;CAGtB;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC;AAEjD,eAAe,aAAa,CAAC"}
@@ -2,16 +2,17 @@
2
2
  * Configuration service to store and retrieve Meilisearch configuration
3
3
  */
4
4
  class ConfigHandler {
5
+ _llmModel = "";
6
+ _aiProviderName = "";
5
7
  _meilisearchHost = "";
8
+ _aiProviderApiKey = "";
6
9
  _meilisearchApiKey = "";
7
- _openaiApiKey = "";
8
- _llmModel = "gpt-3.5-turbo";
9
10
  /**
10
11
  * Set the Meilisearch host URL
11
12
  * @param host The URL of the Meilisearch instance
12
13
  */
13
14
  setMeilisearchHost(host) {
14
- this._meilisearchHost = host;
15
+ this._meilisearchHost = host || "http://localhost:7700";
15
16
  }
16
17
  /**
17
18
  * Set the Meilisearch API key
@@ -35,18 +36,32 @@ class ConfigHandler {
35
36
  return this._meilisearchApiKey;
36
37
  }
37
38
  /**
38
- * Set the OpenAI API key
39
- * @param apiKey The API key for OpenAI
39
+ * Set the provider for AI inference
40
+ * @param provider The provider name: openai, huggingface.
40
41
  */
41
- setOpenaiApiKey(apiKey) {
42
- this._openaiApiKey = apiKey || "";
42
+ setAiProviderName(provider) {
43
+ this._aiProviderName = provider || "openai";
43
44
  }
44
45
  /**
45
- * Get the current OpenAI API key
46
- * @returns The API key for OpenAI
46
+ * Get the current provider for AI inference
47
+ * @returns The provider name
47
48
  */
48
- getOpenaiApiKey() {
49
- return this._openaiApiKey;
49
+ getAiProviderName() {
50
+ return this._aiProviderName;
51
+ }
52
+ /**
53
+ * Set the provider API key
54
+ * @param apiKey The API key for provider
55
+ */
56
+ setAiProviderApiKey(apiKey) {
57
+ this._aiProviderApiKey = apiKey || "";
58
+ }
59
+ /**
60
+ * Get the current provider API key
61
+ * @returns The API key for provider
62
+ */
63
+ getAiProviderApiKey() {
64
+ return this._aiProviderApiKey;
50
65
  }
51
66
  /**
52
67
  * Set the AI model to use
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-meilisearch",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "Model Context Protocol (MCP) implementation for Meilisearch",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,9 +26,11 @@
26
26
  "build": "tsc && tsc -p tsconfig.types.json",
27
27
  "demo": "npm run build & npm run dev --workspace=demo",
28
28
  "server": "npm run build && node --env-file=.env dist/index.js",
29
- "prepublishOnly": "rm -rf dist && npm version minor && npm run build"
29
+ "prepublishOnly": "rm -rf dist && npm version patch && npm run build"
30
30
  },
31
31
  "dependencies": {
32
+ "@anthropic-ai/sdk": "^0.50.4",
33
+ "@huggingface/inference": "^3.13.0",
32
34
  "@modelcontextprotocol/sdk": "^1.11.2",
33
35
  "axios": "^1.9.0",
34
36
  "openai": "^4.98.0",