From 38d863eef731cbc0760152d1dbb81b6e892f43a3 Mon Sep 17 00:00:00 2001 From: adityamishra-hydradb <321510987+adityamishra-hydradb@users.noreply.github.com> Date: Tue, 27 Oct 2026 23:09:32 +0000 Subject: [PATCH 1/3] docs(search): define normalized title matching (ENG-3299) Signed-off-by: adityamishra-hydradb <321510987+adityamishra-hydradb@users.noreply.github.com> --- api-reference/v2/endpoint/list-documents.mdx | 15 ++++++++++-- api-reference/v2/endpoint/query.mdx | 2 +- plugins/mcp.mdx | 24 ++++++++++++++------ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/api-reference/v2/endpoint/list-documents.mdx b/api-reference/v2/endpoint/list-documents.mdx index 5f9ef6dc..fe2ed2f5 100644 --- a/api-reference/v2/endpoint/list-documents.mdx +++ b/api-reference/v2/endpoint/list-documents.mdx @@ -80,7 +80,7 @@ curl -X POST 'https://api.hydradb.com/context/list' \ ### Filters -- `filters` accepts the three categories below. Values must match exactly, except `source_fields.title`, which matches a case-insensitive prefix. +- `filters` accepts the three categories below. Values must match exactly, except `source_fields.title`, which matches a normalized title prefix. - All filter pairs combine with AND. When `ids` is non-empty, filters apply only to those IDs. - Range, contains, and OR operators are not supported. For OR behavior, run separate calls and combine the results in your application. - A `null` filter value returns `400`. @@ -99,10 +99,21 @@ curl -X POST 'https://api.hydradb.com/context/list' \ | --- | --- | --- | | | Context item's schema-aligned `metadata` payload | Exact matches on database metadata fields. See [Metadata and Filters](/essentials/v2/metadata#7-list-sources-with-metadata-filters). | | | Context item's `additional_metadata` payload | Exact matches on free-form metadata. No schema declaration is required. | -| | Built-in and connector fields listed below | `title` matches a case-insensitive prefix. Pair external IDs with `app_provider`. Unsupported keys return `400`. | +| | Built-in and connector fields listed below | `title` matches a normalized prefix. Pair external IDs with `app_provider`. Unsupported keys return `400`. | Supported source fields are `type`, `title`, `description`, `url`, `timestamp`, `app_provider`, `app_kind`, `app_external_id`, and `app_parent_id`. +Title normalization applies Unicode NFKC, removes invisible marks and decoration, +lowercases the title, collapses spaces, and trims it. HydraDB also removes one +final extension from `md`, `markdown`, `txt`, `pdf`, `doc`, `docx`, `rtf`, `odt`, +`ppt`, `pptx`, `xls`, `xlsx`, `csv`, `tsv`, `json`, `html`, or `htm`, but only +when text remains before it. Thus `Runbook.md` has the normalized prefix +`runbook`. Unknown extensions such as `.v2` remain part of the title. + +Source IDs and titles are separate inputs. Use `ids` for source IDs and +`filters.source_fields.title` for title prefixes. HydraDB never guesses from the +input format. + ### Field projection When you don't need every field on every row, pass `include_fields` to keep response payloads small. Only the listed fields are populated; omitted fields should be treated as unavailable in that response. `id`, `database`, and `collection` are always returned. diff --git a/api-reference/v2/endpoint/query.mdx b/api-reference/v2/endpoint/query.mdx index acd4fcec..cb32be7e 100644 --- a/api-reference/v2/endpoint/query.mdx +++ b/api-reference/v2/endpoint/query.mdx @@ -315,7 +315,7 @@ result = client.query( | | Single collection scope. Send the collection the content was saved in. | | | Multi-collection scope. Send a list of collection IDs for equal weighting, or an object mapping collection ID to a positive relative weight (at most one decimal place, e.g. `{"finance": 1.5, "legal": 0.8}`) to bias ranking. Up to 100 collections. Do not combine with `collection`. | | | Query terms or natural-language question. Cannot be empty. Maximum 5,000 words. | -| | Exact source titles, matched case-insensitively. Matches any listed title, then intersects with `ids` if both are sent. | +| | Exact normalized source titles. Normalization applies Unicode NFKC, removes invisible marks and decoration, lowercases, collapses spaces, and removes one final known file extension (`md`, `markdown`, `txt`, `pdf`, `doc`, `docx`, `rtf`, `odt`, `ppt`, `pptx`, `xls`, `xlsx`, `csv`, `tsv`, `json`, `html`, or `htm`) when text remains before it. Matches any listed title, then intersects with `ids` if both are sent. Use `ids` for source IDs and `titles` for titles; HydraDB never guesses from the input format. | | | Caller identities used to filter document ACLs. Omitting `acl`, sending `[]`, or sending `["*"]` disables caller-supplied filtering. For enforced connectors, the authenticated caller is used instead; see [ACL enforcement](/essentials/v2/connectors#enforce-acl). | | | Omit for the result object with `llm_prompt`. `"structured"` leaves out the prompt string. `"markdown"` returns the prompt string directly as `data`. | | | What to query. `"all"` runs knowledge and memory in parallel over the same scope and merges by `relevancy_score`. (default=`"knowledge"`) | diff --git a/plugins/mcp.mdx b/plugins/mcp.mdx index e77d8ae5..db7885eb 100644 --- a/plugins/mcp.mdx +++ b/plugins/mcp.mdx @@ -456,7 +456,7 @@ See the [Glossary](/essentials/v2/glossary) for database and collection terminol | `max_results` | number | No | Chunks to return, 1 to 50 (default: `10`) | | `mode` | string | No | `fast` for a quick single pass, `thinking` for deeper recall with query expansion and graph traversal, or `auto` to pick per query (default: `thinking`) | | `graph_context` | boolean | No | Include knowledge graph relations in the results (default: `true`) | -| `titles` | string[] | No | Restrict the search to documents whose **complete** title exactly matches any value, ignoring case | +| `titles` | string[] | No | Restrict the search to documents whose complete normalized title matches any value. See [Filtering by document title](#filtering-by-document-title). | | `metadata_filters` | object | No | Exact-match metadata filters as `{key: value}` | | `database` | string | No | Database (tenant) scope override for this request | | `collection` | string | No | Collection (sub-tenant) scope override for this request | @@ -474,15 +474,25 @@ those sources. } ``` -- **Exact, complete titles:** `last-usage` does not match `last-usage.csv`. -- **Case-insensitive:** `q3 roadmap.md` matches `Q3 Roadmap.md`. -- **Several titles are ORed:** Surrounding whitespace is trimmed; punctuation such - as commas is part of the title. +- **One title rule:** HydraDB applies Unicode NFKC, removes invisible marks and + decoration, lowercases the title, collapses spaces, and trims it. +- **Known file extensions are optional:** HydraDB removes one final extension from + `md`, `markdown`, `txt`, `pdf`, `doc`, `docx`, `rtf`, `odt`, `ppt`, `pptx`, + `xls`, `xlsx`, `csv`, `tsv`, `json`, `html`, or `htm`. Text must remain before + the extension. `last-usage` therefore matches `last-usage.csv`. `notes.v2` stays + unchanged, and `.md` stays unchanged. +- **Exact after normalization:** `q3 roadmap.md` matches `Q3 Roadmap`, but a + normalized prefix alone does not match in this exact-title field. +- **Several titles are ORed:** Punctuation such as commas remains part of the title. - **No match returns an empty result** rather than widening to the whole corpus. +Source IDs and titles are separate inputs. Use `ids` for source IDs and `titles` +for titles. HydraDB never guesses from the input format. + -Because matching ignores case, two documents whose names differ only by case -(`Report.md` and `report.md`) are treated as the same title and both are returned. +Two documents with the same normalized title are treated as the same title and +both are returned. For example, `Report.md`, `report.pdf`, and `report` share one +normalized title. ### hydradb_ingest From f95347a5a9e89b8ca478ca3d4f98568aaf2ad2f7 Mon Sep 17 00:00:00 2001 From: adityamishra-hydradb <321510987+adityamishra-hydradb@users.noreply.github.com> Date: Tue, 27 Oct 2026 23:29:47 +0000 Subject: [PATCH 2/3] docs(search): clarify normalized title rules (ENG-3299) Signed-off-by: adityamishra-hydradb <321510987+adityamishra-hydradb@users.noreply.github.com> --- api-reference/v2/endpoint/list-documents.mdx | 8 +++++--- api-reference/v2/endpoint/query.mdx | 2 +- plugins/mcp.mdx | 11 +++++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/api-reference/v2/endpoint/list-documents.mdx b/api-reference/v2/endpoint/list-documents.mdx index fe2ed2f5..3f66ccd1 100644 --- a/api-reference/v2/endpoint/list-documents.mdx +++ b/api-reference/v2/endpoint/list-documents.mdx @@ -104,11 +104,13 @@ curl -X POST 'https://api.hydradb.com/context/list' \ Supported source fields are `type`, `title`, `description`, `url`, `timestamp`, `app_provider`, `app_kind`, `app_external_id`, and `app_parent_id`. Title normalization applies Unicode NFKC, removes invisible marks and decoration, -lowercases the title, collapses spaces, and trims it. HydraDB also removes one -final extension from `md`, `markdown`, `txt`, `pdf`, `doc`, `docx`, `rtf`, `odt`, +lowercases the title, collapses spaces, and trims it. HydraDB also removes all +consecutive final extensions from `md`, `markdown`, `txt`, `pdf`, `doc`, `docx`, +`rtf`, `odt`, `ppt`, `pptx`, `xls`, `xlsx`, `csv`, `tsv`, `json`, `html`, or `htm`, but only when text remains before it. Thus `Runbook.md` has the normalized prefix -`runbook`. Unknown extensions such as `.v2` remain part of the title. +`runbook`. `report.pdf.md` matches `report`. Unknown extensions such as `.v2` +remain part of the title. Source IDs and titles are separate inputs. Use `ids` for source IDs and `filters.source_fields.title` for title prefixes. HydraDB never guesses from the diff --git a/api-reference/v2/endpoint/query.mdx b/api-reference/v2/endpoint/query.mdx index cb32be7e..e7bba82f 100644 --- a/api-reference/v2/endpoint/query.mdx +++ b/api-reference/v2/endpoint/query.mdx @@ -315,7 +315,7 @@ result = client.query( | | Single collection scope. Send the collection the content was saved in. | | | Multi-collection scope. Send a list of collection IDs for equal weighting, or an object mapping collection ID to a positive relative weight (at most one decimal place, e.g. `{"finance": 1.5, "legal": 0.8}`) to bias ranking. Up to 100 collections. Do not combine with `collection`. | | | Query terms or natural-language question. Cannot be empty. Maximum 5,000 words. | -| | Exact normalized source titles. Normalization applies Unicode NFKC, removes invisible marks and decoration, lowercases, collapses spaces, and removes one final known file extension (`md`, `markdown`, `txt`, `pdf`, `doc`, `docx`, `rtf`, `odt`, `ppt`, `pptx`, `xls`, `xlsx`, `csv`, `tsv`, `json`, `html`, or `htm`) when text remains before it. Matches any listed title, then intersects with `ids` if both are sent. Use `ids` for source IDs and `titles` for titles; HydraDB never guesses from the input format. | +| | Exact normalized source titles. Normalization applies Unicode NFKC, removes invisible marks and decoration, lowercases, collapses spaces, and removes consecutive final known file extensions (`md`, `markdown`, `txt`, `pdf`, `doc`, `docx`, `rtf`, `odt`, `ppt`, `pptx`, `xls`, `xlsx`, `csv`, `tsv`, `json`, `html`, or `htm`) when text remains before them. Matches any listed title, then intersects with `ids` if both are sent. Use `ids` for source IDs and `titles` for titles; HydraDB never guesses from the input format. | | | Caller identities used to filter document ACLs. Omitting `acl`, sending `[]`, or sending `["*"]` disables caller-supplied filtering. For enforced connectors, the authenticated caller is used instead; see [ACL enforcement](/essentials/v2/connectors#enforce-acl). | | | Omit for the result object with `llm_prompt`. `"structured"` leaves out the prompt string. `"markdown"` returns the prompt string directly as `data`. | | | What to query. `"all"` runs knowledge and memory in parallel over the same scope and merges by `relevancy_score`. (default=`"knowledge"`) | diff --git a/plugins/mcp.mdx b/plugins/mcp.mdx index db7885eb..547f266d 100644 --- a/plugins/mcp.mdx +++ b/plugins/mcp.mdx @@ -476,18 +476,21 @@ those sources. - **One title rule:** HydraDB applies Unicode NFKC, removes invisible marks and decoration, lowercases the title, collapses spaces, and trims it. -- **Known file extensions are optional:** HydraDB removes one final extension from +- **Known file extensions are optional:** HydraDB removes consecutive final + extensions from `md`, `markdown`, `txt`, `pdf`, `doc`, `docx`, `rtf`, `odt`, `ppt`, `pptx`, `xls`, `xlsx`, `csv`, `tsv`, `json`, `html`, or `htm`. Text must remain before the extension. `last-usage` therefore matches `last-usage.csv`. `notes.v2` stays - unchanged, and `.md` stays unchanged. + unchanged, `.md` stays unchanged, and `report.pdf.md` matches `report`. - **Exact after normalization:** `q3 roadmap.md` matches `Q3 Roadmap`, but a normalized prefix alone does not match in this exact-title field. - **Several titles are ORed:** Punctuation such as commas remains part of the title. - **No match returns an empty result** rather than widening to the whole corpus. -Source IDs and titles are separate inputs. Use `ids` for source IDs and `titles` -for titles. HydraDB never guesses from the input format. +Source IDs and titles are separate inputs. `hydradb_query` accepts document names +through `titles`; it does not accept source IDs. Use `hydradb_inspect` or +`hydradb_subgraph` when you have one source ID, or `hydradb_list` with `ids` when +you have several. HydraDB never guesses from the input format. Two documents with the same normalized title are treated as the same title and From bbb794527a341adf94af497281b075e74cc01421 Mon Sep 17 00:00:00 2001 From: adityamishra-hydradb <321510987+adityamishra-hydradb@users.noreply.github.com> Date: Tue, 27 Oct 2026 23:34:49 +0000 Subject: [PATCH 3/3] docs(search): document MCP source scopes (ENG-3299) Signed-off-by: adityamishra-hydradb <321510987+adityamishra-hydradb@users.noreply.github.com> --- plugins/mcp.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/mcp.mdx b/plugins/mcp.mdx index 547f266d..6fe18c93 100644 --- a/plugins/mcp.mdx +++ b/plugins/mcp.mdx @@ -456,6 +456,7 @@ See the [Glossary](/essentials/v2/glossary) for database and collection terminol | `max_results` | number | No | Chunks to return, 1 to 50 (default: `10`) | | `mode` | string | No | `fast` for a quick single pass, `thinking` for deeper recall with query expansion and graph traversal, or `auto` to pick per query (default: `thinking`) | | `graph_context` | boolean | No | Include knowledge graph relations in the results (default: `true`) | +| `source_ids` | string[] | No | Restrict the search to these source IDs. Intersects with `titles` when both are present. | | `titles` | string[] | No | Restrict the search to documents whose complete normalized title matches any value. See [Filtering by document title](#filtering-by-document-title). | | `metadata_filters` | object | No | Exact-match metadata filters as `{key: value}` | | `database` | string | No | Database (tenant) scope override for this request | @@ -487,10 +488,9 @@ those sources. - **Several titles are ORed:** Punctuation such as commas remains part of the title. - **No match returns an empty result** rather than widening to the whole corpus. -Source IDs and titles are separate inputs. `hydradb_query` accepts document names -through `titles`; it does not accept source IDs. Use `hydradb_inspect` or -`hydradb_subgraph` when you have one source ID, or `hydradb_list` with `ids` when -you have several. HydraDB never guesses from the input format. +Source IDs and titles are separate inputs. Use `source_ids` for source IDs and +`titles` for document names. When both are present, HydraDB intersects the two +scopes. HydraDB never guesses from the input format. Two documents with the same normalized title are treated as the same title and