@hydradb/mcp 1.2.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,56 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.4.0] - 2026-09-01
11
+
12
+ ### Added — `recency_bias`, `query_apps` and multi-collection scope on `hydradb_query`
13
+
14
+ Three retrieval controls the API accepts were unreachable through the MCP.
15
+
16
+ - `recency_bias` (0-1) was hardcoded to `0` with no override. That is still the
17
+ default, and the API's own, so ranking is unchanged for callers that do not
18
+ set it — but "where does this stand now" is a different question from "what
19
+ matches this", and it could not be asked. It re-ranks and never excludes, so
20
+ read the dates rather than trusting the top hit. Note that on
21
+ connector-ingested corpora it currently ranks by the date the API reports,
22
+ which is the ingest time rather than the content's own date (HydraDB
23
+ PRO-1832) — the knob is correct, the data behind it is not yet.
24
+ - `query_apps` enables app-aware retrieval over connector-ingested sources:
25
+ exact IDs and actors, thread reconstruction, and parent/child expansion. A
26
+ Jira comment without its issue, or a Slack reply without its thread, is
27
+ usually not an answer.
28
+ - `collections` scopes one query across several collections, as a list or a
29
+ `{collection: weight}` object. It replaces the singular `collection` for that
30
+ request rather than joining it: Hydra DB refuses a request carrying both
31
+ selectors, so passing both is rejected here instead of failing on the wire,
32
+ and the configured default collection is not injected alongside it. OAuth
33
+ confinement is enforced on every named collection, so a multi-scope selector
34
+ cannot reach past what a connection was confined to.
35
+
36
+ Temporal retrieval (`temporal_now` / `temporal_facts`) remains unreachable: the
37
+ fields are live in the API but absent from the OpenAPI spec, so `@hydradb/sdk`
38
+ does not generate them. Blocked on the spec, not on this server.
39
+
40
+ ## [1.3.0] - 2026-08-28
41
+
42
+ ### Added — OAuth resource server ("Sign in with HydraDB")
43
+
44
+ The hosted server can now take part in the MCP authorization flow (PRO-1790).
45
+ Given `HYDRADB_OAUTH_ISSUER`, `HYDRADB_MCP_PUBLIC_URL` and
46
+ `HYDRADB_OAUTH_INTROSPECTION_SECRET`, it serves an RFC 9728 Protected Resource
47
+ Metadata document at `/.well-known/oauth-protected-resource`, points every
48
+ `401` at it through `WWW-Authenticate`, and accepts `hmat_` access tokens
49
+ issued by the HydraDB dashboard, exchanging each (memoised, bounded by the
50
+ token's own expiry) for the API key and database the user approved on the
51
+ consent screen. Tokens minted for another audience are refused; an unreachable
52
+ issuer answers `503` rather than a `401` blaming the caller.
53
+
54
+ Entirely additive. With the three variables unset the server registers no new
55
+ routes and sends no new headers, and every existing path — API keys in
56
+ `Authorization` or `X-HydraDB-Api-Key`, the `X-HydraDB-Database` and collection
57
+ and graph headers, and the single-tenant environment fallback — behaves exactly
58
+ as before whether OAuth is configured or not.
59
+
10
60
  ## [1.2.2] - 2026-08-19
11
61
 
12
62
  ### Added — per-call database and collection scope overrides
package/README.md CHANGED
@@ -17,9 +17,10 @@ Run it two ways, same tools either way:
17
17
  | `hydradb_inspect` | Fetch one source's full content by id |
18
18
  | `hydradb_delete` | Remove one or more items by id, irreversibly |
19
19
  | `hydradb_status` | Check whether an ingested source has finished indexing |
20
+ | `hydradb_subgraph` | Everything connected to one item — its thread, replies, parents, children, links |
20
21
 
21
- Ids flow between these: `hydradb_query` and `hydradb_list` emit them;
22
- `hydradb_inspect`, `hydradb_delete` and `hydradb_status` accept them.
22
+ Ids flow between these: `hydradb_query`, `hydradb_list` and `hydradb_subgraph` emit them;
23
+ `hydradb_inspect`, `hydradb_delete`, `hydradb_status` and `hydradb_subgraph` accept them.
23
24
 
24
25
  ### Graph tools (Cypher)
25
26
 
@@ -93,6 +94,9 @@ chunks with their source id, a relevance score, and knowledge-graph context.
93
94
  | `source_ids` | array | No | Restrict the search to these sources |
94
95
  | `metadata_filters` | object | No | Exact-match filters over stored metadata |
95
96
  | `num_related_chunks` | number | No | Adjacent chunks to attach per match (0-5, default: 0) |
97
+ | `recency_bias` | number | No | Favour recently-updated sources when ranking, 0-1 (default: 0). Re-ranks only; it never excludes older sources |
98
+ | `query_apps` | boolean | No | App-aware retrieval over connector sources — exact IDs and actors, thread reconstruction, parent/child expansion (default: false) |
99
+ | `collections` | array | No | Search several collections at once. Pass either this or `collection`, never both |
96
100
 
97
101
  ### **hydradb_ingest**
98
102
 
@@ -149,6 +153,33 @@ Fetches one source's full content by id.
149
153
  Long sources come back in slices, and binary sources are never inlined — you get
150
154
  their type and size, and `mode: "url"` returns a download link.
151
155
 
156
+ ### **hydradb_subgraph**
157
+
158
+ Returns the connected subgraph of one item: every item reachable from it through
159
+ item-level links — explicit relations declared at ingest, a shared thread,
160
+ parent/child hierarchy — traversed breadth-first. Use it when one result is not
161
+ enough and you need what surrounds it: the rest of a Slack thread, the replies
162
+ under a ticket, the documents a page links to.
163
+
164
+ | Parameter | Type | Required | Description |
165
+ |-----------|------|----------|-------------|
166
+ | `id` | string | Yes | The item to start from, from `hydradb_query` or `hydradb_list` |
167
+ | `kind` | string | No | `knowledge` (default) or `memory` — the two graphs are separate |
168
+ | `depth` | number | No | Hops to traverse (default 5, max 10) |
169
+ | `max_sources` | number | No | Cap on members returned (default 200, max 1000) |
170
+ | `database`, `collection` | string | No | Scope overrides |
171
+
172
+ Each member carries its id, title, depth from the start item and how it was
173
+ reached — `discovered_relation` is the mechanism (`same_thread`, `parent`,
174
+ `child`, or a `relates_to` type such as `reply_to`) and `discovered_via` the id
175
+ of the member it was reached from, so the list is also a tree.
176
+ `structuredContent` carries those same members, in the same order, plus
177
+ `relations`: the edges among them as `{from, to, type}`, so a client can rebuild
178
+ the graph and not just the list. `truncated` means `max_sources` clipped the
179
+ traversal; `structural_link_count` and `structural_truncated` report the
180
+ structural graph (entities, comments, attachments, actors) around the members.
181
+ Chunk-level entity relations are not included; those come from `hydradb_query`.
182
+
152
183
  ### **hydradb_delete**
153
184
 
154
185
  Removes items by id. Irreversible.
@@ -363,8 +394,23 @@ The primary MCP endpoint is `/` (with `/mcp` supported as an alias); `GET /healt
363
394
  The image binds `0.0.0.0` inside the container (the host controls exposure with
364
395
  `-p`) and runs as an unprivileged user.
365
396
 
397
+ ### Sign in with HydraDB (OAuth)
398
+
399
+ With three extra variables the hosted server also speaks the MCP authorization flow: a client that arrives with no credentials gets a `401` pointing at `/.well-known/oauth-protected-resource`, discovers the HydraDB dashboard as its authorization server, opens the browser, and the user signs in and picks a database. No key is ever pasted into a client.
400
+
401
+ | Variable | Description |
402
+ | --- | --- |
403
+ | `HYDRADB_OAUTH_ISSUER` | The authorization server, e.g. `https://app.hydradb.com`. Must match its `NEXTAUTH_URL` exactly |
404
+ | `HYDRADB_MCP_PUBLIC_URL` | This server's public URL as clients see it, e.g. `https://mcp.hydradb.com`. Tokens minted for any other audience are refused |
405
+ | `HYDRADB_OAUTH_INTROSPECTION_SECRET` | Shared secret the issuer's `/api/oauth/introspect` expects; must equal the dashboard's `MCP_INTROSPECTION_SECRET` |
406
+
407
+ All three are required together. With any of them missing, OAuth stays off and the server behaves exactly as before: no new routes, no new headers. Token introspection answers are memoised for up to 30 seconds, so disconnecting an app from the dashboard takes effect within that window.
408
+
409
+ OAuth is purely additive. API keys in `Authorization` / `X-HydraDB-Api-Key` headers, the `X-HydraDB-Database` header and the single-tenant environment fallback all keep working unchanged on the same URL.
410
+
366
411
  ### Server environment variables
367
412
 
413
+
368
414
  These configure the HTTP process itself (the stdio server ignores them). All
369
415
  the `HYDRADB_*` variables from [Environment Variables](#environment-variables)
370
416
  also apply — as the single-tenant default and as operator settings.
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import type { HydraDB as SDK } from "@hydradb/sdk";
11
11
  import type { AddMemoryResponse } from "./types.js";
12
- export declare function toAddMemoryResponse(data: SDK.IngestionV2SourceUploadResponse): AddMemoryResponse;
12
+ export declare function toAddMemoryResponse(data: SDK.IngestionV2IngestResponse): AddMemoryResponse;
13
13
  export interface MemoryListItem {
14
14
  memory_id: string;
15
15
  memory_content: string;
@@ -33,7 +33,7 @@ export interface MemoryList {
33
33
  page: PageInfo;
34
34
  }
35
35
  /** SDK list result → memory rows. Field names vary across v2 records, so read defensively. */
36
- export declare function toMemoryList(data: SDK.ListV2SourceListResponse): MemoryList;
36
+ export declare function toMemoryList(data: SDK.ListV2ListResponse): MemoryList;
37
37
  export interface SourceListItem {
38
38
  id: string;
39
39
  title?: string;
@@ -45,4 +45,4 @@ export interface SourceList {
45
45
  page: PageInfo;
46
46
  }
47
47
  /** SDK list result → knowledge source rows + total. */
48
- export declare function toSourceList(data: SDK.ListV2SourceListResponse): SourceList;
48
+ export declare function toSourceList(data: SDK.ListV2ListResponse): SourceList;
@@ -1 +1 @@
1
- {"version":3,"file":"adapters.js","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapters.js","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;;;;;;;GASG;AACH,SAAS,kBAAkB,CAC1B,IAAqC;IAErC,OAAO;QACN,SAAS,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;QACxB,KAAK,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI;QAC5B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,SAAS;QAChC,0EAA0E;QAC1E,0DAA0D;QAC1D,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;QACzB,UAAU,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;QAClC,eAAe,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI;KAC5C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAClC,IAAmC;IAEnC,OAAO;QACN,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;QAC9B,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;QAC3B,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACrD,aAAa,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC;QACrC,YAAY,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;KACnC,CAAC;AACH,CAAC;AAED,SAAS,GAAG,CAAC,MAA+B,EAAE,GAAG,IAAc;IAC9D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;IAC7C,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAC1B,CAAC,CAAE,KAAmC;QACtC,CAAC,CAAC,SAAS,CAAC;AACd,CAAC;AA2BD,SAAS,GAAG,CAAC,MAA+B,EAAE,GAAG,IAAc;IAC9D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;IAC7C,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAClB,SAAkC,EAClC,QAAgB;IAEhB,MAAM,IAAI,GACR,SAAS,CAAC,UAAkD,IAAI,EAAE,CAAC;IACrE,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5D,OAAO;QACN,KAAK,EAAE,KAAK,IAAI,QAAQ;QACxB,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,CAAC;QAC7C,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,YAAY,CAAC;QACnD,QAAQ,EACP,OAAO,IAAI,CAAC,QAAQ,KAAK,SAAS;YACjC,CAAC,CAAC,IAAI,CAAC,QAAQ;YACf,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS;gBAClC,CAAC,CAAC,IAAI,CAAC,OAAO;gBACd,CAAC,CAAC,SAAS;KACd,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,YAAY,CAAC,IAA4B;IACxD,sEAAsE;IACtE,2EAA2E;IAC3E,MAAM,CAAC,GAAG,IAA0C,CAAC;IACrD,MAAM,SAAS,GACd,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,KAAiC,CAAC,IAAI,CAAC,CAAC;IAC9E,MAAM,OAAO,GACZ,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;QAC1B,SAAS,CAAE,CAAC,CAAC,KAA6C,EAAE,aAAa,CAAC;QAC1E,EAAE,CAAC;IACJ,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACzC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE;QAC5D,cAAc,EACb,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE;KAC1E,CAAC,CAAC,CAAC;IACJ,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;AACnE,CAAC;AAcD,uDAAuD;AACvD,MAAM,UAAU,YAAY,CAAC,IAA4B;IACxD,yEAAyE;IACzE,MAAM,CAAC,GAAG,IAA0C,CAAC;IACrD,MAAM,SAAS,GACd,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,KAAiC,CAAC,IAAI,CAAC,CAAC;IACxE,MAAM,OAAO,GACZ,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QACpB,SAAS,CAAE,CAAC,CAAC,KAA6C,EAAE,OAAO,CAAC;QACpE,EAAE,CAAC;IACJ,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxC,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE;QACxC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;QAC3B,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC;KACxC,CAAC,CAAC,CAAC;IACJ,MAAM,KAAK,GACV,CAAC,CAAC,KAAK,IAAK,CAAC,CAAC,KAA6C,EAAE,KAAK,CAAC;IACpE,OAAO;QACN,OAAO;QACP,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM;QACzD,IAAI,EAAE,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC;KAC3C,CAAC;AACH,CAAC"}
@@ -7,10 +7,16 @@
7
7
  * replacement so the model prefers the new name.
8
8
  */
9
9
  export declare const TOOL_DESCRIPTIONS: {
10
+ readonly hydradb_databases: {
11
+ readonly title: "List Hydra DB Databases";
12
+ readonly description: "List the databases this connection can address, with the default marked. Use it before passing `database` to another tool, when the user asks which databases exist, or when a call was refused for naming a database this connection is confined to. If the list has one entry, that is the only database this connection may use.";
13
+ readonly params: {};
14
+ };
10
15
  readonly hydradb_query: {
11
16
  readonly title: "Query Hydra DB";
12
17
  readonly description: "Search Hydra DB for anything the user has stored: memories (facts, preferences, decisions, past conversations) and ingested knowledge sources (documents, files, playbooks). Returns matching chunks with their source id, a relevance score, and knowledge-graph context — the entity paths and relations that connect facts across separate sources.\n\nCALL THIS BEFORE ANSWERING whenever the answer could depend on the user's history, preferences, prior decisions, project details, or a document they have ingested — including when you are merely unsure. A query that returns nothing costs one call; answering from a blank slate costs the user a correction.\n\nSearches both families by default. Every result carries `[id: …]` — pass it to hydradb_inspect for the full source, or to hydradb_delete to remove it.\n\nExamples:\n {\"query\": \"how does the user prefer code review feedback\"}\n {\"query\": \"postgres connection pooling decision\", \"kind\": \"knowledge\"}\n {\"query\": \"deploy checklist\", \"mode\": \"fast\", \"max_results\": 5}";
13
18
  readonly params: {
19
+ readonly acl: "Principals to answer as, for permission-aware search (RBAC). Each entry is an email, a `domain:<host>`, or a `group:<provider>:<id>`; results are limited to documents whose access list admits at least one of them. Omit it to search everything this API key can reach. An EMPTY list is treated exactly like omitting it, so it is not a way to ask for \"nobody\" — to restrict, name real principals. Pass the principals of the end user you are answering for; a principal the deployment does not recognise fails closed, matching only documents that carry no access list of their own. This scopes results, it does not authenticate anyone: whoever holds the key can name any principal.";
14
20
  readonly query: string;
15
21
  readonly kind: string;
16
22
  readonly max_results: string;
@@ -21,8 +27,11 @@ export declare const TOOL_DESCRIPTIONS: {
21
27
  readonly source_ids: string;
22
28
  readonly metadata_filters: string;
23
29
  readonly num_related_chunks: string;
30
+ readonly recency_bias: string;
31
+ readonly query_apps: string;
24
32
  readonly database: string;
25
33
  readonly collection: string;
34
+ readonly collections: string;
26
35
  };
27
36
  };
28
37
  readonly hydradb_ingest: {
@@ -48,6 +57,7 @@ export declare const TOOL_DESCRIPTIONS: {
48
57
  readonly title: "List Hydra DB Context";
49
58
  readonly description: "Enumerate what is stored in Hydra DB — every memory (kind: \"memory\") or every knowledge source (kind: \"knowledge\"). These are SEPARATE corpora and this tool returns one at a time: listing memories tells you nothing about which knowledge sources exist, and vice versa. Call it twice to see everything.\n\nUse it for inventory questions (\"what do you remember about me?\", \"which documents are indexed?\") and to obtain ids. For \"what do you know about X\", use hydradb_query instead — listing everything and reading it is far more expensive and loses relevance ranking.\n\nResults are paginated. The response says how many of the total it showed and how to reach the rest; do not treat the first page as the whole store.\n\nMemory rows come back as [id] content. Knowledge rows as [id] — title (type), with no content — pass an id to hydradb_inspect for the text.";
50
59
  readonly params: {
60
+ readonly acl: "Principals to answer as, for permission-aware search (RBAC). Each entry is an email, a `domain:<host>`, or a `group:<provider>:<id>`; results are limited to documents whose access list admits at least one of them. Omit it to search everything this API key can reach. An EMPTY list is treated exactly like omitting it, so it is not a way to ask for \"nobody\" — to restrict, name real principals. Pass the principals of the end user you are answering for; a principal the deployment does not recognise fails closed, matching only documents that carry no access list of their own. This scopes results, it does not authenticate anyone: whoever holds the key can name any principal.";
51
61
  readonly kind: string;
52
62
  readonly source_ids: "Optional array of specific source IDs to filter by. If omitted, lists all sources.";
53
63
  readonly page: string;
@@ -56,10 +66,24 @@ export declare const TOOL_DESCRIPTIONS: {
56
66
  readonly collection: string;
57
67
  };
58
68
  };
69
+ readonly hydradb_subgraph: {
70
+ readonly title: "Hydra DB Connected Subgraph";
71
+ readonly description: "Return the connected subgraph of ONE stored item: every item reachable from it through item-level links — explicit relations declared at ingest, the thread it belongs to, and parent/child hierarchy — traversed breadth-first up to `depth` hops. Use it after hydradb_query or hydradb_list when a single result is not enough and you need what surrounds it: the rest of a Slack thread, the replies under a ticket, the documents a page links to.\n\nEach member carries its id, title, depth from the start item (0 is the item itself) and how it was reached: the mechanism (`same_thread`, `parent`, `child`, or a `relates_to` type such as `reply_to`) and the id of the member it was reached from, so the list is also a tree. Pass any member's id to hydradb_inspect for its full content. The response also lists the relations among the members and the structural graph around them — the entities, comments, attachments and people attached to each — but NOT the chunk-level entity relations hydradb_query returns; those are a different read.\n\nAn id nothing links to returns just that item. An unknown id returns an empty result, not an error. `is_truncated` means `max_sources` clipped the traversal; `max_depth_reached` says how far it got.\n\nRead-only; never changes anything.";
72
+ readonly params: {
73
+ readonly id: string;
74
+ readonly kind: "Which family the id belongs to: 'knowledge' (default) or 'memory'. The two graphs are separate.";
75
+ readonly depth: string;
76
+ readonly max_sources: "Cap on members returned (default 200). The result says when this clipped the traversal.";
77
+ readonly acl: "Principals to answer as, for permission-aware search (RBAC). Each entry is an email, a `domain:<host>`, or a `group:<provider>:<id>`; results are limited to documents whose access list admits at least one of them. Omit it to search everything this API key can reach. An EMPTY list is treated exactly like omitting it, so it is not a way to ask for \"nobody\" — to restrict, name real principals. Pass the principals of the end user you are answering for; a principal the deployment does not recognise fails closed, matching only documents that carry no access list of their own. This scopes results, it does not authenticate anyone: whoever holds the key can name any principal.";
78
+ readonly database: string;
79
+ readonly collection: string;
80
+ };
81
+ };
59
82
  readonly hydradb_inspect: {
60
83
  readonly title: "Inspect Hydra DB Source";
61
84
  readonly description: "Fetch the full original content of ONE stored item by its id. Use it after hydradb_query or hydradb_list when a truncated chunk or listing row is not enough and you need the whole document.\n\nThe id is the value shown as `[id: …]` in hydradb_query results and in [brackets] in hydradb_list output. Ids are not guessable — take one from those tools rather than constructing it.\n\nLong sources come back in slices; the response says where it stopped and what offset continues it. Binary sources are never inlined — you get their type and size, and `mode: \"url\"` returns a download link.";
62
85
  readonly params: {
86
+ readonly acl: "Principals to answer as, for permission-aware search (RBAC). Each entry is an email, a `domain:<host>`, or a `group:<provider>:<id>`; results are limited to documents whose access list admits at least one of them. Omit it to search everything this API key can reach. An EMPTY list is treated exactly like omitting it, so it is not a way to ask for \"nobody\" — to restrict, name real principals. Pass the principals of the end user you are answering for; a principal the deployment does not recognise fails closed, matching only documents that carry no access list of their own. This scopes results, it does not authenticate anyone: whoever holds the key can name any principal.";
63
87
  readonly source_id: "The source ID to fetch content for";
64
88
  readonly mode: string;
65
89
  readonly offset: string;
@@ -9,6 +9,7 @@
9
9
  import { ALIAS_REPLACEMENTS, TOOL_NAMES } from "./tool-names.js";
10
10
  // Shared parameter blurbs, reused across canonical tools and their aliases.
11
11
  const PARAM = {
12
+ acl: "Principals to answer as, for permission-aware search (RBAC). Each entry is an email, a `domain:<host>`, or a `group:<provider>:<id>`; results are limited to documents whose access list admits at least one of them. Omit it to search everything this API key can reach. An EMPTY list is treated exactly like omitting it, so it is not a way to ask for \"nobody\" — to restrict, name real principals. Pass the principals of the end user you are answering for; a principal the deployment does not recognise fails closed, matching only documents that carry no access list of their own. This scopes results, it does not authenticate anyone: whoever holds the key can name any principal.",
12
13
  query: "What you want to know, as a natural-language question or topic — this is semantic " +
13
14
  "search, so a full question beats keywords. Search for the CONCEPT, not the words " +
14
15
  "the user used: 'database migration decisions' will find a memory written as 'we " +
@@ -34,6 +35,23 @@ const PARAM = {
34
35
  num_related_chunks: "Adjacent chunks to attach to each match for surrounding context (default: 0). " +
35
36
  "Each one multiplies the response size, so use 1-2 only when snippets are " +
36
37
  "arriving mid-sentence; prefer hydradb_inspect when you want a whole source.",
38
+ recency_bias: "How much to favour recently-updated sources when ranking, 0 to 1 " +
39
+ "(default: 0, no recency preference). Raise it for 'where does this stand " +
40
+ "now' questions, where an older source can answer the words of the query " +
41
+ "perfectly and still be superseded — 0.8-0.9 puts the current version on " +
42
+ "top. Leave it at 0 when the age of a source says nothing about whether it " +
43
+ "is the right one. This re-RANKS; it never excludes older sources, so " +
44
+ "check the dates in the results rather than assuming the top hit is current.",
45
+ query_apps: "Search connector-ingested sources with app awareness (default: false). " +
46
+ "Turn it on for Slack, Jira, Confluence, Drive and similar: it matches " +
47
+ "exact IDs and actors, reconstructs threads, and pulls in parent/child " +
48
+ "pages that plain text matching misses — a Jira comment is unhelpful " +
49
+ "without its issue, and a Slack reply without its thread. Adds a little " +
50
+ "latency, so leave it off for corpora you uploaded directly.",
51
+ collections: "Search SEVERAL collections at once, as a list of names. Use it when the " +
52
+ "answer could live in more than one and you do not know which — otherwise " +
53
+ "prefer a single `collection`, which is both faster and more precise. " +
54
+ "Pass either this or `collection`, never both.",
37
55
  operator: "Switches this query to KEYWORD retrieval (query_by=text) and says how to " +
38
56
  "combine the terms: 'or' matches any, 'and' requires all, 'phrase' matches the " +
39
57
  "words together in order. Hydra DB accepts an operator only on keyword " +
@@ -104,6 +122,12 @@ const PARAM = {
104
122
  "chunk whole; use it when the snippets are being cut off mid-answer. Either way " +
105
123
  "the response is capped, and hydradb_inspect returns any single source in full.",
106
124
  fetch_source_id: "The source ID to fetch content for",
125
+ subgraph_id: "The id of the item to start from — the value shown as [id: …] in hydradb_query results " +
126
+ "or in [brackets] in hydradb_list output.",
127
+ subgraph_kind: "Which family the id belongs to: 'knowledge' (default) or 'memory'. The two graphs are separate.",
128
+ subgraph_depth: "How many hops to traverse from the item (default 5, max 10). 1 is its direct " +
129
+ "links only; larger values reach further along threads and hierarchies.",
130
+ subgraph_max_sources: "Cap on members returned (default 200). The result says when this clipped the traversal.",
107
131
  fetch_mode: "'content' (default) returns the text — normally what you want. 'url' returns a " +
108
132
  "short-lived presigned download link INSTEAD of the text, for binary sources or " +
109
133
  "when handing the user a download. 'both' returns text and link.",
@@ -117,8 +141,10 @@ const PARAM = {
117
141
  "were actually removed. This is irreversible.",
118
142
  delete_kind: "Which context family the ID belongs to: 'memory' or 'knowledge' (default: 'memory')",
119
143
  memory_id: "The ID of the memory to delete",
120
- database: "Database (tenant) to target for this request. Defaults to the server's configured " +
121
- "database. Pass explicitly to switch database scope per request.",
144
+ database: "Database (tenant) to target for this request. Defaults to the database this " +
145
+ "connection was set up with. Pass explicitly to work in another of the user's " +
146
+ "databases; hydradb_databases lists them. A connection the user confined to one " +
147
+ "database refuses any other name.",
122
148
  collection: "Collection (sub-tenant) to target for this request. Defaults to the server's configured " +
123
149
  "collection (or 'hydra-db-mcp'). Pass explicitly to switch collection scope per request.",
124
150
  };
@@ -187,6 +213,13 @@ const LIST_MEMORIES_BODY = "List all stored user memories in Hydra DB. Returns m
187
213
  const LIST_SOURCES_BODY = "List all ingested sources in Hydra DB memory. Returns source IDs, titles, types, " +
188
214
  "and metadata. Use this to see what data sources have been ingested and to find " +
189
215
  "source IDs for fetching content.";
216
+ const SUBGRAPH_BODY = `Return the connected subgraph of ONE stored item: every item reachable from it through item-level links — explicit relations declared at ingest, the thread it belongs to, and parent/child hierarchy — traversed breadth-first up to \`depth\` hops. Use it after hydradb_query or hydradb_list when a single result is not enough and you need what surrounds it: the rest of a Slack thread, the replies under a ticket, the documents a page links to.
217
+
218
+ Each member carries its id, title, depth from the start item (0 is the item itself) and how it was reached: the mechanism (\`same_thread\`, \`parent\`, \`child\`, or a \`relates_to\` type such as \`reply_to\`) and the id of the member it was reached from, so the list is also a tree. Pass any member's id to hydradb_inspect for its full content. The response also lists the relations among the members and the structural graph around them — the entities, comments, attachments and people attached to each — but NOT the chunk-level entity relations hydradb_query returns; those are a different read.
219
+
220
+ An id nothing links to returns just that item. An unknown id returns an empty result, not an error. \`is_truncated\` means \`max_sources\` clipped the traversal; \`max_depth_reached\` says how far it got.
221
+
222
+ Read-only; never changes anything.`;
190
223
  const INSPECT_BODY = `Fetch the full original content of ONE stored item by its id. Use it after hydradb_query or hydradb_list when a truncated chunk or listing row is not enough and you need the whole document.
191
224
 
192
225
  The id is the value shown as \`[id: …]\` in hydradb_query results and in [brackets] in hydradb_list output. Ids are not guessable — take one from those tools rather than constructing it.
@@ -242,12 +275,19 @@ const GRAPH_ADMIN_BODY = `Manage graph databases and collections. Pick one \`act
242
275
  The two drops are IRREVERSIBLE and there is no trash. Confirm with the user before either, and never infer one from a vague instruction — "clean up my graph" authorises nothing until the user has seen ${TOOL_NAMES.GRAPH_COLLECTIONS} output and named what should go.
243
276
 
244
277
  There is no create-collection action: collections come into existence on their first write via ${TOOL_NAMES.GRAPH_QUERY}.`;
278
+ const DATABASES_BODY = `List the databases this connection can address, with the default marked. Use it before passing \`database\` to another tool, when the user asks which databases exist, or when a call was refused for naming a database this connection is confined to. If the list has one entry, that is the only database this connection may use.`;
245
279
  export const TOOL_DESCRIPTIONS = {
246
280
  // --- Canonical tools (CONTRACT §3) ---
281
+ [TOOL_NAMES.DATABASES]: {
282
+ title: "List Hydra DB Databases",
283
+ description: DATABASES_BODY,
284
+ params: {},
285
+ },
247
286
  [TOOL_NAMES.QUERY]: {
248
287
  title: "Query Hydra DB",
249
288
  description: SEARCH_BODY,
250
289
  params: {
290
+ acl: PARAM.acl,
251
291
  query: PARAM.query,
252
292
  kind: PARAM.query_kind,
253
293
  max_results: PARAM.max_results,
@@ -258,8 +298,11 @@ export const TOOL_DESCRIPTIONS = {
258
298
  source_ids: PARAM.query_source_ids,
259
299
  metadata_filters: PARAM.metadata_filters,
260
300
  num_related_chunks: PARAM.num_related_chunks,
301
+ recency_bias: PARAM.recency_bias,
302
+ query_apps: PARAM.query_apps,
261
303
  database: PARAM.database,
262
304
  collection: PARAM.collection,
305
+ collections: PARAM.collections,
263
306
  },
264
307
  },
265
308
  [TOOL_NAMES.INGEST]: {
@@ -298,6 +341,7 @@ Results are paginated. The response says how many of the total it showed and how
298
341
 
299
342
  Memory rows come back as [id] content. Knowledge rows as [id] — title (type), with no content — pass an id to hydradb_inspect for the text.`,
300
343
  params: {
344
+ acl: PARAM.acl,
301
345
  kind: PARAM.kind,
302
346
  source_ids: PARAM.source_ids,
303
347
  page: PARAM.page,
@@ -306,10 +350,24 @@ Memory rows come back as [id] content. Knowledge rows as [id] — title (type),
306
350
  collection: PARAM.collection,
307
351
  },
308
352
  },
353
+ [TOOL_NAMES.SUBGRAPH]: {
354
+ title: "Hydra DB Connected Subgraph",
355
+ description: SUBGRAPH_BODY,
356
+ params: {
357
+ id: PARAM.subgraph_id,
358
+ kind: PARAM.subgraph_kind,
359
+ depth: PARAM.subgraph_depth,
360
+ max_sources: PARAM.subgraph_max_sources,
361
+ acl: PARAM.acl,
362
+ database: PARAM.database,
363
+ collection: PARAM.collection,
364
+ },
365
+ },
309
366
  [TOOL_NAMES.INSPECT]: {
310
367
  title: "Inspect Hydra DB Source",
311
368
  description: INSPECT_BODY,
312
369
  params: {
370
+ acl: PARAM.acl,
313
371
  source_id: PARAM.fetch_source_id,
314
372
  mode: PARAM.fetch_mode,
315
373
  offset: PARAM.fetch_offset,
@@ -475,8 +533,10 @@ THE TOOLS
475
533
  - ${TOOL_NAMES.INSPECT} — the complete original content of one source you already have an id for.
476
534
  - ${TOOL_NAMES.DELETE} — irreversible removal of one item by id.
477
535
  - ${TOOL_NAMES.STATUS} — whether an ingested source has finished indexing. Ingestion is asynchronous, so a query issued straight after a save can legitimately return nothing.
536
+ - ${TOOL_NAMES.SUBGRAPH} — everything connected to one item you already have an id for: the rest of its thread, its replies, its parents and children, the items it links to. Reach for it when one result is not enough and you need what surrounds it.
537
+ - ${TOOL_NAMES.DATABASES} — which databases this connection can address, with the default marked. Every tool takes an optional \`database\`; call this before naming one, or when a call was refused because the user confined this connection to a single database.
478
538
 
479
- Ids flow between these: ${TOOL_NAMES.QUERY} and ${TOOL_NAMES.LIST} emit them, ${TOOL_NAMES.INSPECT}, ${TOOL_NAMES.DELETE} and ${TOOL_NAMES.STATUS} accept them. Never invent one.
539
+ Ids flow between these: ${TOOL_NAMES.QUERY}, ${TOOL_NAMES.LIST} and ${TOOL_NAMES.SUBGRAPH} emit them; ${TOOL_NAMES.INSPECT}, ${TOOL_NAMES.DELETE}, ${TOOL_NAMES.STATUS} and ${TOOL_NAMES.SUBGRAPH} accept them. Never invent one.
480
540
 
481
541
  THE GRAPH TOOLS (a separate product surface)
482
542
 
@@ -1 +1 @@
1
- {"version":3,"file":"descriptions.js","sourceRoot":"","sources":["../src/descriptions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"descriptions.js","sourceRoot":"","sources":["../src/descriptions.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@
20
20
  * to the environment only to keep the single-tenant self-hosting story (set the
21
21
  * env, expose the port, done) working unchanged.
22
22
  */
23
+ import type { OAuthConfig } from "./oauth.js";
23
24
  import { type EnvSource, type GraphConfig } from "./config.js";
24
25
  export interface HttpServerConfig {
25
26
  /** TCP port to listen on. */
@@ -40,6 +41,12 @@ export interface HttpServerConfig {
40
41
  * subnet preset so the real client IP is recovered without trusting all hops.
41
42
  */
42
43
  trustProxy: boolean | number | string;
44
+ /**
45
+ * OAuth resource-server settings, or absent when OAuth is off. Resolved
46
+ * from the environment by {@link resolveHttpServerConfig}; tests pass it
47
+ * directly.
48
+ */
49
+ oauth?: OAuthConfig | null;
43
50
  }
44
51
  export declare const DEFAULT_PORT = 8080;
45
52
  export declare const DEFAULT_BIND_ADDRESS = "127.0.0.1";
@@ -105,6 +112,10 @@ export interface RequestCredentials {
105
112
  apiKey: string;
106
113
  database: string;
107
114
  collection: string;
115
+ /** Databases a per-call override may name; absent means any. */
116
+ allowedDatabases?: string[];
117
+ /** Collections a per-call override may name; absent means any. */
118
+ allowedCollections?: string[];
108
119
  baseUrl?: string;
109
120
  timeoutSeconds?: number;
110
121
  maxRetries?: number;
@@ -148,7 +159,26 @@ export type CredentialResolution = {
148
159
  * request. `baseUrl`/`timeoutSeconds`/`maxRetries` are read from the environment
149
160
  * only — they are the operator's, not the caller's (see {@link RequestCredentials}).
150
161
  */
151
- export declare function resolveRequestCredentials(headers: RequestHeaders, env?: EnvSource): CredentialResolution;
162
+ /**
163
+ * An identity established BEFORE the headers are read: what an OAuth access
164
+ * token was found to stand for.
165
+ *
166
+ * It is passed in rather than resolved here because obtaining it is an
167
+ * asynchronous call to the authorization server, and this resolver is
168
+ * deliberately synchronous and pure. When present it replaces the header
169
+ * credentials entirely: the user approved this exact scope on the consent
170
+ * screen, and nothing in the request may widen it.
171
+ */
172
+ export interface ResolvedIdentity {
173
+ apiKey: string;
174
+ database?: string;
175
+ collection?: string;
176
+ /** See IntrospectedToken.allowedDatabases. */
177
+ allowedDatabases?: string[];
178
+ /** See IntrospectedToken.allowedCollections. */
179
+ allowedCollections?: string[];
180
+ }
181
+ export declare function resolveRequestCredentials(headers: RequestHeaders, env?: EnvSource, identity?: ResolvedIdentity): CredentialResolution;
152
182
  /** A JSON-RPC error body, so every HTTP failure speaks the protocol's dialect. */
153
183
  export declare function jsonRpcError(code: number, message: string): {
154
184
  jsonrpc: "2.0";
@@ -20,6 +20,7 @@
20
20
  * to the environment only to keep the single-tenant self-hosting story (set the
21
21
  * env, expose the port, done) working unchanged.
22
22
  */
23
+ import { resolveOAuthConfig } from "./oauth.js";
23
24
  import { DEFAULT_COLLECTION, nonNegativeInt, positiveInt, readEnv, resolveGraphConfig, } from "./config.js";
24
25
  export const DEFAULT_PORT = 8080;
25
26
  export const DEFAULT_BIND_ADDRESS = "127.0.0.1";
@@ -93,6 +94,7 @@ export function resolveHttpServerConfig(env = process.env) {
93
94
  allowedOrigins: parseList(env.ALLOWED_ORIGINS),
94
95
  allowedHosts: buildAllowedHosts(port, parseList(env.ALLOWED_HOSTS)),
95
96
  trustProxy: parseTrustProxy(env.TRUST_PROXY),
97
+ oauth: resolveOAuthConfig(env),
96
98
  };
97
99
  }
98
100
  // --- Per-request tenant credentials ---
@@ -134,30 +136,9 @@ function bearerToken(authorization) {
134
136
  return match[1].trim() || undefined;
135
137
  return authorization.trim() || undefined;
136
138
  }
137
- /**
138
- * Turn one request's headers (falling back to the environment) into the tenant
139
- * credentials for that request.
140
- *
141
- * The API key and the database resolve TOGETHER, not field-by-field, which is
142
- * the security-relevant part:
143
- * - When the key comes from a request header, the request is
144
- * "caller-authenticated" and its database MUST also come from a header. The
145
- * env is NOT consulted for the database, so a caller who sends their own key
146
- * but omits `X-HydraDB-Database` is refused (400) rather than silently run
147
- * against the operator's env database. Likewise the graph scope defaults to
148
- * the request's own database, never the operator's `HYDRADB_GRAPH_DATABASE`.
149
- * - When there is no key header, the request is unauthenticated and falls back
150
- * entirely to the operator's env credentials — the single-tenant self-host
151
- * case, identical to the stdio server. A hosted, multi-tenant process sets
152
- * no tenant env, so such a request is refused (401).
153
- *
154
- * Resolving field-by-field instead would let a caller's key pair with the
155
- * operator's database (or graph namespace), mixing two identities into one
156
- * request. `baseUrl`/`timeoutSeconds`/`maxRetries` are read from the environment
157
- * only — they are the operator's, not the caller's (see {@link RequestCredentials}).
158
- */
159
- export function resolveRequestCredentials(headers, env = process.env) {
160
- const headerKey = bearerToken(headerValue(headers, HEADER_AUTHORIZATION)) ??
139
+ export function resolveRequestCredentials(headers, env = process.env, identity) {
140
+ const headerKey = identity?.apiKey ??
141
+ bearerToken(headerValue(headers, HEADER_AUTHORIZATION)) ??
161
142
  headerValue(headers, HEADER_API_KEY);
162
143
  // Whether the CALLER authenticated this request with their own key decides
163
144
  // whether the operator's env is allowed to supply the rest of the identity.
@@ -174,7 +155,12 @@ export function resolveRequestCredentials(headers, env = process.env) {
174
155
  "(or the `X-HydraDB-Api-Key` header). Get a key at https://app.hydradb.com.",
175
156
  };
176
157
  }
177
- const headerDatabase = headerValue(headers, HEADER_DATABASE);
158
+ // An OAuth identity is what the user approved on the consent screen. No
159
+ // request header may alter it: the client holding the token could otherwise
160
+ // re-scope the connection after consent by adding a header. Per-call tool
161
+ // arguments remain the sanctioned way to name another database, and those
162
+ // are checked against the grant's allowed list.
163
+ const headerDatabase = identity ? identity.database : headerValue(headers, HEADER_DATABASE);
178
164
  // A caller-authenticated request takes its database ONLY from the header;
179
165
  // the env database belongs to the operator's identity, not the caller's.
180
166
  const database = callerAuthenticated
@@ -190,7 +176,7 @@ export function resolveRequestCredentials(headers, env = process.env) {
190
176
  }
191
177
  // Collection is a partition WITHIN the resolved database, not a cross-tenant
192
178
  // boundary, so an env default is safe for either mode.
193
- const collection = headerValue(headers, HEADER_COLLECTION) ??
179
+ const collection = (identity ? identity.collection : headerValue(headers, HEADER_COLLECTION)) ??
194
180
  readEnv(env, "HYDRADB_COLLECTION", "HYDRA_DB_SUB_TENANT_ID", noopWarn) ??
195
181
  DEFAULT_COLLECTION;
196
182
  // Operator-owned transport knobs. Same env vars, same parsing as resolveConfig.
@@ -203,10 +189,17 @@ export function resolveRequestCredentials(headers, env = process.env) {
203
189
  apiKey,
204
190
  database,
205
191
  collection,
192
+ ...(identity?.allowedDatabases ? { allowedDatabases: identity.allowedDatabases } : {}),
193
+ ...(identity?.allowedCollections
194
+ ? { allowedCollections: identity.allowedCollections }
195
+ : {}),
206
196
  ...(baseUrl != null ? { baseUrl } : {}),
207
197
  ...(timeoutSeconds != null ? { timeoutSeconds } : {}),
208
198
  ...(maxRetries != null ? { maxRetries } : {}),
209
- graph: resolveRequestGraphConfig(headers, env, database, callerAuthenticated),
199
+ graph: resolveRequestGraphConfig(
200
+ // Same rule for the graph namespace: an OAuth connection's graph scope
201
+ // derives from the approved database, never from a header.
202
+ identity ? {} : headers, env, database, callerAuthenticated, identity),
210
203
  },
211
204
  };
212
205
  }
@@ -224,7 +217,7 @@ export function resolveRequestCredentials(headers, env = process.env) {
224
217
  * memory database — which, because the two are genuinely separate stores, is a
225
218
  * real need.
226
219
  */
227
- function resolveRequestGraphConfig(headers, env, database, callerAuthenticated) {
220
+ function resolveRequestGraphConfig(headers, env, database, callerAuthenticated, identity) {
228
221
  // For a caller-authenticated request the fallback database is the request's
229
222
  // own, so `resolveGraphConfig`'s env default is deliberately not consulted.
230
223
  const base = resolveGraphConfig(env, database);
@@ -232,7 +225,14 @@ function resolveRequestGraphConfig(headers, env, database, callerAuthenticated)
232
225
  return {
233
226
  enabled: base.enabled,
234
227
  database: headerValue(headers, HEADER_GRAPH_DATABASE) ?? defaultDatabase,
235
- collection: headerValue(headers, HEADER_GRAPH_COLLECTION) ?? base.collection,
228
+ // For an OAuth connection the graph collection defaults to the one the
229
+ // user approved, NOT the operator's `HYDRADB_GRAPH_COLLECTION`. On a
230
+ // hosted process that environment value is one namespace shared by every
231
+ // tenant, so inheriting it would run one user's graph calls somewhere
232
+ // they never approved and everyone else can reach.
233
+ collection: identity?.collection ??
234
+ headerValue(headers, HEADER_GRAPH_COLLECTION) ??
235
+ base.collection,
236
236
  };
237
237
  }
238
238
  /**