db-mcp 3.0.2 → 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.
Files changed (92) hide show
  1. package/README.md +89 -57
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/adapters/database-adapter.d.ts +2 -1
  4. package/dist/adapters/database-adapter.d.ts.map +1 -1
  5. package/dist/adapters/registration/resources.d.ts.map +1 -1
  6. package/dist/adapters/registration/tools.d.ts.map +1 -1
  7. package/dist/adapters/sqlite/prompts/analysis.d.ts.map +1 -1
  8. package/dist/adapters/sqlite/resources.d.ts +1 -1
  9. package/dist/adapters/sqlite/resources.d.ts.map +1 -1
  10. package/dist/adapters/sqlite/schemas/admin.d.ts +29 -15
  11. package/dist/adapters/sqlite/schemas/admin.d.ts.map +1 -1
  12. package/dist/adapters/sqlite/schemas/core.d.ts +2 -0
  13. package/dist/adapters/sqlite/schemas/core.d.ts.map +1 -1
  14. package/dist/adapters/sqlite/schemas/fts.d.ts +4 -0
  15. package/dist/adapters/sqlite/schemas/fts.d.ts.map +1 -1
  16. package/dist/adapters/sqlite/schemas/introspection.d.ts +20 -11
  17. package/dist/adapters/sqlite/schemas/introspection.d.ts.map +1 -1
  18. package/dist/adapters/sqlite/schemas/spatialite.d.ts +1 -0
  19. package/dist/adapters/sqlite/schemas/spatialite.d.ts.map +1 -1
  20. package/dist/adapters/sqlite/schemas/text.d.ts +36 -0
  21. package/dist/adapters/sqlite/schemas/text.d.ts.map +1 -1
  22. package/dist/adapters/sqlite/sqlite-adapter.d.ts.map +1 -1
  23. package/dist/adapters/sqlite/tools/admin/index.d.ts.map +1 -1
  24. package/dist/adapters/sqlite/tools/admin/pragma.d.ts +0 -4
  25. package/dist/adapters/sqlite/tools/admin/pragma.d.ts.map +1 -1
  26. package/dist/adapters/sqlite/tools/core/queries.d.ts.map +1 -1
  27. package/dist/adapters/sqlite/tools/core/tables.d.ts.map +1 -1
  28. package/dist/adapters/sqlite/tools/fts.d.ts.map +1 -1
  29. package/dist/adapters/sqlite/tools/introspection/diagnostics/indexes.d.ts.map +1 -1
  30. package/dist/adapters/sqlite/tools/json-helpers/read.d.ts.map +1 -1
  31. package/dist/adapters/sqlite/tools/json-operations/crud.d.ts.map +1 -1
  32. package/dist/adapters/sqlite/tools/json-operations/query.d.ts.map +1 -1
  33. package/dist/adapters/sqlite/tools/text/helpers.d.ts +9 -0
  34. package/dist/adapters/sqlite/tools/text/helpers.d.ts.map +1 -1
  35. package/dist/adapters/sqlite/tools/text/index.d.ts.map +1 -1
  36. package/dist/adapters/sqlite/tools/text/search.d.ts +4 -0
  37. package/dist/adapters/sqlite/tools/text/search.d.ts.map +1 -1
  38. package/dist/adapters/sqlite/types.d.ts +4 -0
  39. package/dist/adapters/sqlite/types.d.ts.map +1 -1
  40. package/dist/adapters/sqlite-native/native-sqlite-adapter.d.ts.map +1 -1
  41. package/dist/adapters/sqlite-native/tools/spatialite/tools.d.ts.map +1 -1
  42. package/dist/audit/interceptor.d.ts.map +1 -1
  43. package/dist/audit/logger.d.ts +26 -25
  44. package/dist/audit/logger.d.ts.map +1 -1
  45. package/dist/{chunk-W5WQVNVX.js → chunk-EQF3WZHX.js} +10 -17
  46. package/dist/{chunk-37G4DLL6.js → chunk-NIC5Z2CA.js} +732 -138
  47. package/dist/chunk-R5M4WKDM.js +987 -0
  48. package/dist/{chunk-NV34JSQM.js → chunk-TGE7LFAR.js} +708 -996
  49. package/dist/{chunk-L552U3QS.js → chunk-Y57WFKAP.js} +227 -9
  50. package/dist/cli.js +103 -10
  51. package/dist/codemode/sandbox.d.ts.map +1 -1
  52. package/dist/constants/server-instructions.d.ts +1 -1
  53. package/dist/constants/server-instructions.d.ts.map +1 -1
  54. package/dist/filtering/tool-constants.d.ts +9 -9
  55. package/dist/{http-HWTUVFIA.js → http-2WGR3E5K.js} +13 -1
  56. package/dist/index.js +4 -4
  57. package/dist/observability/metrics.d.ts +36 -0
  58. package/dist/observability/metrics.d.ts.map +1 -0
  59. package/dist/observability/system-db.d.ts +13 -0
  60. package/dist/observability/system-db.d.ts.map +1 -0
  61. package/dist/server/mcp-server.d.ts +3 -0
  62. package/dist/server/mcp-server.d.ts.map +1 -1
  63. package/dist/server/registration/admin-tools.d.ts +6 -0
  64. package/dist/server/registration/admin-tools.d.ts.map +1 -0
  65. package/dist/server/registration/audit-tools.d.ts +4 -0
  66. package/dist/server/registration/audit-tools.d.ts.map +1 -1
  67. package/dist/server/registration/help-resources.d.ts.map +1 -1
  68. package/dist/server/registration/index.d.ts +3 -1
  69. package/dist/server/registration/index.d.ts.map +1 -1
  70. package/dist/server/registration/observability-resources.d.ts +11 -0
  71. package/dist/server/registration/observability-resources.d.ts.map +1 -0
  72. package/dist/server/subscription-manager.d.ts +35 -0
  73. package/dist/server/subscription-manager.d.ts.map +1 -0
  74. package/dist/{sqlite-TB56Z7G3.js → sqlite-D4WCNPU4.js} +8 -5
  75. package/dist/{sqlite-native-IF75BB3O.js → sqlite-native-DLVS2T52.js} +159 -34
  76. package/dist/transports/http/sessions/legacy-sse.d.ts.map +1 -1
  77. package/dist/transports/http/sessions/stateful.d.ts.map +1 -1
  78. package/dist/transports/http/transport.d.ts.map +1 -1
  79. package/dist/transports/http/types.d.ts +2 -0
  80. package/dist/transports/http/types.d.ts.map +1 -1
  81. package/dist/types/server.d.ts +2 -0
  82. package/dist/types/server.d.ts.map +1 -1
  83. package/dist/utils/index.d.ts +1 -0
  84. package/dist/utils/index.d.ts.map +1 -1
  85. package/dist/utils/logger/types.d.ts +1 -1
  86. package/dist/utils/logger/types.d.ts.map +1 -1
  87. package/dist/utils/tokens.d.ts +15 -0
  88. package/dist/utils/tokens.d.ts.map +1 -0
  89. package/package.json +9 -7
  90. package/dist/chunk-E5IESRTK.js +0 -489
  91. package/dist/utils/insights-manager.d.ts +0 -39
  92. 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 (14 WASM)
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 (16 WASM)
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 (15: backup.ts, verify.ts, pragma.ts, reindex.ts, wal.ts)
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 (5: pragma.ts, backup/create.ts, reindex.ts, wal.ts)
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 (60 WASM / 65 Native)
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 (46 WASM / 51 Native)
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 (166 Native / 139 WASM — see TOOL COUNT TAXONOMY above)
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-37G4DLL6.js';
3
- import { VERSION } from './chunk-E5IESRTK.js';
4
- import { logger } from './chunk-L552U3QS.js';
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 config;
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 --auth-token my-secret --sqlite ./data.db
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 (options?.backend === "better-sqlite3") {
347
- const { NativeSqliteAdapter } = await import('./sqlite-native-IF75BB3O.js');
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-TB56Z7G3.js');
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;IAwSzB,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"}
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 | Action |\n| --------------- | -------------------------- |\n| Health check | `server_health` tool |\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.";
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,yxBAmBwC,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAo2BnD,CAAC"}
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: 14 WASM / 19 Native (text/regex+formatting+search+validate+sentiment.ts, fts.ts)
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: 31 WASM / 32 Native (admin/backup+verify+pragma+reindex+wal.ts, virtual/views+vtable+extensions+analysis.ts; dump.ts is NATIVE ONLY)
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
- * 5 tools (server/registration/audit-tools.ts)
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 (Code Mode sqlite.help() base total)
25
- * Audit tools: 5 Native / 5 WASM (MCP-only)
26
- * Inventory: 171 Native / 144 WASM (Group + Audit)
27
- * Built-in: 4 / 4 (server_info, health, adapters, + Code Mode injected)
28
- * MCP total: 175 Native / 148 WASM (tools/list response)
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-L552U3QS.js';
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-37G4DLL6.js';
2
- export { DatabaseAdapter } from './chunk-W5WQVNVX.js';
3
- export { NAME, VERSION } from './chunk-E5IESRTK.js';
4
- export { ALL_TOOL_GROUPS, AuthenticationError, AuthorizationError, ConnectionError, DbMcpError, META_GROUPS, QueryError, TOOL_GROUPS, ValidationError, filterTools, getFilterSummary, getToolFilterFromEnv, isToolEnabled, parseToolFilter } from './chunk-L552U3QS.js';
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