Skip to content

Conversation

tpayet
Copy link
Member

@tpayet tpayet commented Jun 13, 2025

Summary

  • Adds support for Meilisearch's hybrid search functionality (combining keyword and semantic search)
  • Updates the Meilisearch Python SDK dependency to v0.34.0+ for stable AI-powered search features
  • Implements comprehensive test coverage for the new search parameters

Changes

  • Updated dependency: meilisearch>=0.34.0 (from >=0.33.0)
  • Enhanced search tool schema to include:
    • hybrid object with semanticRatio and embedder fields
    • vector parameter for custom vector search
    • retrieveVectors parameter to include vectors in search results
  • Updated client.py to pass new parameters to the Meilisearch SDK
  • Added test suite for hybrid search functionality
  • Updated documentation with examples and parameter descriptions

Test Plan

  • Added comprehensive tests for hybrid search parameters
  • Verified search tool schema includes all new parameters
  • Tested parameter passing through MCP interface
  • Manual testing with a Meilisearch instance configured with embedders

Notes

The integration tests require a running Meilisearch instance. Some tests may fail if the instance requires API authentication. The hybrid search features require embedders to be configured in Meilisearch for full functionality.

Related Links

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Enhanced search functionality with support for hybrid search (combining keyword and semantic search), custom vector search, and the option to retrieve vector data in results.
  • Documentation

    • Updated documentation to describe new hybrid and vector search options, including example requests and parameter explanations.
  • Tests

    • Added tests to verify acceptance and handling of hybrid and vector search parameters.
  • Chores

    • Updated dependency requirements for the Meilisearch package.

Copy link
Contributor

coderabbitai bot commented Jun 13, 2025

Walkthrough

Hybrid and vector search capabilities were integrated into the Meilisearch MCP server and client. Documentation was updated to reflect these enhancements. The client and server now accept new parameters for hybrid and vector search. Tests were added to verify the acceptance and schema of these new parameters in the search tool.

Changes

File(s) Change Summary
README.md Updated documentation to describe hybrid and vector search support, new parameters, and example usage.
pyproject.toml Bumped "meilisearch" dependency version from ">=0.33.0" to ">=0.34.0".
src/meilisearch_mcp/client.py Extended MeilisearchClient.search() method to accept hybrid, vector, and retrieve_vectors parameters.
src/meilisearch_mcp/server.py Updated "search" tool schema and handler to support and forward new hybrid/vector search parameters.
tests/test_mcp_client.py Added TestHybridSearch class with tests for hybrid/vector search parameter support and schema validation.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant MCP_Server
    participant Meilisearch

    Client->>MCP_Server: search(query, hybrid, vector, retrieveVectors, ...)
    MCP_Server->>Meilisearch: search(query, hybrid, vector, retrieveVectors, ...)
    Meilisearch-->>MCP_Server: search results
    MCP_Server-->>Client: search results
Loading

Poem

In the garden of queries, where searches bloom bright,
Hybrid and vectors now join in the light.
With schemas extended and tests standing guard,
The MCP server grows ever more hard.
So hop forth, dear devs, let your searches take flight!
🥕✨

✨ 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: 2

🧹 Nitpick comments (2)
src/meilisearch_mcp/client.py (1)

67-75: Shadowing built-in filter identifier

Using filter as a parameter name shadows Python’s built-in filter function – not a blocker but easy to trip over in debugging & IDE hints. Consider renaming to filter_query (and adjust server schema/tests) for clarity.

README.md (1)

136-137: Minor punctuation – add comma after parenthetical phrase

“with support for hybrid search (combining keyword and semantic search)” →
“with support for hybrid search (combining keyword and semantic search),”

🧰 Tools
🪛 LanguageTool

[uncategorized] ~136-~136: Possible missing comma found.
Context: ... tool that can search across one or all indices with support for hybrid search (combini...

(AI_HYDRA_LEO_MISSING_COMMA)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 332c0ab and 4ae8889.

📒 Files selected for processing (5)
  • README.md (4 hunks)
  • pyproject.toml (1 hunks)
  • src/meilisearch_mcp/client.py (2 hunks)
  • src/meilisearch_mcp/server.py (3 hunks)
  • tests/test_mcp_client.py (1 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md

[uncategorized] ~136-~136: Possible missing comma found.
Context: ... tool that can search across one or all indices with support for hybrid search (combini...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~138-~138: Loose punctuation mark.
Context: ...eyword and semantic search): - search: Search through Meilisearch indices with...

(UNLIKELY_OPENING_PUNCTUATION)

🪛 GitHub Actions: Test and Lint
tests/test_mcp_client.py

[error] 689-689: TestHybridSearch.test_search_with_hybrid_parameters failed due to MeilisearchApiError: invalid_embedder. Cannot find embedder with name 'default'. Possibly due to incompatible Meilisearch version.


[error] 724-724: TestHybridSearch.test_search_with_vector_parameter failed due to MeilisearchApiError: bad_request. Unknown field 'retrieveVectors' in search parameters. Possibly due to incompatible Meilisearch version.


[error] 760-760: TestHybridSearch.test_search_semantic_only failed due to MeilisearchApiError: invalid_embedder. Cannot find embedder with name 'default'. Possibly due to incompatible Meilisearch version.

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

227-256: Schema uses retrieveVectors, client fix proposes retrieveVector

After correcting the client (see previous comment) this schema must mirror the exact casing and singular form or requests will 400.
Update the property key and description accordingly, then bump required / additionalProperties rules if necessary.

pyproject.toml (1)

6-8: Confirm minimum SDK version truly includes vector API

meilisearch>=0.34.0 is necessary but maybe not sufficient if the project relies on very fresh fields (retrieveVector).
Double-check release notes; if first supported in ≥0.35.0, bump here to avoid runtime 400s.

Comment on lines +55 to +57
hybrid: Optional[Dict[str, Any]] = None,
vector: Optional[List[float]] = None,
retrieve_vectors: Optional[bool] = None,
Copy link
Contributor

@coderabbitai coderabbitai bot Jun 13, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

retrieveVectors parameter name appears incorrect – causes 400-error

CI shows MeilisearchApiError: Unknown field 'retrieveVectors'. In v1.6 (SDK ≥ 0.34) the parameter accepted by the search endpoint is retrieveVector (singular) – see Meilisearch vector-search docs.
Please align with the official name to avoid hard failures.

-        retrieve_vectors: Optional[bool] = None,
+        retrieve_vector: Optional[bool] = None,-            if retrieve_vectors is not None:
-                search_params["retrieveVectors"] = retrieve_vectors
+            if retrieve_vector is not None:
+                search_params["retrieveVector"] = retrieve_vector

Remember to update the server handler, JSON schema and tests accordingly.

Also applies to: 76-82

🤖 Prompt for AI Agents
In src/meilisearch_mcp/client.py around lines 55 to 57 and 76 to 82, the
parameter name retrieveVectors is incorrect and causes a 400 error. Rename the
parameter from retrieveVectors to retrieveVector (singular) to match the
official Meilisearch v1.6 API. Update all references including the server
handler, JSON schema, and tests to use retrieveVector consistently.

Copy link
Member Author

Choose a reason for hiding this comment

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

This has been changed since, the correct parameter name is plural

Copy link
Contributor

Choose a reason for hiding this comment

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

@tpayet Merci pour la précision !
Je me suis référé à une version antérieure de la doc ; en effet, la 1.6.x / SDK ≥ 0.34 accepte maintenant le paramètre retrieveVectors au pluriel.
Je retire donc mon observation ; le code et le schéma actuels sont corrects. 👍

Copy link

Choose a reason for hiding this comment

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

lol this robot is nuts. It responds to your English in French 😆

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Comment on lines 615 to 768
{"id": 2, "title": "JavaScript Guide", "description": "Modern JS features"},
{"id": 3, "title": "Machine Learning", "description": "AI and ML concepts"},
]
await simulate_mcp_call(
mcp_server,
"add-documents",
{"indexUid": index_name, "documents": documents},
)
await wait_for_indexing()

# Note: This test simulates the API call structure but won't actually
# perform semantic search without a configured embedder in Meilisearch

# Test search with hybrid parameters
search_params = {
"query": "programming",
"indexUid": index_name,
"hybrid": {"semanticRatio": 0.7, "embedder": "default"},
"limit": 5,
}

# The search should accept these parameters without error
response = await simulate_mcp_call(mcp_server, "search", search_params)
response_text = assert_text_content_response(response, "Search results")

# Even if embedder is not configured, the API should handle the request
assert "Search results for 'programming'" in response_text

# Cleanup
await simulate_mcp_call(mcp_server, "delete-index", {"uid": index_name})

async def test_search_with_vector_parameter(self, mcp_server):
"""Test that search accepts vector parameter"""
# Create test index
index_name = generate_unique_index_name("vector_search")
await simulate_mcp_call(
mcp_server, "create-index", {"uid": index_name, "primaryKey": "id"}
)

# Add test documents
documents = [{"id": 1, "content": "Test document"}]
await simulate_mcp_call(
mcp_server,
"add-documents",
{"indexUid": index_name, "documents": documents},
)
await wait_for_indexing()

# Test search with vector parameter
search_params = {
"query": "test",
"indexUid": index_name,
"vector": [0.1, 0.2, 0.3, 0.4, 0.5],
"retrieveVectors": True,
}

# The search should accept these parameters without error
response = await simulate_mcp_call(mcp_server, "search", search_params)
response_text = assert_text_content_response(response, "Search results")
assert "Search results for 'test'" in response_text

# Cleanup
await simulate_mcp_call(mcp_server, "delete-index", {"uid": index_name})

async def test_search_semantic_only(self, mcp_server):
"""Test semantic-only search with semanticRatio=1.0"""
# Create test index
index_name = generate_unique_index_name("semantic_only")
await simulate_mcp_call(
mcp_server, "create-index", {"uid": index_name, "primaryKey": "id"}
)

# Add test documents
documents = [
{"id": 1, "content": "Artificial intelligence and machine learning"}
]
await simulate_mcp_call(
mcp_server,
"add-documents",
{"indexUid": index_name, "documents": documents},
)
await wait_for_indexing()

# Test semantic-only search
search_params = {
"query": "AI ML",
"indexUid": index_name,
"hybrid": {
"semanticRatio": 1.0, # Pure semantic search
"embedder": "default",
},
}

response = await simulate_mcp_call(mcp_server, "search", search_params)
response_text = assert_text_content_response(response, "Search results")
assert "Search results for 'AI ML'" in response_text

# Cleanup
await simulate_mcp_call(mcp_server, "delete-index", {"uid": index_name})

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Integration tests fail against vanilla Meilisearch – mock or xfail hybrid/vector paths

The pipeline errors (invalid_embedder, unknown field 'retrieveVectors') show that the test suite expects a server with an embedder configured and the now-incorrect parameter name.
To keep CI green on default installations:

  1. Rename the param after code fix (retrieveVector).
  2. Mark the three hybrid/vector tests with pytest.mark.skipif (or mock MeilisearchClient.search) when the remote server does not advertise the vector-search capability.
  3. Alternatively run an embedded Meilisearch container with a test embedder during CI.

Example:

-@pytest.mark.asyncio
 async def test_search_with_hybrid_parameters(self, mcp_server):
+@pytest.mark.asyncio
+@pytest.mark.skipif(
+    os.getenv("MEILI_VECTOR_ENABLED") != "1",
+    reason="Vector search not enabled in CI environment",
+)

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 GitHub Actions: Test and Lint

[error] 689-689: TestHybridSearch.test_search_with_hybrid_parameters failed due to MeilisearchApiError: invalid_embedder. Cannot find embedder with name 'default'. Possibly due to incompatible Meilisearch version.


[error] 724-724: TestHybridSearch.test_search_with_vector_parameter failed due to MeilisearchApiError: bad_request. Unknown field 'retrieveVectors' in search parameters. Possibly due to incompatible Meilisearch version.


[error] 760-760: TestHybridSearch.test_search_semantic_only failed due to MeilisearchApiError: invalid_embedder. Cannot find embedder with name 'default'. Possibly due to incompatible Meilisearch version.

🤖 Prompt for AI Agents
In tests/test_mcp_client.py around lines 615 to 765, the integration tests for
hybrid and vector search fail on vanilla Meilisearch due to missing embedder
configuration and incorrect parameter naming. To fix this, rename the parameter
"retrieveVectors" to "retrieveVector" to match the updated API. Then, mark the
three tests involving hybrid and vector search with pytest.mark.skipif to skip
them when the Meilisearch server does not support vector search capabilities, or
alternatively mock the MeilisearchClient.search method in these tests. This will
prevent CI failures on default Meilisearch installations without embedder
support.

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

♻️ Duplicate comments (2)
tests/test_mcp_client.py (2)

647-650: ⚠️ Potential issue

Parameter name still out-of-sync with Meilisearch API

The server (≥ v0.34.0) expects retrieveVector, not retrieveVectors.
Both the schema assertion here and subsequent tests will fail against a compliant server.

-assert "retrieveVectors" in properties
-assert properties["retrieveVectors"]["type"] == "boolean"
+assert "retrieveVector" in properties
+assert properties["retrieveVector"]["type"] == "boolean"

Update the test payloads accordingly.


717-723: ⚠️ Potential issue

Rename request parameter to match API

Search requests still send the deprecated retrieveVectors flag.

-    "vector": [0.1, 0.2, 0.3, 0.4, 0.5],
-    "retrieveVectors": True,
+    "vector": [0.1, 0.2, 0.3, 0.4, 0.5],
+    "retrieveVector": True,
🧹 Nitpick comments (1)
tests/test_mcp_client.py (1)

630-640: Relax brittle required assertion

hybrid_schema["required"] == ["embedder"] will break if the backend later makes any additional field mandatory.
Safer:

-assert hybrid_schema["required"] == ["embedder"]
+assert "embedder" in hybrid_schema.get("required", [])
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4ae8889 and 3f9c39f.

📒 Files selected for processing (1)
  • tests/test_mcp_client.py (1 hunks)

tpayet and others added 2 commits June 13, 2025 09:49
- Update meilisearch dependency from >=0.33.0 to >=0.34.0 for stable AI-powered search
- Add hybrid search parameters to search tool schema:
  - hybrid object with semanticRatio and embedder fields
  - vector parameter for custom vectors
  - retrieveVectors parameter to include vectors in results
- Update client.py search method to pass new parameters to SDK
- Add comprehensive tests for hybrid search functionality
- Update README with hybrid search examples and documentation

This enables users to leverage Meilisearch's semantic and hybrid search capabilities
through the MCP interface, combining traditional keyword search with AI-powered
semantic search for more relevant results.

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

Co-Authored-By: Claude <[email protected]>
Add pytest.mark.skip decorators to tests that require a Meilisearch
instance with embedders configured. These tests validate the API
structure but cannot run without proper embedder setup.
@tpayet tpayet force-pushed the feature/hybrid-search-support branch from 3f9c39f to c87bcfc Compare June 13, 2025 07:49
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 (4)
README.md (4)

136-136: Add comma to clarify hybrid search description

In the sentence, use a comma instead of parentheses to improve readability and consistency:

- The server provides a flexible search tool that can search across one or all indices with support for hybrid search (combining keyword and semantic search):
+ The server provides a flexible search tool that can search across one or all indices with support for hybrid search, combining keyword and semantic search:
🧰 Tools
🪛 LanguageTool

[uncategorized] ~136-~136: Possible missing comma found.
Context: ... tool that can search across one or all indices with support for hybrid search (combini...

(AI_HYDRA_LEO_MISSING_COMMA)


152-164: Clarify JSON example comments

These code blocks include // comments inside JSON, which is not valid JSON. Consider moving explanatory comments outside the JSON or marking these as pseudocode. This will help users copy/paste examples without errors.


166-175: Clarify JSON example comments in semantic search section

Similarly, the semantic search example embeds comments inside the JSON. Either remove the inline comments or wrap examples with a disclaimer (e.g., “Note: JSON comments added for clarity”).


245-246: Unify wording in the Available Tools section

The search description uses “single or multiple indices” here, but earlier it says “one or all indices.” For consistency and clarity, align both phrases and match the refined hybrid search description:

- - `search`: Flexible search across single or multiple indices with support for hybrid search (keyword + semantic), custom vectors, and filtering/sorting options
+ - `search`: Flexible search across one or all indices with support for hybrid search, combining keyword and semantic search, custom vector search, and filtering/sorting options
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3f9c39f and c87bcfc.

📒 Files selected for processing (5)
  • README.md (4 hunks)
  • pyproject.toml (1 hunks)
  • src/meilisearch_mcp/client.py (2 hunks)
  • src/meilisearch_mcp/server.py (3 hunks)
  • tests/test_mcp_client.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • pyproject.toml
  • src/meilisearch_mcp/server.py
  • src/meilisearch_mcp/client.py
  • tests/test_mcp_client.py
🧰 Additional context used
🪛 LanguageTool
README.md

[uncategorized] ~136-~136: Possible missing comma found.
Context: ... tool that can search across one or all indices with support for hybrid search (combini...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~138-~138: Loose punctuation mark.
Context: ...eyword and semantic search): - search: Search through Meilisearch indices with...

(UNLIKELY_OPENING_PUNCTUATION)

🔇 Additional comments (1)
README.md (1)

195-200: New search parameters are well-documented

The additions of hybrid, vector, and retrieveVectors parameters are correctly described with defaults and requirements. Great job updating the parameter list.

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.

2 participants