Skip to content

Commit 1799e05

Browse files
tpayetclaude
andcommitted
Fix get-documents tool to return JSON instead of Python objects
Fixes #16: The get-documents tool was returning Python object string representations instead of proper JSON-formatted data. Changes: - Fix documents.py to properly serialize DocumentsResults and Document objects - Add default values for offset (0) and limit (20) to fix None parameter issues - Improve JSON serializer to handle Meilisearch model objects recursively - Add comprehensive tests for JSON serialization behavior - Update existing test to handle async index creation timing The fix ensures that: - get-documents returns valid JSON instead of object representations - Document fields are properly accessible in the response - Empty indexes return valid JSON structure - Parameter validation prevents API errors 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 9016948 commit 1799e05

File tree

3 files changed

+507
-6
lines changed

3 files changed

+507
-6
lines changed

src/meilisearch_mcp/documents.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,43 @@ async def get_documents(
1818
"""Get documents from an index"""
1919
try:
2020
index = self.client.index(index_uid)
21-
return index.get_documents(
22-
{"offset": offset, "limit": limit, "fields": fields}
23-
)
21+
# Build parameters dict, excluding None values to avoid API errors
22+
params = {}
23+
if offset is not None:
24+
params["offset"] = offset
25+
if limit is not None:
26+
params["limit"] = limit
27+
if fields is not None:
28+
params["fields"] = fields
29+
30+
result = index.get_documents(params if params else {})
31+
32+
# Convert meilisearch model objects to JSON-serializable format
33+
if hasattr(result, '__dict__'):
34+
result_dict = result.__dict__.copy()
35+
# Convert individual document objects in results if they exist
36+
if 'results' in result_dict and isinstance(result_dict['results'], list):
37+
serialized_results = []
38+
for doc in result_dict['results']:
39+
if hasattr(doc, '__dict__'):
40+
# Extract the actual document data
41+
doc_dict = doc.__dict__.copy()
42+
# Look for private attributes that might contain the actual data
43+
for key, value in doc_dict.items():
44+
if key.startswith('_') and isinstance(value, dict):
45+
# Use the dict content instead of the wrapper
46+
serialized_results.append(value)
47+
break
48+
else:
49+
# If no private dict found, use the object dict directly
50+
serialized_results.append(doc_dict)
51+
else:
52+
serialized_results.append(doc)
53+
result_dict['results'] = serialized_results
54+
return result_dict
55+
else:
56+
return result
57+
2458
except Exception as e:
2559
raise Exception(f"Failed to get documents: {str(e)}")
2660

src/meilisearch_mcp/server.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ def json_serializer(obj: Any) -> str:
1818
"""Custom JSON serializer for objects not serializable by default json code"""
1919
if isinstance(obj, datetime):
2020
return obj.isoformat()
21+
# Handle Meilisearch model objects by using their __dict__ if available
22+
if hasattr(obj, '__dict__'):
23+
return obj.__dict__
2124
return str(obj)
2225

2326

@@ -318,13 +321,19 @@ async def handle_call_tool(
318321
]
319322

320323
elif name == "get-documents":
324+
# Use default values to fix issue #17 (None offset/limit causes API errors)
325+
offset = arguments.get("offset", 0)
326+
limit = arguments.get("limit", 20)
321327
documents = await self.meili_client.documents.get_documents(
322328
arguments["indexUid"],
323-
arguments.get("offset"),
324-
arguments.get("limit"),
329+
offset,
330+
limit,
325331
)
332+
# Convert DocumentsResults object to proper JSON format
333+
# The documents object should be directly JSON serializable from Meilisearch client
334+
formatted_json = json.dumps(documents, indent=2, default=json_serializer)
326335
return [
327-
types.TextContent(type="text", text=f"Documents: {documents}")
336+
types.TextContent(type="text", text=f"Documents:\n{formatted_json}")
328337
]
329338

330339
elif name == "add-documents":

0 commit comments

Comments
 (0)