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 +9 -11
- package/dist/client.d.ts +0 -10
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -17
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +19 -26
- package/dist/stdio.js +0 -1
- package/dist/tools/ai-tools.js +1 -1
- package/dist/types/options.d.ts +11 -7
- package/dist/types/options.d.ts.map +1 -1
- package/dist/utils/ai-handler.d.ts +13 -7
- package/dist/utils/ai-handler.d.ts.map +1 -1
- package/dist/utils/ai-handler.js +104 -25
- package/dist/utils/config-handler.d.ts +21 -9
- package/dist/utils/config-handler.d.ts.map +1 -1
- package/dist/utils/config-handler.js +26 -11
- package/package.json +4 -2
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
|
|
17
|
-
- **AI Inference**:
|
|
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
|
-
-
|
|
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
|
-
- `
|
|
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: "
|
|
106
|
-
|
|
107
|
-
|
|
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
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,qBAAa,SAAS;IACpB;;;OAGG;IACH,
|
|
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 (
|
|
56
|
+
catch (error) {
|
|
69
57
|
this.tries++;
|
|
70
58
|
if (this.tries > 5) {
|
|
71
59
|
this.isConnected = false;
|
|
72
|
-
throw
|
|
60
|
+
throw error;
|
|
73
61
|
}
|
|
74
62
|
await new Promise((resolve) => setTimeout(resolve, this.tries * 1000));
|
|
75
63
|
await this.connectToServer(serverUrl);
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,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.
|
|
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.
|
|
26
|
+
const apiKey = configHandler.getAiProviderApiKey();
|
|
22
27
|
if (apiKey) {
|
|
23
|
-
|
|
28
|
+
const llmModel = configHandler.getLlmModel();
|
|
29
|
+
const aiProviderName = configHandler.getAiProviderName();
|
|
30
|
+
aiService.initialize(apiKey, aiProviderName, llmModel);
|
|
24
31
|
}
|
|
25
32
|
else {
|
|
26
|
-
console.warn("
|
|
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.
|
|
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.
|
|
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 "
|
|
139
|
-
options.
|
|
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.
|
|
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
package/dist/server.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
|
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 = { ...
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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,
|
|
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,
|
|
286
|
+
const server = new MCPServer(serverInstance, customConfig);
|
|
294
287
|
const transport = new StdioServerTransport();
|
|
295
288
|
await serverInstance.connect(transport);
|
|
296
|
-
console.
|
|
289
|
+
console.info("Meilisearch MCP Server is running on stdio transport");
|
|
297
290
|
process.on("SIGINT", () => {
|
|
298
|
-
console.
|
|
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
package/dist/tools/ai-tools.js
CHANGED
|
@@ -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.
|
|
27
|
+
if (!aiService.ensureInitialized()) {
|
|
28
28
|
return {
|
|
29
29
|
isError: true,
|
|
30
30
|
content: [
|
package/dist/types/options.d.ts
CHANGED
|
@@ -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
|
-
* @
|
|
5
|
-
* @example "http://localhost:7700"
|
|
5
|
+
* @default "http://localhost:7700"
|
|
6
6
|
*/
|
|
7
|
-
meilisearchHost
|
|
7
|
+
meilisearchHost?: string;
|
|
8
8
|
/**
|
|
9
9
|
* The API key for authenticating with Meilisearch
|
|
10
|
-
* @required
|
|
11
10
|
*/
|
|
12
|
-
meilisearchApiKey
|
|
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
|
-
*
|
|
38
|
+
* AI inference provider name
|
|
39
|
+
* @default "openai"
|
|
40
40
|
*/
|
|
41
|
-
|
|
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
|
|
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 {
|
|
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
|
|
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
|
|
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":"
|
|
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"}
|
package/dist/utils/ai-handler.js
CHANGED
|
@@ -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
|
|
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.
|
|
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
|
|
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
|
-
|
|
115
|
-
tools,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
31
|
-
* @param
|
|
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
|
-
|
|
45
|
+
setAiProviderApiKey(apiKey?: string): void;
|
|
34
46
|
/**
|
|
35
|
-
* Get the current
|
|
36
|
-
* @returns The API key for
|
|
47
|
+
* Get the current provider API key
|
|
48
|
+
* @returns The API key for provider
|
|
37
49
|
*/
|
|
38
|
-
|
|
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,
|
|
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
|
|
39
|
-
* @param
|
|
39
|
+
* Set the provider for AI inference
|
|
40
|
+
* @param provider The provider name: openai, huggingface.
|
|
40
41
|
*/
|
|
41
|
-
|
|
42
|
-
this.
|
|
42
|
+
setAiProviderName(provider) {
|
|
43
|
+
this._aiProviderName = provider || "openai";
|
|
43
44
|
}
|
|
44
45
|
/**
|
|
45
|
-
* Get the current
|
|
46
|
-
* @returns The
|
|
46
|
+
* Get the current provider for AI inference
|
|
47
|
+
* @returns The provider name
|
|
47
48
|
*/
|
|
48
|
-
|
|
49
|
-
return this.
|
|
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.
|
|
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
|
|
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",
|