@@ -24,7 +24,9 @@ def json_serializer(obj: Any) -> str:
2424 return str (obj )
2525
2626
27- def create_server (url : str = "http://localhost:7700" , api_key : Optional [str ] = None ) -> "MeilisearchMCPServer" :
27+ def create_server (
28+ url : str = "http://localhost:7700" , api_key : Optional [str ] = None
29+ ) -> "MeilisearchMCPServer" :
2830 """Create and return a configured MeilisearchMCPServer instance"""
2931 return MeilisearchMCPServer (url , api_key )
3032
@@ -48,13 +50,15 @@ def __init__(
4850 self .server = Server ("meilisearch" )
4951 self ._setup_handlers ()
5052
51- async def update_connection (self , url : Optional [str ] = None , api_key : Optional [str ] = None ):
53+ async def update_connection (
54+ self , url : Optional [str ] = None , api_key : Optional [str ] = None
55+ ):
5256 """Update connection settings and reinitialize client if needed"""
5357 if url :
5458 self .url = url
5559 if api_key :
5660 self .api_key = api_key
57-
61+
5862 self .meili_client = MeilisearchClient (self .url , self .api_key )
5963 self .logger .info ("Updated Meilisearch connection settings" , url = self .url )
6064
@@ -171,7 +175,11 @@ async def handle_list_tools() -> list[types.Tool]:
171175 "limit" : {"type" : "integer" , "optional" : True },
172176 "offset" : {"type" : "integer" , "optional" : True },
173177 "filter" : {"type" : "string" , "optional" : True },
174- "sort" : {"type" : "array" , "items" : {"type" : "string" }, "optional" : True },
178+ "sort" : {
179+ "type" : "array" ,
180+ "items" : {"type" : "string" },
181+ "optional" : True ,
182+ },
175183 },
176184 "required" : ["query" ],
177185 },
@@ -194,20 +202,44 @@ async def handle_list_tools() -> list[types.Tool]:
194202 "limit" : {"type" : "integer" , "optional" : True },
195203 "from" : {"type" : "integer" , "optional" : True },
196204 "reverse" : {"type" : "boolean" , "optional" : True },
197- "batchUids" : {"type" : "array" , "items" : {"type" : "string" }, "optional" : True },
198- "uids" : {"type" : "array" , "items" : {"type" : "integer" }, "optional" : True },
199- "canceledBy" : {"type" : "array" , "items" : {"type" : "string" }, "optional" : True },
200- "types" : {"type" : "array" , "items" : {"type" : "string" }, "optional" : True },
201- "statuses" : {"type" : "array" , "items" : {"type" : "string" }, "optional" : True },
202- "indexUids" : {"type" : "array" , "items" : {"type" : "string" }, "optional" : True },
205+ "batchUids" : {
206+ "type" : "array" ,
207+ "items" : {"type" : "string" },
208+ "optional" : True ,
209+ },
210+ "uids" : {
211+ "type" : "array" ,
212+ "items" : {"type" : "integer" },
213+ "optional" : True ,
214+ },
215+ "canceledBy" : {
216+ "type" : "array" ,
217+ "items" : {"type" : "string" },
218+ "optional" : True ,
219+ },
220+ "types" : {
221+ "type" : "array" ,
222+ "items" : {"type" : "string" },
223+ "optional" : True ,
224+ },
225+ "statuses" : {
226+ "type" : "array" ,
227+ "items" : {"type" : "string" },
228+ "optional" : True ,
229+ },
230+ "indexUids" : {
231+ "type" : "array" ,
232+ "items" : {"type" : "string" },
233+ "optional" : True ,
234+ },
203235 "afterEnqueuedAt" : {"type" : "string" , "optional" : True },
204236 "beforeEnqueuedAt" : {"type" : "string" , "optional" : True },
205237 "afterStartedAt" : {"type" : "string" , "optional" : True },
206238 "beforeStartedAt" : {"type" : "string" , "optional" : True },
207239 "afterFinishedAt" : {"type" : "string" , "optional" : True },
208- "beforeFinishedAt" : {"type" : "string" , "optional" : True }
209- }
210- }
240+ "beforeFinishedAt" : {"type" : "string" , "optional" : True },
241+ },
242+ },
211243 ),
212244 types .Tool (
213245 name = "cancel-tasks" ,
@@ -293,8 +325,7 @@ async def handle_call_tool(
293325
294326 elif name == "update-connection-settings" :
295327 await self .update_connection (
296- arguments .get ("url" ),
297- arguments .get ("api_key" )
328+ arguments .get ("url" ), arguments .get ("api_key" )
298329 )
299330 return [
300331 types .TextContent (
@@ -313,7 +344,9 @@ async def handle_call_tool(
313344
314345 elif name == "list-indexes" :
315346 indexes = await self .meili_client .get_indexes ()
316- formatted_json = json .dumps (indexes , indent = 2 , default = json_serializer )
347+ formatted_json = json .dumps (
348+ indexes , indent = 2 , default = json_serializer
349+ )
317350 return [
318351 types .TextContent (
319352 type = "text" , text = f"Indexes:\n { formatted_json } "
@@ -397,13 +430,15 @@ async def handle_call_tool(
397430 filter = arguments .get ("filter" ),
398431 sort = arguments .get ("sort" ),
399432 )
400-
433+
401434 # Format the results for better readability
402- formatted_results = json .dumps (search_results , indent = 2 , default = json_serializer )
435+ formatted_results = json .dumps (
436+ search_results , indent = 2 , default = json_serializer
437+ )
403438 return [
404439 types .TextContent (
405440 type = "text" ,
406- text = f"Search results for '{ arguments ['query' ]} ':\n { formatted_results } "
441+ text = f"Search results for '{ arguments ['query' ]} ':\n { formatted_results } " ,
407442 )
408443 ]
409444
@@ -416,11 +451,27 @@ async def handle_call_tool(
416451 elif name == "get-tasks" :
417452 # Filter out any invalid parameters
418453 valid_params = {
419- "limit" , "from" , "reverse" , "batchUids" , "uids" , "canceledBy" ,
420- "types" , "statuses" , "indexUids" , "afterEnqueuedAt" , "beforeEnqueuedAt" ,
421- "afterStartedAt" , "beforeStartedAt" , "afterFinishedAt" , "beforeFinishedAt"
454+ "limit" ,
455+ "from" ,
456+ "reverse" ,
457+ "batchUids" ,
458+ "uids" ,
459+ "canceledBy" ,
460+ "types" ,
461+ "statuses" ,
462+ "indexUids" ,
463+ "afterEnqueuedAt" ,
464+ "beforeEnqueuedAt" ,
465+ "afterStartedAt" ,
466+ "beforeStartedAt" ,
467+ "afterFinishedAt" ,
468+ "beforeFinishedAt" ,
422469 }
423- filtered_args = {k : v for k , v in arguments .items () if k in valid_params } if arguments else {}
470+ filtered_args = (
471+ {k : v for k , v in arguments .items () if k in valid_params }
472+ if arguments
473+ else {}
474+ )
424475 tasks = await self .meili_client .tasks .get_tasks (filtered_args )
425476 return [types .TextContent (type = "text" , text = f"Tasks: { tasks } " )]
426477
@@ -479,7 +530,8 @@ async def handle_call_tool(
479530 )
480531 return [
481532 types .TextContent (
482- type = "text" , text = f"Index metrics: { json .dumps (metrics .__dict__ , default = json_serializer )} "
533+ type = "text" ,
534+ text = f"Index metrics: { json .dumps (metrics .__dict__ , default = json_serializer )} " ,
483535 )
484536 ]
485537
@@ -526,13 +578,15 @@ async def cleanup(self):
526578 self .logger .info ("Shutting down MCP server" )
527579 self .logger .shutdown ()
528580
581+
529582def main ():
530583 """Main entry point"""
531584 url = os .getenv ("MEILI_HTTP_ADDR" , "http://localhost:7700" )
532585 api_key = os .getenv ("MEILI_MASTER_KEY" )
533-
586+
534587 server = create_server (url , api_key )
535588 asyncio .run (server .run ())
536589
590+
537591if __name__ == "__main__" :
538592 main ()
0 commit comments