Skip to content

Implement JSON filter parsing for Qdrant queries #2

@leynos

Description

@leynos

Description

The parse_filter method in crates/dear-diary-mcp/src/server.rs currently cannot parse arbitrary JSON filters into Qdrant Filter objects because Qdrant's protobuf Filter type does not implement serde's Deserialize trait.

Current Behaviour

When allow_arbitrary_filter is set to true in the configuration, the server returns an error:

InvalidFilter("Arbitrary JSON filter parsing is not yet implemented")

See: crates/dear-diary-mcp/src/server.rs lines 63-81

Desired Behaviour

The server should be able to:

  1. Accept JSON filter structures via the filter parameter in qdrant_find requests
  2. Parse these JSON structures into Qdrant Filter objects
  3. Apply these filters when querying the vector database

Potential Approaches

  1. Manual JSON→Filter construction: Write custom deserialisation logic to manually construct Filter objects from JSON structures by traversing the JSON and building the protobuf types directly.

  2. Wrapper types with serde: Create wrapper types that implement serde traits and provide conversion methods to/from Qdrant's protobuf types.

  3. Upstream serde support: Investigate whether Qdrant's Rust client could add serde support for protobuf types, or contribute this feature upstream.

  4. Alternative filter API: Design a simplified, serde-compatible filter DSL specific to Dear Diary's use cases that can be translated to Qdrant filters.

  5. serde_protobuf crate: Explore using the serde_protobuf crate for dynamic schema deserialisation, though this may require additional runtime overhead.

Technical Background

Protobuf-generated Rust types (using prost) typically do not implement serde traits by default. The Qdrant Rust client uses prost-generated types for its protobuf definitions, which means Filter lacks Deserialize implementation.

Possible technical solutions:

  • Custom conversion logic from JSON → protobuf structures
  • Intermediate representation that is serde-compatible
  • Wrapper types with manual trait implementations

References

Related Code

fn parse_filter(&self, filter: Option<Value>) -> Result<Option<Filter>, McpServerError> {
    let Some(_filter_value) = filter else {
        return Ok(None);
    };

    if !self.settings.qdrant.allow_arbitrary_filter {
        return Err(McpServerError::InvalidFilter(
            "Arbitrary filters are not enabled".to_owned(),
        ));
    }

    // TODO: Implement proper filter parsing from JSON
    Err(McpServerError::InvalidFilter(
        "Arbitrary JSON filter parsing is not yet implemented".to_owned(),
    ))
}

Impact

  • Users cannot currently use the allow_arbitrary_filter configuration option
  • Limited to filterable_fields configuration for query filtering
  • Reduces flexibility for advanced filtering use cases

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions