mcp-meilisearch 1.0.25 → 1.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -110,7 +110,7 @@ The package also exports the MCPClient class for client-side integration:
110
110
  import { MCPClient } from "mcp-meilisearch/client";
111
111
 
112
112
  const client = new MCPClient("mcp-meilisearch-client");
113
- await client.connectToServer("http://localhost:3000/mcp");
113
+ await client.connectToServer("http://localhost:4995/mcp");
114
114
 
115
115
  // Call a tool
116
116
  const result = await client.callTool("search-across-all-indexes", {
@@ -0,0 +1,4 @@
1
+ import { AzureFunction } from "@azure/functions";
2
+ declare const httpTrigger: AzureFunction;
3
+ export default httpTrigger;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/azure/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAwB,MAAM,kBAAkB,CAAC;AAsFvE,QAAA,MAAM,WAAW,EAAE,aAgHlB,CAAC;AA8BF,eAAe,WAAW,CAAC"}
@@ -0,0 +1,196 @@
1
+ import { IncomingMessage } from "http";
2
+ import { randomUUID } from "node:crypto";
3
+ import { initServer } from "../server.js";
4
+ import { configHandler } from "../utils/config-handler.js";
5
+ import { createErrorResponse } from "../utils/error-handler.js";
6
+ const SESSION_ID_HEADER_NAME = "mcp-session-id";
7
+ const SESSION_TIMEOUT = Number(process.env.SESSION_TIMEOUT) || 3600000;
8
+ let mcpServer = null;
9
+ const sessions = new Map();
10
+ const baseHeaders = {
11
+ "Access-Control-Allow-Origin": process.env.ALLOWED_ORIGINS || "*",
12
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
13
+ "Access-Control-Allow-Headers": `Origin, X-Requested-With, Content-Type, Accept, ${SESSION_ID_HEADER_NAME}`,
14
+ };
15
+ function adaptRequest(req) {
16
+ const adaptedReq = Object.create(IncomingMessage.prototype);
17
+ adaptedReq.headers = req.headers;
18
+ adaptedReq.method = req.method;
19
+ adaptedReq.url = req.url;
20
+ adaptedReq.body = req.body;
21
+ return adaptedReq;
22
+ }
23
+ function createResponseAdapter(context, extraHeaders = {}) {
24
+ const res = {
25
+ headers: new Map(),
26
+ statusCode: 200,
27
+ bodyChunks: [],
28
+ setHeader(name, value) {
29
+ this.headers.set(name, value);
30
+ return this;
31
+ },
32
+ writeHead(statusCode, headers) {
33
+ this.statusCode = statusCode;
34
+ if (headers && !Array.isArray(headers)) {
35
+ Object.entries(headers).forEach(([k, v]) => this.headers.set(k, v));
36
+ }
37
+ return this;
38
+ },
39
+ write(chunk) {
40
+ if (chunk)
41
+ this.bodyChunks.push(chunk);
42
+ return this;
43
+ },
44
+ end(data) {
45
+ if (data)
46
+ this.bodyChunks.push(data);
47
+ const responseHeaders = {};
48
+ this.headers.forEach((value, key) => {
49
+ responseHeaders[key] = value;
50
+ });
51
+ context.res = {
52
+ status: this.statusCode,
53
+ headers: { ...responseHeaders, ...baseHeaders, ...extraHeaders },
54
+ body: this.bodyChunks.join(""),
55
+ };
56
+ return this;
57
+ },
58
+ };
59
+ return res;
60
+ }
61
+ function sendError(context, status, message) {
62
+ context.res = {
63
+ status,
64
+ headers: { "Content-Type": "application/json", ...baseHeaders },
65
+ body: JSON.stringify(createErrorResponse(message)),
66
+ };
67
+ }
68
+ const httpTrigger = async function (context, req) {
69
+ if (!mcpServer) {
70
+ try {
71
+ const options = {
72
+ httpPort: 0,
73
+ transport: "http",
74
+ mcpEndpoint: "/api/mcp",
75
+ meilisearchApiKey: process.env.MEILISEARCH_API_KEY || "",
76
+ meilisearchHost: process.env.MEILISEARCH_HOST || "http://localhost:7700",
77
+ };
78
+ configHandler.setMeilisearchHost(options.meilisearchHost);
79
+ configHandler.setMeilisearchApiKey(options.meilisearchApiKey);
80
+ const server = await initServer("http", options);
81
+ if (server.mcpServer) {
82
+ mcpServer = server.mcpServer;
83
+ context.log("MCP server initialized successfully");
84
+ }
85
+ else {
86
+ throw new Error("Failed to initialize MCP server");
87
+ }
88
+ }
89
+ catch (error) {
90
+ sendError(context, 503, "Failed to initialize MCP server");
91
+ return;
92
+ }
93
+ }
94
+ if (req.method === "OPTIONS") {
95
+ context.res = { status: 200, headers: baseHeaders, body: "" };
96
+ return;
97
+ }
98
+ const sessionId = req.headers[SESSION_ID_HEADER_NAME.toLowerCase()];
99
+ try {
100
+ if (req.method === "GET") {
101
+ if (!sessionId || !sessions.has(sessionId)) {
102
+ sendError(context, 400, "Bad Request: invalid session ID");
103
+ return;
104
+ }
105
+ const session = sessions.get(sessionId);
106
+ session.lastActivity = Date.now();
107
+ try {
108
+ const res = createResponseAdapter(context);
109
+ await mcpServer.handleGetRequest(adaptRequest(req), res);
110
+ if (!context.res)
111
+ res.end();
112
+ }
113
+ catch (error) {
114
+ context.log.error(`Error handling GET request: ${error}`);
115
+ sendError(context, 500, `Error in GET request: ${error}`);
116
+ }
117
+ return;
118
+ }
119
+ if (req.method === "POST") {
120
+ if (sessionId && sessions.has(sessionId)) {
121
+ const session = sessions.get(sessionId);
122
+ session.lastActivity = Date.now();
123
+ try {
124
+ const res = createResponseAdapter(context);
125
+ await mcpServer.handlePostRequest(adaptRequest(req), res, req.body);
126
+ if (!context.res)
127
+ res.end();
128
+ }
129
+ catch (error) {
130
+ context.log.error(`Error handling POST request: ${error}`);
131
+ sendError(context, 500, `Error in POST request: ${error}`);
132
+ }
133
+ return;
134
+ }
135
+ if (mcpServer.isInitializeRequest?.(req.body)) {
136
+ const newSessionId = randomUUID();
137
+ sessions.set(newSessionId, {
138
+ transport: null,
139
+ lastActivity: Date.now(),
140
+ });
141
+ try {
142
+ const res = createResponseAdapter(context, {
143
+ [SESSION_ID_HEADER_NAME]: newSessionId,
144
+ "Access-Control-Expose-Headers": SESSION_ID_HEADER_NAME,
145
+ });
146
+ await mcpServer.handlePostRequest(adaptRequest(req), res, req.body);
147
+ if (!context.res)
148
+ res.end();
149
+ context.log(`New session created: ${newSessionId}`);
150
+ }
151
+ catch (error) {
152
+ context.log.error(`Error initializing session: ${error}`);
153
+ sessions.delete(newSessionId);
154
+ sendError(context, 500, `Error initializing session: ${error}`);
155
+ }
156
+ return;
157
+ }
158
+ sendError(context, 400, "Invalid request: missing session ID or not an initialize request");
159
+ return;
160
+ }
161
+ sendError(context, 405, "Method not allowed");
162
+ }
163
+ catch (error) {
164
+ context.log.error(`Error handling MCP request: ${error}`);
165
+ sendError(context, 500, `Internal server error: ${error}`);
166
+ }
167
+ };
168
+ const cleanupInterval = setInterval(() => {
169
+ const now = Date.now();
170
+ for (const [id, info] of sessions.entries()) {
171
+ if (now - info.lastActivity > SESSION_TIMEOUT) {
172
+ try {
173
+ if (info.transport)
174
+ info.transport.close();
175
+ sessions.delete(id);
176
+ }
177
+ catch (error) {
178
+ console.error(`Error cleaning up session ${id}:`, error);
179
+ }
180
+ }
181
+ }
182
+ }, 60000);
183
+ if (typeof process !== "undefined" && process.env.FUNCTIONS_WORKER_RUNTIME) {
184
+ process.on("SIGTERM", () => {
185
+ clearInterval(cleanupInterval);
186
+ if (mcpServer && typeof mcpServer.shutdown === "function") {
187
+ try {
188
+ mcpServer.shutdown();
189
+ }
190
+ catch (error) {
191
+ console.error(`Error shutting down MCP server: ${error}`);
192
+ }
193
+ }
194
+ });
195
+ }
196
+ export default httpTrigger;
package/dist/client.d.ts CHANGED
@@ -7,14 +7,14 @@ export declare class MCPClient {
7
7
  private client;
8
8
  private tries;
9
9
  private transport;
10
- private onToolsUpdatedCallback;
10
+ private toolsUpdatedCallback;
11
11
  constructor(serverName: string);
12
- setOnToolsUpdatedCallback(callback: (tools: Array<{
12
+ onToolsUpdatedCallback(callback: (tools: Array<{
13
13
  name: string;
14
14
  description: string;
15
15
  }>) => void): void;
16
16
  connectToServer(serverUrl: string): Promise<void>;
17
- listTools(): Promise<void>;
17
+ private listTools;
18
18
  private setUpNotifications;
19
19
  callTool(name: string, args?: Record<string, any>): Promise<{
20
20
  success: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,qBAAa,SAAS;IACpB,WAAW,EAAE,OAAO,CAAS;IAC7B,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAM;IAEpD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,sBAAsB,CAEd;gBAEJ,UAAU,EAAE,MAAM;IAIvB,yBAAyB,CAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,IAAI;IAKnE,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBjD,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBhC,OAAO,CAAC,kBAAkB;IAWpB,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;IAoCF,OAAO,CAAC,cAAc;IAKhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,qBAAa,SAAS;IACpB,WAAW,EAAE,OAAO,CAAS;IAC7B,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAM;IAEpD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,oBAAoB,CAEZ;gBAEJ,UAAU,EAAE,MAAM;IAIvB,sBAAsB,CAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,IAAI;IAKnE,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAsBzC,SAAS;IAuBvB,OAAO,CAAC,kBAAkB;IAWpB,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;IAoCF,OAAO,CAAC,cAAc;IAKhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}
package/dist/client.js CHANGED
@@ -7,12 +7,12 @@ export class MCPClient {
7
7
  client;
8
8
  tries = 0;
9
9
  transport = null;
10
- onToolsUpdatedCallback = null;
10
+ toolsUpdatedCallback = null;
11
11
  constructor(serverName) {
12
12
  this.client = new Client({ name: serverName, version: "1.0.0" });
13
13
  }
14
- setOnToolsUpdatedCallback(callback) {
15
- this.onToolsUpdatedCallback = callback;
14
+ onToolsUpdatedCallback(callback) {
15
+ this.toolsUpdatedCallback = callback;
16
16
  }
17
17
  async connectToServer(serverUrl) {
18
18
  const url = new URL(serverUrl);
@@ -54,8 +54,8 @@ export class MCPClient {
54
54
  this.tools = [];
55
55
  }
56
56
  finally {
57
- if (this.onToolsUpdatedCallback) {
58
- this.onToolsUpdatedCallback([...this.tools]);
57
+ if (this.toolsUpdatedCallback) {
58
+ this.toolsUpdatedCallback([...this.tools]);
59
59
  }
60
60
  }
61
61
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-meilisearch",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "Model Context Protocol (MCP) implementation for Meilisearch",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/dist/browser.d.ts DELETED
@@ -1,14 +0,0 @@
1
- /**
2
- * This file provides browser-compatible exports for the MCP client
3
- * It avoids importing any Node.js specific modules
4
- */
5
- import { ServerOptions } from './types/options.js';
6
- export { MCPClient } from './client.js';
7
- export type { ServerOptions } from './types/options.js';
8
- /**
9
- * Browser-compatible version of mcpMeilisearchServer
10
- * In browser environments, this sets up the configuration but doesn't start a server
11
- */
12
- export declare const mcpMeilisearchServer: (options?: ServerOptions) => Promise<null>;
13
- export default mcpMeilisearchServer;
14
- //# sourceMappingURL=browser.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAS,aAGR,KACA,OAAO,CAAC,IAAI,CAOd,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
package/dist/browser.js DELETED
@@ -1,22 +0,0 @@
1
- /**
2
- * This file provides browser-compatible exports for the MCP client
3
- * It avoids importing any Node.js specific modules
4
- */
5
- import { configHandler } from "./utils/config-handler.js";
6
- // Export only what's needed for browser clients
7
- export { MCPClient } from './client.js';
8
- /**
9
- * Browser-compatible version of mcpMeilisearchServer
10
- * In browser environments, this sets up the configuration but doesn't start a server
11
- */
12
- export const mcpMeilisearchServer = async (options = {
13
- meilisearchApiKey: "",
14
- meilisearchHost: "http://localhost:7700",
15
- }) => {
16
- // Still set configuration values for potential client usage
17
- configHandler.setMeilisearchHost(options.meilisearchHost);
18
- configHandler.setMeilisearchApiKey(options.meilisearchApiKey);
19
- console.warn('mcpMeilisearchServer cannot be run in a browser environment. Use MCPClient instead.');
20
- return null;
21
- };
22
- export default mcpMeilisearchServer;