Skip to content

Conversation

@tpayet
Copy link
Member

@tpayet tpayet commented Jun 6, 2025

Summary

Fixes #16: The get-documents tool was returning Python object string representations instead of proper JSON-formatted data.

Problem

The issue reported that get-documents was returning:

Documents: <meilisearch.models.document.DocumentsResults object at 0x...>

Instead of actual JSON with accessible document fields.

Solution

Core Changes

  • documents.py: Enhanced get_documents() to properly serialize DocumentsResults and Document objects to JSON-compatible dictionaries
  • server.py: Improved json_serializer() to handle Meilisearch model objects using __dict__ attributes
  • Added proper JSON formatting with json.dumps() for the get-documents tool response
  • Added default values for offset (0) and limit (20) to prevent None parameter API errors

Test Coverage

  • Added TestIssue16GetDocumentsJsonSerialization with focused test for this specific issue
  • Verifies no Python object representations in response
  • Confirms actual document data is accessible in JSON format
  • Validates proper JSON structure

Before vs After

Before:

Documents: <meilisearch.models.document.DocumentsResults object at 0x...>

After:

Documents:
{
  "results": [
    {
      "id": 1,
      "title": "Test Document",
      "content": "Test content"
    }
  ],
  "offset": 0,
  "limit": 20,
  "total": 1
}

Testing

python -m pytest tests/test_mcp_client.py::TestIssue16GetDocumentsJsonSerialization -v

Test confirms:

  • ✅ No Python object string representations
  • ✅ Valid JSON structure
  • ✅ Document fields are accessible

Closes #16

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved JSON serialization for document retrieval, ensuring responses are properly formatted as JSON rather than Python object strings.
    • Default values for pagination parameters are now applied to prevent issues when values are not provided.
  • Tests
    • Added new tests to verify that document retrieval returns correctly formatted JSON responses.

Fixes #16: The get-documents tool was returning Python object string
representations like '<meilisearch.models.document.DocumentsResults object at 0x...>'
instead of proper JSON-formatted data.

Changes:
- documents.py: Enhanced get_documents() to properly serialize DocumentsResults
  and Document objects to JSON-compatible dictionaries
- server.py: Improved json_serializer to handle Meilisearch model objects
  and added proper JSON formatting for get-documents tool response
- Added default values for offset/limit to prevent None parameter API errors
- tests: Added specific test for issue #16 to verify JSON serialization

The fix ensures get-documents returns valid JSON with accessible document
fields instead of Python object representations.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 6, 2025

Walkthrough

The changes update the handling and serialization of document retrieval in the Meilisearch MCP server. The get_documents method now ensures returned objects are JSON-serializable, and the server returns properly formatted JSON for the "get-documents" tool. A new test verifies that the response is valid JSON, not a Python object string.

Changes

File(s) Change Summary
src/meilisearch_mcp/documents.py Improved get_documents to dynamically build query params and serialize returned objects as JSON.
src/meilisearch_mcp/server.py Enhanced json_serializer for Meilisearch objects; ensured "get-documents" returns JSON text.
tests/test_mcp_client.py Added a test class to assert "get-documents" returns JSON, not Python object string.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Server
    participant DocumentsModule

    Client->>Server: Call "get-documents" tool
    Server->>DocumentsModule: get_documents(offset, limit, ...)
    DocumentsModule-->>Server: DocumentsResults (object)
    Server->>Server: Serialize DocumentsResults to JSON
    Server-->>Client: Response with JSON-formatted document data
Loading

Assessment against linked issues

Objective Addressed Explanation
Ensure "get-documents" returns JSON, not Python object string (#16)

Poem

In a warren of code, where data once slept,
A rabbit awoke, and JSON it kept.
No Pythonic riddles, just clarity clear,
Now documents speak so all can hear.
With tests as our burrow, and carrots in sight,
Serialization’s fixed—what a delight! 🥕

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/meilisearch_mcp/server.py (1)

21-23: Enhance the json_serializer function with proper error handling.

The addition to handle Meilisearch model objects by accessing their __dict__ is correct and addresses the core issue. However, consider adding error handling for edge cases.

Consider this improvement for robustness:

 # Handle Meilisearch model objects by using their __dict__ if available
 if hasattr(obj, '__dict__'):
-    return obj.__dict__
+    try:
+        return obj.__dict__
+    except AttributeError:
+        pass
 return str(obj)
src/meilisearch_mcp/documents.py (1)

32-56: Complex but necessary serialization logic with a minor structural improvement needed.

The document serialization logic correctly handles the conversion of Meilisearch model objects to JSON-serializable format. The approach of looking for private attributes containing actual data is pragmatic for handling wrapped objects.

Address the static analysis hint by removing the unnecessary else after return:

-            if hasattr(result, '__dict__'):
-                result_dict = result.__dict__.copy()
-                # ... rest of the logic ...
-                return result_dict
-            else:
-                return result
+            if hasattr(result, '__dict__'):
+                result_dict = result.__dict__.copy()
+                # ... rest of the logic ...
+                return result_dict
+            return result
🧰 Tools
🪛 Pylint (3.3.7)

[refactor] 33-56: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

tests/test_mcp_client.py (1)

320-369: Comprehensive test with minor import optimization needed.

The test thoroughly validates the fix by:

  • Creating a test index and document
  • Verifying the response doesn't contain Python object representations
  • Confirming valid JSON structure and content
  • Properly parsing and validating the JSON response

Fix the import redefinitions flagged by static analysis:

 async def test_get_documents_returns_json_not_python_object(self, server):
     """Test that get-documents returns JSON-formatted text, not Python object string representation (issue #16)"""
-    import time
+    import time
     test_index = f"test_issue16_{int(time.time() * 1000)}"
     
     # Create index and add a test document
     await simulate_mcp_call(server, "create-index", {"uid": test_index})
     
     test_document = {"id": 1, "title": "Test Document", "content": "Test content"}
     await simulate_mcp_call(server, "add-documents", {
         "indexUid": test_index,
         "documents": [test_document]
     })
     
     # Wait for indexing
-    import asyncio
     await asyncio.sleep(0.5)

Since asyncio and json are already imported at module level (lines 10, 12), remove the redundant local imports.

🧰 Tools
🪛 Ruff (0.11.9)

335-335: Redefinition of unused asyncio from line 10

Remove definition: asyncio

(F811)


361-361: Redefinition of unused json from line 12

Remove definition: json

(F811)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9016948 and 270c2c5.

📒 Files selected for processing (3)
  • src/meilisearch_mcp/documents.py (1 hunks)
  • src/meilisearch_mcp/server.py (2 hunks)
  • tests/test_mcp_client.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/meilisearch_mcp/server.py (1)
src/meilisearch_mcp/documents.py (1)
  • get_documents (11-59)
tests/test_mcp_client.py (1)
src/meilisearch_mcp/server.py (2)
  • create_server (27-29)
  • cleanup (524-527)
🪛 Ruff (0.11.9)
tests/test_mcp_client.py

335-335: Redefinition of unused asyncio from line 10

Remove definition: asyncio

(F811)


361-361: Redefinition of unused json from line 12

Remove definition: json

(F811)

🪛 Pylint (3.3.7)
src/meilisearch_mcp/documents.py

[refactor] 33-56: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

🔇 Additional comments (3)
src/meilisearch_mcp/server.py (1)

324-336: Excellent fix for the JSON serialization issue.

The implementation correctly addresses issue #16 by:

  • Providing sensible default values for offset and limit to prevent API errors
  • Using json.dumps() with the enhanced json_serializer to ensure proper JSON formatting
  • Maintaining consistent response format with other tools

The solution ensures that clients receive valid JSON instead of Python object string representations like <meilisearch.models.document.DocumentsResults object at 0x...>.

src/meilisearch_mcp/documents.py (1)

21-30: Good approach to parameter filtering.

Building the parameters dictionary dynamically and excluding None values is the correct approach to avoid API errors. This prevents passing None values that could cause issues with the Meilisearch API.

tests/test_mcp_client.py (1)

308-319: Well-structured test fixture for issue #16.

The test class and fixture setup properly isolate the test and ensure cleanup. Good practice using environment variables for configuration.

@tpayet tpayet merged commit f5455b0 into main Jun 6, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Get documents request returns q python object instead of JSON

2 participants