db-mcp 3.0.1 → 4.0.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/README.md +92 -75
- package/dist/.tsbuildinfo +1 -1
- package/dist/adapters/database-adapter.d.ts +2 -1
- package/dist/adapters/database-adapter.d.ts.map +1 -1
- package/dist/adapters/registration/resources.d.ts.map +1 -1
- package/dist/adapters/registration/tools.d.ts.map +1 -1
- package/dist/adapters/sqlite/prompts/analysis.d.ts.map +1 -1
- package/dist/adapters/sqlite/resources.d.ts +1 -1
- package/dist/adapters/sqlite/resources.d.ts.map +1 -1
- package/dist/adapters/sqlite/schemas/admin.d.ts +29 -15
- package/dist/adapters/sqlite/schemas/admin.d.ts.map +1 -1
- package/dist/adapters/sqlite/schemas/core.d.ts +2 -0
- package/dist/adapters/sqlite/schemas/core.d.ts.map +1 -1
- package/dist/adapters/sqlite/schemas/fts.d.ts +4 -0
- package/dist/adapters/sqlite/schemas/fts.d.ts.map +1 -1
- package/dist/adapters/sqlite/schemas/introspection.d.ts +20 -11
- package/dist/adapters/sqlite/schemas/introspection.d.ts.map +1 -1
- package/dist/adapters/sqlite/schemas/spatialite.d.ts +1 -0
- package/dist/adapters/sqlite/schemas/spatialite.d.ts.map +1 -1
- package/dist/adapters/sqlite/schemas/text.d.ts +36 -0
- package/dist/adapters/sqlite/schemas/text.d.ts.map +1 -1
- package/dist/adapters/sqlite/sqlite-adapter.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/admin/index.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/admin/pragma.d.ts +0 -4
- package/dist/adapters/sqlite/tools/admin/pragma.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/core/queries.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/core/tables.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/fts.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/introspection/diagnostics/indexes.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/json-helpers/read.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/json-operations/crud.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/json-operations/query.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/text/helpers.d.ts +9 -0
- package/dist/adapters/sqlite/tools/text/helpers.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/text/index.d.ts.map +1 -1
- package/dist/adapters/sqlite/tools/text/search.d.ts +4 -0
- package/dist/adapters/sqlite/tools/text/search.d.ts.map +1 -1
- package/dist/adapters/sqlite/types.d.ts +4 -0
- package/dist/adapters/sqlite/types.d.ts.map +1 -1
- package/dist/adapters/sqlite-native/native-sqlite-adapter.d.ts.map +1 -1
- package/dist/adapters/sqlite-native/tools/spatialite/tools.d.ts.map +1 -1
- package/dist/audit/interceptor.d.ts.map +1 -1
- package/dist/audit/logger.d.ts +26 -25
- package/dist/audit/logger.d.ts.map +1 -1
- package/dist/{chunk-W5WQVNVX.js → chunk-EQF3WZHX.js} +10 -17
- package/dist/{chunk-37G4DLL6.js → chunk-NIC5Z2CA.js} +732 -138
- package/dist/chunk-R5M4WKDM.js +987 -0
- package/dist/{chunk-NV34JSQM.js → chunk-TGE7LFAR.js} +708 -996
- package/dist/{chunk-L552U3QS.js → chunk-Y57WFKAP.js} +227 -9
- package/dist/cli.js +103 -10
- package/dist/codemode/sandbox.d.ts.map +1 -1
- package/dist/constants/server-instructions.d.ts +1 -1
- package/dist/constants/server-instructions.d.ts.map +1 -1
- package/dist/filtering/tool-constants.d.ts +9 -9
- package/dist/{http-HWTUVFIA.js → http-2WGR3E5K.js} +13 -1
- package/dist/index.js +4 -4
- package/dist/observability/metrics.d.ts +36 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/system-db.d.ts +13 -0
- package/dist/observability/system-db.d.ts.map +1 -0
- package/dist/server/mcp-server.d.ts +3 -0
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/registration/admin-tools.d.ts +6 -0
- package/dist/server/registration/admin-tools.d.ts.map +1 -0
- package/dist/server/registration/audit-tools.d.ts +4 -0
- package/dist/server/registration/audit-tools.d.ts.map +1 -1
- package/dist/server/registration/help-resources.d.ts.map +1 -1
- package/dist/server/registration/index.d.ts +3 -1
- package/dist/server/registration/index.d.ts.map +1 -1
- package/dist/server/registration/observability-resources.d.ts +11 -0
- package/dist/server/registration/observability-resources.d.ts.map +1 -0
- package/dist/server/subscription-manager.d.ts +35 -0
- package/dist/server/subscription-manager.d.ts.map +1 -0
- package/dist/{sqlite-TB56Z7G3.js → sqlite-D4WCNPU4.js} +8 -5
- package/dist/{sqlite-native-IF75BB3O.js → sqlite-native-DLVS2T52.js} +159 -34
- package/dist/transports/http/sessions/legacy-sse.d.ts.map +1 -1
- package/dist/transports/http/sessions/stateful.d.ts.map +1 -1
- package/dist/transports/http/transport.d.ts.map +1 -1
- package/dist/transports/http/types.d.ts +2 -0
- package/dist/transports/http/types.d.ts.map +1 -1
- package/dist/types/server.d.ts +2 -0
- package/dist/types/server.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/logger/types.d.ts +1 -1
- package/dist/utils/logger/types.d.ts.map +1 -1
- package/dist/utils/tokens.d.ts +15 -0
- package/dist/utils/tokens.d.ts.map +1 -0
- package/package.json +10 -7
- package/dist/chunk-E5IESRTK.js +0 -489
- package/dist/utils/insights-manager.d.ts +0 -39
- package/dist/utils/insights-manager.d.ts.map +0 -1
|
@@ -71,7 +71,7 @@ var TOOL_GROUPS = {
|
|
|
71
71
|
"json_diff"
|
|
72
72
|
],
|
|
73
73
|
text: [
|
|
74
|
-
// Text Tools (
|
|
74
|
+
// Text Tools (15 WASM)
|
|
75
75
|
"regex_extract",
|
|
76
76
|
"regex_match",
|
|
77
77
|
"text_split",
|
|
@@ -85,6 +85,7 @@ var TOOL_GROUPS = {
|
|
|
85
85
|
"text_normalize",
|
|
86
86
|
"text_validate",
|
|
87
87
|
"advanced_search",
|
|
88
|
+
"hybrid_search",
|
|
88
89
|
"text_sentiment",
|
|
89
90
|
// FTS5 Tools (5 Native-only)
|
|
90
91
|
"fts_create",
|
|
@@ -94,7 +95,7 @@ var TOOL_GROUPS = {
|
|
|
94
95
|
"fts_headline"
|
|
95
96
|
],
|
|
96
97
|
stats: [
|
|
97
|
-
// Stats Tools (
|
|
98
|
+
// Stats Tools (13 WASM)
|
|
98
99
|
"stats_basic",
|
|
99
100
|
"stats_count",
|
|
100
101
|
"stats_group_by",
|
|
@@ -136,7 +137,7 @@ var TOOL_GROUPS = {
|
|
|
136
137
|
"vector_distance"
|
|
137
138
|
],
|
|
138
139
|
admin: [
|
|
139
|
-
// Admin Tools (
|
|
140
|
+
// Admin Tools (12: backup.ts, verify.ts, pragma.ts)
|
|
140
141
|
"backup",
|
|
141
142
|
"analyze",
|
|
142
143
|
"integrity_check",
|
|
@@ -149,7 +150,6 @@ var TOOL_GROUPS = {
|
|
|
149
150
|
"pragma_optimize",
|
|
150
151
|
"pragma_settings",
|
|
151
152
|
"pragma_table_info",
|
|
152
|
-
"append_insight",
|
|
153
153
|
// Virtual Table Tools (13: views.ts, vtable.ts, extensions.ts, analysis.ts)
|
|
154
154
|
"generate_series",
|
|
155
155
|
"create_view",
|
|
@@ -164,7 +164,7 @@ var TOOL_GROUPS = {
|
|
|
164
164
|
"analyze_csv_schema",
|
|
165
165
|
"create_rtree_table",
|
|
166
166
|
"create_series_table",
|
|
167
|
-
// Database management (
|
|
167
|
+
// Database management (6: pragma.ts, backup/create.ts, dump.ts, reindex.ts, wal.ts)
|
|
168
168
|
"attach_database",
|
|
169
169
|
"detach_database",
|
|
170
170
|
"vacuum_into",
|
|
@@ -223,11 +223,11 @@ var TOOL_GROUPS = {
|
|
|
223
223
|
codemode: ["execute_code"]
|
|
224
224
|
};
|
|
225
225
|
var META_GROUPS = {
|
|
226
|
-
// General development - Core + JSON + Text (
|
|
226
|
+
// General development - Core + JSON + Text (61 WASM / 66 Native)
|
|
227
227
|
starter: ["core", "json", "text", "codemode"],
|
|
228
228
|
// Data analysis - Core + JSON + Stats (63 WASM / 69 Native)
|
|
229
229
|
analytics: ["core", "json", "stats", "codemode"],
|
|
230
|
-
// Search workloads - Core + Text + Vector (
|
|
230
|
+
// Search workloads - Core + Text + Vector (47 WASM / 52 Native)
|
|
231
231
|
search: ["core", "text", "vector", "codemode"],
|
|
232
232
|
// Geospatial workloads - Core + Geo + Vector (36 WASM / 43 Native)
|
|
233
233
|
spatial: ["core", "geo", "vector", "codemode"],
|
|
@@ -235,7 +235,7 @@ var META_GROUPS = {
|
|
|
235
235
|
"dev-schema": ["core", "introspection", "migration", "codemode"],
|
|
236
236
|
// Bare minimum - Core (21 tools)
|
|
237
237
|
minimal: ["core", "codemode"],
|
|
238
|
-
// All group tools enabled (
|
|
238
|
+
// All group tools enabled (167 Native / 140 WASM — see TOOL COUNT TAXONOMY above)
|
|
239
239
|
full: [
|
|
240
240
|
"core",
|
|
241
241
|
"json",
|
|
@@ -1174,6 +1174,224 @@ function formatHandlerError(error, _context) {
|
|
|
1174
1174
|
details: void 0
|
|
1175
1175
|
};
|
|
1176
1176
|
}
|
|
1177
|
+
|
|
1178
|
+
// src/observability/metrics.ts
|
|
1179
|
+
var MAX_SAMPLES = 1e3;
|
|
1180
|
+
var ToolMetric = class {
|
|
1181
|
+
calls = 0;
|
|
1182
|
+
errors = 0;
|
|
1183
|
+
tokens = 0;
|
|
1184
|
+
// Circular buffer for latency samples
|
|
1185
|
+
samples = new Array(MAX_SAMPLES).fill(0);
|
|
1186
|
+
sampleIndex = 0;
|
|
1187
|
+
sampleCount = 0;
|
|
1188
|
+
record(durationMs, success, tokens = 0) {
|
|
1189
|
+
this.calls++;
|
|
1190
|
+
if (!success) this.errors++;
|
|
1191
|
+
this.tokens += tokens;
|
|
1192
|
+
this.samples[this.sampleIndex] = durationMs;
|
|
1193
|
+
this.sampleIndex = (this.sampleIndex + 1) % MAX_SAMPLES;
|
|
1194
|
+
if (this.sampleCount < MAX_SAMPLES) {
|
|
1195
|
+
this.sampleCount++;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
getSummary() {
|
|
1199
|
+
if (this.sampleCount === 0) {
|
|
1200
|
+
return {
|
|
1201
|
+
calls: this.calls,
|
|
1202
|
+
errors: this.errors,
|
|
1203
|
+
tokens: this.tokens,
|
|
1204
|
+
p50: 0,
|
|
1205
|
+
p95: 0,
|
|
1206
|
+
p99: 0
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
const activeSamples = this.samples.slice(0, this.sampleCount).sort((a, b) => a - b);
|
|
1210
|
+
return {
|
|
1211
|
+
calls: this.calls,
|
|
1212
|
+
errors: this.errors,
|
|
1213
|
+
tokens: this.tokens,
|
|
1214
|
+
p50: this.getPercentile(activeSamples, 0.5),
|
|
1215
|
+
p95: this.getPercentile(activeSamples, 0.95),
|
|
1216
|
+
p99: this.getPercentile(activeSamples, 0.99)
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
getPercentile(sorted, p) {
|
|
1220
|
+
if (sorted.length === 0) return 0;
|
|
1221
|
+
const idx = (sorted.length - 1) * p;
|
|
1222
|
+
const base = Math.floor(idx);
|
|
1223
|
+
const rest = idx - base;
|
|
1224
|
+
const v0 = sorted[base] ?? 0;
|
|
1225
|
+
const v1 = sorted[base + 1];
|
|
1226
|
+
if (v1 !== void 0) {
|
|
1227
|
+
return Math.round(v0 + rest * (v1 - v0));
|
|
1228
|
+
} else {
|
|
1229
|
+
return v0;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
var ResourceMetric = class {
|
|
1234
|
+
reads = 0;
|
|
1235
|
+
record() {
|
|
1236
|
+
this.reads++;
|
|
1237
|
+
}
|
|
1238
|
+
getSummary() {
|
|
1239
|
+
return { reads: this.reads };
|
|
1240
|
+
}
|
|
1241
|
+
};
|
|
1242
|
+
var MetricsRegistry = class {
|
|
1243
|
+
tools = /* @__PURE__ */ new Map();
|
|
1244
|
+
resources = /* @__PURE__ */ new Map();
|
|
1245
|
+
systemDb = null;
|
|
1246
|
+
flushTimer = null;
|
|
1247
|
+
setSystemDb(systemDb) {
|
|
1248
|
+
this.systemDb = systemDb;
|
|
1249
|
+
this.loadHistorical();
|
|
1250
|
+
this.startFlushTimer();
|
|
1251
|
+
}
|
|
1252
|
+
loadHistorical() {
|
|
1253
|
+
if (!this.systemDb) return;
|
|
1254
|
+
try {
|
|
1255
|
+
const db = this.systemDb.getDb();
|
|
1256
|
+
const rows = db.prepare(
|
|
1257
|
+
`
|
|
1258
|
+
SELECT tool, MAX(calls) as max_calls, MAX(errors) as max_errors, MAX(tokens) as max_tokens
|
|
1259
|
+
FROM metrics_snapshots
|
|
1260
|
+
GROUP BY tool
|
|
1261
|
+
`
|
|
1262
|
+
).all();
|
|
1263
|
+
for (const row of rows) {
|
|
1264
|
+
const metric = new ToolMetric();
|
|
1265
|
+
metric.calls = row.max_calls;
|
|
1266
|
+
metric.errors = row.max_errors;
|
|
1267
|
+
metric.tokens = row.max_tokens;
|
|
1268
|
+
this.tools.set(row.tool, metric);
|
|
1269
|
+
}
|
|
1270
|
+
logger.info(`Loaded historical metrics for ${rows.length} tools`, {
|
|
1271
|
+
module: "METRICS"
|
|
1272
|
+
});
|
|
1273
|
+
} catch (err) {
|
|
1274
|
+
logger.warning("Failed to load historical metrics", {
|
|
1275
|
+
module: "METRICS",
|
|
1276
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
startFlushTimer() {
|
|
1281
|
+
if (this.flushTimer) clearInterval(this.flushTimer);
|
|
1282
|
+
this.flushTimer = setInterval(
|
|
1283
|
+
() => {
|
|
1284
|
+
this.flushToDb();
|
|
1285
|
+
},
|
|
1286
|
+
5 * 60 * 1e3
|
|
1287
|
+
);
|
|
1288
|
+
this.flushTimer.unref();
|
|
1289
|
+
}
|
|
1290
|
+
flushToDb() {
|
|
1291
|
+
if (!this.systemDb) return;
|
|
1292
|
+
try {
|
|
1293
|
+
const db = this.systemDb.getDb();
|
|
1294
|
+
const stmt = db.prepare(`
|
|
1295
|
+
INSERT INTO metrics_snapshots (timestamp, tool, calls, errors, p50, p95, p99, tokens)
|
|
1296
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1297
|
+
`);
|
|
1298
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1299
|
+
const transaction = db.transaction(() => {
|
|
1300
|
+
for (const [name, metric] of this.tools.entries()) {
|
|
1301
|
+
const summary = metric.getSummary();
|
|
1302
|
+
stmt.run(
|
|
1303
|
+
timestamp,
|
|
1304
|
+
name,
|
|
1305
|
+
summary.calls,
|
|
1306
|
+
summary.errors,
|
|
1307
|
+
summary.p50,
|
|
1308
|
+
summary.p95,
|
|
1309
|
+
summary.p99,
|
|
1310
|
+
summary.tokens
|
|
1311
|
+
);
|
|
1312
|
+
}
|
|
1313
|
+
});
|
|
1314
|
+
transaction();
|
|
1315
|
+
} catch (err) {
|
|
1316
|
+
logger.warning("Failed to flush metrics to db", {
|
|
1317
|
+
module: "METRICS",
|
|
1318
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
close() {
|
|
1323
|
+
if (this.flushTimer) {
|
|
1324
|
+
clearInterval(this.flushTimer);
|
|
1325
|
+
this.flushTimer = null;
|
|
1326
|
+
}
|
|
1327
|
+
this.flushToDb();
|
|
1328
|
+
}
|
|
1329
|
+
recordToolCall(toolName, durationMs, success, tokens = 0) {
|
|
1330
|
+
let metric = this.tools.get(toolName);
|
|
1331
|
+
if (!metric) {
|
|
1332
|
+
metric = new ToolMetric();
|
|
1333
|
+
this.tools.set(toolName, metric);
|
|
1334
|
+
}
|
|
1335
|
+
metric.record(durationMs, success, tokens);
|
|
1336
|
+
}
|
|
1337
|
+
recordResourceRead(uri) {
|
|
1338
|
+
let metric = this.resources.get(uri);
|
|
1339
|
+
if (!metric) {
|
|
1340
|
+
metric = new ResourceMetric();
|
|
1341
|
+
this.resources.set(uri, metric);
|
|
1342
|
+
}
|
|
1343
|
+
metric.record();
|
|
1344
|
+
}
|
|
1345
|
+
getSummary() {
|
|
1346
|
+
const toolsSummary = {};
|
|
1347
|
+
for (const [name, metric] of this.tools.entries()) {
|
|
1348
|
+
toolsSummary[name] = metric.getSummary();
|
|
1349
|
+
}
|
|
1350
|
+
const resourcesSummary = {};
|
|
1351
|
+
for (const [uri, metric] of this.resources.entries()) {
|
|
1352
|
+
resourcesSummary[uri] = metric.getSummary();
|
|
1353
|
+
}
|
|
1354
|
+
return {
|
|
1355
|
+
tools: toolsSummary,
|
|
1356
|
+
resources: resourcesSummary,
|
|
1357
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
toPrometheus() {
|
|
1361
|
+
const lines = [];
|
|
1362
|
+
lines.push("# HELP db_mcp_tool_calls_total Total tool calls");
|
|
1363
|
+
lines.push("# TYPE db_mcp_tool_calls_total counter");
|
|
1364
|
+
lines.push("# HELP db_mcp_tool_errors_total Total tool errors");
|
|
1365
|
+
lines.push("# TYPE db_mcp_tool_errors_total counter");
|
|
1366
|
+
lines.push("# HELP db_mcp_tool_tokens_total Total tokens estimated");
|
|
1367
|
+
lines.push("# TYPE db_mcp_tool_tokens_total counter");
|
|
1368
|
+
lines.push("# HELP db_mcp_tool_latency_ms_p50 P50 Latency (ms)");
|
|
1369
|
+
lines.push("# TYPE db_mcp_tool_latency_ms_p50 gauge");
|
|
1370
|
+
lines.push("# HELP db_mcp_tool_latency_ms_p95 P95 Latency (ms)");
|
|
1371
|
+
lines.push("# TYPE db_mcp_tool_latency_ms_p95 gauge");
|
|
1372
|
+
lines.push("# HELP db_mcp_tool_latency_ms_p99 P99 Latency (ms)");
|
|
1373
|
+
lines.push("# TYPE db_mcp_tool_latency_ms_p99 gauge");
|
|
1374
|
+
for (const [name, metric] of this.tools.entries()) {
|
|
1375
|
+
const summary = metric.getSummary();
|
|
1376
|
+
const labels = `{tool="${name}"}`;
|
|
1377
|
+
lines.push(`db_mcp_tool_calls_total${labels} ${summary.calls}`);
|
|
1378
|
+
lines.push(`db_mcp_tool_errors_total${labels} ${summary.errors}`);
|
|
1379
|
+
lines.push(`db_mcp_tool_tokens_total${labels} ${summary.tokens}`);
|
|
1380
|
+
lines.push(`db_mcp_tool_latency_ms_p50${labels} ${summary.p50}`);
|
|
1381
|
+
lines.push(`db_mcp_tool_latency_ms_p95${labels} ${summary.p95}`);
|
|
1382
|
+
lines.push(`db_mcp_tool_latency_ms_p99${labels} ${summary.p99}`);
|
|
1383
|
+
}
|
|
1384
|
+
lines.push("# HELP db_mcp_resource_reads_total Total resource reads");
|
|
1385
|
+
lines.push("# TYPE db_mcp_resource_reads_total counter");
|
|
1386
|
+
for (const [uri, metric] of this.resources.entries()) {
|
|
1387
|
+
const summary = metric.getSummary();
|
|
1388
|
+
const labels = `{resource="${uri}"}`;
|
|
1389
|
+
lines.push(`db_mcp_resource_reads_total${labels} ${summary.reads}`);
|
|
1390
|
+
}
|
|
1391
|
+
return lines.join("\n") + "\n";
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1394
|
+
var metrics = new MetricsRegistry();
|
|
1177
1395
|
var authContextStorage = new AsyncLocalStorage();
|
|
1178
1396
|
function runWithAuthContext(context, fn) {
|
|
1179
1397
|
return authContextStorage.run(context, fn);
|
|
@@ -1555,4 +1773,4 @@ function isOAuthError(error) {
|
|
|
1555
1773
|
return error instanceof OAuthError;
|
|
1556
1774
|
}
|
|
1557
1775
|
|
|
1558
|
-
export { ALL_TOOL_GROUPS, AuthServerDiscoveryError, AuthenticationError, AuthorizationError, BASE_SCOPES, ConfigurationError, ConnectionError, DbMcpError, ERROR_CODES, ExtensionNotAvailableError, InsufficientScopeError, InvalidSignatureError, InvalidTokenError, JwksFetchError, META_GROUPS, QueryError, ResourceNotFoundError, SCOPES, SUPPORTED_SCOPES, TOOL_GROUPS, TokenExpiredError, TokenMissingError, ValidationError, createModuleLogger, filterTools, findSuggestion, formatHandlerError, getAuthContext, getFilterSummary, getToolFilterFromEnv, hasAdminScope, hasReadScope, isOAuthError, isToolEnabled, logger, parseScopes, parseToolFilter, registerToolScopes, runWithAuthContext, sanitizeErrorMessage, scopesGrantToolAccess };
|
|
1776
|
+
export { ALL_TOOL_GROUPS, AuthServerDiscoveryError, AuthenticationError, AuthorizationError, BASE_SCOPES, ConfigurationError, ConnectionError, DbMcpError, ERROR_CODES, ExtensionNotAvailableError, InsufficientScopeError, InvalidSignatureError, InvalidTokenError, JwksFetchError, META_GROUPS, QueryError, ResourceNotFoundError, SCOPES, SUPPORTED_SCOPES, TOOL_GROUPS, TokenExpiredError, TokenMissingError, ValidationError, createModuleLogger, filterTools, findSuggestion, formatHandlerError, getAuthContext, getFilterSummary, getToolFilterFromEnv, hasAdminScope, hasReadScope, isOAuthError, isToolEnabled, logger, metrics, parseScopes, parseToolFilter, registerToolScopes, runWithAuthContext, sanitizeErrorMessage, scopesGrantToolAccess };
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { DEFAULT_CONFIG, createServer } from './chunk-
|
|
3
|
-
import { VERSION } from './chunk-
|
|
4
|
-
import { logger } from './chunk-
|
|
2
|
+
import { DEFAULT_CONFIG, createServer } from './chunk-NIC5Z2CA.js';
|
|
3
|
+
import { VERSION } from './chunk-R5M4WKDM.js';
|
|
4
|
+
import { logger } from './chunk-Y57WFKAP.js';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import yaml from 'yaml';
|
|
5
7
|
|
|
6
8
|
// src/audit/types.ts
|
|
7
9
|
var DEFAULT_AUDIT_LOG_MAX_SIZE_BYTES = 10 * 1024 * 1024;
|
|
@@ -21,6 +23,9 @@ function parseArgs() {
|
|
|
21
23
|
let auditReads = false;
|
|
22
24
|
let auditBackup = false;
|
|
23
25
|
let auditBackupData = false;
|
|
26
|
+
let metricsExport;
|
|
27
|
+
let dumpConfig = false;
|
|
28
|
+
let configPath;
|
|
24
29
|
for (let i = 0; i < args.length; i++) {
|
|
25
30
|
const arg = args[i];
|
|
26
31
|
if (arg === "--transport" || arg === "-t") {
|
|
@@ -123,6 +128,19 @@ function parseArgs() {
|
|
|
123
128
|
if (lastDb?.options && "backend" in lastDb.options) {
|
|
124
129
|
lastDb.options["spatialite"] = true;
|
|
125
130
|
}
|
|
131
|
+
} else if (arg === "--encryption-key") {
|
|
132
|
+
const keyValue = args[++i];
|
|
133
|
+
if (keyValue) {
|
|
134
|
+
const lastDb = databases[databases.length - 1];
|
|
135
|
+
if (lastDb?.options && "backend" in lastDb.options) {
|
|
136
|
+
lastDb.options["encryptionKey"] = keyValue;
|
|
137
|
+
} else {
|
|
138
|
+
console.error(
|
|
139
|
+
"Error: --encryption-key must be specified after --sqlite-native"
|
|
140
|
+
);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
126
144
|
} else if (arg === "--audit-log") {
|
|
127
145
|
const logPath = args[++i];
|
|
128
146
|
if (logPath) {
|
|
@@ -136,6 +154,18 @@ function parseArgs() {
|
|
|
136
154
|
auditBackup = true;
|
|
137
155
|
} else if (arg === "--audit-backup-data") {
|
|
138
156
|
auditBackupData = true;
|
|
157
|
+
} else if (arg === "--metrics-export") {
|
|
158
|
+
const metricsValue = args[++i];
|
|
159
|
+
if (metricsValue === "prometheus") {
|
|
160
|
+
metricsExport = "prometheus";
|
|
161
|
+
}
|
|
162
|
+
} else if (arg === "--config" || arg === "-c") {
|
|
163
|
+
const pathValue = args[++i];
|
|
164
|
+
if (pathValue) {
|
|
165
|
+
configPath = pathValue;
|
|
166
|
+
}
|
|
167
|
+
} else if (arg === "--dump-config") {
|
|
168
|
+
dumpConfig = true;
|
|
139
169
|
} else if (arg === "--help" || arg === "-h") {
|
|
140
170
|
printHelp();
|
|
141
171
|
process.exit(0);
|
|
@@ -144,6 +174,9 @@ function parseArgs() {
|
|
|
144
174
|
if (databases.length > 0) {
|
|
145
175
|
config.databases = databases;
|
|
146
176
|
}
|
|
177
|
+
if (metricsExport) {
|
|
178
|
+
config.metricsExport = metricsExport;
|
|
179
|
+
}
|
|
147
180
|
if (auditLogPath) {
|
|
148
181
|
config.audit = {
|
|
149
182
|
enabled: true,
|
|
@@ -162,7 +195,11 @@ function parseArgs() {
|
|
|
162
195
|
}
|
|
163
196
|
};
|
|
164
197
|
}
|
|
165
|
-
return
|
|
198
|
+
return {
|
|
199
|
+
cliConfig: config,
|
|
200
|
+
dumpConfig,
|
|
201
|
+
...configPath !== void 0 ? { configPath } : {}
|
|
202
|
+
};
|
|
166
203
|
}
|
|
167
204
|
function printHelp() {
|
|
168
205
|
console.error(`
|
|
@@ -194,6 +231,7 @@ Database Options:
|
|
|
194
231
|
Extension Options (Native only):
|
|
195
232
|
--csv Load CSV extension for CSV virtual tables
|
|
196
233
|
--spatialite Load SpatiaLite extension for GIS capabilities
|
|
234
|
+
--encryption-key <key> Set SQLCipher encryption key for the database
|
|
197
235
|
|
|
198
236
|
Audit Options:
|
|
199
237
|
--audit-log <path> Enable audit logging (JSONL file path, or "stderr")
|
|
@@ -203,8 +241,11 @@ Audit Options:
|
|
|
203
241
|
--audit-backup-data Include sample data rows in snapshots
|
|
204
242
|
|
|
205
243
|
Server Options:
|
|
244
|
+
--config, -c <path> Load configuration from YAML/JSON file
|
|
245
|
+
--dump-config Print the resolved configuration and exit
|
|
206
246
|
--name <name> Server name (default: db-mcp)
|
|
207
247
|
--version <version> Server version (default: ${VERSION})
|
|
248
|
+
--metrics-export <type> Export metrics at HTTP /metrics (e.g., prometheus)
|
|
208
249
|
--tool-filter <filter> Tool filter string. Supports:
|
|
209
250
|
Shortcuts: starter, analytics, search, spatial, minimal, full
|
|
210
251
|
Groups: core, json, text, fts5, stats, vector, geo, ...
|
|
@@ -222,8 +263,10 @@ Environment Variables:
|
|
|
222
263
|
MCP_ENABLE_HSTS Enable HSTS header (same as --enable-hsts)
|
|
223
264
|
DB_MCP_TOOL_FILTER Tool filter string
|
|
224
265
|
SQLITE_DATABASE SQLite database path
|
|
266
|
+
DB_ENCRYPTION_KEY SQLCipher encryption key (Native only)
|
|
225
267
|
CSV_EXTENSION_PATH Custom path to CSV extension binary
|
|
226
268
|
SPATIALITE_PATH Custom path to SpatiaLite extension binary
|
|
269
|
+
METRICS_EXPORT Export metrics (e.g., prometheus)
|
|
227
270
|
AUDIT_LOG Audit log file path (or "stderr")
|
|
228
271
|
AUDIT_REDACT Redact arguments (default: true, set false to include args)
|
|
229
272
|
AUDIT_READS Log reads (true/false)
|
|
@@ -233,7 +276,7 @@ Environment Variables:
|
|
|
233
276
|
Examples:
|
|
234
277
|
db-mcp --sqlite-native ./data.db
|
|
235
278
|
db-mcp --sqlite-native ./data.db --tool-filter "starter"
|
|
236
|
-
db-mcp --transport http --port 3000 --
|
|
279
|
+
MCP_AUTH_TOKEN=my-secret db-mcp --transport http --port 3000 --sqlite ./data.db
|
|
237
280
|
db-mcp --transport http --oauth-enabled --oauth-issuer http://keycloak:8080/realms/mcp --oauth-audience db-mcp --sqlite ./data.db
|
|
238
281
|
|
|
239
282
|
For more information, visit: https://github.com/neverinfamous/db-mcp
|
|
@@ -304,24 +347,60 @@ function loadEnvConfig() {
|
|
|
304
347
|
if (sqliteUri) {
|
|
305
348
|
databases.push({ type: "sqlite", connectionString: sqliteUri });
|
|
306
349
|
}
|
|
350
|
+
if (process.env["METRICS_EXPORT"] === "prometheus") {
|
|
351
|
+
config.metricsExport = "prometheus";
|
|
352
|
+
}
|
|
307
353
|
if (databases.length > 0) {
|
|
308
354
|
config.databases = databases;
|
|
309
355
|
}
|
|
310
356
|
return config;
|
|
311
357
|
}
|
|
358
|
+
function loadConfigFile(configPath) {
|
|
359
|
+
try {
|
|
360
|
+
const fileContent = fs.readFileSync(configPath, "utf-8");
|
|
361
|
+
if (configPath.endsWith(".yaml") || configPath.endsWith(".yml")) {
|
|
362
|
+
return yaml.parse(fileContent);
|
|
363
|
+
} else {
|
|
364
|
+
return JSON.parse(fileContent);
|
|
365
|
+
}
|
|
366
|
+
} catch (error) {
|
|
367
|
+
logger.error(`Failed to load config file: ${configPath}`, {
|
|
368
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
369
|
+
module: "CLI"
|
|
370
|
+
});
|
|
371
|
+
process.exit(1);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
312
374
|
async function main() {
|
|
313
375
|
try {
|
|
376
|
+
const { cliConfig, dumpConfig, configPath } = parseArgs();
|
|
377
|
+
const fileConfig = configPath ? loadConfigFile(configPath) : {};
|
|
314
378
|
const envConfig = loadEnvConfig();
|
|
315
|
-
const cliConfig = parseArgs();
|
|
316
379
|
const config = {
|
|
317
380
|
...DEFAULT_CONFIG,
|
|
381
|
+
...fileConfig,
|
|
318
382
|
...envConfig,
|
|
319
383
|
...cliConfig,
|
|
320
384
|
databases: [
|
|
385
|
+
...fileConfig.databases ?? [],
|
|
321
386
|
...envConfig.databases ?? [],
|
|
322
387
|
...cliConfig.databases ?? []
|
|
323
388
|
]
|
|
324
389
|
};
|
|
390
|
+
if (dumpConfig) {
|
|
391
|
+
const safeConfig = JSON.parse(JSON.stringify(config));
|
|
392
|
+
if (typeof safeConfig["authToken"] === "string") {
|
|
393
|
+
safeConfig["authToken"] = "***REDACTED***";
|
|
394
|
+
}
|
|
395
|
+
if (typeof safeConfig["oauth"] === "object" && safeConfig["oauth"] !== null) {
|
|
396
|
+
const oauth = safeConfig["oauth"];
|
|
397
|
+
if (typeof oauth["jwksUri"] === "string") {
|
|
398
|
+
oauth["jwksUri"] = "***REDACTED***";
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
process.stdout.write(JSON.stringify(safeConfig, null, 2) + "\n");
|
|
402
|
+
process.exit(0);
|
|
403
|
+
}
|
|
325
404
|
if (process.env["NODE_ENV"] === "production" && config.transport === "http" && !config.oauth?.enabled && !config.authToken && !config.noAuthEnforcement) {
|
|
326
405
|
logger.error(
|
|
327
406
|
"FATAL SECURITY ERROR: HTTP transport in production requires authentication (--oauth-enabled or --auth-token). If you intend to run without authentication, you must explicitly pass --no-auth-enforcement.",
|
|
@@ -340,15 +419,29 @@ async function main() {
|
|
|
340
419
|
process.exit(0);
|
|
341
420
|
});
|
|
342
421
|
});
|
|
422
|
+
const globalEncryptionKey = process.env["DB_ENCRYPTION_KEY"];
|
|
343
423
|
for (const dbConfig of config.databases) {
|
|
344
424
|
if (dbConfig.type === "sqlite") {
|
|
345
|
-
const options = dbConfig.options;
|
|
346
|
-
if (
|
|
347
|
-
|
|
425
|
+
const options = dbConfig.options ?? {};
|
|
426
|
+
if (globalEncryptionKey && !options.encryptionKey) {
|
|
427
|
+
if (options.backend === "better-sqlite3") {
|
|
428
|
+
options.encryptionKey = globalEncryptionKey;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
dbConfig.options = options;
|
|
432
|
+
if (options.encryptionKey && options.backend !== "better-sqlite3") {
|
|
433
|
+
logger.error(
|
|
434
|
+
"FATAL: SQLCipher encryption is only supported with the native better-sqlite3 backend. Use --sqlite-native or specify backend: 'better-sqlite3' in config.",
|
|
435
|
+
{ module: "CLI" }
|
|
436
|
+
);
|
|
437
|
+
process.exit(1);
|
|
438
|
+
}
|
|
439
|
+
if (options.backend === "better-sqlite3") {
|
|
440
|
+
const { NativeSqliteAdapter } = await import('./sqlite-native-DLVS2T52.js');
|
|
348
441
|
const adapter = new NativeSqliteAdapter();
|
|
349
442
|
await server.registerAdapter(adapter, dbConfig);
|
|
350
443
|
} else {
|
|
351
|
-
const { SqliteAdapter } = await import('./sqlite-
|
|
444
|
+
const { SqliteAdapter } = await import('./sqlite-D4WCNPU4.js');
|
|
352
445
|
const adapter = new SqliteAdapter();
|
|
353
446
|
await server.registerAdapter(adapter, dbConfig);
|
|
354
447
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/codemode/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AAEnC,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAGpB;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAAgB;IAEvC,OAAO;IAIP;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,eAAe;IAQxD;;OAEG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/codemode/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AAEnC,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAGpB;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAAgB;IAEvC,OAAO;IAIP;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,eAAe;IAQxD;;OAEG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC;IAkUzB,gBAAgB,IAAI,MAAM,EAAE;IAI5B,kBAAkB,IAAI,IAAI;IAI1B,SAAS,IAAI,OAAO;IAIpB,OAAO,IAAI,IAAI;CAIhB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2B;IAC1D,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,MAAM,CAAC,UAAU,CAAoC;IAC7D,OAAO,CAAC,MAAM,CAAC,YAAY,CAA2B;gBAE1C,WAAW,CAAC,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,cAAc;IAKtE,MAAM,CAAC,SAAS,IAAI,OAAO,GAAG;WAOjB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC;IAgCzB,OAAO,IAAI,IAAI;IAOf,QAAQ,IAAI;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAS3E,OAAO,IAAI,IAAI;CAGhB"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Slim instructions for the MCP instructions field (~600 chars).
|
|
13
13
|
* Points agents to sqlite://help resources for detailed reference.
|
|
14
14
|
*/
|
|
15
|
-
export declare const INSTRUCTIONS = "# db-mcp (SQLite MCP Server)\n\n## Quick Access\n\n| Purpose
|
|
15
|
+
export declare const INSTRUCTIONS = "# db-mcp (SQLite MCP Server)\n\n## Quick Access\n\n| Purpose | Action |\n| ------------------ | -------------------------- |\n| Health check | `server_health` tool |\n| Live server health | `sqlite://health` resource |\n| Server info | `server_info` tool |\n| Database schema | `sqlite://schema` resource |\n| Tool help | `sqlite://help` resource |\n\n## Built-in Tools\n\n`server_info`, `server_health`, `list_adapters`, `sqlite_execute_code` \u2014 injected into all configurations.\n\n## Help Resources\n\nRead `sqlite://help` for gotchas and critical usage patterns.\nRead `sqlite://help/{group}` for group-specific tool reference (core, json, text, stats, vector, geo, admin, transactions, introspection, migration).\nOnly help resources for your enabled tool groups are registered.";
|
|
16
16
|
/**
|
|
17
17
|
* Help content keyed by group name.
|
|
18
18
|
* 'gotchas' is the always-available help (sqlite://help).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-instructions.d.ts","sourceRoot":"","sources":["../../src/constants/server-instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;GAGG;AACH,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"server-instructions.d.ts","sourceRoot":"","sources":["../../src/constants/server-instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;GAGG;AACH,eAAO,MAAM,YAAY,g2BAoBwC,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAs3BnD,CAAC"}
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
* GROUP TOOLS (adapter-registered, accessible via Code Mode sqlite.help()):
|
|
7
7
|
* core: 21 tools (core/queries.ts, core/tables.ts, core/indexes.ts, core/convenience.ts, core/triggers.ts, core/constraints.ts, core/datetime.ts, core/alter-table.ts)
|
|
8
8
|
* json: 25 tools (json-operations/crud+query+transform+security+diff.ts, json-helpers/read+write.ts)
|
|
9
|
-
* text:
|
|
9
|
+
* text: 15 WASM / 20 Native (text/regex+formatting+search+validate+sentiment.ts, fts.ts)
|
|
10
10
|
* stats: 17 WASM / 23 Native (stats/basic+advanced.ts, inference/, anomaly-detection.ts, schema-risks.ts, native: window.ts)
|
|
11
11
|
* vector: 11 tools (vector/storage+search+metadata.ts)
|
|
12
|
-
* admin:
|
|
12
|
+
* admin: 30 WASM / 31 Native (admin/backup+verify+pragma+reindex+wal.ts, virtual/views+vtable+extensions+analysis.ts; dump.ts is NATIVE ONLY)
|
|
13
13
|
* transactions: 8 Native (native: transactions.ts)
|
|
14
14
|
* geo: 4 WASM / 11 Native (geo.ts, native: spatialite/tools+analysis.ts)
|
|
15
15
|
* introspection: 10 tools (introspection/graph/tools.ts, analysis/constraints+risks+snapshot+diff.ts, diagnostics/storage+indexes+query-plan.ts)
|
|
@@ -17,15 +17,15 @@
|
|
|
17
17
|
* codemode: 1 tool (codemode.ts)
|
|
18
18
|
* Subtotal: 139 WASM / 166 Native (excluding Code Mode)
|
|
19
19
|
*
|
|
20
|
-
* AUDIT TOOLS (server-level, MCP-only — NOT exposed in Code Mode):
|
|
21
|
-
*
|
|
20
|
+
* AUDIT & ADMIN TOOLS (server-level, MCP-only — NOT exposed in Code Mode):
|
|
21
|
+
* 7 tools (server/registration/audit-tools.ts, admin-tools.ts)
|
|
22
22
|
*
|
|
23
23
|
* TOOL COUNT TAXONOMY:
|
|
24
|
-
* Group tools: 166 Native / 139 WASM (
|
|
25
|
-
* Audit tools:
|
|
26
|
-
* Inventory:
|
|
27
|
-
* Built-in: 4 / 4 (server_info, health, adapters,
|
|
28
|
-
* MCP total:
|
|
24
|
+
* Group tools: 166 Native / 139 WASM (10 groups excluding Code Mode)
|
|
25
|
+
* Audit tools: 7 Native / 7 WASM (MCP-only)
|
|
26
|
+
* Inventory: 173 Native / 146 WASM (Group + Audit)
|
|
27
|
+
* Built-in: 4 / 4 (server_info, health, adapters, execute_code)
|
|
28
|
+
* MCP total: 177 Native / 150 WASM (tools/list response)
|
|
29
29
|
*/
|
|
30
30
|
import type { ToolGroup, MetaGroup } from "../types/index.js";
|
|
31
31
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createModuleLogger, DbMcpError, runWithAuthContext, ERROR_CODES, logger, SUPPORTED_SCOPES, scopesGrantToolAccess, InsufficientScopeError, hasAdminScope, hasReadScope, isOAuthError, BASE_SCOPES, AuthServerDiscoveryError, JwksFetchError, parseScopes, TokenExpiredError, InvalidSignatureError, InvalidTokenError, TokenMissingError } from './chunk-
|
|
1
|
+
import { createModuleLogger, DbMcpError, metrics, runWithAuthContext, ERROR_CODES, logger, SUPPORTED_SCOPES, scopesGrantToolAccess, InsufficientScopeError, hasAdminScope, hasReadScope, isOAuthError, BASE_SCOPES, AuthServerDiscoveryError, JwksFetchError, parseScopes, TokenExpiredError, InvalidSignatureError, InvalidTokenError, TokenMissingError } from './chunk-Y57WFKAP.js';
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import { localhostHostValidation } from '@modelcontextprotocol/sdk/server/middleware/hostHeaderValidation.js';
|
|
4
4
|
import cors from 'cors';
|
|
@@ -446,6 +446,9 @@ function setupStatefulEndpoints(state) {
|
|
|
446
446
|
});
|
|
447
447
|
state.transports.delete(sid);
|
|
448
448
|
state.sessionOwners.delete(sid);
|
|
449
|
+
if ("subscriptionManager" in server) {
|
|
450
|
+
server.subscriptionManager.unsubscribeSession(sid);
|
|
451
|
+
}
|
|
449
452
|
}
|
|
450
453
|
};
|
|
451
454
|
await connectionMutex.acquire().then(async (release) => {
|
|
@@ -606,6 +609,9 @@ function setupLegacySSEEndpoints(state) {
|
|
|
606
609
|
});
|
|
607
610
|
state.sseTransports.delete(sseTransport.sessionId);
|
|
608
611
|
state.sessionOwners.delete(sseTransport.sessionId);
|
|
612
|
+
if ("subscriptionManager" in server) {
|
|
613
|
+
server.subscriptionManager.unsubscribeSession(sseTransport.sessionId);
|
|
614
|
+
}
|
|
609
615
|
};
|
|
610
616
|
const origSend = sseTransport.send.bind(sseTransport);
|
|
611
617
|
sseTransport.send = async (message) => {
|
|
@@ -1590,6 +1596,12 @@ var HttpTransport = class {
|
|
|
1590
1596
|
});
|
|
1591
1597
|
applyAuthMiddleware(this.state);
|
|
1592
1598
|
applyScopeEnforcementMiddleware(this.state);
|
|
1599
|
+
if (this.state.config.metricsExport === "prometheus") {
|
|
1600
|
+
this.state.app.get("/metrics", (_req, res) => {
|
|
1601
|
+
res.set("Content-Type", "text/plain");
|
|
1602
|
+
res.send(metrics.toPrometheus());
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
1593
1605
|
const oauthEnabled = this.state.config.oauth?.enabled ?? false;
|
|
1594
1606
|
let lastNoAuthWarning = 0;
|
|
1595
1607
|
this.state.app.use((req, _res, next) => {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { DEFAULT_CONFIG, DbMcpServer, createServer } from './chunk-
|
|
2
|
-
export { DatabaseAdapter } from './chunk-
|
|
3
|
-
export { NAME, VERSION } from './chunk-
|
|
4
|
-
export { ALL_TOOL_GROUPS, AuthenticationError, AuthorizationError, ConnectionError, DbMcpError, META_GROUPS, QueryError, TOOL_GROUPS, ValidationError, filterTools, getFilterSummary, getToolFilterFromEnv, isToolEnabled, parseToolFilter } from './chunk-
|
|
1
|
+
export { DEFAULT_CONFIG, DbMcpServer, createServer } from './chunk-NIC5Z2CA.js';
|
|
2
|
+
export { DatabaseAdapter } from './chunk-EQF3WZHX.js';
|
|
3
|
+
export { NAME, VERSION } from './chunk-R5M4WKDM.js';
|
|
4
|
+
export { ALL_TOOL_GROUPS, AuthenticationError, AuthorizationError, ConnectionError, DbMcpError, META_GROUPS, QueryError, TOOL_GROUPS, ValidationError, filterTools, getFilterSummary, getToolFilterFromEnv, isToolEnabled, parseToolFilter } from './chunk-Y57WFKAP.js';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp — Observability Metrics
|
|
3
|
+
*
|
|
4
|
+
* In-memory streaming metrics aggregator for tools and resources.
|
|
5
|
+
* Uses a zero-dependency circular buffer to estimate latency percentiles
|
|
6
|
+
* (p50, p95, p99) without memory bloat.
|
|
7
|
+
*/
|
|
8
|
+
import type { SystemDb } from "./system-db.js";
|
|
9
|
+
export interface MetricSummary {
|
|
10
|
+
calls: number;
|
|
11
|
+
errors: number;
|
|
12
|
+
tokens: number;
|
|
13
|
+
p50: number;
|
|
14
|
+
p95: number;
|
|
15
|
+
p99: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ResourceMetricSummary {
|
|
18
|
+
reads: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class MetricsRegistry {
|
|
21
|
+
private tools;
|
|
22
|
+
private resources;
|
|
23
|
+
private systemDb;
|
|
24
|
+
private flushTimer;
|
|
25
|
+
setSystemDb(systemDb: SystemDb): void;
|
|
26
|
+
private loadHistorical;
|
|
27
|
+
private startFlushTimer;
|
|
28
|
+
private flushToDb;
|
|
29
|
+
close(): void;
|
|
30
|
+
recordToolCall(toolName: string, durationMs: number, success: boolean, tokens?: number): void;
|
|
31
|
+
recordResourceRead(uri: string): void;
|
|
32
|
+
getSummary(): Record<string, unknown>;
|
|
33
|
+
toPrometheus(): string;
|
|
34
|
+
}
|
|
35
|
+
export declare const metrics: MetricsRegistry;
|
|
36
|
+
//# sourceMappingURL=metrics.d.ts.map
|