@hydradb/mcp 1.2.1 → 1.2.2
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 +121 -0
- package/README.md +170 -0
- package/dist/config.d.ts +40 -0
- package/dist/config.js +40 -3
- package/dist/config.js.map +1 -1
- package/dist/cypher.d.ts +51 -0
- package/dist/cypher.js +145 -0
- package/dist/cypher.js.map +1 -0
- package/dist/descriptions.d.ts +55 -0
- package/dist/descriptions.js +150 -1
- package/dist/descriptions.js.map +1 -1
- package/dist/http-config.d.ts +160 -0
- package/dist/http-config.js +253 -0
- package/dist/http-config.js.map +1 -0
- package/dist/http.d.ts +31 -0
- package/dist/http.js +350 -0
- package/dist/http.js.map +1 -0
- package/dist/hydra/client.d.ts +21 -1
- package/dist/hydra/client.js +20 -12
- package/dist/hydra/client.js.map +1 -1
- package/dist/hydra/errors.d.ts +14 -0
- package/dist/hydra/errors.js +16 -0
- package/dist/hydra/errors.js.map +1 -1
- package/dist/hydra/graph.d.ts +82 -0
- package/dist/hydra/graph.js +217 -0
- package/dist/hydra/graph.js.map +1 -0
- package/dist/hydra/index.d.ts +3 -1
- package/dist/hydra/index.js +2 -1
- package/dist/hydra/index.js.map +1 -1
- package/dist/server.d.ts +7 -1
- package/dist/server.js +359 -11
- package/dist/server.js.map +1 -1
- package/dist/tool-names.d.ts +5 -0
- package/dist/tool-names.js +15 -0
- package/dist/tool-names.js.map +1 -1
- package/package.json +10 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cypher.js","sourceRoot":"","sources":["../src/cypher.ts"],"names":[],"mappings":"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"}
|
package/dist/descriptions.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
21
21
|
readonly source_ids: string;
|
|
22
22
|
readonly metadata_filters: string;
|
|
23
23
|
readonly num_related_chunks: string;
|
|
24
|
+
readonly database: string;
|
|
25
|
+
readonly collection: string;
|
|
24
26
|
};
|
|
25
27
|
};
|
|
26
28
|
readonly hydradb_ingest: {
|
|
@@ -38,6 +40,8 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
38
40
|
readonly observation_date: string;
|
|
39
41
|
readonly turns: string;
|
|
40
42
|
readonly user_name: string;
|
|
43
|
+
readonly database: string;
|
|
44
|
+
readonly collection: string;
|
|
41
45
|
};
|
|
42
46
|
};
|
|
43
47
|
readonly hydradb_list: {
|
|
@@ -48,6 +52,8 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
48
52
|
readonly source_ids: "Optional array of specific source IDs to filter by. If omitted, lists all sources.";
|
|
49
53
|
readonly page: string;
|
|
50
54
|
readonly page_size: string;
|
|
55
|
+
readonly database: string;
|
|
56
|
+
readonly collection: string;
|
|
51
57
|
};
|
|
52
58
|
};
|
|
53
59
|
readonly hydradb_inspect: {
|
|
@@ -59,6 +65,8 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
59
65
|
readonly offset: string;
|
|
60
66
|
readonly limit: string;
|
|
61
67
|
readonly expiry_seconds: string;
|
|
68
|
+
readonly database: string;
|
|
69
|
+
readonly collection: string;
|
|
62
70
|
};
|
|
63
71
|
};
|
|
64
72
|
readonly hydradb_delete: {
|
|
@@ -68,6 +76,8 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
68
76
|
readonly ids: string;
|
|
69
77
|
readonly id: "A single ID to delete. Prefer `ids` when removing more than one.";
|
|
70
78
|
readonly kind: "Which context family the ID belongs to: 'memory' or 'knowledge' (default: 'memory')";
|
|
79
|
+
readonly database: string;
|
|
80
|
+
readonly collection: string;
|
|
71
81
|
};
|
|
72
82
|
};
|
|
73
83
|
readonly hydradb_status: {
|
|
@@ -75,6 +85,35 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
75
85
|
readonly description: string;
|
|
76
86
|
readonly params: {
|
|
77
87
|
readonly ids: "The source IDs to check, as returned by hydradb_ingest.";
|
|
88
|
+
readonly database: string;
|
|
89
|
+
readonly collection: string;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
readonly hydradb_graph_query: {
|
|
93
|
+
readonly title: "Query Graph (Cypher)";
|
|
94
|
+
readonly description: string;
|
|
95
|
+
readonly params: {
|
|
96
|
+
readonly query: string;
|
|
97
|
+
readonly params: string;
|
|
98
|
+
readonly database: string;
|
|
99
|
+
readonly collection: string;
|
|
100
|
+
readonly max_rows: string;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
readonly hydradb_graph_collections: {
|
|
104
|
+
readonly title: "List Graph Collections";
|
|
105
|
+
readonly description: "List the graph collections in a graph database. Each collection is an independent graph with its own nodes, relationships and schema.\n\nUse it to discover what exists before querying, or to confirm a write created the collection you expected. Collections auto-create on first write, so a name missing here has simply never been written to.";
|
|
106
|
+
readonly params: {
|
|
107
|
+
readonly database: string;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
readonly hydradb_graph_admin: {
|
|
111
|
+
readonly title: "Manage Graph Databases";
|
|
112
|
+
readonly description: string;
|
|
113
|
+
readonly params: {
|
|
114
|
+
readonly action: string;
|
|
115
|
+
readonly database: string;
|
|
116
|
+
readonly collection: "The collection to drop. Required for \"drop_collection\" and ignored otherwise.";
|
|
78
117
|
};
|
|
79
118
|
};
|
|
80
119
|
readonly hydra_db_search: {
|
|
@@ -86,6 +125,8 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
86
125
|
readonly max_results: string;
|
|
87
126
|
readonly mode: string;
|
|
88
127
|
readonly graph_context: string;
|
|
128
|
+
readonly database: string;
|
|
129
|
+
readonly collection: string;
|
|
89
130
|
};
|
|
90
131
|
};
|
|
91
132
|
readonly hydra_db_store: {
|
|
@@ -100,6 +141,8 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
100
141
|
readonly infer: string;
|
|
101
142
|
readonly is_markdown: string;
|
|
102
143
|
readonly overwrite: string;
|
|
144
|
+
readonly database: string;
|
|
145
|
+
readonly collection: string;
|
|
103
146
|
};
|
|
104
147
|
};
|
|
105
148
|
readonly hydra_db_ingest_conversation: {
|
|
@@ -109,17 +152,25 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
109
152
|
readonly turns: "Array of conversation turns, each with a 'user' and 'assistant' field";
|
|
110
153
|
readonly source_id: "Source identifier to group all turns from the same session together";
|
|
111
154
|
readonly user_name: string;
|
|
155
|
+
readonly database: string;
|
|
156
|
+
readonly collection: string;
|
|
112
157
|
};
|
|
113
158
|
};
|
|
114
159
|
readonly hydra_db_list_memories: {
|
|
115
160
|
readonly title: "List Memories (deprecated)";
|
|
116
161
|
readonly description: string;
|
|
162
|
+
readonly params: {
|
|
163
|
+
readonly database: string;
|
|
164
|
+
readonly collection: string;
|
|
165
|
+
};
|
|
117
166
|
};
|
|
118
167
|
readonly hydra_db_list_sources: {
|
|
119
168
|
readonly title: "List Sources (deprecated)";
|
|
120
169
|
readonly description: string;
|
|
121
170
|
readonly params: {
|
|
122
171
|
readonly source_ids: "Optional array of specific source IDs to filter by. If omitted, lists all sources.";
|
|
172
|
+
readonly database: string;
|
|
173
|
+
readonly collection: string;
|
|
123
174
|
};
|
|
124
175
|
};
|
|
125
176
|
readonly hydra_db_fetch_content: {
|
|
@@ -130,6 +181,8 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
130
181
|
readonly mode: string;
|
|
131
182
|
readonly offset: string;
|
|
132
183
|
readonly limit: string;
|
|
184
|
+
readonly database: string;
|
|
185
|
+
readonly collection: string;
|
|
133
186
|
};
|
|
134
187
|
};
|
|
135
188
|
readonly hydra_db_delete_memory: {
|
|
@@ -137,6 +190,8 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
137
190
|
readonly description: string;
|
|
138
191
|
readonly params: {
|
|
139
192
|
readonly memory_id: "The ID of the memory to delete";
|
|
193
|
+
readonly database: string;
|
|
194
|
+
readonly collection: string;
|
|
140
195
|
};
|
|
141
196
|
};
|
|
142
197
|
};
|
package/dist/descriptions.js
CHANGED
|
@@ -117,6 +117,37 @@ const PARAM = {
|
|
|
117
117
|
"were actually removed. This is irreversible.",
|
|
118
118
|
delete_kind: "Which context family the ID belongs to: 'memory' or 'knowledge' (default: 'memory')",
|
|
119
119
|
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.",
|
|
122
|
+
collection: "Collection (sub-tenant) to target for this request. Defaults to the server's configured " +
|
|
123
|
+
"collection (or 'hydra-db-mcp'). Pass explicitly to switch collection scope per request.",
|
|
124
|
+
};
|
|
125
|
+
/** Parameter blurbs for the BYOG graph tools. */
|
|
126
|
+
const GRAPH_PARAM = {
|
|
127
|
+
query: "The Cypher to run — a read (MATCH/RETURN, traversal, aggregation) or a write " +
|
|
128
|
+
"(CREATE, MERGE, SET, DELETE, REMOVE, FOREACH, index statements). Write data as " +
|
|
129
|
+
"$parameters, not as string-concatenated literals, and alias every returned " +
|
|
130
|
+
"expression (`RETURN n.name AS name`). Prefer MERGE on a key you own over bare " +
|
|
131
|
+
"CREATE so a retry cannot duplicate. Deletes are irreversible.",
|
|
132
|
+
params: "Values referenced by $name in the query, as {name: value}. Always pass user data " +
|
|
133
|
+
"this way rather than building it into the query text: parameters are bound safely " +
|
|
134
|
+
"and keep query plans cacheable. Lists work too — `UNWIND $rows AS row` with " +
|
|
135
|
+
'{"rows": [...]} is the supported way to write many nodes in one call.',
|
|
136
|
+
database: "Graph database to run against. Defaults to the server's configured graph " +
|
|
137
|
+
"database. This is a DIFFERENT namespace from the memory/knowledge database — a " +
|
|
138
|
+
"query aimed at the wrong one reads an empty graph rather than failing.",
|
|
139
|
+
collection: "Graph collection to run against. Defaults to the server's configured graph " +
|
|
140
|
+
"collection. Each collection is an independent graph; a query sees exactly one " +
|
|
141
|
+
"and never another's data.",
|
|
142
|
+
max_rows: "Maximum rows to render in the response (default: 100). Caps what reaches the " +
|
|
143
|
+
"conversation, not what the query computes — to actually limit the work, put " +
|
|
144
|
+
"`LIMIT` in the Cypher.",
|
|
145
|
+
action: 'Which operation to perform: "create_database", "drop_collection", or ' +
|
|
146
|
+
'"drop_database". The two drops are irreversible.',
|
|
147
|
+
admin_database: "The graph database to create or drop, or the one containing the collection " +
|
|
148
|
+
"being dropped. Defaults to the server's configured graph database — pass it " +
|
|
149
|
+
"explicitly for any drop, so the target is stated rather than inherited.",
|
|
150
|
+
admin_collection: 'The collection to drop. Required for "drop_collection" and ignored otherwise.',
|
|
120
151
|
};
|
|
121
152
|
function deprecated(alias, body) {
|
|
122
153
|
return `DEPRECATED — use \`${ALIAS_REPLACEMENTS[alias]}\` instead. ${body}`;
|
|
@@ -161,6 +192,56 @@ const INSPECT_BODY = `Fetch the full original content of ONE stored item by its
|
|
|
161
192
|
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.
|
|
162
193
|
|
|
163
194
|
Long 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.`;
|
|
195
|
+
/**
|
|
196
|
+
* The dialect notes every graph tool needs to state.
|
|
197
|
+
*
|
|
198
|
+
* These are not general Cypher advice — each one is a construct that a model
|
|
199
|
+
* trained on Neo4j will reach for and that HydraDB REJECTS before running
|
|
200
|
+
* anything. A rejected query fails identically on retry, so the only way out is
|
|
201
|
+
* knowing the rule beforehand.
|
|
202
|
+
*/
|
|
203
|
+
const CYPHER_DIALECT = `HydraDB runs your Cypher verbatim and never rewrites it. Near-complete openCypher, with these differences from Neo4j:
|
|
204
|
+
- Procedure calls are rejected — no \`CALL db.*\`, no \`CALL apoc.*\`. \`CALL { ... }\` subqueries ARE supported. To learn a collection's structure, query it: \`MATCH (n) UNWIND labels(n) AS l RETURN l, count(*) AS c ORDER BY l\`.
|
|
205
|
+
- \`LOAD CSV\` is rejected. Pass data through \`params\`: \`UNWIND $rows AS row MERGE (n:Thing {id: row.id}) SET n += row\`.
|
|
206
|
+
- Existence checks are bare pattern predicates — \`WHERE (p)-[:KNOWS]->()\`. The \`EXISTS { ... }\` block and the \`exists()\` function are not accepted.
|
|
207
|
+
- \`shortestPath\` goes in RETURN or WITH (not \`MATCH p = ...\`) and the traversal must be directed.
|
|
208
|
+
- Do NOT use \`EXPLAIN\`/\`PROFILE\` to preview a query: they EXECUTE it rather than planning it.`;
|
|
209
|
+
const GRAPH_SCOPE = `Queries run against exactly ONE collection — collections never see each other's data, so \`MATCH (n) RETURN n\` returns that collection's nodes and nothing else. \`database\` and \`collection\` default to the server's configured graph scope; pass them to target another.`;
|
|
210
|
+
const GRAPH_QUERY_BODY = `Run Cypher against a HydraDB graph collection — reads and writes alike. This is the graph database product: property graphs you model and own end to end, entirely separate from the memory/knowledge corpora that ${TOOL_NAMES.QUERY} searches.
|
|
211
|
+
|
|
212
|
+
Reads are what a graph is for — multi-hop traversal, variable-length paths, neighbourhood expansion, shortest paths, aggregation over relationships:
|
|
213
|
+
MATCH (a:Person {name:$n})-[:KNOWS*1..4]->(reach) RETURN DISTINCT reach.name AS name
|
|
214
|
+
MATCH (p:Person {name:$n})-[r]-(nbr) RETURN type(r) AS rel, nbr.name AS neighbor
|
|
215
|
+
MATCH (a:Person {name:$x}),(b:Person {name:$y}) RETURN shortestPath((a)-[:KNOWS*..8]->(b)) AS path
|
|
216
|
+
|
|
217
|
+
Writes go through this same tool — CREATE, MERGE, SET, DELETE, REMOVE, FOREACH, and index management:
|
|
218
|
+
UNWIND $rows AS row MERGE (p:Person {ext_id: row.ext_id}) SET p += row
|
|
219
|
+
|
|
220
|
+
THIS TOOL CAN DESTROY DATA. \`MATCH (n:Person) DELETE n\` empties a label and \`DETACH DELETE\` also removes its relationships; neither can be undone and there is no trash. Confirm with the user before running anything destructive they did not explicitly ask for, and prefer MERGE on a key you own over bare CREATE — a retried CREATE duplicates nodes where a MERGE does not.
|
|
221
|
+
|
|
222
|
+
Always pass user data through \`params\` rather than building it into the query string: parameters are bound safely and keep query plans cacheable.
|
|
223
|
+
|
|
224
|
+
ALIAS EVERYTHING you intend to read — \`RETURN n.name AS name\`. Unaliased expressions are keyed by their raw expression text.
|
|
225
|
+
|
|
226
|
+
Large results are silently truncated server-side, so paginate anything that could be big: \`ORDER BY ... SKIP $offset LIMIT $limit\`. Without ORDER BY, the rows you lose are arbitrary.
|
|
227
|
+
|
|
228
|
+
Collections auto-create on first write, so there is no create-collection call. A write with no RETURN succeeds with zero rows — that is success, not failure. Requests are capped at 256 KiB, so batch bulk loads (~500 rows per call is a good start).
|
|
229
|
+
|
|
230
|
+
${GRAPH_SCOPE}
|
|
231
|
+
|
|
232
|
+
${CYPHER_DIALECT}`;
|
|
233
|
+
const GRAPH_COLLECTIONS_BODY = `List the graph collections in a graph database. Each collection is an independent graph with its own nodes, relationships and schema.
|
|
234
|
+
|
|
235
|
+
Use it to discover what exists before querying, or to confirm a write created the collection you expected. Collections auto-create on first write, so a name missing here has simply never been written to.`;
|
|
236
|
+
const GRAPH_ADMIN_BODY = `Manage graph databases and collections. Pick one \`action\`:
|
|
237
|
+
|
|
238
|
+
"create_database" — create a graph database. Ready immediately, no provisioning wait. Fails if the name already exists.
|
|
239
|
+
"drop_collection" — drop ONE collection and all its data. Idempotent: dropping a collection that does not exist succeeds.
|
|
240
|
+
"drop_database" — drop EVERY collection in the database, and the database itself if it was created as a graph database.
|
|
241
|
+
|
|
242
|
+
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
|
+
|
|
244
|
+
There is no create-collection action: collections come into existence on their first write via ${TOOL_NAMES.GRAPH_QUERY}.`;
|
|
164
245
|
export const TOOL_DESCRIPTIONS = {
|
|
165
246
|
// --- Canonical tools (CONTRACT §3) ---
|
|
166
247
|
[TOOL_NAMES.QUERY]: {
|
|
@@ -177,6 +258,8 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
177
258
|
source_ids: PARAM.query_source_ids,
|
|
178
259
|
metadata_filters: PARAM.metadata_filters,
|
|
179
260
|
num_related_chunks: PARAM.num_related_chunks,
|
|
261
|
+
database: PARAM.database,
|
|
262
|
+
collection: PARAM.collection,
|
|
180
263
|
},
|
|
181
264
|
},
|
|
182
265
|
[TOOL_NAMES.INGEST]: {
|
|
@@ -201,6 +284,8 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
201
284
|
"neither. Use this when the exchange itself is worth preserving; when only the " +
|
|
202
285
|
"conclusion matters, prefer `text` with the distilled fact.",
|
|
203
286
|
user_name: PARAM.user_name,
|
|
287
|
+
database: PARAM.database,
|
|
288
|
+
collection: PARAM.collection,
|
|
204
289
|
},
|
|
205
290
|
},
|
|
206
291
|
[TOOL_NAMES.LIST]: {
|
|
@@ -217,6 +302,8 @@ Memory rows come back as [id] content. Knowledge rows as [id] — title (type),
|
|
|
217
302
|
source_ids: PARAM.source_ids,
|
|
218
303
|
page: PARAM.page,
|
|
219
304
|
page_size: PARAM.page_size,
|
|
305
|
+
database: PARAM.database,
|
|
306
|
+
collection: PARAM.collection,
|
|
220
307
|
},
|
|
221
308
|
},
|
|
222
309
|
[TOOL_NAMES.INSPECT]: {
|
|
@@ -228,6 +315,8 @@ Memory rows come back as [id] content. Knowledge rows as [id] — title (type),
|
|
|
228
315
|
offset: PARAM.fetch_offset,
|
|
229
316
|
limit: PARAM.fetch_limit,
|
|
230
317
|
expiry_seconds: PARAM.expiry_seconds,
|
|
318
|
+
database: PARAM.database,
|
|
319
|
+
collection: PARAM.collection,
|
|
231
320
|
},
|
|
232
321
|
},
|
|
233
322
|
[TOOL_NAMES.DELETE]: {
|
|
@@ -241,6 +330,8 @@ Take the id from hydradb_query or hydradb_list — never guess one. Confirm with
|
|
|
241
330
|
ids: PARAM.delete_ids,
|
|
242
331
|
id: PARAM.delete_id,
|
|
243
332
|
kind: PARAM.delete_kind,
|
|
333
|
+
database: PARAM.database,
|
|
334
|
+
collection: PARAM.collection,
|
|
244
335
|
},
|
|
245
336
|
},
|
|
246
337
|
[TOOL_NAMES.STATUS]: {
|
|
@@ -253,6 +344,36 @@ Take the id from hydradb_query or hydradb_list — never guess one. Confirm with
|
|
|
253
344
|
"'still indexing', not 'the save failed'.",
|
|
254
345
|
params: {
|
|
255
346
|
ids: "The source IDs to check, as returned by hydradb_ingest.",
|
|
347
|
+
database: PARAM.database,
|
|
348
|
+
collection: PARAM.collection,
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
// --- BYOG graph tools (PRO-1681) ---
|
|
352
|
+
[TOOL_NAMES.GRAPH_QUERY]: {
|
|
353
|
+
title: "Query Graph (Cypher)",
|
|
354
|
+
description: GRAPH_QUERY_BODY,
|
|
355
|
+
params: {
|
|
356
|
+
query: GRAPH_PARAM.query,
|
|
357
|
+
params: GRAPH_PARAM.params,
|
|
358
|
+
database: GRAPH_PARAM.database,
|
|
359
|
+
collection: GRAPH_PARAM.collection,
|
|
360
|
+
max_rows: GRAPH_PARAM.max_rows,
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
[TOOL_NAMES.GRAPH_COLLECTIONS]: {
|
|
364
|
+
title: "List Graph Collections",
|
|
365
|
+
description: GRAPH_COLLECTIONS_BODY,
|
|
366
|
+
params: {
|
|
367
|
+
database: GRAPH_PARAM.database,
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
[TOOL_NAMES.GRAPH_ADMIN]: {
|
|
371
|
+
title: "Manage Graph Databases",
|
|
372
|
+
description: GRAPH_ADMIN_BODY,
|
|
373
|
+
params: {
|
|
374
|
+
action: GRAPH_PARAM.action,
|
|
375
|
+
database: GRAPH_PARAM.admin_database,
|
|
376
|
+
collection: GRAPH_PARAM.admin_collection,
|
|
256
377
|
},
|
|
257
378
|
},
|
|
258
379
|
// --- Deprecated aliases ---
|
|
@@ -265,6 +386,8 @@ Take the id from hydradb_query or hydradb_list — never guess one. Confirm with
|
|
|
265
386
|
max_results: PARAM.max_results,
|
|
266
387
|
mode: PARAM.mode,
|
|
267
388
|
graph_context: PARAM.graph_context,
|
|
389
|
+
database: PARAM.database,
|
|
390
|
+
collection: PARAM.collection,
|
|
268
391
|
},
|
|
269
392
|
},
|
|
270
393
|
[TOOL_NAMES.STORE]: {
|
|
@@ -281,6 +404,8 @@ Take the id from hydradb_query or hydradb_list — never guess one. Confirm with
|
|
|
281
404
|
infer: PARAM.infer,
|
|
282
405
|
is_markdown: PARAM.is_markdown,
|
|
283
406
|
overwrite: PARAM.overwrite,
|
|
407
|
+
database: PARAM.database,
|
|
408
|
+
collection: PARAM.collection,
|
|
284
409
|
},
|
|
285
410
|
},
|
|
286
411
|
[TOOL_NAMES.INGEST_CONVERSATION]: {
|
|
@@ -290,17 +415,25 @@ Take the id from hydradb_query or hydradb_list — never guess one. Confirm with
|
|
|
290
415
|
turns: PARAM.turns,
|
|
291
416
|
source_id: "Source identifier to group all turns from the same session together",
|
|
292
417
|
user_name: PARAM.user_name,
|
|
418
|
+
database: PARAM.database,
|
|
419
|
+
collection: PARAM.collection,
|
|
293
420
|
},
|
|
294
421
|
},
|
|
295
422
|
[TOOL_NAMES.LIST_MEMORIES]: {
|
|
296
423
|
title: "List Memories (deprecated)",
|
|
297
424
|
description: deprecated(TOOL_NAMES.LIST_MEMORIES, LIST_MEMORIES_BODY),
|
|
425
|
+
params: {
|
|
426
|
+
database: PARAM.database,
|
|
427
|
+
collection: PARAM.collection,
|
|
428
|
+
},
|
|
298
429
|
},
|
|
299
430
|
[TOOL_NAMES.LIST_SOURCES]: {
|
|
300
431
|
title: "List Sources (deprecated)",
|
|
301
432
|
description: deprecated(TOOL_NAMES.LIST_SOURCES, LIST_SOURCES_BODY),
|
|
302
433
|
params: {
|
|
303
434
|
source_ids: PARAM.source_ids,
|
|
435
|
+
database: PARAM.database,
|
|
436
|
+
collection: PARAM.collection,
|
|
304
437
|
},
|
|
305
438
|
},
|
|
306
439
|
[TOOL_NAMES.FETCH_CONTENT]: {
|
|
@@ -311,6 +444,8 @@ Take the id from hydradb_query or hydradb_list — never guess one. Confirm with
|
|
|
311
444
|
mode: PARAM.fetch_mode,
|
|
312
445
|
offset: PARAM.fetch_offset,
|
|
313
446
|
limit: PARAM.fetch_limit,
|
|
447
|
+
database: PARAM.database,
|
|
448
|
+
collection: PARAM.collection,
|
|
314
449
|
},
|
|
315
450
|
},
|
|
316
451
|
[TOOL_NAMES.DELETE_MEMORY]: {
|
|
@@ -318,6 +453,8 @@ Take the id from hydradb_query or hydradb_list — never guess one. Confirm with
|
|
|
318
453
|
description: deprecated(TOOL_NAMES.DELETE_MEMORY, "Delete a specific user memory from Hydra DB by its memory ID. This action is irreversible."),
|
|
319
454
|
params: {
|
|
320
455
|
memory_id: PARAM.memory_id,
|
|
456
|
+
database: PARAM.database,
|
|
457
|
+
collection: PARAM.collection,
|
|
321
458
|
},
|
|
322
459
|
},
|
|
323
460
|
};
|
|
@@ -341,5 +478,17 @@ THE TOOLS
|
|
|
341
478
|
|
|
342
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.
|
|
343
480
|
|
|
344
|
-
|
|
481
|
+
THE GRAPH TOOLS (a separate product surface)
|
|
482
|
+
|
|
483
|
+
Hydra DB also runs property graphs the user models and owns end to end, queried in Cypher. These are NOT the same store as the memory and knowledge above, and nothing crosses between them: ${TOOL_NAMES.QUERY} cannot see graph data, and ${TOOL_NAMES.GRAPH_QUERY} cannot see memories.
|
|
484
|
+
|
|
485
|
+
- ${TOOL_NAMES.GRAPH_QUERY} — Cypher, reads and writes alike: traversal, paths, neighbourhoods, aggregation, CREATE/MERGE/SET/DELETE. It can destroy data, so confirm before running anything destructive the user did not ask for.
|
|
486
|
+
- ${TOOL_NAMES.GRAPH_COLLECTIONS} — which graphs exist in a graph database.
|
|
487
|
+
- ${TOOL_NAMES.GRAPH_ADMIN} — create a graph database, drop a collection, drop a database. Irreversible; confirm first.
|
|
488
|
+
|
|
489
|
+
Choose by the question, not the vocabulary: "what has the user told me about X" is ${TOOL_NAMES.QUERY}; "how is X connected to Y in my graph" is ${TOOL_NAMES.GRAPH_QUERY}. If the user has written Cypher, or speaks of nodes, labels, relationships and traversals they themselves created, they mean the graph tools.
|
|
490
|
+
|
|
491
|
+
Working against an unfamiliar collection, discover its structure by querying it — \`MATCH (n) UNWIND labels(n) AS l RETURN l, count(*) AS c ORDER BY l\` — rather than guessing labels, which yields empty results that look like missing data.
|
|
492
|
+
|
|
493
|
+
All tools require HYDRADB_API_KEY and HYDRADB_DATABASE in the environment. The graph tools additionally read HYDRADB_GRAPH_DATABASE and HYDRADB_GRAPH_COLLECTION for their default scope, and can be disabled with HYDRADB_MCP_GRAPH_TOOLS=0.`;
|
|
345
494
|
//# sourceMappingURL=descriptions.js.map
|
package/dist/descriptions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"descriptions.js","sourceRoot":"","sources":["../src/descriptions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEjE,4EAA4E;AAC5E,MAAM,KAAK,GAAG;IACb,KAAK,EACJ,oFAAoF;QACpF,mFAAmF;QACnF,kFAAkF;QAClF,uCAAuC;IACxC,UAAU,EACT,qEAAqE;QACrE,oEAAoE;QACpE,mFAAmF;IACpF,WAAW,EACV,8EAA8E;QAC9E,kFAAkF;QAClF,+EAA+E;QAC/E,WAAW;IACZ,IAAI,EACH,8EAA8E;QAC9E,iFAAiF;QACjF,mFAAmF;QACnF,kFAAkF;QAClF,mCAAmC;IACpC,gBAAgB,EACf,uEAAuE;QACvE,+EAA+E;QAC/E,8EAA8E;IAC/E,gBAAgB,EACf,gFAAgF;QAChF,+EAA+E;QAC/E,uDAAuD;IACxD,kBAAkB,EACjB,gFAAgF;QAChF,2EAA2E;QAC3E,6EAA6E;IAC9E,QAAQ,EACP,2EAA2E;QAC3E,gFAAgF;QAChF,wEAAwE;QACxE,0EAA0E;QAC1E,gFAAgF;QAChF,+EAA+E;QAC/E,0EAA0E;QAC1E,8CAA8C;IAC/C,cAAc,EACb,2EAA2E;QAC3E,0CAA0C;IAC3C,aAAa,EACZ,kFAAkF;QAClF,mFAAmF;QACnF,mFAAmF;QACnF,8CAA8C;IAC/C,IAAI,EACH,+EAA+E;QAC/E,kFAAkF;QAClF,mFAAmF;QACnF,wDAAwD;IACzD,WAAW,EACV,0EAA0E;QAC1E,wEAAwE;QACxE,+EAA+E;QAC/E,0DAA0D;IAC3D,KAAK,EACJ,gFAAgF;QAChF,gFAAgF;QAChF,+EAA+E;QAC/E,6EAA6E;IAC9E,SAAS,EACR,iFAAiF;QACjF,sFAAsF;QACtF,uFAAuF;QACvF,0FAA0F;IAC3F,SAAS,EACR,gFAAgF;QAChF,4EAA4E;QAC5E,4DAA4D;IAC7D,QAAQ,EACP,8EAA8E;QAC9E,iFAAiF;QACjF,qFAAqF;IACtF,6EAA6E;IAC7E,8DAA8D;IAC9D,8EAA8E;IAC9E,gBAAgB,EACf,8EAA8E;QAC9E,gFAAgF;QAChF,mFAAmF;QACnF,mFAAmF;QACnF,qBAAqB;IACtB,KAAK,EACJ,4EAA4E;QAC5E,iFAAiF;QACjF,oFAAoF;QACpF,+EAA+E;QAC/E,wBAAwB;IACzB,WAAW,EACV,oFAAoF;QACpF,sEAAsE;IACvE,KAAK,EAAE,uEAAuE;IAC9E,SAAS,EACR,kFAAkF;QAClF,8EAA8E;QAC9E,sEAAsE;IACvE,IAAI,EACH,4EAA4E;QAC5E,gFAAgF;QAChF,gEAAgE;IACjE,UAAU,EACT,oFAAoF;IACrF,IAAI,EACH,oFAAoF;QACpF,mFAAmF;QACnF,+BAA+B;IAChC,SAAS,EACR,iFAAiF;QACjF,oEAAoE;IACrE,MAAM,EACL,4EAA4E;QAC5E,gFAAgF;QAChF,+EAA+E;QAC/E,iFAAiF;QACjF,gFAAgF;IACjF,eAAe,EAAE,oCAAoC;IACrD,UAAU,EACT,iFAAiF;QACjF,iFAAiF;QACjF,iEAAiE;IAClE,YAAY,EACX,iFAAiF;QACjF,6EAA6E;IAC9E,WAAW,EACV,mFAAmF;QACnF,iDAAiD;IAClD,SAAS,EAAE,kEAAkE;IAC7E,UAAU,EACT,8EAA8E;QAC9E,+EAA+E;QAC/E,8CAA8C;IAC/C,WAAW,EACV,qFAAqF;IACtF,SAAS,EAAE,gCAAgC;
|
|
1
|
+
{"version":3,"file":"descriptions.js","sourceRoot":"","sources":["../src/descriptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for the remotely hostable HTTP transport.
|
|
3
|
+
*
|
|
4
|
+
* There are two configurations here, and they belong to two different people.
|
|
5
|
+
*
|
|
6
|
+
* - {@link resolveHttpServerConfig} is the OPERATOR's config: the port, the
|
|
7
|
+
* bind address, and the Host/Origin allowlists that decide who may reach the
|
|
8
|
+
* process at all. It is read once at startup from the environment.
|
|
9
|
+
*
|
|
10
|
+
* - {@link resolveRequestCredentials} is the CALLER's config: which Hydra DB
|
|
11
|
+
* account, database and collection a single request runs against. On a
|
|
12
|
+
* multi-tenant deployment (one process serving `mcp.hydradb.com` for many
|
|
13
|
+
* users) this MUST come per request, from headers, because the process has
|
|
14
|
+
* no single tenant of its own. It is resolved fresh on every `/mcp` call.
|
|
15
|
+
*
|
|
16
|
+
* The stdio server ({@link file://./index.ts}) has only the second concern and
|
|
17
|
+
* reads it from the environment via {@link file://./config.ts}; a hosted server
|
|
18
|
+
* cannot, because one env-configured key would make every user share one
|
|
19
|
+
* account. So the header path is the substantive new surface, and it falls back
|
|
20
|
+
* to the environment only to keep the single-tenant self-hosting story (set the
|
|
21
|
+
* env, expose the port, done) working unchanged.
|
|
22
|
+
*/
|
|
23
|
+
import { type EnvSource, type GraphConfig } from "./config.js";
|
|
24
|
+
export interface HttpServerConfig {
|
|
25
|
+
/** TCP port to listen on. */
|
|
26
|
+
port: number;
|
|
27
|
+
/**
|
|
28
|
+
* Interface to bind. Defaults to loopback so an unconfigured server is not
|
|
29
|
+
* reachable off-box; a hosted deployment sets `0.0.0.0` deliberately.
|
|
30
|
+
*/
|
|
31
|
+
bindAddress: string;
|
|
32
|
+
/** CORS allowlist. Empty means no cross-origin browser request is accepted. */
|
|
33
|
+
allowedOrigins: string[];
|
|
34
|
+
/** Accepted `Host` headers, lowercased. Loopback + the configured port always. */
|
|
35
|
+
allowedHosts: Set<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Express's `trust proxy` setting. `false` (the default) trusts no
|
|
38
|
+
* `X-Forwarded-*`, so a direct client cannot spoof its address in the logs;
|
|
39
|
+
* a deployment behind a known proxy sets `TRUST_PROXY` to a hop count or a
|
|
40
|
+
* subnet preset so the real client IP is recovered without trusting all hops.
|
|
41
|
+
*/
|
|
42
|
+
trustProxy: boolean | number | string;
|
|
43
|
+
}
|
|
44
|
+
export declare const DEFAULT_PORT = 8080;
|
|
45
|
+
export declare const DEFAULT_BIND_ADDRESS = "127.0.0.1";
|
|
46
|
+
/** Split a comma-separated env var into trimmed, non-empty entries. */
|
|
47
|
+
export declare function parseList(value: string | undefined): string[];
|
|
48
|
+
/**
|
|
49
|
+
* A port, or the default when the value is absent or not a usable port.
|
|
50
|
+
*
|
|
51
|
+
* A typo'd `PORT` should not crash startup with a stack trace; it should fall
|
|
52
|
+
* back and let the startup banner show what it actually bound. Ports outside
|
|
53
|
+
* 1-65535 fall back for the same reason `parseInt("8080abc")` must not become
|
|
54
|
+
* `8080` silently — `Number` rejects the trailing garbage that `parseInt` keeps.
|
|
55
|
+
*/
|
|
56
|
+
export declare function parsePort(raw: string | undefined, fallback?: number): number;
|
|
57
|
+
/**
|
|
58
|
+
* The set of `Host` headers this server answers to.
|
|
59
|
+
*
|
|
60
|
+
* Loopback names on the bound port are always included so a local run works with
|
|
61
|
+
* no configuration. A hosted deployment adds its public hostname(s) via
|
|
62
|
+
* `ALLOWED_HOSTS`. The bare (portless) loopback names cover clients that omit
|
|
63
|
+
* the port on the default HTTP/HTTPS port.
|
|
64
|
+
*/
|
|
65
|
+
export declare function buildAllowedHosts(port: number, extra: string[]): Set<string>;
|
|
66
|
+
/**
|
|
67
|
+
* Interpret `TRUST_PROXY` for Express's `trust proxy` setting.
|
|
68
|
+
*
|
|
69
|
+
* Absent → `false` (trust nothing, the safe default). `true`/`false` → boolean.
|
|
70
|
+
* An integer → that many hops. Anything else is passed through as an Express
|
|
71
|
+
* preset or subnet list (e.g. `loopback`, `10.0.0.0/8`), so an operator can name
|
|
72
|
+
* exactly their proxy without this needing to know the syntax.
|
|
73
|
+
*/
|
|
74
|
+
export declare function parseTrustProxy(raw: string | undefined): boolean | number | string;
|
|
75
|
+
export declare function resolveHttpServerConfig(env?: EnvSource): HttpServerConfig;
|
|
76
|
+
/**
|
|
77
|
+
* Header names a caller uses to select and authenticate against their tenant.
|
|
78
|
+
*
|
|
79
|
+
* Lowercased because Node lowercases incoming header names, and every lookup
|
|
80
|
+
* here goes through {@link headerValue} which reads them off `req.headers`.
|
|
81
|
+
*
|
|
82
|
+
* The API key is read from the standard `Authorization: Bearer <key>` first;
|
|
83
|
+
* `X-HydraDB-Api-Key` exists only for clients whose MCP config cannot set an
|
|
84
|
+
* `Authorization` header. Everything else — which database, which collection —
|
|
85
|
+
* has no standard header, so it takes an `X-HydraDB-*` one.
|
|
86
|
+
*/
|
|
87
|
+
export declare const HEADER_AUTHORIZATION = "authorization";
|
|
88
|
+
export declare const HEADER_API_KEY = "x-hydradb-api-key";
|
|
89
|
+
export declare const HEADER_DATABASE = "x-hydradb-database";
|
|
90
|
+
export declare const HEADER_COLLECTION = "x-hydradb-collection";
|
|
91
|
+
export declare const HEADER_GRAPH_DATABASE = "x-hydradb-graph-database";
|
|
92
|
+
export declare const HEADER_GRAPH_COLLECTION = "x-hydradb-graph-collection";
|
|
93
|
+
/** The request headers this resolver reads. Matches Node's `IncomingHttpHeaders`. */
|
|
94
|
+
export type RequestHeaders = Record<string, string | string[] | undefined>;
|
|
95
|
+
/**
|
|
96
|
+
* Everything needed to construct a scoped {@link HydraDB} for one request.
|
|
97
|
+
*
|
|
98
|
+
* `baseUrl`, `timeoutSeconds` and `maxRetries` are deliberately absent from the
|
|
99
|
+
* header surface: they are OPERATOR knobs read from the environment, not caller
|
|
100
|
+
* ones. Letting a caller set `baseUrl` per request would point this server's
|
|
101
|
+
* outbound calls at a host of the caller's choosing, which is a request-forgery
|
|
102
|
+
* primitive the tenant selection has no reason to hand out.
|
|
103
|
+
*/
|
|
104
|
+
export interface RequestCredentials {
|
|
105
|
+
apiKey: string;
|
|
106
|
+
database: string;
|
|
107
|
+
collection: string;
|
|
108
|
+
baseUrl?: string;
|
|
109
|
+
timeoutSeconds?: number;
|
|
110
|
+
maxRetries?: number;
|
|
111
|
+
graph: GraphConfig;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Resolution is either credentials or the exact HTTP failure to return.
|
|
115
|
+
*
|
|
116
|
+
* The status and message are carried out rather than thrown so the caller can
|
|
117
|
+
* answer with a JSON-RPC error body at the right code — 401 when nothing
|
|
118
|
+
* authenticated the request, 400 when it authenticated but named no database —
|
|
119
|
+
* instead of a generic 500 that tells the client nothing about what to fix.
|
|
120
|
+
*/
|
|
121
|
+
export type CredentialResolution = {
|
|
122
|
+
ok: true;
|
|
123
|
+
credentials: RequestCredentials;
|
|
124
|
+
} | {
|
|
125
|
+
ok: false;
|
|
126
|
+
status: number;
|
|
127
|
+
message: string;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Turn one request's headers (falling back to the environment) into the tenant
|
|
131
|
+
* credentials for that request.
|
|
132
|
+
*
|
|
133
|
+
* The API key and the database resolve TOGETHER, not field-by-field, which is
|
|
134
|
+
* the security-relevant part:
|
|
135
|
+
* - When the key comes from a request header, the request is
|
|
136
|
+
* "caller-authenticated" and its database MUST also come from a header. The
|
|
137
|
+
* env is NOT consulted for the database, so a caller who sends their own key
|
|
138
|
+
* but omits `X-HydraDB-Database` is refused (400) rather than silently run
|
|
139
|
+
* against the operator's env database. Likewise the graph scope defaults to
|
|
140
|
+
* the request's own database, never the operator's `HYDRADB_GRAPH_DATABASE`.
|
|
141
|
+
* - When there is no key header, the request is unauthenticated and falls back
|
|
142
|
+
* entirely to the operator's env credentials — the single-tenant self-host
|
|
143
|
+
* case, identical to the stdio server. A hosted, multi-tenant process sets
|
|
144
|
+
* no tenant env, so such a request is refused (401).
|
|
145
|
+
*
|
|
146
|
+
* Resolving field-by-field instead would let a caller's key pair with the
|
|
147
|
+
* operator's database (or graph namespace), mixing two identities into one
|
|
148
|
+
* request. `baseUrl`/`timeoutSeconds`/`maxRetries` are read from the environment
|
|
149
|
+
* only — they are the operator's, not the caller's (see {@link RequestCredentials}).
|
|
150
|
+
*/
|
|
151
|
+
export declare function resolveRequestCredentials(headers: RequestHeaders, env?: EnvSource): CredentialResolution;
|
|
152
|
+
/** A JSON-RPC error body, so every HTTP failure speaks the protocol's dialect. */
|
|
153
|
+
export declare function jsonRpcError(code: number, message: string): {
|
|
154
|
+
jsonrpc: "2.0";
|
|
155
|
+
error: {
|
|
156
|
+
code: number;
|
|
157
|
+
message: string;
|
|
158
|
+
};
|
|
159
|
+
id: null;
|
|
160
|
+
};
|