mcp-meilisearch 1.3.9 → 1.4.0
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 +13 -4
- package/dist/client.d.ts +9 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +14 -2
- package/dist/tools/meilisearch/search-tools.d.ts.map +1 -1
- package/dist/tools/meilisearch/search-tools.js +64 -65
- package/dist/types/enums.d.ts +5 -0
- package/dist/types/enums.d.ts.map +1 -0
- package/dist/types/enums.js +5 -0
- package/dist/utils/ai-handler.d.ts +2 -1
- package/dist/utils/ai-handler.d.ts.map +1 -1
- package/dist/utils/ai-handler.js +11 -8
- package/dist/utils/response-handler.js +30 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -92,7 +92,7 @@ const client = new MCPClient("mcp-meilisearch-client");
|
|
|
92
92
|
|
|
93
93
|
await client.connectToServer("http://localhost:4995/mcp");
|
|
94
94
|
|
|
95
|
-
const result = await client.callTool("search
|
|
95
|
+
const result = await client.callTool("global-search", {
|
|
96
96
|
q: "search kiosco antonio",
|
|
97
97
|
});
|
|
98
98
|
|
|
@@ -106,7 +106,16 @@ console.log(`Results: ${JSON.stringify(result.data)}`);
|
|
|
106
106
|
|
|
107
107
|
#### AI Inference Client Methods
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
#### `callToolWithAI(query, options)`
|
|
110
|
+
|
|
111
|
+
Processes a user query through AI to determine and execute the most appropriate tool.
|
|
112
|
+
|
|
113
|
+
**Parameters:**
|
|
114
|
+
|
|
115
|
+
- `query`: String - The user's query or request to be processed
|
|
116
|
+
- `options`: Object (Optional) - Configuration options
|
|
117
|
+
- `specificTools`: String[] (Optional) - Restricts tool selection to this list of tool names
|
|
118
|
+
- `justReasoning`: Boolean (Optional) - When set to `true`, returns only the AI's reasoning without executing the selected tool
|
|
110
119
|
|
|
111
120
|
### Starting the Server
|
|
112
121
|
|
|
@@ -304,9 +313,9 @@ The MCP server exposes various tools that allow you to interact with Meilisearch
|
|
|
304
313
|
|
|
305
314
|
- **Description**: Perform multiple searches in one request.
|
|
306
315
|
- **Parameters**:
|
|
307
|
-
- `
|
|
316
|
+
- `queries` (string, required): JSON array of search queries, each containing the same parameters as the `search` tool.
|
|
308
317
|
|
|
309
|
-
#### search
|
|
318
|
+
#### global-search
|
|
310
319
|
|
|
311
320
|
- **Description**: Search for a term across all available Meilisearch indexes and return combined results.
|
|
312
321
|
- **Parameters**:
|
package/dist/client.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export declare class MCPClient {
|
|
|
46
46
|
* Parses and processes the response from the server
|
|
47
47
|
* @param name The name of the tool to call
|
|
48
48
|
* @param args Optional arguments to pass to the tool
|
|
49
|
+
* @throws Error if the tool call fails
|
|
49
50
|
* @returns Object containing success status and either data or error message
|
|
50
51
|
*/
|
|
51
52
|
callTool(name: string, args?: Record<string, any>): Promise<{
|
|
@@ -56,10 +57,16 @@ export declare class MCPClient {
|
|
|
56
57
|
/**
|
|
57
58
|
* Process a user query through the AI to determine which tool to use
|
|
58
59
|
* @param query The user's query
|
|
59
|
-
* @param
|
|
60
|
+
* @param options Options for the AI processing
|
|
61
|
+
* @param options.specificTools Optional array of specific tool names to consider
|
|
62
|
+
* @param options.justReasoning If true, only returns the reasoning without calling the tool
|
|
63
|
+
* @throws Error if AI inference fails
|
|
60
64
|
* @returns The result of calling the selected tool, or an error
|
|
61
65
|
*/
|
|
62
|
-
callToolWithAI(query: string,
|
|
66
|
+
callToolWithAI(query: string, options?: {
|
|
67
|
+
specificTools?: string[];
|
|
68
|
+
justReasoning?: boolean;
|
|
69
|
+
}): Promise<{
|
|
63
70
|
success: boolean;
|
|
64
71
|
data?: any;
|
|
65
72
|
error?: string;
|
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,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;IA0BvB,OAAO,CAAC,kBAAkB;IAW1B
|
|
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;IA0BvB,OAAO,CAAC,kBAAkB;IAW1B;;;;;;;OAOG;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;;;;;;;;OAQG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAO,GAClE,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;IA6CF,OAAO,CAAC,cAAc;IAKtB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}
|
package/dist/client.js
CHANGED
|
@@ -100,6 +100,7 @@ export class MCPClient {
|
|
|
100
100
|
* Parses and processes the response from the server
|
|
101
101
|
* @param name The name of the tool to call
|
|
102
102
|
* @param args Optional arguments to pass to the tool
|
|
103
|
+
* @throws Error if the tool call fails
|
|
103
104
|
* @returns Object containing success status and either data or error message
|
|
104
105
|
*/
|
|
105
106
|
async callTool(name, args) {
|
|
@@ -143,10 +144,14 @@ export class MCPClient {
|
|
|
143
144
|
/**
|
|
144
145
|
* Process a user query through the AI to determine which tool to use
|
|
145
146
|
* @param query The user's query
|
|
146
|
-
* @param
|
|
147
|
+
* @param options Options for the AI processing
|
|
148
|
+
* @param options.specificTools Optional array of specific tool names to consider
|
|
149
|
+
* @param options.justReasoning If true, only returns the reasoning without calling the tool
|
|
150
|
+
* @throws Error if AI inference fails
|
|
147
151
|
* @returns The result of calling the selected tool, or an error
|
|
148
152
|
*/
|
|
149
|
-
async callToolWithAI(query,
|
|
153
|
+
async callToolWithAI(query, options = {}) {
|
|
154
|
+
const { specificTools, justReasoning } = options;
|
|
150
155
|
try {
|
|
151
156
|
const result = await this.callTool("process-ai-query", {
|
|
152
157
|
query,
|
|
@@ -161,6 +166,13 @@ export class MCPClient {
|
|
|
161
166
|
error: "AI could not determine which tool to use for this query",
|
|
162
167
|
};
|
|
163
168
|
}
|
|
169
|
+
if (justReasoning) {
|
|
170
|
+
return {
|
|
171
|
+
reasoning,
|
|
172
|
+
success: true,
|
|
173
|
+
toolUsed: toolName,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
164
176
|
const toolResult = await this.callTool(toolName, parameters);
|
|
165
177
|
return {
|
|
166
178
|
...toolResult,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-tools.d.ts","sourceRoot":"","sources":["../../../src/tools/meilisearch/search-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"search-tools.d.ts","sourceRoot":"","sources":["../../../src/tools/meilisearch/search-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwFpE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,SAAS,SA6NpD,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -1,6 +1,59 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import apiClient from "../../utils/api-handler.js";
|
|
3
3
|
import { createErrorResponse } from "../../utils/error-handler.js";
|
|
4
|
+
const SearchParamsSchema = {
|
|
5
|
+
indexUid: z.string().describe("Unique identifier of the index"),
|
|
6
|
+
q: z.string().describe("Search query"),
|
|
7
|
+
limit: z
|
|
8
|
+
.number()
|
|
9
|
+
.min(1)
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Maximum number of results to return (default: 20)"),
|
|
12
|
+
offset: z
|
|
13
|
+
.number()
|
|
14
|
+
.min(0)
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Number of results to skip (default: 0)"),
|
|
17
|
+
filter: z.string().optional().describe("Filter query to apply"),
|
|
18
|
+
sort: z
|
|
19
|
+
.array(z.string())
|
|
20
|
+
.optional()
|
|
21
|
+
.describe('Attributes to sort by, e.g. ["price:asc"]'),
|
|
22
|
+
facets: z.array(z.string()).optional().describe("Facets to return"),
|
|
23
|
+
attributesToRetrieve: z
|
|
24
|
+
.array(z.string())
|
|
25
|
+
.optional()
|
|
26
|
+
.default(["*"])
|
|
27
|
+
.describe("Attributes to include in results"),
|
|
28
|
+
attributesToCrop: z
|
|
29
|
+
.array(z.string())
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Attributes to crop"),
|
|
32
|
+
cropLength: z
|
|
33
|
+
.number()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Length at which to crop cropped attributes"),
|
|
36
|
+
attributesToHighlight: z
|
|
37
|
+
.array(z.string())
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("Attributes to highlight"),
|
|
40
|
+
highlightPreTag: z
|
|
41
|
+
.string()
|
|
42
|
+
.optional()
|
|
43
|
+
.describe("Tag to insert before highlighted text"),
|
|
44
|
+
highlightPostTag: z
|
|
45
|
+
.string()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe("Tag to insert after highlighted text"),
|
|
48
|
+
showMatchesPosition: z
|
|
49
|
+
.boolean()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe("Whether to include match positions in results"),
|
|
52
|
+
matchingStrategy: z
|
|
53
|
+
.string()
|
|
54
|
+
.optional()
|
|
55
|
+
.describe("Matching strategy: 'all' or 'last'"),
|
|
56
|
+
};
|
|
4
57
|
/**
|
|
5
58
|
* Register search tools with the MCP server
|
|
6
59
|
*
|
|
@@ -8,59 +61,7 @@ import { createErrorResponse } from "../../utils/error-handler.js";
|
|
|
8
61
|
*/
|
|
9
62
|
export const registerSearchTools = (server) => {
|
|
10
63
|
// Search in an index
|
|
11
|
-
server.tool("search", "Search for documents in a Meilisearch index", {
|
|
12
|
-
indexUid: z.string().describe("Unique identifier of the index"),
|
|
13
|
-
q: z.string().describe("Search query"),
|
|
14
|
-
limit: z
|
|
15
|
-
.number()
|
|
16
|
-
.min(1)
|
|
17
|
-
.optional()
|
|
18
|
-
.describe("Maximum number of results to return (default: 20)"),
|
|
19
|
-
offset: z
|
|
20
|
-
.number()
|
|
21
|
-
.min(0)
|
|
22
|
-
.optional()
|
|
23
|
-
.describe("Number of results to skip (default: 0)"),
|
|
24
|
-
filter: z.string().optional().describe("Filter query to apply"),
|
|
25
|
-
sort: z
|
|
26
|
-
.array(z.string())
|
|
27
|
-
.optional()
|
|
28
|
-
.describe('Attributes to sort by, e.g. ["price:asc"]'),
|
|
29
|
-
facets: z.array(z.string()).optional().describe("Facets to return"),
|
|
30
|
-
attributesToRetrieve: z
|
|
31
|
-
.array(z.string())
|
|
32
|
-
.optional()
|
|
33
|
-
.default(["*"])
|
|
34
|
-
.describe("Attributes to include in results"),
|
|
35
|
-
attributesToCrop: z
|
|
36
|
-
.array(z.string())
|
|
37
|
-
.optional()
|
|
38
|
-
.describe("Attributes to crop"),
|
|
39
|
-
cropLength: z
|
|
40
|
-
.number()
|
|
41
|
-
.optional()
|
|
42
|
-
.describe("Length at which to crop cropped attributes"),
|
|
43
|
-
attributesToHighlight: z
|
|
44
|
-
.array(z.string())
|
|
45
|
-
.optional()
|
|
46
|
-
.describe("Attributes to highlight"),
|
|
47
|
-
highlightPreTag: z
|
|
48
|
-
.string()
|
|
49
|
-
.optional()
|
|
50
|
-
.describe("Tag to insert before highlighted text"),
|
|
51
|
-
highlightPostTag: z
|
|
52
|
-
.string()
|
|
53
|
-
.optional()
|
|
54
|
-
.describe("Tag to insert after highlighted text"),
|
|
55
|
-
showMatchesPosition: z
|
|
56
|
-
.boolean()
|
|
57
|
-
.optional()
|
|
58
|
-
.describe("Whether to include match positions in results"),
|
|
59
|
-
matchingStrategy: z
|
|
60
|
-
.string()
|
|
61
|
-
.optional()
|
|
62
|
-
.describe("Matching strategy: 'all' or 'last'"),
|
|
63
|
-
}, { category: "meilisearch" }, async ({ indexUid, q, limit, offset, filter, sort, facets, attributesToRetrieve, attributesToCrop, cropLength, attributesToHighlight, highlightPreTag, highlightPostTag, showMatchesPosition, matchingStrategy, }) => {
|
|
64
|
+
server.tool("search", "Search for documents in a Meilisearch index", SearchParamsSchema, { category: "meilisearch" }, async ({ indexUid, q, limit, offset, filter, sort, facets, attributesToRetrieve, attributesToCrop, cropLength, attributesToHighlight, highlightPreTag, highlightPostTag, showMatchesPosition, matchingStrategy, }) => {
|
|
64
65
|
try {
|
|
65
66
|
const response = await apiClient.post(`/indexes/${indexUid}/search`, {
|
|
66
67
|
q,
|
|
@@ -90,22 +91,20 @@ export const registerSearchTools = (server) => {
|
|
|
90
91
|
});
|
|
91
92
|
// Multi-search across multiple indexes
|
|
92
93
|
server.tool("multi-search", "Perform multiple searches in one request", {
|
|
93
|
-
|
|
94
|
-
.
|
|
95
|
-
.describe("JSON array of search queries, each
|
|
96
|
-
}, { category: "meilisearch" }, async ({
|
|
94
|
+
queries: z
|
|
95
|
+
.array(z.object(SearchParamsSchema))
|
|
96
|
+
.describe("JSON array of search queries, each containing the same parameters as the `search` tool"),
|
|
97
|
+
}, { category: "meilisearch" }, async ({ queries }) => {
|
|
97
98
|
try {
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
// Ensure searches is an array
|
|
101
|
-
if (!Array.isArray(parsedSearches)) {
|
|
99
|
+
// Ensure queries is an array
|
|
100
|
+
if (!Array.isArray(queries)) {
|
|
102
101
|
return {
|
|
103
102
|
isError: true,
|
|
104
|
-
content: [{ type: "text", text: "
|
|
103
|
+
content: [{ type: "text", text: "Queries must be a JSON array" }],
|
|
105
104
|
};
|
|
106
105
|
}
|
|
107
106
|
// Ensure each search has at least indexUid
|
|
108
|
-
for (const search of
|
|
107
|
+
for (const search of queries) {
|
|
109
108
|
if (!search.indexUid) {
|
|
110
109
|
return {
|
|
111
110
|
isError: true,
|
|
@@ -119,7 +118,7 @@ export const registerSearchTools = (server) => {
|
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
120
|
const response = await apiClient.post("/multi-search", {
|
|
122
|
-
queries
|
|
121
|
+
queries,
|
|
123
122
|
});
|
|
124
123
|
return {
|
|
125
124
|
content: [
|
|
@@ -131,7 +130,7 @@ export const registerSearchTools = (server) => {
|
|
|
131
130
|
return createErrorResponse(error);
|
|
132
131
|
}
|
|
133
132
|
});
|
|
134
|
-
server.tool("search
|
|
133
|
+
server.tool("global-search", "Search for a term across all available Meilisearch indexes and return combined results", {
|
|
135
134
|
q: z.string().describe("Search query"),
|
|
136
135
|
limit: z
|
|
137
136
|
.number()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../src/types/enums.ts"],"names":[],"mappings":"AAAA,oBAAY,eAAe;IACzB,OAAO,iCAAiC;IACxC,IAAI,sCAAoB;CACzB"}
|
|
@@ -16,6 +16,7 @@ interface AIToolResponse {
|
|
|
16
16
|
* to use based on the user's query
|
|
17
17
|
*/
|
|
18
18
|
export declare class AIService {
|
|
19
|
+
private apiKey;
|
|
19
20
|
private model;
|
|
20
21
|
private static instance;
|
|
21
22
|
private static serverInitialized;
|
|
@@ -40,7 +41,7 @@ export declare class AIService {
|
|
|
40
41
|
* @param provider AI provider name (defaults to openai)
|
|
41
42
|
* @param model Optional model to use (defaults to gpt-3.5-turbo)
|
|
42
43
|
*/
|
|
43
|
-
initialize(apiKey: string, provider?: AiProviderNameOptions, model?: string): void;
|
|
44
|
+
initialize(apiKey: string, provider?: AiProviderNameOptions, model?: string, forceNewInit?: boolean): void;
|
|
44
45
|
/**
|
|
45
46
|
* Set the available tools that can be used by the AI
|
|
46
47
|
* @param tools Array of tools with name, description, and parameters
|
|
@@ -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":"AAKA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACjC;AAiBD,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACjC;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0B;IACjD,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwB;IACrD,OAAO,CAAC,MAAM,CAAyC;IACvD,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,EACd,YAAY,GAAE,OAAe,GAC5B,IAAI;IA6BP;;;OAGG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAIxC,iBAAiB,IAAI,OAAO;IAI5B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;;OAKG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;YAwBnB,kBAAkB;YAiClB,uBAAuB;CAiCtC"}
|
package/dist/utils/ai-handler.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OpenAI } from "openai";
|
|
2
2
|
import systemPrompt from "../prompts/system.js";
|
|
3
|
+
import { OPEN_ROUTER_API } from "../types/enums.js";
|
|
3
4
|
import { markdownToJson } from "./response-handler.js";
|
|
4
5
|
import { InferenceClient } from "@huggingface/inference";
|
|
5
6
|
/**
|
|
@@ -9,6 +10,7 @@ import { InferenceClient } from "@huggingface/inference";
|
|
|
9
10
|
* to use based on the user's query
|
|
10
11
|
*/
|
|
11
12
|
export class AIService {
|
|
13
|
+
apiKey = "";
|
|
12
14
|
model = "gpt-3.5-turbo";
|
|
13
15
|
static instance = null;
|
|
14
16
|
static serverInitialized = false;
|
|
@@ -38,26 +40,27 @@ export class AIService {
|
|
|
38
40
|
* @param provider AI provider name (defaults to openai)
|
|
39
41
|
* @param model Optional model to use (defaults to gpt-3.5-turbo)
|
|
40
42
|
*/
|
|
41
|
-
initialize(apiKey, provider = "openai", model) {
|
|
42
|
-
if (AIService.serverInitialized) {
|
|
43
|
+
initialize(apiKey, provider = "openai", model, forceNewInit = false) {
|
|
44
|
+
if (AIService.serverInitialized && !forceNewInit) {
|
|
43
45
|
console.warn("AIService has already been initialized by the server.");
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
48
|
+
this.apiKey = apiKey;
|
|
46
49
|
this.provider = provider;
|
|
47
50
|
if (model)
|
|
48
51
|
this.model = model;
|
|
49
52
|
switch (this.provider) {
|
|
50
53
|
case "openai":
|
|
51
|
-
this.client = new OpenAI({ apiKey });
|
|
54
|
+
this.client = new OpenAI({ apiKey: this.apiKey });
|
|
52
55
|
break;
|
|
53
56
|
case "openrouter":
|
|
54
57
|
this.client = new OpenAI({
|
|
55
|
-
apiKey,
|
|
56
|
-
baseURL:
|
|
58
|
+
apiKey: this.apiKey,
|
|
59
|
+
baseURL: OPEN_ROUTER_API.baseURL,
|
|
57
60
|
});
|
|
58
61
|
break;
|
|
59
62
|
case "huggingface":
|
|
60
|
-
this.client = new InferenceClient(apiKey);
|
|
63
|
+
this.client = new InferenceClient(this.apiKey);
|
|
61
64
|
break;
|
|
62
65
|
default:
|
|
63
66
|
throw new Error(`Unsupported AI provider: ${this.provider}`);
|
|
@@ -126,9 +129,9 @@ export class AIService {
|
|
|
126
129
|
{ role: "user", content: query },
|
|
127
130
|
];
|
|
128
131
|
if (this.provider === "huggingface") {
|
|
129
|
-
return this.processHuggingFaceQuery(tools, messages);
|
|
132
|
+
return await this.processHuggingFaceQuery(tools, messages);
|
|
130
133
|
}
|
|
131
|
-
return this.processOpenAIQuery(tools, messages);
|
|
134
|
+
return await this.processOpenAIQuery(tools, messages);
|
|
132
135
|
}
|
|
133
136
|
async processOpenAIQuery(tools, messages) {
|
|
134
137
|
const client = this.client;
|
|
@@ -23,7 +23,7 @@ export function markdownToJson(markdownJsonString) {
|
|
|
23
23
|
S = S.replace(/,\s*([}\]])/g, "$1");
|
|
24
24
|
try {
|
|
25
25
|
const parsedJson = JSON.parse(S);
|
|
26
|
-
return parsedJson;
|
|
26
|
+
return parseNestedJsonStrings(parsedJson);
|
|
27
27
|
}
|
|
28
28
|
catch (error) {
|
|
29
29
|
console.error("Failed to parse JSON after transformations.");
|
|
@@ -33,3 +33,32 @@ export function markdownToJson(markdownJsonString) {
|
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
function tryParseJsonString(str) {
|
|
37
|
+
try {
|
|
38
|
+
if (typeof str === "string" &&
|
|
39
|
+
((str.startsWith("[") && str.endsWith("]")) ||
|
|
40
|
+
(str.startsWith("{") && str.endsWith("}")))) {
|
|
41
|
+
return JSON.parse(str);
|
|
42
|
+
}
|
|
43
|
+
return str;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return str;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function parseNestedJsonStrings(obj) {
|
|
50
|
+
if (Array.isArray(obj)) {
|
|
51
|
+
return obj.map((item) => parseNestedJsonStrings(item));
|
|
52
|
+
}
|
|
53
|
+
else if (obj !== null && typeof obj === "object") {
|
|
54
|
+
const result = {};
|
|
55
|
+
for (const key of Object.keys(obj)) {
|
|
56
|
+
result[key] = parseNestedJsonStrings(obj[key]);
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
else if (typeof obj === "string") {
|
|
61
|
+
return tryParseJsonString(obj);
|
|
62
|
+
}
|
|
63
|
+
return obj;
|
|
64
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-meilisearch",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Model Context Protocol (MCP) implementation for Meilisearch",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"build": "tsc && tsc -p tsconfig.types.json",
|
|
27
27
|
"demo": "npm run build & npm run preview --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 minor && npm run build"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@huggingface/inference": "^3.13.1",
|