mcp-meilisearch 1.0.3 → 1.0.6

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/dist/config.js CHANGED
@@ -11,7 +11,7 @@ export const loadConfig = () => {
11
11
  return {
12
12
  host: process.env.MEILISEARCH_HOST || "http://localhost:7700",
13
13
  apiKey: process.env.MEILISEARCH_API_KEY || "",
14
- timeout: parseInt(process.env.MEILISEARCH_TIMEOUT || "5000", 10),
14
+ timeout: parseInt("5000", 10),
15
15
  };
16
16
  };
17
17
  // Export the config instance
package/dist/index.d.ts CHANGED
@@ -1,13 +1,54 @@
1
- export { MCPClient } from "./client.js";
2
- export * from "./server.js";
3
- export * from "./config.js";
4
- export * from "./tools/document-tools.js";
5
- export * from "./tools/index-tools.js";
6
- export * from "./tools/search-tools.js";
7
- export * from "./tools/settings-tools.js";
8
- export * from "./tools/system-tools.js";
9
- export * from "./tools/task-tools.js";
10
- export * from "./tools/vector-tools.js";
11
- export * from "./utils/api-handler.js";
12
- export * from "./utils/error-handler.js";
1
+ import { Plugin } from "vite";
2
+ import { MCPClient } from "./client.js";
3
+ /**
4
+ * Options for the MCP Vite plugin
5
+ */
6
+ export interface MCPPluginOptions {
7
+ /**
8
+ * Transport type for MCP server ("http" | "stdio")
9
+ * @default "http"
10
+ */
11
+ transport?: "http" | "stdio";
12
+ /**
13
+ * HTTP port for MCP server
14
+ * @default 8080
15
+ */
16
+ httpPort?: number;
17
+ /**
18
+ * MCP endpoint path
19
+ * @default "/mcp"
20
+ */
21
+ mcpEndpoint?: string;
22
+ /**
23
+ * Server name
24
+ * @default "meilisearch"
25
+ */
26
+ serverName?: string;
27
+ /**
28
+ * Server version
29
+ * @default "1.0.0"
30
+ */
31
+ serverVersion?: string;
32
+ /**
33
+ * Session timeout in milliseconds
34
+ * @default 3600000 (1 hour)
35
+ */
36
+ sessionTimeout?: number;
37
+ /**
38
+ * Session cleanup interval in milliseconds
39
+ * @default 60000 (1 minute)
40
+ */
41
+ sessionCleanupInterval?: number;
42
+ }
43
+ /**
44
+ * Creates a Vite plugin that integrates with the MCP server
45
+ * @param options Configuration options for the MCP server
46
+ * @returns A Vite plugin
47
+ */
48
+ export declare function mcpPlugin(options?: MCPPluginOptions): Plugin;
49
+ export { MCPClient };
50
+ /**
51
+ * Default export for convenience
52
+ */
53
+ export default mcpPlugin;
13
54
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAG5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAKxC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;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,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,MAAM,CA0IhE;AAGD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB;;GAEG;AACH,eAAe,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,14 +1,130 @@
1
- export { MCPClient } from "./client.js";
2
- export * from "./server.js";
3
- export * from "./config.js";
4
- // Re-export tools
5
- export * from "./tools/document-tools.js";
6
- export * from "./tools/index-tools.js";
7
- export * from "./tools/search-tools.js";
8
- export * from "./tools/settings-tools.js";
9
- export * from "./tools/system-tools.js";
10
- export * from "./tools/task-tools.js";
11
- export * from "./tools/vector-tools.js";
12
- // Re-export utils
13
- export * from "./utils/api-handler.js";
14
- export * from "./utils/error-handler.js";
1
+ import { MCPClient } from "./client.js";
2
+ import { initServer } from "./server.js";
3
+ import { randomUUID } from "node:crypto";
4
+ import { createErrorResponse } from "./utils/error-handler.js";
5
+ /**
6
+ * Creates a Vite plugin that integrates with the MCP server
7
+ * @param options Configuration options for the MCP server
8
+ * @returns A Vite plugin
9
+ */
10
+ export function mcpPlugin(options = {}) {
11
+ const pluginId = `mcp-plugin-${randomUUID().slice(0, 8)}`;
12
+ let mcpServerInstance = null;
13
+ // Set default options
14
+ const transport = options.transport || "http";
15
+ return {
16
+ name: "vite:mcp-plugin",
17
+ apply: "serve", // Only apply this plugin during development
18
+ configureServer(server) {
19
+ // Store the custom config in Vite's server context for sharing
20
+ server.config.env.VITE_MCP_PLUGIN_ID = pluginId;
21
+ // Configure process.env variables with MCP server options
22
+ if (options.httpPort)
23
+ process.env.MCP_HTTP_PORT = String(options.httpPort);
24
+ if (options.mcpEndpoint)
25
+ process.env.MCP_ENDPOINT = options.mcpEndpoint;
26
+ if (options.serverName)
27
+ process.env.MCP_SERVER_NAME = options.serverName;
28
+ if (options.serverVersion)
29
+ process.env.MCP_SERVER_VERSION = options.serverVersion;
30
+ if (options.sessionTimeout)
31
+ process.env.MCP_SESSION_TIMEOUT = String(options.sessionTimeout);
32
+ if (options.sessionCleanupInterval)
33
+ process.env.MCP_SESSION_CLEANUP_INTERVAL = String(options.sessionCleanupInterval);
34
+ // Add CORS middleware
35
+ server.middlewares.use((req, res, next) => {
36
+ res.setHeader("Access-Control-Allow-Origin", "*");
37
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
38
+ res.setHeader("Access-Control-Allow-Headers", `Origin, X-Requested-With, Content-Type, Accept, mcp-session-id`);
39
+ if (req.method === "OPTIONS") {
40
+ res.statusCode = 200;
41
+ res.end();
42
+ return;
43
+ }
44
+ next();
45
+ });
46
+ // Handle MCP endpoint requests
47
+ server.middlewares.use(async (req, res, next) => {
48
+ const mcpEndpoint = options.mcpEndpoint || "/mcp";
49
+ const url = req.url || "/";
50
+ if (url.startsWith(mcpEndpoint)) {
51
+ // Only proceed if MCP server is initialized
52
+ if (!mcpServerInstance) {
53
+ console.error("MCP server not initialized yet");
54
+ res.statusCode = 503;
55
+ res.setHeader("Content-Type", "application/json");
56
+ res.end(JSON.stringify(createErrorResponse("MCP server not initialized yet")));
57
+ return;
58
+ }
59
+ if (req.method === "GET") {
60
+ await mcpServerInstance.handleGetRequest(req, res);
61
+ }
62
+ else if (req.method === "POST") {
63
+ let body = "";
64
+ req.on("data", (chunk) => {
65
+ body += chunk.toString();
66
+ });
67
+ req.on("end", async () => {
68
+ try {
69
+ const jsonBody = JSON.parse(body);
70
+ await mcpServerInstance.handlePostRequest(req, res, jsonBody);
71
+ }
72
+ catch (error) {
73
+ console.error("Error parsing request body:", error);
74
+ res.statusCode = 400;
75
+ res.end(JSON.stringify(createErrorResponse("Invalid JSON body")));
76
+ }
77
+ });
78
+ }
79
+ else {
80
+ next();
81
+ }
82
+ }
83
+ else {
84
+ next();
85
+ }
86
+ });
87
+ // Start the MCP server when Vite server is ready
88
+ server.httpServer?.on("listening", async () => {
89
+ console.log(`Vite server is ready, initializing MCP server with ${transport} transport`);
90
+ try {
91
+ // Initialize the MCP server
92
+ const serverInstances = await initServer(transport);
93
+ mcpServerInstance = serverInstances.mcpServer;
94
+ const hostConfig = server.config.server;
95
+ const protocol = hostConfig.https ? "https" : "http";
96
+ const host = hostConfig.host === true
97
+ ? "localhost"
98
+ : hostConfig.host || "localhost";
99
+ const port = hostConfig.port || 3000;
100
+ const mcpEndpoint = options.mcpEndpoint || "/mcp";
101
+ console.log(`MCP server initialized with ${transport} transport`);
102
+ console.log(`MCP endpoint available at: ${protocol}://${host}:${port}${mcpEndpoint}`);
103
+ }
104
+ catch (error) {
105
+ console.error("Failed to initialize MCP server:", error);
106
+ }
107
+ });
108
+ },
109
+ closeBundle() {
110
+ // Clean up resources when Vite is shutting down
111
+ if (mcpServerInstance) {
112
+ try {
113
+ console.log("Shutting down MCP server...");
114
+ if (typeof mcpServerInstance.shutdown === "function") {
115
+ mcpServerInstance.shutdown();
116
+ }
117
+ }
118
+ catch (error) {
119
+ console.error("Error shutting down MCP server:", error);
120
+ }
121
+ }
122
+ },
123
+ };
124
+ }
125
+ // Export the MCPClient class for external use
126
+ export { MCPClient };
127
+ /**
128
+ * Default export for convenience
129
+ */
130
+ export default mcpPlugin;
package/dist/server.d.ts CHANGED
@@ -1,7 +1,102 @@
1
+ import { IncomingMessage, ServerResponse } from "http";
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ /**
4
+ * Configuration for the MCP server
5
+ */
6
+ interface ServerConfig {
7
+ httpPort: number;
8
+ mcpEndpoint: string;
9
+ serverName: string;
10
+ serverVersion: string;
11
+ sessionTimeout: number;
12
+ sessionCleanupInterval: number;
13
+ }
14
+ /**
15
+ * Implementation of an MCP server for Meilisearch
16
+ */
17
+ declare class MCPServer {
18
+ private readonly JSON_RPC;
19
+ private readonly SESSION_ID_HEADER_NAME;
20
+ private server;
21
+ private cleanupInterval;
22
+ private sessions;
23
+ private config;
24
+ /**
25
+ * Creates a new MCP server instance
26
+ * @param server The underlying MCP server implementation
27
+ * @param config Configuration options
28
+ */
29
+ constructor(server: McpServer, config?: Partial<ServerConfig>);
30
+ /**
31
+ * Handles an HTTP GET request
32
+ * @param req The HTTP request
33
+ * @param res The HTTP response
34
+ */
35
+ handleGetRequest(req: IncomingMessage, res: ServerResponse): Promise<void>;
36
+ /**
37
+ * Handles an HTTP POST request (executes MCP commands)
38
+ * @param req The HTTP request
39
+ * @param res The HTTP response
40
+ * @param body The request body
41
+ */
42
+ handlePostRequest(req: IncomingMessage, res: ServerResponse, body: any): Promise<void>;
43
+ /**
44
+ * Clean up and release server resources
45
+ */
46
+ shutdown(): void;
47
+ /**
48
+ * Handles the initial connection request
49
+ * @param req The HTTP request
50
+ * @param res The HTTP response
51
+ * @param body The request body
52
+ */
53
+ private handleInitializeRequest;
54
+ /**
55
+ * Sends a notification about tool list changes
56
+ */
57
+ private sendToolListChangedNotification;
58
+ /**
59
+ * Sends a notification through the transport
60
+ */
61
+ private sendNotification;
62
+ /**
63
+ * Checks if the request body represents an initialize request
64
+ */
65
+ private isInitializeRequest;
66
+ /**
67
+ * Extracts session ID from request headers
68
+ */
69
+ private extractSessionId;
70
+ /**
71
+ * Updates the activity timestamp for a session
72
+ */
73
+ private updateSessionActivity;
74
+ /**
75
+ * Sends an error response with the specified status code and message
76
+ */
77
+ private sendErrorResponse;
78
+ /**
79
+ * Starts the session cleanup process
80
+ */
81
+ private startSessionCleanup;
82
+ /**
83
+ * Removes expired sessions
84
+ */
85
+ private cleanupExpiredSessions;
86
+ }
87
+ /**
88
+ * Return type for the initServer function
89
+ */
90
+ export interface ServerInstances {
91
+ mcpServer?: MCPServer;
92
+ viteServer?: any;
93
+ }
1
94
  /**
2
95
  * Initialize the MCP server with the specified transport
3
96
  * @param transport The transport type to use ("stdio" or "http")
97
+ * @returns A promise that resolves to the server instances
4
98
  * @throws Error if the transport type is unsupported
5
99
  */
6
- export declare const initServer: (transport: "stdio" | "http") => void;
100
+ export declare const initServer: (transport: "stdio" | "http") => Promise<ServerInstances>;
101
+ export {};
7
102
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAieA;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,WAAW,OAAO,GAAG,MAAM,KAAG,IAcxD,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,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAmBD;;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,eAAe,CAA+B;IACtD,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,MAAM,CAAe;IAE7B;;;;OAIG;gBACS,MAAM,EAAE,SAAS,EAAE,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAQjE;;;;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;IAkChB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAsBhB;;;;;OAKG;YACW,uBAAuB;IA6CrC;;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;CA4B/B;AAyKD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,WAAW,OAAO,GAAG,MAAM,KAC1B,OAAO,CAAC,eAAe,CAezB,CAAC"}
package/dist/server.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import { createServer as createViteServer } from "vite";
2
3
  import { InitializeRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
3
4
  import registerTaskTools from "./tools/task-tools.js";
4
5
  import registerIndexTools from "./tools/index-tools.js";
@@ -8,7 +9,6 @@ import registerVectorTools from "./tools/vector-tools.js";
8
9
  import registerDocumentTools from "./tools/document-tools.js";
9
10
  import registerSettingsTools from "./tools/settings-tools.js";
10
11
  import { createErrorResponse } from "./utils/error-handler.js";
11
- import express from "express";
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";
@@ -27,9 +27,8 @@ class MCPServer {
27
27
  JSON_RPC = "2.0";
28
28
  SESSION_ID_HEADER_NAME = "mcp-session-id";
29
29
  server;
30
- sessions = new Map();
31
- toolsRegistered = false;
32
30
  cleanupInterval = null;
31
+ sessions = new Map();
33
32
  config;
34
33
  /**
35
34
  * Creates a new MCP server instance
@@ -39,7 +38,6 @@ class MCPServer {
39
38
  constructor(server, config = {}) {
40
39
  this.server = server;
41
40
  this.config = { ...DEFAULT_CONFIG, ...config };
42
- this.toolsRegistered = this.registerTools();
43
41
  // Start session cleanup if using HTTP transport
44
42
  this.startSessionCleanup();
45
43
  }
@@ -76,21 +74,22 @@ class MCPServer {
76
74
  * Handles an HTTP POST request (executes MCP commands)
77
75
  * @param req The HTTP request
78
76
  * @param res The HTTP response
77
+ * @param body The request body
79
78
  */
80
- async handlePostRequest(req, res) {
79
+ async handlePostRequest(req, res, body) {
81
80
  const sessionId = this.extractSessionId(req);
82
81
  try {
83
82
  // Case 1: Existing session
84
83
  if (sessionId && this.sessions.has(sessionId)) {
85
84
  console.log(`POST request for existing session ${sessionId}`);
86
85
  const sessionInfo = this.sessions.get(sessionId);
87
- await sessionInfo.transport.handleRequest(req, res, req.body);
86
+ await sessionInfo.transport.handleRequest(req, res, body);
88
87
  this.updateSessionActivity(sessionId);
89
88
  return;
90
89
  }
91
90
  // Case 2: Initialize request
92
- if (!sessionId && this.isInitializeRequest(req.body)) {
93
- await this.handleInitializeRequest(req, res);
91
+ if (!sessionId && this.isInitializeRequest(body)) {
92
+ await this.handleInitializeRequest(req, res, body);
94
93
  return;
95
94
  }
96
95
  // Case 3: Invalid request
@@ -128,8 +127,9 @@ class MCPServer {
128
127
  * Handles the initial connection request
129
128
  * @param req The HTTP request
130
129
  * @param res The HTTP response
130
+ * @param body The request body
131
131
  */
132
- async handleInitializeRequest(req, res) {
132
+ async handleInitializeRequest(req, res, body) {
133
133
  console.log("Handling initialize request");
134
134
  const newSessionId = randomUUID();
135
135
  const transport = new StreamableHTTPServerTransport({
@@ -143,7 +143,7 @@ class MCPServer {
143
143
  res.setHeader(this.SESSION_ID_HEADER_NAME, newSessionId);
144
144
  res.setHeader("Access-Control-Expose-Headers", this.SESSION_ID_HEADER_NAME);
145
145
  // Handle the initialize request
146
- await transport.handleRequest(req, res, req.body);
146
+ await transport.handleRequest(req, res, body);
147
147
  // Register the session
148
148
  this.sessions.set(newSessionId, {
149
149
  transport,
@@ -159,30 +159,6 @@ class MCPServer {
159
159
  this.sendErrorResponse(res, 500, `Failed to initialize: ${error}`);
160
160
  }
161
161
  }
162
- /**
163
- * Registers all available tools with the MCP server
164
- */
165
- registerTools() {
166
- try {
167
- console.log("Registering MCP tools...");
168
- const tools = [
169
- registerSystemTools,
170
- registerIndexTools,
171
- registerSearchTools,
172
- registerSettingsTools,
173
- registerDocumentTools,
174
- registerTaskTools,
175
- registerVectorTools,
176
- ];
177
- tools.forEach((registerFn) => registerFn(this.server));
178
- console.log("Successfully registered all tools");
179
- return true;
180
- }
181
- catch (error) {
182
- console.error("Failed to register tools:", error);
183
- return false;
184
- }
185
- }
186
162
  /**
187
163
  * Sends a notification about tool list changes
188
164
  */
@@ -226,7 +202,8 @@ class MCPServer {
226
202
  * Extracts session ID from request headers
227
203
  */
228
204
  extractSessionId(req) {
229
- return req.headers[this.SESSION_ID_HEADER_NAME.toLowerCase()];
205
+ const headerValue = req.headers[this.SESSION_ID_HEADER_NAME.toLowerCase()];
206
+ return Array.isArray(headerValue) ? headerValue[0] : headerValue;
230
207
  }
231
208
  /**
232
209
  * Updates the activity timestamp for a session
@@ -241,7 +218,9 @@ class MCPServer {
241
218
  * Sends an error response with the specified status code and message
242
219
  */
243
220
  sendErrorResponse(res, status, message) {
244
- res.status(status).json(createErrorResponse(message));
221
+ res.statusCode = status;
222
+ res.setHeader("Content-Type", "application/json");
223
+ res.end(JSON.stringify(createErrorResponse(message)));
245
224
  }
246
225
  /**
247
226
  * Starts the session cleanup process
@@ -282,102 +261,163 @@ class MCPServer {
282
261
  }
283
262
  }
284
263
  /**
285
- * Initialize the MCP server with HTTP transport
264
+ * Initialize the MCP server with HTTP transport using Vite
286
265
  */
287
- const initServerHTTPTransport = () => {
288
- const config = DEFAULT_CONFIG;
266
+ const initServerHTTPTransport = async () => {
267
+ const config = {
268
+ ...DEFAULT_CONFIG,
269
+ httpPort: process.env.MCP_HTTP_PORT
270
+ ? parseInt(process.env.MCP_HTTP_PORT, 10)
271
+ : DEFAULT_CONFIG.httpPort,
272
+ mcpEndpoint: process.env.MCP_ENDPOINT || DEFAULT_CONFIG.mcpEndpoint,
273
+ serverName: process.env.MCP_SERVER_NAME || DEFAULT_CONFIG.serverName,
274
+ serverVersion: process.env.MCP_SERVER_VERSION || DEFAULT_CONFIG.serverVersion,
275
+ sessionTimeout: process.env.MCP_SESSION_TIMEOUT
276
+ ? parseInt(process.env.MCP_SESSION_TIMEOUT, 10)
277
+ : DEFAULT_CONFIG.sessionTimeout,
278
+ sessionCleanupInterval: process.env.MCP_SESSION_CLEANUP_INTERVAL
279
+ ? parseInt(process.env.MCP_SESSION_CLEANUP_INTERVAL, 10)
280
+ : DEFAULT_CONFIG.sessionCleanupInterval,
281
+ };
289
282
  const serverInstance = new McpServer({
290
283
  name: config.serverName,
291
284
  version: config.serverVersion,
292
285
  });
286
+ // Register all tools
287
+ registerIndexTools(serverInstance);
288
+ registerDocumentTools(serverInstance);
289
+ registerSearchTools(serverInstance);
290
+ registerSettingsTools(serverInstance);
291
+ registerVectorTools(serverInstance);
292
+ registerSystemTools(serverInstance);
293
+ registerTaskTools(serverInstance);
293
294
  const server = new MCPServer(serverInstance, config);
294
- const app = express();
295
- app.use(express.json());
296
- // Configure CORS and preflight handling
297
- app.use((req, res, next) => {
298
- res.header("Access-Control-Allow-Origin", "*");
299
- res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
300
- res.header("Access-Control-Allow-Headers", `Origin, X-Requested-With, Content-Type, Accept, ${server["SESSION_ID_HEADER_NAME"]}`);
301
- if (req.method === "OPTIONS") {
302
- res.sendStatus(200);
303
- return;
304
- }
305
- next();
306
- });
307
- // Set up routes
308
- const router = express.Router();
309
- router.post(config.mcpEndpoint, async (req, res) => {
310
- console.log(`Received POST request to ${config.mcpEndpoint}`);
311
- await server.handlePostRequest(req, res);
312
- });
313
- router.get(config.mcpEndpoint, async (req, res) => {
314
- console.log(`Received GET request to ${config.mcpEndpoint}`);
315
- await server.handleGetRequest(req, res);
316
- });
317
- app.use("/", router);
318
- // Start the server
319
- const httpServer = app.listen(config.httpPort, () => {
320
- console.log("Meilisearch MCP Server is running on http transport:", `http://localhost:${config.httpPort}${config.mcpEndpoint}`);
321
- });
322
- // Handle server shutdown
323
- process.on("SIGINT", async () => {
324
- console.log("Received SIGINT signal");
325
- server.shutdown();
326
- httpServer.close(() => {
327
- console.log("HTTP server closed");
295
+ const isPluginMode = process.env.VITE_MCP_PLUGIN_ID !== undefined;
296
+ let vite;
297
+ if (!isPluginMode) {
298
+ vite = await createViteServer({
299
+ server: {
300
+ port: config.httpPort,
301
+ middlewareMode: true,
302
+ },
303
+ });
304
+ // Add CORS middleware
305
+ vite.middlewares.use((req, res, next) => {
306
+ res.setHeader("Access-Control-Allow-Origin", "*");
307
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
308
+ res.setHeader("Access-Control-Allow-Headers", `Origin, X-Requested-With, Content-Type, Accept, ${server["SESSION_ID_HEADER_NAME"]}`);
309
+ if (req.method === "OPTIONS") {
310
+ res.statusCode = 200;
311
+ res.end();
312
+ return;
313
+ }
314
+ next();
315
+ });
316
+ vite.middlewares.use(async (req, res, next) => {
317
+ const url = req.url || "/";
318
+ if (url.startsWith(config.mcpEndpoint)) {
319
+ if (req.method === "GET") {
320
+ await server.handleGetRequest(req, res);
321
+ }
322
+ else if (req.method === "POST") {
323
+ let body = "";
324
+ req.on("data", (chunk) => {
325
+ body += chunk.toString();
326
+ });
327
+ req.on("end", async () => {
328
+ try {
329
+ const jsonBody = JSON.parse(body);
330
+ await server.handlePostRequest(req, res, jsonBody);
331
+ }
332
+ catch (error) {
333
+ console.error("Error parsing request body:", error);
334
+ res.statusCode = 400;
335
+ res.end(JSON.stringify(createErrorResponse("Invalid JSON body")));
336
+ }
337
+ });
338
+ }
339
+ else {
340
+ next();
341
+ }
342
+ }
343
+ else {
344
+ next();
345
+ }
346
+ });
347
+ console.log("Meilisearch MCP Server is running on Vite HTTP transport (standalone mode):", `http://localhost:${config.httpPort}${config.mcpEndpoint}`);
348
+ // Handle server shutdown in standalone mode
349
+ process.on("SIGINT", async () => {
350
+ console.log("Received SIGINT signal");
351
+ server.shutdown();
352
+ if (vite) {
353
+ await vite.close();
354
+ console.log("Vite server closed");
355
+ }
328
356
  process.exit(0);
329
357
  });
330
- // Force exit after timeout
331
- setTimeout(() => {
332
- console.log("Forcing process exit");
333
- process.exit(1);
334
- }, 5000);
335
- });
358
+ }
359
+ else {
360
+ console.log("Meilisearch MCP Server is running on Vite HTTP transport (plugin mode):", `${config.mcpEndpoint}`);
361
+ }
362
+ // Return both server instances for proper cleanup
363
+ return { mcpServer: server, viteServer: vite };
336
364
  };
337
365
  /**
338
366
  * Initialize the MCP server with stdio transport
367
+ * @returns MCP server instance
339
368
  */
340
369
  const initServerStdioTransport = async () => {
341
- const config = DEFAULT_CONFIG;
342
- const server = new McpServer({
370
+ // Use environment variables if available, otherwise use defaults
371
+ const config = {
372
+ ...DEFAULT_CONFIG,
373
+ serverName: process.env.MCP_SERVER_NAME || DEFAULT_CONFIG.serverName,
374
+ serverVersion: process.env.MCP_SERVER_VERSION || DEFAULT_CONFIG.serverVersion,
375
+ };
376
+ const serverInstance = new McpServer({
343
377
  name: config.serverName,
344
378
  version: config.serverVersion,
345
379
  });
346
380
  // Register all tools
347
- registerIndexTools(server);
348
- registerDocumentTools(server);
349
- registerSearchTools(server);
350
- registerSettingsTools(server);
351
- registerVectorTools(server);
352
- registerSystemTools(server);
353
- registerTaskTools(server);
381
+ registerIndexTools(serverInstance);
382
+ registerDocumentTools(serverInstance);
383
+ registerSearchTools(serverInstance);
384
+ registerSettingsTools(serverInstance);
385
+ registerVectorTools(serverInstance);
386
+ registerSystemTools(serverInstance);
387
+ registerTaskTools(serverInstance);
388
+ // Create MCPServer instance
389
+ const server = new MCPServer(serverInstance, config);
354
390
  // Connect stdio transport
355
391
  const transport = new StdioServerTransport();
356
- await server.connect(transport);
392
+ await serverInstance.connect(transport);
357
393
  console.log("Meilisearch MCP Server is running on stdio transport");
358
394
  // Handle process termination
359
395
  process.on("SIGINT", () => {
360
396
  console.log("Shutting down stdio server...");
361
397
  process.exit(0);
362
398
  });
399
+ return server;
363
400
  };
364
401
  /**
365
402
  * Initialize the MCP server with the specified transport
366
403
  * @param transport The transport type to use ("stdio" or "http")
404
+ * @returns A promise that resolves to the server instances
367
405
  * @throws Error if the transport type is unsupported
368
406
  */
369
- export const initServer = (transport) => {
370
- switch (transport) {
371
- case "stdio":
372
- initServerStdioTransport().catch((error) => {
373
- console.error("Fatal error initializing stdio transport:", error);
374
- process.exit(1);
375
- });
376
- break;
377
- case "http":
378
- initServerHTTPTransport();
379
- break;
380
- default:
381
- throw new Error(`Unsupported transport type: ${transport}`);
407
+ export const initServer = async (transport) => {
408
+ try {
409
+ switch (transport) {
410
+ case "stdio":
411
+ const stdioServer = await initServerStdioTransport();
412
+ return { mcpServer: stdioServer };
413
+ case "http":
414
+ return await initServerHTTPTransport();
415
+ default:
416
+ throw new Error(`Unsupported transport type: ${transport}`);
417
+ }
418
+ }
419
+ catch (error) {
420
+ console.error(`Fatal error initializing ${transport} transport:`, error);
421
+ throw error;
382
422
  }
383
423
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-meilisearch",
3
- "version": "1.0.3",
3
+ "version": "1.0.6",
4
4
  "description": "Model Context Protocol (MCP) implementation for Meilisearch",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -24,17 +24,12 @@
24
24
  "dependencies": {
25
25
  "@modelcontextprotocol/sdk": "^1.10.1",
26
26
  "axios": "^1.9.0",
27
- "express": "^5.1.0",
28
- "vue": "^3.5.13",
27
+ "vite": "^6.3.5",
29
28
  "zod": "^3.24.4"
30
29
  },
31
30
  "devDependencies": {
32
- "@types/express": "^5.0.1",
33
31
  "@types/node": "^22.14.0",
34
- "@vitejs/plugin-vue": "^5.2.3",
35
- "@vue/tsconfig": "^0.7.0",
36
- "typescript": "^5.8.3",
37
- "vite": "^6.3.5"
32
+ "typescript": "^5.8.3"
38
33
  },
39
34
  "engines": {
40
35
  "node": ">=20.12.2",