mcp-meilisearch 1.0.13 → 1.0.15
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 +5 -49
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +133 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -24
- package/package.json +2 -3
- package/dist/config.d.ts +0 -21
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -20
- package/dist/http.d.ts +0 -2
- package/dist/http.d.ts.map +0 -1
- package/dist/http.js +0 -2
- package/dist/plugin.d.ts +0 -9
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -95
- package/dist/standalone.d.ts +0 -10
- package/dist/standalone.d.ts.map +0 -1
- package/dist/standalone.js +0 -133
- package/dist/stdio.d.ts +0 -2
- package/dist/stdio.d.ts.map +0 -1
- package/dist/stdio.js +0 -2
- package/dist/utils/config-service.d.ts +0 -30
- package/dist/utils/config-service.d.ts.map +0 -1
- package/dist/utils/config-service.js +0 -37
package/README.md
CHANGED
|
@@ -84,35 +84,12 @@ This project uses:
|
|
|
84
84
|
- **Express**: Powers the web server.
|
|
85
85
|
- **Model Context Protocol SDK**: Facilitates AI integration.
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
### Using the MCP Vite Plugin
|
|
92
|
-
|
|
93
|
-
Add the plugin to your Vite configuration:
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
// vite.config.ts
|
|
97
|
-
import { defineConfig } from "vite";
|
|
98
|
-
import { mcpPlugin } from "mcp-meilisearch";
|
|
99
|
-
|
|
100
|
-
export default defineConfig({
|
|
101
|
-
plugins: [
|
|
102
|
-
// Your other plugins...
|
|
103
|
-
mcpPlugin({
|
|
104
|
-
transport: "http",
|
|
105
|
-
mcpEndpoint: "/mcp",
|
|
106
|
-
sessionTimeout: 3600000, // 1 hour
|
|
107
|
-
sessionCleanupInterval: 60000, // 1 minute
|
|
108
|
-
meilisearchApiKey: "your-api-key-here",
|
|
109
|
-
meilisearchHost: "http://localhost:7700",
|
|
110
|
-
}),
|
|
111
|
-
],
|
|
112
|
-
});
|
|
113
|
-
```
|
|
87
|
+
### Options
|
|
88
|
+
|
|
89
|
+
#### Meilisearch Connection Options
|
|
114
90
|
|
|
115
|
-
|
|
91
|
+
- `meilisearchHost`: URL of the Meilisearch instance (Default: "http://localhost:7700")
|
|
92
|
+
- `meilisearchApiKey`: API key for authenticating with Meilisearch (Default: "")
|
|
116
93
|
|
|
117
94
|
#### MCP Server Options
|
|
118
95
|
|
|
@@ -124,24 +101,3 @@ export default defineConfig({
|
|
|
124
101
|
|
|
125
102
|
- `sessionTimeout`: Session timeout in milliseconds (Default: 3600000)
|
|
126
103
|
- `sessionCleanupInterval`: Session cleanup interval in milliseconds (Default: 60000)
|
|
127
|
-
|
|
128
|
-
#### Meilisearch Connection Options
|
|
129
|
-
|
|
130
|
-
- `meilisearchHost`: URL of the Meilisearch instance (Default: "http://localhost:7700")
|
|
131
|
-
- `meilisearchApiKey`: API key for authenticating with Meilisearch (Default: "")
|
|
132
|
-
|
|
133
|
-
### Using the MCPClient
|
|
134
|
-
|
|
135
|
-
The package also exports the MCPClient class for client-side integration:
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
import { MCPClient } from "mcp-meilisearch";
|
|
139
|
-
|
|
140
|
-
const client = new MCPClient("meilisearch");
|
|
141
|
-
await client.connectToServer("http://localhost:3000/mcp");
|
|
142
|
-
|
|
143
|
-
// Call a tool
|
|
144
|
-
const result = await client.callTool("search-across-all-indexes", {
|
|
145
|
-
q: "search kiosco antonio",
|
|
146
|
-
});
|
|
147
|
-
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import { ServerOptions } from "./types/options.js";
|
|
3
|
+
/**
|
|
4
|
+
* Start a standalone MCP server
|
|
5
|
+
* @param options Configuration options for the MCP server
|
|
6
|
+
* @returns A promise that resolves to the HTTP server instance
|
|
7
|
+
*/
|
|
8
|
+
export declare function mcpMeilisearchServer(options?: ServerOptions): Promise<http.Server>;
|
|
9
|
+
export default mcpMeilisearchServer;
|
|
3
10
|
//# sourceMappingURL=index.d.ts.map
|
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,EAAE,
|
|
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;AAInD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,aAGR,GACA,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAmGtB;AAqCD,eAAe,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,133 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { initServer } from "./server.js";
|
|
3
|
+
import { parse as parseUrl } from "node:url";
|
|
4
|
+
import { configHandler } from "./utils/config-handler.js";
|
|
5
|
+
import { createErrorResponse } from "./utils/error-handler.js";
|
|
6
|
+
/**
|
|
7
|
+
* Start a standalone MCP server
|
|
8
|
+
* @param options Configuration options for the MCP server
|
|
9
|
+
* @returns A promise that resolves to the HTTP server instance
|
|
10
|
+
*/
|
|
11
|
+
export async function mcpMeilisearchServer(options = {
|
|
12
|
+
meilisearchApiKey: "",
|
|
13
|
+
meilisearchHost: "http://localhost:7700",
|
|
14
|
+
}) {
|
|
15
|
+
configHandler.setMeilisearchHost(options.meilisearchHost);
|
|
16
|
+
configHandler.setMeilisearchApiKey(options.meilisearchApiKey);
|
|
17
|
+
let mcpServerInstance = null;
|
|
18
|
+
const httpPort = options.httpPort || 8080;
|
|
19
|
+
const transport = options.transport || "http";
|
|
20
|
+
const mcpEndpoint = options.mcpEndpoint || "/mcp";
|
|
21
|
+
const server = createServer(async (req, res) => {
|
|
22
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
23
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
24
|
+
res.setHeader("Access-Control-Allow-Headers", `Origin, X-Requested-With, Content-Type, Accept, mcp-session-id`);
|
|
25
|
+
if (req.method === "OPTIONS") {
|
|
26
|
+
res.statusCode = 200;
|
|
27
|
+
res.end();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const parsedUrl = parseUrl(req.url || "/", true);
|
|
31
|
+
const pathname = parsedUrl.pathname || "/";
|
|
32
|
+
if (pathname.startsWith(mcpEndpoint)) {
|
|
33
|
+
if (!mcpServerInstance) {
|
|
34
|
+
console.error("MCP server not initialized yet");
|
|
35
|
+
res.statusCode = 503;
|
|
36
|
+
res.setHeader("Content-Type", "application/json");
|
|
37
|
+
res.end(JSON.stringify(createErrorResponse("MCP server not initialized yet")));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (req.method === "GET") {
|
|
41
|
+
await mcpServerInstance.handleGetRequest(req, res);
|
|
42
|
+
}
|
|
43
|
+
else if (req.method === "POST") {
|
|
44
|
+
let body = "";
|
|
45
|
+
req.on("data", (chunk) => {
|
|
46
|
+
body += chunk.toString();
|
|
47
|
+
});
|
|
48
|
+
req.on("end", async () => {
|
|
49
|
+
try {
|
|
50
|
+
const jsonBody = JSON.parse(body);
|
|
51
|
+
await mcpServerInstance.handlePostRequest(req, res, jsonBody);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.error("Error parsing request body:", error);
|
|
55
|
+
res.statusCode = 400;
|
|
56
|
+
res.end(JSON.stringify(createErrorResponse("Invalid JSON body")));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
res.statusCode = 405;
|
|
62
|
+
res.end(JSON.stringify(createErrorResponse("Method not allowed")));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
res.statusCode = 404;
|
|
67
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
await new Promise((resolve) => {
|
|
71
|
+
server.listen(httpPort, () => {
|
|
72
|
+
console.log(`MCP server listening on port ${httpPort}`);
|
|
73
|
+
resolve();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
const serverInstances = await initServer(transport, options);
|
|
78
|
+
mcpServerInstance = serverInstances.mcpServer;
|
|
79
|
+
console.log("MCP server initialized successfully");
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.error("Failed to initialize MCP server:", error);
|
|
83
|
+
server.close();
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
const shutdownHandler = () => {
|
|
87
|
+
console.log("Shutting down MCP server...");
|
|
88
|
+
if (mcpServerInstance && typeof mcpServerInstance.shutdown === "function") {
|
|
89
|
+
try {
|
|
90
|
+
mcpServerInstance.shutdown();
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error("Error shutting down MCP server:", error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
server.close();
|
|
97
|
+
};
|
|
98
|
+
process.on("SIGINT", shutdownHandler);
|
|
99
|
+
process.on("SIGTERM", shutdownHandler);
|
|
100
|
+
return server;
|
|
101
|
+
}
|
|
102
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
103
|
+
const args = process.argv.slice(2);
|
|
104
|
+
const options = {
|
|
105
|
+
meilisearchHost: "http://localhost:7700",
|
|
106
|
+
meilisearchApiKey: "",
|
|
107
|
+
};
|
|
108
|
+
for (let i = 0; i < args.length; i += 2) {
|
|
109
|
+
const key = args[i].replace("--", "");
|
|
110
|
+
const value = args[i + 1];
|
|
111
|
+
switch (key) {
|
|
112
|
+
case "port":
|
|
113
|
+
options.httpPort = parseInt(value, 10);
|
|
114
|
+
break;
|
|
115
|
+
case "endpoint":
|
|
116
|
+
options.mcpEndpoint = value;
|
|
117
|
+
break;
|
|
118
|
+
case "host":
|
|
119
|
+
options.meilisearchHost = value;
|
|
120
|
+
break;
|
|
121
|
+
case "apiKey":
|
|
122
|
+
options.meilisearchApiKey = value;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
mcpMeilisearchServer(options)
|
|
127
|
+
.then(() => console.log("MCP server running"))
|
|
128
|
+
.catch((err) => {
|
|
129
|
+
console.error("Failed to start server:", err);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
export default mcpMeilisearchServer;
|
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;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAevD,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,eAAe;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB;AAiBD;;GAEG;AACH,cAAM,SAAS;IACb,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;IAwCrC;;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;AAsED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,WAAW,OAAO,GAAG,MAAM,EAC3B,SAAS,OAAO,CAAC,YAAY,CAAC,KAC7B,OAAO,CAAC,eAAe,CAczB,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -35,7 +35,6 @@ class MCPServer {
|
|
|
35
35
|
constructor(server, config = {}) {
|
|
36
36
|
this.server = server;
|
|
37
37
|
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
38
|
-
// Start session cleanup if using HTTP transport
|
|
39
38
|
this.startSessionCleanup();
|
|
40
39
|
}
|
|
41
40
|
/**
|
|
@@ -76,7 +75,6 @@ class MCPServer {
|
|
|
76
75
|
async handlePostRequest(req, res, body) {
|
|
77
76
|
const sessionId = this.extractSessionId(req);
|
|
78
77
|
try {
|
|
79
|
-
// Case 1: Existing session
|
|
80
78
|
if (sessionId && this.sessions.has(sessionId)) {
|
|
81
79
|
console.log(`POST request for existing session ${sessionId}`);
|
|
82
80
|
const sessionInfo = this.sessions.get(sessionId);
|
|
@@ -84,12 +82,10 @@ class MCPServer {
|
|
|
84
82
|
this.updateSessionActivity(sessionId);
|
|
85
83
|
return;
|
|
86
84
|
}
|
|
87
|
-
// Case 2: Initialize request
|
|
88
85
|
if (!sessionId && this.isInitializeRequest(body)) {
|
|
89
86
|
await this.handleInitializeRequest(req, res, body);
|
|
90
87
|
return;
|
|
91
88
|
}
|
|
92
|
-
// Case 3: Invalid request
|
|
93
89
|
console.error("Invalid request: missing session ID or not an initialize request");
|
|
94
90
|
this.sendErrorResponse(res, 400, "Bad Request: invalid session ID or not an initialize request");
|
|
95
91
|
}
|
|
@@ -107,7 +103,6 @@ class MCPServer {
|
|
|
107
103
|
clearInterval(this.cleanupInterval);
|
|
108
104
|
this.cleanupInterval = null;
|
|
109
105
|
}
|
|
110
|
-
// Close all active sessions
|
|
111
106
|
for (const [sessionId, sessionInfo] of this.sessions.entries()) {
|
|
112
107
|
try {
|
|
113
108
|
console.log(`Closing session ${sessionId}`);
|
|
@@ -134,19 +129,14 @@ class MCPServer {
|
|
|
134
129
|
});
|
|
135
130
|
transport.sessionId = newSessionId;
|
|
136
131
|
try {
|
|
137
|
-
// Connect the transport to the MCP server
|
|
138
132
|
await this.server.connect(transport);
|
|
139
|
-
// Set response headers
|
|
140
133
|
res.setHeader(this.SESSION_ID_HEADER_NAME, newSessionId);
|
|
141
134
|
res.setHeader("Access-Control-Expose-Headers", this.SESSION_ID_HEADER_NAME);
|
|
142
|
-
// Handle the initialize request
|
|
143
135
|
await transport.handleRequest(req, res, body);
|
|
144
|
-
// Register the session
|
|
145
136
|
this.sessions.set(newSessionId, {
|
|
146
137
|
transport,
|
|
147
138
|
lastActivity: Date.now(),
|
|
148
139
|
});
|
|
149
|
-
// Notify client about available tools
|
|
150
140
|
this.sendToolListChangedNotification(transport);
|
|
151
141
|
console.log(`New session established: ${newSessionId}`);
|
|
152
142
|
}
|
|
@@ -233,13 +223,11 @@ class MCPServer {
|
|
|
233
223
|
cleanupExpiredSessions() {
|
|
234
224
|
const now = Date.now();
|
|
235
225
|
const expiredIds = [];
|
|
236
|
-
// Find expired sessions
|
|
237
226
|
for (const [sessionId, info] of this.sessions.entries()) {
|
|
238
227
|
if (now - info.lastActivity > this.config.sessionTimeout) {
|
|
239
228
|
expiredIds.push(sessionId);
|
|
240
229
|
}
|
|
241
230
|
}
|
|
242
|
-
// Remove expired sessions
|
|
243
231
|
if (expiredIds.length) {
|
|
244
232
|
console.log(`Cleaning up ${expiredIds.length} expired sessions`);
|
|
245
233
|
for (const sessionId of expiredIds) {
|
|
@@ -269,7 +257,6 @@ const initServerHTTPTransport = async (customConfig) => {
|
|
|
269
257
|
version: "1.0.0",
|
|
270
258
|
name: "mcp-meilisearch",
|
|
271
259
|
});
|
|
272
|
-
// Register all tools
|
|
273
260
|
registerIndexTools(serverInstance);
|
|
274
261
|
registerDocumentTools(serverInstance);
|
|
275
262
|
registerSearchTools(serverInstance);
|
|
@@ -278,9 +265,7 @@ const initServerHTTPTransport = async (customConfig) => {
|
|
|
278
265
|
registerSystemTools(serverInstance);
|
|
279
266
|
registerTaskTools(serverInstance);
|
|
280
267
|
const server = new MCPServer(serverInstance, config);
|
|
281
|
-
|
|
282
|
-
// Return both server instances for proper cleanup
|
|
283
|
-
return { mcpServer: server, viteServer: vite };
|
|
268
|
+
return { mcpServer: server };
|
|
284
269
|
};
|
|
285
270
|
/**
|
|
286
271
|
* Initialize the MCP server with stdio transport
|
|
@@ -292,12 +277,10 @@ const initServerStdioTransport = async () => {
|
|
|
292
277
|
host: process.env.MEILISEARCH_HOST,
|
|
293
278
|
apiKey: process.env.MEILISEARCH_API_KEY,
|
|
294
279
|
};
|
|
295
|
-
// Use environment variables if available, otherwise use defaults
|
|
296
280
|
const serverInstance = new McpServer({
|
|
297
281
|
version: "1.0.0",
|
|
298
282
|
name: "mcp-meilisearch",
|
|
299
283
|
});
|
|
300
|
-
// Register all tools
|
|
301
284
|
registerIndexTools(serverInstance);
|
|
302
285
|
registerDocumentTools(serverInstance);
|
|
303
286
|
registerSearchTools(serverInstance);
|
|
@@ -305,18 +288,15 @@ const initServerStdioTransport = async () => {
|
|
|
305
288
|
registerVectorTools(serverInstance);
|
|
306
289
|
registerSystemTools(serverInstance);
|
|
307
290
|
registerTaskTools(serverInstance);
|
|
308
|
-
// Create MCPServer instance
|
|
309
291
|
const server = new MCPServer(serverInstance, config);
|
|
310
|
-
// Connect stdio transport
|
|
311
292
|
const transport = new StdioServerTransport();
|
|
312
293
|
await serverInstance.connect(transport);
|
|
313
294
|
console.log("Meilisearch MCP Server is running on stdio transport");
|
|
314
|
-
// Handle process termination
|
|
315
295
|
process.on("SIGINT", () => {
|
|
316
296
|
console.log("Shutting down stdio server...");
|
|
317
297
|
process.exit(0);
|
|
318
298
|
});
|
|
319
|
-
return server;
|
|
299
|
+
return { mcpServer: server };
|
|
320
300
|
};
|
|
321
301
|
/**
|
|
322
302
|
* Initialize the MCP server with the specified transport
|
|
@@ -328,8 +308,7 @@ export const initServer = async (transport, config) => {
|
|
|
328
308
|
try {
|
|
329
309
|
switch (transport) {
|
|
330
310
|
case "stdio":
|
|
331
|
-
|
|
332
|
-
return { mcpServer: stdioServer };
|
|
311
|
+
return await initServerStdioTransport();
|
|
333
312
|
case "http":
|
|
334
313
|
return await initServerHTTPTransport(config);
|
|
335
314
|
default:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-meilisearch",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "Model Context Protocol (MCP) implementation for Meilisearch",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,13 +15,12 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "tsc && tsc --project tsconfig.types.json",
|
|
17
17
|
"server": "npm run build && node --env-file=.env dist/standalone.js",
|
|
18
|
-
"demo": "npm run build
|
|
18
|
+
"demo": "npm run build & npm run preview --workspace=demo",
|
|
19
19
|
"prepublishOnly": "npm version patch && npm run build"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@modelcontextprotocol/sdk": "^1.10.1",
|
|
23
23
|
"axios": "^1.9.0",
|
|
24
|
-
"vite": "^6.3.5",
|
|
25
24
|
"zod": "^3.24.4"
|
|
26
25
|
},
|
|
27
26
|
"devDependencies": {
|
package/dist/config.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Meilisearch Configuration
|
|
3
|
-
*
|
|
4
|
-
* This file contains the configuration settings for connecting to the Meilisearch server.
|
|
5
|
-
* Configuration is loaded from environment variables with sensible defaults.
|
|
6
|
-
*/
|
|
7
|
-
export interface MeilisearchConfig {
|
|
8
|
-
/** The URL of the Meilisearch instance */
|
|
9
|
-
host: string;
|
|
10
|
-
/** The API key for authenticating with Meilisearch */
|
|
11
|
-
apiKey: string;
|
|
12
|
-
/** The timeout for API requests in milliseconds */
|
|
13
|
-
timeout: number;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Load and initialize configuration from environment variables
|
|
17
|
-
*/
|
|
18
|
-
export declare const loadConfig: () => MeilisearchConfig;
|
|
19
|
-
export declare const config: MeilisearchConfig;
|
|
20
|
-
export default config;
|
|
21
|
-
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,QAAO,iBAM7B,CAAC;AAGF,eAAO,MAAM,MAAM,mBAAe,CAAC;AAGnC,eAAe,MAAM,CAAC"}
|
package/dist/config.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Meilisearch Configuration
|
|
3
|
-
*
|
|
4
|
-
* This file contains the configuration settings for connecting to the Meilisearch server.
|
|
5
|
-
* Configuration is loaded from environment variables with sensible defaults.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Load and initialize configuration from environment variables
|
|
9
|
-
*/
|
|
10
|
-
export const loadConfig = () => {
|
|
11
|
-
return {
|
|
12
|
-
host: process.env.MEILISEARCH_HOST || "http://localhost:7700",
|
|
13
|
-
apiKey: process.env.MEILISEARCH_API_KEY || "",
|
|
14
|
-
timeout: parseInt("5000", 10),
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
// Export the config instance
|
|
18
|
-
export const config = loadConfig();
|
|
19
|
-
// Re-export for direct use
|
|
20
|
-
export default config;
|
package/dist/http.d.ts
DELETED
package/dist/http.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":""}
|
package/dist/http.js
DELETED
package/dist/plugin.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Plugin } from "vite";
|
|
2
|
-
import { ServerOptions } from "./types/options.js";
|
|
3
|
-
/**
|
|
4
|
-
* Creates a Vite plugin that integrates with the MCP server
|
|
5
|
-
* @param options Configuration options for the MCP server
|
|
6
|
-
* @returns A Vite plugin
|
|
7
|
-
*/
|
|
8
|
-
export declare function mcpPlugin(options?: ServerOptions): Plugin;
|
|
9
|
-
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,OAAO,GAAE,aAGR,GACA,MAAM,CAmGR"}
|
package/dist/plugin.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { initServer } from "./server.js";
|
|
2
|
-
import { configHandler } from "./utils/config-handler.js";
|
|
3
|
-
import { createErrorResponse } from "./utils/error-handler.js";
|
|
4
|
-
/**
|
|
5
|
-
* Creates a Vite plugin that integrates with the MCP server
|
|
6
|
-
* @param options Configuration options for the MCP server
|
|
7
|
-
* @returns A Vite plugin
|
|
8
|
-
*/
|
|
9
|
-
export function mcpPlugin(options = {
|
|
10
|
-
meilisearchApiKey: "",
|
|
11
|
-
meilisearchHost: "http://localhost:7700",
|
|
12
|
-
}) {
|
|
13
|
-
configHandler.setMeilisearchHost(options.meilisearchHost);
|
|
14
|
-
configHandler.setMeilisearchApiKey(options.meilisearchApiKey);
|
|
15
|
-
let mcpServerInstance = null;
|
|
16
|
-
const transport = options.transport || "http";
|
|
17
|
-
return {
|
|
18
|
-
name: "vite:mcp-plugin",
|
|
19
|
-
configureServer(server) {
|
|
20
|
-
server.middlewares.use((req, res, next) => {
|
|
21
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
22
|
-
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
23
|
-
res.setHeader("Access-Control-Allow-Headers", `Origin, X-Requested-With, Content-Type, Accept, mcp-session-id`);
|
|
24
|
-
if (req.method === "OPTIONS") {
|
|
25
|
-
res.statusCode = 200;
|
|
26
|
-
res.end();
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
next();
|
|
30
|
-
});
|
|
31
|
-
server.middlewares.use(async (req, res, next) => {
|
|
32
|
-
const mcpEndpoint = options.mcpEndpoint || "/mcp";
|
|
33
|
-
const url = req.url || "/";
|
|
34
|
-
if (url.startsWith(mcpEndpoint)) {
|
|
35
|
-
if (!mcpServerInstance) {
|
|
36
|
-
console.error("MCP server not initialized yet");
|
|
37
|
-
res.statusCode = 503;
|
|
38
|
-
res.setHeader("Content-Type", "application/json");
|
|
39
|
-
res.end(JSON.stringify(createErrorResponse("MCP server not initialized yet")));
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if (req.method === "GET") {
|
|
43
|
-
await mcpServerInstance.handleGetRequest(req, res);
|
|
44
|
-
}
|
|
45
|
-
else if (req.method === "POST") {
|
|
46
|
-
let body = "";
|
|
47
|
-
req.on("data", (chunk) => {
|
|
48
|
-
body += chunk.toString();
|
|
49
|
-
});
|
|
50
|
-
req.on("end", async () => {
|
|
51
|
-
try {
|
|
52
|
-
const jsonBody = JSON.parse(body);
|
|
53
|
-
await mcpServerInstance.handlePostRequest(req, res, jsonBody);
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
console.error("Error parsing request body:", error);
|
|
57
|
-
res.statusCode = 400;
|
|
58
|
-
res.end(JSON.stringify(createErrorResponse("Invalid JSON body")));
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
next();
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
next();
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
server.httpServer?.on("listening", async () => {
|
|
71
|
-
console.log(`Meilisearch MCP Server is running on ${transport} transport`);
|
|
72
|
-
try {
|
|
73
|
-
const serverInstances = await initServer(transport, options);
|
|
74
|
-
mcpServerInstance = serverInstances.mcpServer;
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
console.error("Failed to initialize MCP server:", error);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
},
|
|
81
|
-
closeBundle() {
|
|
82
|
-
if (mcpServerInstance) {
|
|
83
|
-
try {
|
|
84
|
-
console.log("Shutting down MCP server...");
|
|
85
|
-
if (typeof mcpServerInstance.shutdown === "function") {
|
|
86
|
-
mcpServerInstance.shutdown();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
console.error("Error shutting down MCP server:", error);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
}
|
package/dist/standalone.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import http from "node:http";
|
|
2
|
-
import { ServerOptions } from "./types/options.js";
|
|
3
|
-
/**
|
|
4
|
-
* Start a standalone MCP server
|
|
5
|
-
* @param options Configuration options for the MCP server
|
|
6
|
-
* @returns A promise that resolves to the HTTP server instance
|
|
7
|
-
*/
|
|
8
|
-
export declare function mcpStandalone(options?: ServerOptions): Promise<http.Server>;
|
|
9
|
-
export default mcpStandalone;
|
|
10
|
-
//# sourceMappingURL=standalone.d.ts.map
|
package/dist/standalone.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../src/standalone.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,aAGR,GACA,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAmGtB;AAqCD,eAAe,aAAa,CAAC"}
|
package/dist/standalone.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { createServer } from "node:http";
|
|
2
|
-
import { initServer } from "./server.js";
|
|
3
|
-
import { parse as parseUrl } from "node:url";
|
|
4
|
-
import { configHandler } from "./utils/config-handler.js";
|
|
5
|
-
import { createErrorResponse } from "./utils/error-handler.js";
|
|
6
|
-
/**
|
|
7
|
-
* Start a standalone MCP server
|
|
8
|
-
* @param options Configuration options for the MCP server
|
|
9
|
-
* @returns A promise that resolves to the HTTP server instance
|
|
10
|
-
*/
|
|
11
|
-
export async function mcpStandalone(options = {
|
|
12
|
-
meilisearchApiKey: "",
|
|
13
|
-
meilisearchHost: "http://localhost:7700",
|
|
14
|
-
}) {
|
|
15
|
-
configHandler.setMeilisearchHost(options.meilisearchHost);
|
|
16
|
-
configHandler.setMeilisearchApiKey(options.meilisearchApiKey);
|
|
17
|
-
let mcpServerInstance = null;
|
|
18
|
-
const httpPort = options.httpPort || 8080;
|
|
19
|
-
const transport = options.transport || "http";
|
|
20
|
-
const mcpEndpoint = options.mcpEndpoint || "/mcp";
|
|
21
|
-
const server = createServer(async (req, res) => {
|
|
22
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
23
|
-
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
24
|
-
res.setHeader("Access-Control-Allow-Headers", `Origin, X-Requested-With, Content-Type, Accept, mcp-session-id`);
|
|
25
|
-
if (req.method === "OPTIONS") {
|
|
26
|
-
res.statusCode = 200;
|
|
27
|
-
res.end();
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
const parsedUrl = parseUrl(req.url || "/", true);
|
|
31
|
-
const pathname = parsedUrl.pathname || "/";
|
|
32
|
-
if (pathname.startsWith(mcpEndpoint)) {
|
|
33
|
-
if (!mcpServerInstance) {
|
|
34
|
-
console.error("MCP server not initialized yet");
|
|
35
|
-
res.statusCode = 503;
|
|
36
|
-
res.setHeader("Content-Type", "application/json");
|
|
37
|
-
res.end(JSON.stringify(createErrorResponse("MCP server not initialized yet")));
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
if (req.method === "GET") {
|
|
41
|
-
await mcpServerInstance.handleGetRequest(req, res);
|
|
42
|
-
}
|
|
43
|
-
else if (req.method === "POST") {
|
|
44
|
-
let body = "";
|
|
45
|
-
req.on("data", (chunk) => {
|
|
46
|
-
body += chunk.toString();
|
|
47
|
-
});
|
|
48
|
-
req.on("end", async () => {
|
|
49
|
-
try {
|
|
50
|
-
const jsonBody = JSON.parse(body);
|
|
51
|
-
await mcpServerInstance.handlePostRequest(req, res, jsonBody);
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
console.error("Error parsing request body:", error);
|
|
55
|
-
res.statusCode = 400;
|
|
56
|
-
res.end(JSON.stringify(createErrorResponse("Invalid JSON body")));
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
res.statusCode = 405;
|
|
62
|
-
res.end(JSON.stringify(createErrorResponse("Method not allowed")));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
res.statusCode = 404;
|
|
67
|
-
res.end(JSON.stringify({ error: "Not found" }));
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
await new Promise((resolve) => {
|
|
71
|
-
server.listen(httpPort, () => {
|
|
72
|
-
console.log(`MCP server listening on port ${httpPort}`);
|
|
73
|
-
resolve();
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
try {
|
|
77
|
-
const serverInstances = await initServer(transport, options);
|
|
78
|
-
mcpServerInstance = serverInstances.mcpServer;
|
|
79
|
-
console.log("MCP server initialized successfully");
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
console.error("Failed to initialize MCP server:", error);
|
|
83
|
-
server.close();
|
|
84
|
-
throw error;
|
|
85
|
-
}
|
|
86
|
-
const shutdownHandler = () => {
|
|
87
|
-
console.log("Shutting down MCP server...");
|
|
88
|
-
if (mcpServerInstance && typeof mcpServerInstance.shutdown === "function") {
|
|
89
|
-
try {
|
|
90
|
-
mcpServerInstance.shutdown();
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
console.error("Error shutting down MCP server:", error);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
server.close();
|
|
97
|
-
};
|
|
98
|
-
process.on("SIGINT", shutdownHandler);
|
|
99
|
-
process.on("SIGTERM", shutdownHandler);
|
|
100
|
-
return server;
|
|
101
|
-
}
|
|
102
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
103
|
-
const args = process.argv.slice(2);
|
|
104
|
-
const options = {
|
|
105
|
-
meilisearchHost: "http://localhost:7700",
|
|
106
|
-
meilisearchApiKey: "",
|
|
107
|
-
};
|
|
108
|
-
for (let i = 0; i < args.length; i += 2) {
|
|
109
|
-
const key = args[i].replace("--", "");
|
|
110
|
-
const value = args[i + 1];
|
|
111
|
-
switch (key) {
|
|
112
|
-
case "port":
|
|
113
|
-
options.httpPort = parseInt(value, 10);
|
|
114
|
-
break;
|
|
115
|
-
case "endpoint":
|
|
116
|
-
options.mcpEndpoint = value;
|
|
117
|
-
break;
|
|
118
|
-
case "host":
|
|
119
|
-
options.meilisearchHost = value;
|
|
120
|
-
break;
|
|
121
|
-
case "apiKey":
|
|
122
|
-
options.meilisearchApiKey = value;
|
|
123
|
-
break;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
mcpStandalone(options)
|
|
127
|
-
.then(() => console.log("MCP server running"))
|
|
128
|
-
.catch((err) => {
|
|
129
|
-
console.error("Failed to start server:", err);
|
|
130
|
-
process.exit(1);
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
export default mcpStandalone;
|
package/dist/stdio.d.ts
DELETED
package/dist/stdio.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":""}
|
package/dist/stdio.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A simple configuration service to store and retrieve Meilisearch configuration
|
|
3
|
-
*/
|
|
4
|
-
declare class ConfigService {
|
|
5
|
-
private _meilisearchHost;
|
|
6
|
-
private _meilisearchApiKey;
|
|
7
|
-
/**
|
|
8
|
-
* Set the Meilisearch host URL
|
|
9
|
-
* @param host The URL of the Meilisearch instance
|
|
10
|
-
*/
|
|
11
|
-
setMeilisearchHost(host: string): void;
|
|
12
|
-
/**
|
|
13
|
-
* Set the Meilisearch API key
|
|
14
|
-
* @param apiKey The API key for Meilisearch
|
|
15
|
-
*/
|
|
16
|
-
setMeilisearchApiKey(apiKey: string): void;
|
|
17
|
-
/**
|
|
18
|
-
* Get the current Meilisearch host URL
|
|
19
|
-
* @returns The URL of the Meilisearch instance
|
|
20
|
-
*/
|
|
21
|
-
getMeilisearchHost(): string;
|
|
22
|
-
/**
|
|
23
|
-
* Get the current Meilisearch API key
|
|
24
|
-
* @returns The API key for Meilisearch
|
|
25
|
-
*/
|
|
26
|
-
getMeilisearchApiKey(): string;
|
|
27
|
-
}
|
|
28
|
-
export declare const configService: ConfigService;
|
|
29
|
-
export default configService;
|
|
30
|
-
//# sourceMappingURL=config-service.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config-service.d.ts","sourceRoot":"","sources":["../../src/utils/config-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,kBAAkB,CAAM;IAEhC;;;OAGG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAItC;;;OAGG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI1C;;;OAGG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;;OAGG;IACH,oBAAoB,IAAI,MAAM;CAG/B;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC;AAEjD,eAAe,aAAa,CAAC"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A simple configuration service to store and retrieve Meilisearch configuration
|
|
3
|
-
*/
|
|
4
|
-
class ConfigService {
|
|
5
|
-
_meilisearchHost = "";
|
|
6
|
-
_meilisearchApiKey = "";
|
|
7
|
-
/**
|
|
8
|
-
* Set the Meilisearch host URL
|
|
9
|
-
* @param host The URL of the Meilisearch instance
|
|
10
|
-
*/
|
|
11
|
-
setMeilisearchHost(host) {
|
|
12
|
-
this._meilisearchHost = host;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Set the Meilisearch API key
|
|
16
|
-
* @param apiKey The API key for Meilisearch
|
|
17
|
-
*/
|
|
18
|
-
setMeilisearchApiKey(apiKey) {
|
|
19
|
-
this._meilisearchApiKey = apiKey || "";
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Get the current Meilisearch host URL
|
|
23
|
-
* @returns The URL of the Meilisearch instance
|
|
24
|
-
*/
|
|
25
|
-
getMeilisearchHost() {
|
|
26
|
-
return this._meilisearchHost;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Get the current Meilisearch API key
|
|
30
|
-
* @returns The API key for Meilisearch
|
|
31
|
-
*/
|
|
32
|
-
getMeilisearchApiKey() {
|
|
33
|
-
return this._meilisearchApiKey;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export const configService = new ConfigService();
|
|
37
|
-
export default configService;
|