@hydradb/mcp 1.2.1 → 1.3.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 +141 -0
- package/README.md +185 -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 +60 -0
- package/dist/descriptions.js +159 -1
- package/dist/descriptions.js.map +1 -1
- package/dist/http-config.d.ts +190 -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 +427 -0
- package/dist/http.js.map +1 -0
- package/dist/hydra/client.d.ts +69 -4
- package/dist/hydra/client.js +84 -19
- 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 +4 -1
- package/dist/hydra/index.js +3 -1
- package/dist/hydra/index.js.map +1 -1
- package/dist/oauth.d.ts +109 -0
- package/dist/oauth.js +228 -0
- package/dist/oauth.js.map +1 -0
- package/dist/server.d.ts +15 -1
- package/dist/server.js +440 -12
- package/dist/server.js.map +1 -1
- package/dist/tool-names.d.ts +13 -0
- package/dist/tool-names.js +26 -0
- package/dist/tool-names.js.map +1 -1
- package/package.json +10 -2
package/dist/oauth.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The OAuth 2.1 RESOURCE-SERVER half of MCP authorization (PRO-1790).
|
|
3
|
+
*
|
|
4
|
+
* This server never issues tokens and never talks to the user. It does three
|
|
5
|
+
* things the MCP authorization spec asks of a protected resource:
|
|
6
|
+
*
|
|
7
|
+
* 1. Advertise where its authorization server is, via an RFC 9728 Protected
|
|
8
|
+
* Resource Metadata document at `/.well-known/oauth-protected-resource`,
|
|
9
|
+
* and point at that document from every 401 (`WWW-Authenticate`).
|
|
10
|
+
* 2. Recognise an access token the authorization server issued and turn it
|
|
11
|
+
* into the same {@link RequestCredentials} an API key would produce, by
|
|
12
|
+
* asking the authorization server what the token stands for (RFC 7662
|
|
13
|
+
* introspection). The answer carries the API key the dashboard minted on
|
|
14
|
+
* the user's Approve click, so the tool layer keeps calling Hydra DB
|
|
15
|
+
* exactly as it does for a key: nothing downstream knows OAuth exists.
|
|
16
|
+
* 3. Refuse a token that was not issued for THIS server (audience binding,
|
|
17
|
+
* RFC 8707), so a token minted for another resource cannot be replayed
|
|
18
|
+
* here.
|
|
19
|
+
*
|
|
20
|
+
* All of it is additive and switched on only by configuration: with no
|
|
21
|
+
* `HYDRADB_OAUTH_ISSUER` the server behaves exactly as before.
|
|
22
|
+
*/
|
|
23
|
+
/** Access tokens the dashboard issues carry this prefix; keys carry `sk_`. */
|
|
24
|
+
export declare const ACCESS_TOKEN_PREFIX = "hmat_";
|
|
25
|
+
/** The one scope this resource defines. Granularity is PRO-1789's problem. */
|
|
26
|
+
export declare const SCOPE = "hydradb";
|
|
27
|
+
export interface OAuthConfig {
|
|
28
|
+
/** The authorization server, e.g. `https://app.hydradb.com`. No trailing slash. */
|
|
29
|
+
issuer: string;
|
|
30
|
+
/** This server's canonical URL as clients know it, e.g. `https://mcp.hydradb.com`. */
|
|
31
|
+
resource: string;
|
|
32
|
+
/** Shared secret presented to the issuer's introspection endpoint. */
|
|
33
|
+
introspectionSecret: string;
|
|
34
|
+
/** Overrides for tests. */
|
|
35
|
+
fetchFn?: typeof fetch;
|
|
36
|
+
now?: () => number;
|
|
37
|
+
}
|
|
38
|
+
/** Everything an introspected token stands for. Mirrors the dashboard's response. */
|
|
39
|
+
export interface IntrospectedToken {
|
|
40
|
+
apiKey: string;
|
|
41
|
+
database?: string;
|
|
42
|
+
collection?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Databases a per-call `database` argument may name. Absent means any (the
|
|
45
|
+
* user chose to let the app switch when asked); present means the user
|
|
46
|
+
* confined the app to exactly these on the consent screen, and this server
|
|
47
|
+
* is where that promise is kept, because the API key behind the token is
|
|
48
|
+
* org-wide and the key never leaves this process.
|
|
49
|
+
*/
|
|
50
|
+
allowedDatabases?: string[];
|
|
51
|
+
/**
|
|
52
|
+
* Collections a per-call `collection` argument may name, on the same terms.
|
|
53
|
+
* Confinement has to cover both or it means nothing: a caller pinned to one
|
|
54
|
+
* database could still step sideways into a collection the consent screen
|
|
55
|
+
* never showed and, through `drop_collection`, delete it.
|
|
56
|
+
*/
|
|
57
|
+
allowedCollections?: string[];
|
|
58
|
+
userId?: string;
|
|
59
|
+
clientId?: string;
|
|
60
|
+
clientName?: string;
|
|
61
|
+
/** Epoch seconds. */
|
|
62
|
+
expiresAt: number;
|
|
63
|
+
}
|
|
64
|
+
export type IntrospectionResult = {
|
|
65
|
+
ok: true;
|
|
66
|
+
token: IntrospectedToken;
|
|
67
|
+
} | {
|
|
68
|
+
ok: false;
|
|
69
|
+
reason: "invalid_token" | "wrong_audience" | "unavailable";
|
|
70
|
+
detail?: string;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Read the OAuth configuration, or `null` when the feature is off.
|
|
74
|
+
*
|
|
75
|
+
* All three values are needed: an issuer says where to send clients, a
|
|
76
|
+
* resource says which audience to accept, and the secret is what makes the
|
|
77
|
+
* introspection answer trustworthy. Half a configuration is treated as none,
|
|
78
|
+
* with a startup warning, rather than as a server that advertises an
|
|
79
|
+
* authorization flow it cannot complete.
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveOAuthConfig(env?: Record<string, string | undefined>, warn?: (message: string) => void): OAuthConfig | null;
|
|
82
|
+
/** Where the Protected Resource Metadata document lives for this server. */
|
|
83
|
+
export declare function metadataUrl(config: OAuthConfig, mcpPath?: string): string;
|
|
84
|
+
/** The RFC 9728 document itself. */
|
|
85
|
+
export declare function protectedResourceMetadata(config: OAuthConfig): Record<string, unknown>;
|
|
86
|
+
/**
|
|
87
|
+
* The `WWW-Authenticate` value for a 401.
|
|
88
|
+
*
|
|
89
|
+
* `resource_metadata` is how a client that arrived with nothing learns where
|
|
90
|
+
* to log in (the MCP spec's first discovery step), and `scope` tells it what
|
|
91
|
+
* to ask for. `error` is included only when a token was PRESENTED and refused,
|
|
92
|
+
* so an anonymous first contact reads as "authenticate" rather than "your
|
|
93
|
+
* token is bad".
|
|
94
|
+
*/
|
|
95
|
+
export declare function wwwAuthenticate(config: OAuthConfig, error?: "invalid_token" | "insufficient_scope", description?: string): string;
|
|
96
|
+
/** Whether a bearer value is one of OUR access tokens rather than an API key. */
|
|
97
|
+
export declare function isAccessToken(bearer: string | undefined): bearer is string;
|
|
98
|
+
/** Test-only. */
|
|
99
|
+
export declare function __resetIntrospectionCache(): void;
|
|
100
|
+
/**
|
|
101
|
+
* Ask the issuer what a token stands for.
|
|
102
|
+
*
|
|
103
|
+
* The response shape is the contract in PRO-1790: `active`, `aud`, `exp`,
|
|
104
|
+
* `api_key`, `database`, `collection`, `sub`, `client_id`, `client_name`.
|
|
105
|
+
* Audience is checked HERE, not trusted from the issuer's say-so: the issuer
|
|
106
|
+
* may legitimately serve several resources, and this server must only honour
|
|
107
|
+
* tokens minted for itself.
|
|
108
|
+
*/
|
|
109
|
+
export declare function introspect(config: OAuthConfig, token: string): Promise<IntrospectionResult>;
|
package/dist/oauth.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The OAuth 2.1 RESOURCE-SERVER half of MCP authorization (PRO-1790).
|
|
3
|
+
*
|
|
4
|
+
* This server never issues tokens and never talks to the user. It does three
|
|
5
|
+
* things the MCP authorization spec asks of a protected resource:
|
|
6
|
+
*
|
|
7
|
+
* 1. Advertise where its authorization server is, via an RFC 9728 Protected
|
|
8
|
+
* Resource Metadata document at `/.well-known/oauth-protected-resource`,
|
|
9
|
+
* and point at that document from every 401 (`WWW-Authenticate`).
|
|
10
|
+
* 2. Recognise an access token the authorization server issued and turn it
|
|
11
|
+
* into the same {@link RequestCredentials} an API key would produce, by
|
|
12
|
+
* asking the authorization server what the token stands for (RFC 7662
|
|
13
|
+
* introspection). The answer carries the API key the dashboard minted on
|
|
14
|
+
* the user's Approve click, so the tool layer keeps calling Hydra DB
|
|
15
|
+
* exactly as it does for a key: nothing downstream knows OAuth exists.
|
|
16
|
+
* 3. Refuse a token that was not issued for THIS server (audience binding,
|
|
17
|
+
* RFC 8707), so a token minted for another resource cannot be replayed
|
|
18
|
+
* here.
|
|
19
|
+
*
|
|
20
|
+
* All of it is additive and switched on only by configuration: with no
|
|
21
|
+
* `HYDRADB_OAUTH_ISSUER` the server behaves exactly as before.
|
|
22
|
+
*/
|
|
23
|
+
import { createHash } from "node:crypto";
|
|
24
|
+
import { logger } from "./logger.js";
|
|
25
|
+
/** Access tokens the dashboard issues carry this prefix; keys carry `sk_`. */
|
|
26
|
+
export const ACCESS_TOKEN_PREFIX = "hmat_";
|
|
27
|
+
/** The one scope this resource defines. Granularity is PRO-1789's problem. */
|
|
28
|
+
export const SCOPE = "hydradb";
|
|
29
|
+
function stripSlash(url) {
|
|
30
|
+
return url.replace(/\/+$/, "");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Read the OAuth configuration, or `null` when the feature is off.
|
|
34
|
+
*
|
|
35
|
+
* All three values are needed: an issuer says where to send clients, a
|
|
36
|
+
* resource says which audience to accept, and the secret is what makes the
|
|
37
|
+
* introspection answer trustworthy. Half a configuration is treated as none,
|
|
38
|
+
* with a startup warning, rather than as a server that advertises an
|
|
39
|
+
* authorization flow it cannot complete.
|
|
40
|
+
*/
|
|
41
|
+
export function resolveOAuthConfig(env = process.env, warn = (m) => console.error(`[hydradb-mcp] ${m}`)) {
|
|
42
|
+
const issuer = env.HYDRADB_OAUTH_ISSUER?.trim();
|
|
43
|
+
const resource = env.HYDRADB_MCP_PUBLIC_URL?.trim();
|
|
44
|
+
const introspectionSecret = env.HYDRADB_OAUTH_INTROSPECTION_SECRET?.trim();
|
|
45
|
+
if (!issuer && !resource && !introspectionSecret)
|
|
46
|
+
return null;
|
|
47
|
+
const missing = [
|
|
48
|
+
!issuer && "HYDRADB_OAUTH_ISSUER",
|
|
49
|
+
!resource && "HYDRADB_MCP_PUBLIC_URL",
|
|
50
|
+
!introspectionSecret && "HYDRADB_OAUTH_INTROSPECTION_SECRET",
|
|
51
|
+
].filter(Boolean);
|
|
52
|
+
if (missing.length > 0) {
|
|
53
|
+
warn(`WARNING: OAuth is partially configured (missing ${missing.join(", ")}); ` +
|
|
54
|
+
"it stays OFF until all three are set.");
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
for (const [name, value] of [
|
|
58
|
+
["HYDRADB_OAUTH_ISSUER", issuer],
|
|
59
|
+
["HYDRADB_MCP_PUBLIC_URL", resource],
|
|
60
|
+
]) {
|
|
61
|
+
if (!/^https?:\/\//i.test(value)) {
|
|
62
|
+
warn(`WARNING: ${name} must be an absolute http(s) URL; OAuth stays OFF.`);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
issuer: stripSlash(issuer),
|
|
68
|
+
resource: stripSlash(resource),
|
|
69
|
+
introspectionSecret: introspectionSecret,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Where the Protected Resource Metadata document lives for this server. */
|
|
73
|
+
export function metadataUrl(config, mcpPath = "") {
|
|
74
|
+
// RFC 9728 puts the well-known segment BEFORE the resource's path, so a
|
|
75
|
+
// server at /mcp advertises at /.well-known/oauth-protected-resource/mcp.
|
|
76
|
+
return `${config.resource}/.well-known/oauth-protected-resource${mcpPath}`;
|
|
77
|
+
}
|
|
78
|
+
/** The RFC 9728 document itself. */
|
|
79
|
+
export function protectedResourceMetadata(config) {
|
|
80
|
+
return {
|
|
81
|
+
resource: config.resource,
|
|
82
|
+
authorization_servers: [config.issuer],
|
|
83
|
+
scopes_supported: [SCOPE],
|
|
84
|
+
bearer_methods_supported: ["header"],
|
|
85
|
+
resource_name: "Hydra DB MCP",
|
|
86
|
+
resource_documentation: "https://docs.hydradb.com/mcp",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The `WWW-Authenticate` value for a 401.
|
|
91
|
+
*
|
|
92
|
+
* `resource_metadata` is how a client that arrived with nothing learns where
|
|
93
|
+
* to log in (the MCP spec's first discovery step), and `scope` tells it what
|
|
94
|
+
* to ask for. `error` is included only when a token was PRESENTED and refused,
|
|
95
|
+
* so an anonymous first contact reads as "authenticate" rather than "your
|
|
96
|
+
* token is bad".
|
|
97
|
+
*/
|
|
98
|
+
export function wwwAuthenticate(config, error, description) {
|
|
99
|
+
const parts = [`Bearer realm="Hydra DB MCP"`];
|
|
100
|
+
if (error)
|
|
101
|
+
parts.push(`error="${error}"`);
|
|
102
|
+
if (description)
|
|
103
|
+
parts.push(`error_description="${description.replace(/"/g, "'")}"`);
|
|
104
|
+
parts.push(`resource_metadata="${metadataUrl(config)}"`);
|
|
105
|
+
parts.push(`scope="${SCOPE}"`);
|
|
106
|
+
return parts.join(", ");
|
|
107
|
+
}
|
|
108
|
+
/** Whether a bearer value is one of OUR access tokens rather than an API key. */
|
|
109
|
+
export function isAccessToken(bearer) {
|
|
110
|
+
return typeof bearer === "string" && bearer.startsWith(ACCESS_TOKEN_PREFIX);
|
|
111
|
+
}
|
|
112
|
+
// --- Introspection, with a bounded memo ---
|
|
113
|
+
/**
|
|
114
|
+
* Introspection answers are memoised per token so the hosted server, which
|
|
115
|
+
* builds a client per request, does not ask the dashboard on every tool call.
|
|
116
|
+
* Only successes are cached, for the shorter of the token's own expiry and
|
|
117
|
+
* this ceiling. The ceiling IS the revocation lag: measured end to end, a
|
|
118
|
+
* disconnect or a refresh-token reuse detection reaches this server exactly
|
|
119
|
+
* one ceiling later. Thirty seconds keeps an agent's burst of tool calls at
|
|
120
|
+
* one hop while keeping that lag short enough that a revoked token cannot do
|
|
121
|
+
* much with it.
|
|
122
|
+
*/
|
|
123
|
+
const INTROSPECTION_CACHE_TTL_MS = 30000;
|
|
124
|
+
const INTROSPECTION_CACHE_MAX = 5000;
|
|
125
|
+
const INTROSPECTION_TIMEOUT_MS = 5000;
|
|
126
|
+
const cache = new Map();
|
|
127
|
+
/** Test-only. */
|
|
128
|
+
export function __resetIntrospectionCache() {
|
|
129
|
+
cache.clear();
|
|
130
|
+
}
|
|
131
|
+
function cacheKey(token) {
|
|
132
|
+
// Never keep the raw token as a Map key: it would sit in memory in the
|
|
133
|
+
// clear for as long as the entry lives.
|
|
134
|
+
return createHash("sha256").update(token).digest("hex");
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Ask the issuer what a token stands for.
|
|
138
|
+
*
|
|
139
|
+
* The response shape is the contract in PRO-1790: `active`, `aud`, `exp`,
|
|
140
|
+
* `api_key`, `database`, `collection`, `sub`, `client_id`, `client_name`.
|
|
141
|
+
* Audience is checked HERE, not trusted from the issuer's say-so: the issuer
|
|
142
|
+
* may legitimately serve several resources, and this server must only honour
|
|
143
|
+
* tokens minted for itself.
|
|
144
|
+
*/
|
|
145
|
+
export async function introspect(config, token) {
|
|
146
|
+
const now = config.now ?? Date.now;
|
|
147
|
+
const key = cacheKey(token);
|
|
148
|
+
const hit = cache.get(key);
|
|
149
|
+
if (hit && hit.expires > now())
|
|
150
|
+
return { ok: true, token: hit.token };
|
|
151
|
+
if (hit)
|
|
152
|
+
cache.delete(key);
|
|
153
|
+
const fetchFn = config.fetchFn ?? fetch;
|
|
154
|
+
const controller = new AbortController();
|
|
155
|
+
const timer = setTimeout(() => controller.abort(), INTROSPECTION_TIMEOUT_MS);
|
|
156
|
+
let body;
|
|
157
|
+
try {
|
|
158
|
+
const res = await fetchFn(`${config.issuer}/api/oauth/introspect`, {
|
|
159
|
+
method: "POST",
|
|
160
|
+
headers: {
|
|
161
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
162
|
+
Accept: "application/json",
|
|
163
|
+
Authorization: `Bearer ${config.introspectionSecret}`,
|
|
164
|
+
},
|
|
165
|
+
body: new URLSearchParams({ token }).toString(),
|
|
166
|
+
signal: controller.signal,
|
|
167
|
+
});
|
|
168
|
+
if (res.status === 401 || res.status === 403) {
|
|
169
|
+
// Our secret was refused. That is an operator problem, not the
|
|
170
|
+
// caller's, and it must not read as "your token is invalid".
|
|
171
|
+
logger.error("introspection refused: HYDRADB_OAUTH_INTROSPECTION_SECRET is not accepted by the issuer");
|
|
172
|
+
return { ok: false, reason: "unavailable", detail: "introspection refused" };
|
|
173
|
+
}
|
|
174
|
+
if (!res.ok) {
|
|
175
|
+
return { ok: false, reason: "unavailable", detail: `introspection HTTP ${res.status}` };
|
|
176
|
+
}
|
|
177
|
+
body = (await res.json());
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
return {
|
|
181
|
+
ok: false,
|
|
182
|
+
reason: "unavailable",
|
|
183
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
clearTimeout(timer);
|
|
188
|
+
}
|
|
189
|
+
if (body.active !== true)
|
|
190
|
+
return { ok: false, reason: "invalid_token" };
|
|
191
|
+
const aud = body.aud;
|
|
192
|
+
const audiences = Array.isArray(aud) ? aud : typeof aud === "string" ? [aud] : [];
|
|
193
|
+
if (!audiences.some((a) => typeof a === "string" && stripSlash(a) === config.resource)) {
|
|
194
|
+
return { ok: false, reason: "wrong_audience" };
|
|
195
|
+
}
|
|
196
|
+
const apiKey = typeof body.api_key === "string" ? body.api_key : "";
|
|
197
|
+
const exp = typeof body.exp === "number" ? body.exp : 0;
|
|
198
|
+
if (!apiKey || exp <= Math.floor(now() / 1000)) {
|
|
199
|
+
return { ok: false, reason: "invalid_token" };
|
|
200
|
+
}
|
|
201
|
+
const stringList = (v) => Array.isArray(v)
|
|
202
|
+
? v.filter((d) => typeof d === "string" && d.length > 0)
|
|
203
|
+
: undefined;
|
|
204
|
+
const allowed = stringList(body.databases);
|
|
205
|
+
const allowedCols = stringList(body.collections);
|
|
206
|
+
const resolved = {
|
|
207
|
+
apiKey,
|
|
208
|
+
...(allowed ? { allowedDatabases: allowed } : {}),
|
|
209
|
+
...(allowedCols ? { allowedCollections: allowedCols } : {}),
|
|
210
|
+
database: typeof body.database === "string" && body.database ? body.database : undefined,
|
|
211
|
+
collection: typeof body.collection === "string" && body.collection ? body.collection : undefined,
|
|
212
|
+
userId: typeof body.sub === "string" ? body.sub : undefined,
|
|
213
|
+
clientId: typeof body.client_id === "string" ? body.client_id : undefined,
|
|
214
|
+
clientName: typeof body.client_name === "string" ? body.client_name : undefined,
|
|
215
|
+
expiresAt: exp,
|
|
216
|
+
};
|
|
217
|
+
if (cache.size >= INTROSPECTION_CACHE_MAX) {
|
|
218
|
+
const oldest = cache.keys().next().value;
|
|
219
|
+
if (oldest != null)
|
|
220
|
+
cache.delete(oldest);
|
|
221
|
+
}
|
|
222
|
+
cache.set(key, {
|
|
223
|
+
token: resolved,
|
|
224
|
+
expires: Math.min(now() + INTROSPECTION_CACHE_TTL_MS, exp * 1000),
|
|
225
|
+
});
|
|
226
|
+
return { ok: true, token: resolved };
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { GraphConfig } from "./config.js";
|
|
1
2
|
import { HydraDB } from "./hydra/index.js";
|
|
2
3
|
/** Stop accepting tool calls. Idempotent. */
|
|
3
4
|
export declare function beginShutdown(): void;
|
|
@@ -18,7 +19,20 @@ export declare function inFlightCount(): number;
|
|
|
18
19
|
export declare function legacyToolsEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
19
20
|
/** Test-only: reset the once-per-process alias warning dedupe. */
|
|
20
21
|
export declare function __resetAliasWarnings(): void;
|
|
21
|
-
export
|
|
22
|
+
export interface ServerOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Register the OAuth-connection tools (currently `hydradb_databases`).
|
|
25
|
+
* Set by the HTTP transport when the request authenticated with an OAuth
|
|
26
|
+
* token; never for API keys, so their tool list is unchanged.
|
|
27
|
+
*/
|
|
28
|
+
oauthTools?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare function createHydraDBServer(hydraOverride?: HydraDB,
|
|
31
|
+
/**
|
|
32
|
+
* Graph scope/gating override, for tests and embedders. Without it the graph
|
|
33
|
+
* config is read from the environment exactly as the rest of the config is.
|
|
34
|
+
*/
|
|
35
|
+
graphOverride?: Partial<GraphConfig>, options?: ServerOptions): import("@modelcontextprotocol/sdk/server").Server<{
|
|
22
36
|
method: string;
|
|
23
37
|
params?: {
|
|
24
38
|
[x: string]: unknown;
|