db-mcp 3.0.2 → 5.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 (183) hide show
  1. package/README.md +112 -75
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/adapters/database-adapter.d.ts +11 -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/query-executor.d.ts.map +1 -1
  9. package/dist/adapters/sqlite/read-write-lock.d.ts +49 -0
  10. package/dist/adapters/sqlite/read-write-lock.d.ts.map +1 -0
  11. package/dist/adapters/sqlite/resources.d.ts +1 -1
  12. package/dist/adapters/sqlite/resources.d.ts.map +1 -1
  13. package/dist/adapters/sqlite/schemas/admin.d.ts +33 -19
  14. package/dist/adapters/sqlite/schemas/admin.d.ts.map +1 -1
  15. package/dist/adapters/sqlite/schemas/core.d.ts +96 -0
  16. package/dist/adapters/sqlite/schemas/core.d.ts.map +1 -1
  17. package/dist/adapters/sqlite/schemas/fts.d.ts +4 -0
  18. package/dist/adapters/sqlite/schemas/fts.d.ts.map +1 -1
  19. package/dist/adapters/sqlite/schemas/introspection.d.ts +25 -15
  20. package/dist/adapters/sqlite/schemas/introspection.d.ts.map +1 -1
  21. package/dist/adapters/sqlite/schemas/migration.d.ts +2 -2
  22. package/dist/adapters/sqlite/schemas/migration.d.ts.map +1 -1
  23. package/dist/adapters/sqlite/schemas/spatialite.d.ts +1 -0
  24. package/dist/adapters/sqlite/schemas/spatialite.d.ts.map +1 -1
  25. package/dist/adapters/sqlite/schemas/text.d.ts +36 -0
  26. package/dist/adapters/sqlite/schemas/text.d.ts.map +1 -1
  27. package/dist/adapters/sqlite/sqlite-adapter.d.ts +6 -0
  28. package/dist/adapters/sqlite/sqlite-adapter.d.ts.map +1 -1
  29. package/dist/adapters/sqlite/tools/admin/backup/create.d.ts.map +1 -1
  30. package/dist/adapters/sqlite/tools/admin/backup/dump.d.ts.map +1 -1
  31. package/dist/adapters/sqlite/tools/admin/backup/restore.d.ts.map +1 -1
  32. package/dist/adapters/sqlite/tools/admin/index.d.ts.map +1 -1
  33. package/dist/adapters/sqlite/tools/admin/pragma.d.ts +0 -4
  34. package/dist/adapters/sqlite/tools/admin/pragma.d.ts.map +1 -1
  35. package/dist/adapters/sqlite/tools/admin/verify.d.ts.map +1 -1
  36. package/dist/adapters/sqlite/tools/codemode.d.ts.map +1 -1
  37. package/dist/adapters/sqlite/tools/core/convenience.d.ts.map +1 -1
  38. package/dist/adapters/sqlite/tools/core/index.d.ts.map +1 -1
  39. package/dist/adapters/sqlite/tools/core/queries.d.ts.map +1 -1
  40. package/dist/adapters/sqlite/tools/core/tables.d.ts.map +1 -1
  41. package/dist/adapters/sqlite/tools/core/versioning.d.ts +19 -0
  42. package/dist/adapters/sqlite/tools/core/versioning.d.ts.map +1 -0
  43. package/dist/adapters/sqlite/tools/fts.d.ts.map +1 -1
  44. package/dist/adapters/sqlite/tools/introspection/diagnostics/indexes.d.ts.map +1 -1
  45. package/dist/adapters/sqlite/tools/introspection/graph/tools.d.ts.map +1 -1
  46. package/dist/adapters/sqlite/tools/json-helpers/read.d.ts.map +1 -1
  47. package/dist/adapters/sqlite/tools/json-operations/crud.d.ts.map +1 -1
  48. package/dist/adapters/sqlite/tools/json-operations/query.d.ts.map +1 -1
  49. package/dist/adapters/sqlite/tools/migration/helpers.d.ts.map +1 -1
  50. package/dist/adapters/sqlite/tools/text/helpers.d.ts +9 -0
  51. package/dist/adapters/sqlite/tools/text/helpers.d.ts.map +1 -1
  52. package/dist/adapters/sqlite/tools/text/index.d.ts.map +1 -1
  53. package/dist/adapters/sqlite/tools/text/search.d.ts +4 -0
  54. package/dist/adapters/sqlite/tools/text/search.d.ts.map +1 -1
  55. package/dist/adapters/sqlite/tools/vector/metadata.d.ts.map +1 -1
  56. package/dist/adapters/sqlite/tools/vector/search.d.ts.map +1 -1
  57. package/dist/adapters/sqlite/tools/vector/storage.d.ts.map +1 -1
  58. package/dist/adapters/sqlite/tools/virtual/vtable/analyze-csv.d.ts.map +1 -1
  59. package/dist/adapters/sqlite/tools/virtual/vtable/csv.d.ts.map +1 -1
  60. package/dist/adapters/sqlite/tools/virtual/vtable/info.d.ts.map +1 -1
  61. package/dist/adapters/sqlite/types.d.ts +5 -1
  62. package/dist/adapters/sqlite/types.d.ts.map +1 -1
  63. package/dist/adapters/sqlite-native/index.d.ts +1 -1
  64. package/dist/adapters/sqlite-native/index.d.ts.map +1 -1
  65. package/dist/adapters/sqlite-native/native-sqlite-adapter.d.ts.map +1 -1
  66. package/dist/adapters/sqlite-native/tools/spatialite/tools.d.ts.map +1 -1
  67. package/dist/adapters/sqlite-native/tools/window/helpers.d.ts +52 -0
  68. package/dist/adapters/sqlite-native/tools/window/helpers.d.ts.map +1 -0
  69. package/dist/adapters/sqlite-native/tools/window/index.d.ts +7 -0
  70. package/dist/adapters/sqlite-native/tools/window/index.d.ts.map +1 -0
  71. package/dist/adapters/sqlite-native/tools/window/lag-lead.d.ts +7 -0
  72. package/dist/adapters/sqlite-native/tools/window/lag-lead.d.ts.map +1 -0
  73. package/dist/adapters/sqlite-native/tools/window/moving-average.d.ts +7 -0
  74. package/dist/adapters/sqlite-native/tools/window/moving-average.d.ts.map +1 -0
  75. package/dist/adapters/sqlite-native/tools/window/ntile.d.ts +7 -0
  76. package/dist/adapters/sqlite-native/tools/window/ntile.d.ts.map +1 -0
  77. package/dist/adapters/sqlite-native/tools/window/rank.d.ts +7 -0
  78. package/dist/adapters/sqlite-native/tools/window/rank.d.ts.map +1 -0
  79. package/dist/adapters/sqlite-native/tools/window/row-number.d.ts +7 -0
  80. package/dist/adapters/sqlite-native/tools/window/row-number.d.ts.map +1 -0
  81. package/dist/adapters/sqlite-native/tools/window/running-total.d.ts +7 -0
  82. package/dist/adapters/sqlite-native/tools/window/running-total.d.ts.map +1 -0
  83. package/dist/adapters/sqlite-native/tools/window/schemas.d.ts +159 -0
  84. package/dist/adapters/sqlite-native/tools/window/schemas.d.ts.map +1 -0
  85. package/dist/adapters/sqlite-native/transaction-methods.d.ts.map +1 -1
  86. package/dist/audit/interceptor.d.ts.map +1 -1
  87. package/dist/audit/logger.d.ts +26 -25
  88. package/dist/audit/logger.d.ts.map +1 -1
  89. package/dist/auth/authorization-server-discovery.d.ts.map +1 -1
  90. package/dist/auth/scopes/mapping.d.ts.map +1 -1
  91. package/dist/auth/token-validator.d.ts.map +1 -1
  92. package/dist/{chunk-W5WQVNVX.js → chunk-27C5EE6U.js} +23 -17
  93. package/dist/chunk-2TYICG7B.js +1183 -0
  94. package/dist/{chunk-37G4DLL6.js → chunk-LLIAIJPO.js} +1146 -539
  95. package/dist/{chunk-NV34JSQM.js → chunk-UE7GVOBV.js} +1757 -1331
  96. package/dist/{chunk-L552U3QS.js → chunk-XLIYO3YA.js} +401 -77
  97. package/dist/cli.js +116 -11
  98. package/dist/codemode/api-constants.d.ts.map +1 -1
  99. package/dist/codemode/api.d.ts.map +1 -1
  100. package/dist/codemode/sandbox-factory.d.ts.map +1 -1
  101. package/dist/codemode/sandbox.d.ts +0 -3
  102. package/dist/codemode/sandbox.d.ts.map +1 -1
  103. package/dist/codemode/security.d.ts.map +1 -1
  104. package/dist/codemode/types.d.ts +2 -0
  105. package/dist/codemode/types.d.ts.map +1 -1
  106. package/dist/constants/server-instructions.d.ts +1 -1
  107. package/dist/constants/server-instructions.d.ts.map +1 -1
  108. package/dist/filtering/tool-constants.d.ts +11 -11
  109. package/dist/filtering/tool-constants.d.ts.map +1 -1
  110. package/dist/{http-HWTUVFIA.js → http-ZDMK46QU.js} +195 -32
  111. package/dist/index.js +4 -4
  112. package/dist/observability/metrics.d.ts +36 -0
  113. package/dist/observability/metrics.d.ts.map +1 -0
  114. package/dist/observability/system-db.d.ts +13 -0
  115. package/dist/observability/system-db.d.ts.map +1 -0
  116. package/dist/server/mcp-server.d.ts +3 -0
  117. package/dist/server/mcp-server.d.ts.map +1 -1
  118. package/dist/server/registration/admin-tools.d.ts +6 -0
  119. package/dist/server/registration/admin-tools.d.ts.map +1 -0
  120. package/dist/server/registration/audit-tools/backup.d.ts +8 -0
  121. package/dist/server/registration/audit-tools/backup.d.ts.map +1 -0
  122. package/dist/server/registration/audit-tools/helpers.d.ts +11 -0
  123. package/dist/server/registration/audit-tools/helpers.d.ts.map +1 -0
  124. package/dist/server/registration/audit-tools/index.d.ts +4 -0
  125. package/dist/server/registration/audit-tools/index.d.ts.map +1 -0
  126. package/dist/server/registration/audit-tools/resource.d.ts +8 -0
  127. package/dist/server/registration/audit-tools/resource.d.ts.map +1 -0
  128. package/dist/server/registration/audit-tools/search.d.ts +7 -0
  129. package/dist/server/registration/audit-tools/search.d.ts.map +1 -0
  130. package/dist/server/registration/help-resources.d.ts.map +1 -1
  131. package/dist/server/registration/index.d.ts +3 -1
  132. package/dist/server/registration/index.d.ts.map +1 -1
  133. package/dist/server/registration/observability-resources.d.ts +11 -0
  134. package/dist/server/registration/observability-resources.d.ts.map +1 -0
  135. package/dist/server/subscription-manager.d.ts +35 -0
  136. package/dist/server/subscription-manager.d.ts.map +1 -0
  137. package/dist/{sqlite-TB56Z7G3.js → sqlite-XWZPEZJO.js} +195 -19
  138. package/dist/{sqlite-native-IF75BB3O.js → sqlite-native-5GQ3WKCZ.js} +311 -147
  139. package/dist/transports/http/middleware.d.ts.map +1 -1
  140. package/dist/transports/http/oauth.d.ts.map +1 -1
  141. package/dist/transports/http/sessions/legacy-sse.d.ts.map +1 -1
  142. package/dist/transports/http/sessions/stateful.d.ts +5 -1
  143. package/dist/transports/http/sessions/stateful.d.ts.map +1 -1
  144. package/dist/transports/http/transport.d.ts +2 -0
  145. package/dist/transports/http/transport.d.ts.map +1 -1
  146. package/dist/transports/http/types.d.ts +11 -0
  147. package/dist/transports/http/types.d.ts.map +1 -1
  148. package/dist/types/auth.d.ts +4 -0
  149. package/dist/types/auth.d.ts.map +1 -1
  150. package/dist/types/server.d.ts +5 -0
  151. package/dist/types/server.d.ts.map +1 -1
  152. package/dist/utils/annotations.d.ts +8 -0
  153. package/dist/utils/annotations.d.ts.map +1 -1
  154. package/dist/utils/errors/categories.d.ts +16 -11
  155. package/dist/utils/errors/categories.d.ts.map +1 -1
  156. package/dist/utils/errors/classes.d.ts +37 -0
  157. package/dist/utils/errors/classes.d.ts.map +1 -1
  158. package/dist/utils/errors/format.d.ts +2 -2
  159. package/dist/utils/errors/format.d.ts.map +1 -1
  160. package/dist/utils/errors/index.d.ts +1 -1
  161. package/dist/utils/errors/index.d.ts.map +1 -1
  162. package/dist/utils/errors/suggestions.d.ts +1 -0
  163. package/dist/utils/errors/suggestions.d.ts.map +1 -1
  164. package/dist/utils/index.d.ts +3 -0
  165. package/dist/utils/index.d.ts.map +1 -1
  166. package/dist/utils/logger/types.d.ts +1 -1
  167. package/dist/utils/logger/types.d.ts.map +1 -1
  168. package/dist/utils/security-utils.d.ts +29 -0
  169. package/dist/utils/security-utils.d.ts.map +1 -0
  170. package/dist/utils/stream-utils.d.ts +14 -0
  171. package/dist/utils/stream-utils.d.ts.map +1 -0
  172. package/dist/utils/tokens.d.ts +15 -0
  173. package/dist/utils/tokens.d.ts.map +1 -0
  174. package/dist/utils/where-clause.d.ts +0 -13
  175. package/dist/utils/where-clause.d.ts.map +1 -1
  176. package/package.json +43 -44
  177. package/dist/adapters/sqlite-native/tools/window.d.ts +0 -7
  178. package/dist/adapters/sqlite-native/tools/window.d.ts.map +0 -1
  179. package/dist/chunk-E5IESRTK.js +0 -489
  180. package/dist/server/registration/audit-tools.d.ts +0 -13
  181. package/dist/server/registration/audit-tools.d.ts.map +0 -1
  182. package/dist/utils/insights-manager.d.ts +0 -39
  183. package/dist/utils/insights-manager.d.ts.map +0 -1
@@ -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, ErrorCategory, metrics, runWithAuthContext, ERROR_CODES, logger, ConfigurationError, SUPPORTED_SCOPES, scopesGrantToolAccess, InsufficientScopeError, hasAdminScope, hasReadScope, isOAuthError, BASE_SCOPES, AuthServerDiscoveryError, JwksFetchError, parseScopes, TokenExpiredError, InvalidSignatureError, InvalidTokenError, TokenMissingError } from './chunk-XLIYO3YA.js';
2
2
  import express from 'express';
3
3
  import { localhostHostValidation } from '@modelcontextprotocol/sdk/server/middleware/hostHeaderValidation.js';
4
4
  import cors from 'cors';
@@ -148,6 +148,9 @@ var JSONRPC_INTERNAL_ERROR = -32603;
148
148
  var HTTP_REQUEST_TIMEOUT_MS = 12e4;
149
149
  var HTTP_KEEP_ALIVE_TIMEOUT_MS = 65e3;
150
150
  var HTTP_HEADERS_TIMEOUT_MS = 66e3;
151
+ var SESSION_TIMEOUT_MS = 30 * 60 * 1e3;
152
+ var SESSION_SWEEP_INTERVAL_MS = 1 * 60 * 1e3;
153
+ var SESSION_ABSOLUTE_TTL_MS = 24 * 60 * 60 * 1e3;
151
154
  function setupSecurityHeaders(state) {
152
155
  if (!state.app) return;
153
156
  state.app.disable("x-powered-by");
@@ -251,7 +254,12 @@ function setupRateLimiting(state) {
251
254
  skip: (req) => req.path === "/health",
252
255
  handler: (_req, res, _next, options) => {
253
256
  res.status(options.statusCode).json({
254
- error: "Too Many Requests"
257
+ success: false,
258
+ error: "Too Many Requests",
259
+ code: "RATE_LIMIT_ERROR",
260
+ category: "rate_limit",
261
+ suggestion: "Wait before retrying. Reduce request frequency or configure MCP_RATE_LIMIT_MAX.",
262
+ recoverable: true
255
263
  });
256
264
  }
257
265
  });
@@ -273,7 +281,7 @@ async function setupStatelessEndpoints(state) {
273
281
  throw new DbMcpError(
274
282
  "Transport or server not initialized",
275
283
  ERROR_CODES.SERVER.TRANSPORT_ERROR.full,
276
- "internal" /* INTERNAL */
284
+ ErrorCategory.INTERNAL
277
285
  );
278
286
  }
279
287
  state.statelessTransport = new StreamableHTTPServerTransport({
@@ -354,15 +362,49 @@ function isValidSessionId(id) {
354
362
  if (id.length !== 36) return false;
355
363
  return /^[0-9a-fA-F-]{36}$/.test(id);
356
364
  }
365
+ function touchSession(state, sessionId) {
366
+ state.sessionLastActivity.set(sessionId, Date.now());
367
+ }
357
368
  function setupStatefulEndpoints(state) {
358
369
  if (!state.app || !state.mcpServer) {
359
370
  throw new DbMcpError(
360
371
  "Transport or server not initialized",
361
372
  ERROR_CODES.SERVER.TRANSPORT_ERROR.full,
362
- "internal" /* INTERNAL */
373
+ ErrorCategory.INTERNAL
363
374
  );
364
375
  }
365
376
  const server = state.mcpServer;
377
+ const sessionSweepTimer = setInterval(() => {
378
+ const now = Date.now();
379
+ for (const [sid, lastActivity] of state.sessionLastActivity) {
380
+ const idleMs = now - lastActivity;
381
+ if (idleMs <= SESSION_TIMEOUT_MS) continue;
382
+ if ((state.sessionLocks.get(sid) ?? 0) > 0) continue;
383
+ if (state.transports.has(sid)) {
384
+ logger5.info("Expiring idle HTTP session", {
385
+ code: "HTTP_SESSION_EXPIRE",
386
+ sessionId: sid,
387
+ idleMinutes: Math.round(idleMs / 6e4)
388
+ });
389
+ const t = state.transports.get(sid);
390
+ if (t) {
391
+ void t.close();
392
+ }
393
+ }
394
+ if (state.sseTransports.has(sid)) {
395
+ logger5.info("Expiring idle SSE session", {
396
+ code: "SSE_SESSION_EXPIRE",
397
+ sessionId: sid,
398
+ idleMinutes: Math.round(idleMs / 6e4)
399
+ });
400
+ const t = state.sseTransports.get(sid);
401
+ if (t) {
402
+ void t.close();
403
+ }
404
+ }
405
+ }
406
+ }, SESSION_SWEEP_INTERVAL_MS);
407
+ sessionSweepTimer.unref();
366
408
  state.app.post("/mcp", (req, res) => {
367
409
  const sessionId = req.headers["mcp-session-id"];
368
410
  if (sessionId !== void 0 && !isValidSessionId(sessionId)) {
@@ -412,10 +454,23 @@ function setupStatefulEndpoints(state) {
412
454
  });
413
455
  return;
414
456
  }
457
+ const createdAt = state.sessionCreatedAt.get(sessionId) ?? Date.now();
458
+ if (Date.now() - createdAt > SESSION_ABSOLUTE_TTL_MS) {
459
+ res.status(401).json({
460
+ jsonrpc: "2.0",
461
+ error: {
462
+ code: JSONRPC_SERVER_ERROR,
463
+ message: "Unauthorized: Session absolute TTL expired"
464
+ },
465
+ id: null
466
+ });
467
+ return;
468
+ }
469
+ touchSession(state, sessionId);
415
470
  httpTransport = existingTransport;
416
471
  } else if (sessionId === void 0 && isNewSessionRequest(req.body)) {
417
472
  const maxSessions = state.config.maxSessions ?? 1e3;
418
- if (state.transports.size >= maxSessions) {
473
+ if (state.transports.size + state.sseTransports.size >= maxSessions) {
419
474
  res.status(429).json({
420
475
  jsonrpc: "2.0",
421
476
  error: {
@@ -434,6 +489,8 @@ function setupStatefulEndpoints(state) {
434
489
  sessionId: sid
435
490
  });
436
491
  state.transports.set(sid, newTransport);
492
+ touchSession(state, sid);
493
+ state.sessionCreatedAt.set(sid, Date.now());
437
494
  state.sessionOwners.set(sid, req.auth?.sub);
438
495
  }
439
496
  });
@@ -446,6 +503,12 @@ function setupStatefulEndpoints(state) {
446
503
  });
447
504
  state.transports.delete(sid);
448
505
  state.sessionOwners.delete(sid);
506
+ state.sessionLastActivity.delete(sid);
507
+ state.sessionCreatedAt.delete(sid);
508
+ state.sessionLocks.delete(sid);
509
+ if ("subscriptionManager" in server) {
510
+ server.subscriptionManager.unsubscribeSession(sid);
511
+ }
449
512
  }
450
513
  };
451
514
  await connectionMutex.acquire().then(async (release) => {
@@ -489,11 +552,28 @@ function setupStatefulEndpoints(state) {
489
552
  release();
490
553
  }
491
554
  });
492
- await newTransport.handleRequest(
493
- asIncoming(req),
494
- asServerResponse(res),
495
- req.body
496
- );
555
+ const activeSid = newTransport.sessionId;
556
+ try {
557
+ if (activeSid) {
558
+ const count = state.sessionLocks.get(activeSid) ?? 0;
559
+ state.sessionLocks.set(activeSid, count + 1);
560
+ }
561
+ await newTransport.handleRequest(
562
+ asIncoming(req),
563
+ asServerResponse(res),
564
+ req.body
565
+ );
566
+ } finally {
567
+ if (activeSid) {
568
+ const count = state.sessionLocks.get(activeSid) ?? 0;
569
+ if (count > 1) {
570
+ state.sessionLocks.set(activeSid, count - 1);
571
+ } else {
572
+ state.sessionLocks.delete(activeSid);
573
+ }
574
+ touchSession(state, activeSid);
575
+ }
576
+ }
497
577
  return;
498
578
  } else {
499
579
  res.status(400).json({
@@ -507,11 +587,28 @@ function setupStatefulEndpoints(state) {
507
587
  return;
508
588
  }
509
589
  if (httpTransport !== void 0) {
510
- await httpTransport.handleRequest(
511
- asIncoming(req),
512
- asServerResponse(res),
513
- req.body
514
- );
590
+ const activeSid = sessionId;
591
+ try {
592
+ if (activeSid) {
593
+ const count = state.sessionLocks.get(activeSid) ?? 0;
594
+ state.sessionLocks.set(activeSid, count + 1);
595
+ }
596
+ await httpTransport.handleRequest(
597
+ asIncoming(req),
598
+ asServerResponse(res),
599
+ req.body
600
+ );
601
+ } finally {
602
+ if (activeSid) {
603
+ const count = state.sessionLocks.get(activeSid) ?? 0;
604
+ if (count > 1) {
605
+ state.sessionLocks.set(activeSid, count - 1);
606
+ } else {
607
+ state.sessionLocks.delete(activeSid);
608
+ }
609
+ touchSession(state, activeSid);
610
+ }
611
+ }
515
612
  }
516
613
  } catch (error) {
517
614
  logger5.error("Error handling MCP request", {
@@ -546,6 +643,12 @@ function setupStatefulEndpoints(state) {
546
643
  res.status(403).send("Forbidden: session belongs to a different client");
547
644
  return;
548
645
  }
646
+ const createdAt = state.sessionCreatedAt.get(sessionId) ?? Date.now();
647
+ if (Date.now() - createdAt > SESSION_ABSOLUTE_TTL_MS) {
648
+ res.status(401).send("Unauthorized: Session absolute TTL expired");
649
+ return;
650
+ }
651
+ touchSession(state, sessionId);
549
652
  const lastEventId = req.headers["last-event-id"];
550
653
  if (lastEventId !== void 0) {
551
654
  logger5.debug("Client reconnecting with Last-Event-ID", {
@@ -555,7 +658,24 @@ function setupStatefulEndpoints(state) {
555
658
  });
556
659
  }
557
660
  if (httpTransport !== void 0) {
558
- void httpTransport.handleRequest(asIncoming(req), asServerResponse(res));
661
+ void (async () => {
662
+ try {
663
+ const count = state.sessionLocks.get(sessionId) ?? 0;
664
+ state.sessionLocks.set(sessionId, count + 1);
665
+ await httpTransport.handleRequest(
666
+ asIncoming(req),
667
+ asServerResponse(res)
668
+ );
669
+ } finally {
670
+ const count = state.sessionLocks.get(sessionId) ?? 0;
671
+ if (count > 1) {
672
+ state.sessionLocks.set(sessionId, count - 1);
673
+ } else {
674
+ state.sessionLocks.delete(sessionId);
675
+ }
676
+ touchSession(state, sessionId);
677
+ }
678
+ })();
559
679
  }
560
680
  });
561
681
  state.app.delete("/mcp", (req, res) => {
@@ -578,9 +698,27 @@ function setupStatefulEndpoints(state) {
578
698
  sessionId
579
699
  });
580
700
  if (httpTransport !== void 0) {
581
- void httpTransport.handleRequest(asIncoming(req), asServerResponse(res));
701
+ void (async () => {
702
+ try {
703
+ const count = state.sessionLocks.get(sessionId) ?? 0;
704
+ state.sessionLocks.set(sessionId, count + 1);
705
+ await httpTransport.handleRequest(
706
+ asIncoming(req),
707
+ asServerResponse(res)
708
+ );
709
+ } finally {
710
+ const count = state.sessionLocks.get(sessionId) ?? 0;
711
+ if (count > 1) {
712
+ state.sessionLocks.set(sessionId, count - 1);
713
+ } else {
714
+ state.sessionLocks.delete(sessionId);
715
+ }
716
+ touchSession(state, sessionId);
717
+ }
718
+ })();
582
719
  }
583
720
  });
721
+ return sessionSweepTimer;
584
722
  }
585
723
  var logger6 = createModuleLogger("HTTP");
586
724
  var connectionMutex2 = new Mutex();
@@ -598,6 +736,8 @@ function setupLegacySSEEndpoints(state) {
598
736
  void (async () => {
599
737
  try {
600
738
  state.sseTransports.set(sseTransport.sessionId, sseTransport);
739
+ touchSession(state, sseTransport.sessionId);
740
+ state.sessionCreatedAt.set(sseTransport.sessionId, Date.now());
601
741
  state.sessionOwners.set(sseTransport.sessionId, req.auth?.sub);
602
742
  sseTransport.onclose = () => {
603
743
  logger6.info("Legacy SSE transport closed", {
@@ -606,6 +746,11 @@ function setupLegacySSEEndpoints(state) {
606
746
  });
607
747
  state.sseTransports.delete(sseTransport.sessionId);
608
748
  state.sessionOwners.delete(sseTransport.sessionId);
749
+ state.sessionLastActivity.delete(sseTransport.sessionId);
750
+ state.sessionCreatedAt.delete(sseTransport.sessionId);
751
+ if ("subscriptionManager" in server) {
752
+ server.subscriptionManager.unsubscribeSession(sseTransport.sessionId);
753
+ }
609
754
  };
610
755
  const origSend = sseTransport.send.bind(sseTransport);
611
756
  sseTransport.send = async (message) => {
@@ -666,6 +811,8 @@ function setupLegacySSEEndpoints(state) {
666
811
  req.on("close", () => {
667
812
  state.sseTransports.delete(sseTransport.sessionId);
668
813
  state.sessionOwners.delete(sseTransport.sessionId);
814
+ state.sessionLastActivity.delete(sseTransport.sessionId);
815
+ state.sessionCreatedAt.delete(sseTransport.sessionId);
669
816
  });
670
817
  });
671
818
  state.app.post("/messages", (req, res) => {
@@ -704,6 +851,7 @@ function setupLegacySSEEndpoints(state) {
704
851
  });
705
852
  return;
706
853
  }
854
+ touchSession(state, sessionId);
707
855
  void sseTransport.handlePostMessage(
708
856
  asIncoming(req),
709
857
  asServerResponse(res),
@@ -852,7 +1000,7 @@ var AuthorizationServerDiscovery = class {
852
1000
  const url = new URL(this.authServerUrl);
853
1001
  const isLocalDev = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
854
1002
  if (!isLocalDev) {
855
- throw new Error(
1003
+ throw new ConfigurationError(
856
1004
  `Security: Authorization server URL must use HTTPS in production. Got: ${this.authServerUrl}. Set NODE_ENV=development to allow HTTP for local testing.`
857
1005
  );
858
1006
  }
@@ -897,7 +1045,7 @@ var AuthorizationServerDiscovery = class {
897
1045
  throw new DbMcpError(
898
1046
  `HTTP ${String(response.status)}: ${response.statusText}`,
899
1047
  ERROR_CODES.AUTH.DISCOVERY_FAILED.full,
900
- "connection" /* CONNECTION */
1048
+ ErrorCategory.CONNECTION
901
1049
  );
902
1050
  }
903
1051
  const metadata = await response.json();
@@ -931,14 +1079,14 @@ var AuthorizationServerDiscovery = class {
931
1079
  throw new DbMcpError(
932
1080
  "Missing required field: issuer",
933
1081
  "AUTH_DISCOVERY_INVALID",
934
- "validation" /* VALIDATION */
1082
+ ErrorCategory.VALIDATION
935
1083
  );
936
1084
  }
937
1085
  if (!metadata.token_endpoint) {
938
1086
  throw new DbMcpError(
939
1087
  "Missing required field: token_endpoint",
940
1088
  "AUTH_DISCOVERY_INVALID",
941
- "validation" /* VALIDATION */
1089
+ ErrorCategory.VALIDATION
942
1090
  );
943
1091
  }
944
1092
  try {
@@ -948,7 +1096,7 @@ var AuthorizationServerDiscovery = class {
948
1096
  throw new DbMcpError(
949
1097
  "Invalid URL format in metadata fields",
950
1098
  "AUTH_DISCOVERY_INVALID",
951
- "validation" /* VALIDATION */
1099
+ ErrorCategory.VALIDATION
952
1100
  );
953
1101
  }
954
1102
  const expectedIssuer = this.authServerUrl;
@@ -956,7 +1104,7 @@ var AuthorizationServerDiscovery = class {
956
1104
  throw new DbMcpError(
957
1105
  `Issuer validation failed. Per RFC 8414 \xA73.3, the issuer MUST be identical to the authorization server URL.`,
958
1106
  "AUTH_ISSUER_MISMATCH",
959
- "validation" /* VALIDATION */
1107
+ ErrorCategory.VALIDATION
960
1108
  );
961
1109
  }
962
1110
  }
@@ -968,7 +1116,7 @@ var AuthorizationServerDiscovery = class {
968
1116
  throw new DbMcpError(
969
1117
  "Authorization server metadata not yet discovered. Call discover() first.",
970
1118
  "AUTH_DISCOVERY_REQUIRED",
971
- "internal" /* INTERNAL */
1119
+ ErrorCategory.INTERNAL
972
1120
  );
973
1121
  }
974
1122
  return this.cachedMetadata;
@@ -984,7 +1132,7 @@ var AuthorizationServerDiscovery = class {
984
1132
  throw new DbMcpError(
985
1133
  "Authorization server does not provide jwks_uri",
986
1134
  "AUTH_DISCOVERY_INVALID",
987
- "validation" /* VALIDATION */
1135
+ ErrorCategory.VALIDATION
988
1136
  );
989
1137
  }
990
1138
  return metadata.jwks_uri;
@@ -1076,7 +1224,7 @@ var TokenValidator = class _TokenValidator {
1076
1224
  const url = new URL(config.jwksUri);
1077
1225
  const isLocalDev = url.hostname === "localhost" || url.hostname === "127.0.0.1";
1078
1226
  if (!isLocalDev) {
1079
- throw new Error(
1227
+ throw new ConfigurationError(
1080
1228
  `Security: JWKS URI must use HTTPS in production. Got: ${config.jwksUri}. Set ALLOW_HTTP_JWKS=true to allow HTTP for local testing.`
1081
1229
  );
1082
1230
  }
@@ -1286,7 +1434,7 @@ function applyAuthMiddleware(state) {
1286
1434
  const corsOrigins = state.config.corsOrigins ?? [];
1287
1435
  const isPubliclyExposed = state.config.oauth.enabled || state.config.noAuthEnforcement;
1288
1436
  if (corsOrigins.includes("*") && isPubliclyExposed) {
1289
- throw new Error(
1437
+ throw new ConfigurationError(
1290
1438
  "Security: CORS wildcard origin ('*') is forbidden when authentication is enabled or enforcement is explicitly disabled. Configure explicit origins via --cors-origins for production deployments."
1291
1439
  );
1292
1440
  }
@@ -1435,7 +1583,7 @@ function applyScopeEnforcementMiddleware(state) {
1435
1583
  async function setupOAuth(state, resourceUri) {
1436
1584
  logger10.info("Setting up OAuth 2.1...", { code: "HTTP_OAUTH_SETUP" });
1437
1585
  if (state.config.oauth.enabled && !state.config.oauth.audience) {
1438
- throw new Error(
1586
+ throw new ConfigurationError(
1439
1587
  "Security: OAuth audience must be explicitly configured when OAuth is enabled."
1440
1588
  );
1441
1589
  }
@@ -1489,6 +1637,8 @@ var logger11 = createModuleLogger("HTTP");
1489
1637
  var HttpTransport = class {
1490
1638
  /** Internal state shared with session/middleware/oauth modules */
1491
1639
  state;
1640
+ /** Sweep timer for session timeout cleanup */
1641
+ sweepTimer = null;
1492
1642
  constructor(config) {
1493
1643
  this.state = {
1494
1644
  config: {
@@ -1502,6 +1652,9 @@ var HttpTransport = class {
1502
1652
  transports: /* @__PURE__ */ new Map(),
1503
1653
  sseTransports: /* @__PURE__ */ new Map(),
1504
1654
  sessionOwners: /* @__PURE__ */ new Map(),
1655
+ sessionLastActivity: /* @__PURE__ */ new Map(),
1656
+ sessionCreatedAt: /* @__PURE__ */ new Map(),
1657
+ sessionLocks: /* @__PURE__ */ new Map(),
1505
1658
  statelessTransport: null,
1506
1659
  resourceServer: null,
1507
1660
  authServerDiscovery: null,
@@ -1530,7 +1683,7 @@ var HttpTransport = class {
1530
1683
  throw new DbMcpError(
1531
1684
  "trustedProxyIps cannot be an empty array if specified",
1532
1685
  "CONFIG_ERROR",
1533
- "config" /* CONFIGURATION */
1686
+ ErrorCategory.CONFIGURATION
1534
1687
  );
1535
1688
  }
1536
1689
  this.state.app.set("trust proxy", this.state.config.trustedProxyIps);
@@ -1549,7 +1702,7 @@ var HttpTransport = class {
1549
1702
  throw new DbMcpError(
1550
1703
  "HTTP transport is enabled without authentication. You must configure OAuth (--oauth-enabled) or explicitly bypass this check with --no-auth-enforcement.",
1551
1704
  "AUTH_REQUIRED",
1552
- "config" /* CONFIGURATION */
1705
+ ErrorCategory.CONFIGURATION
1553
1706
  );
1554
1707
  }
1555
1708
  if (this.state.config.oauth.enabled) {
@@ -1590,6 +1743,12 @@ var HttpTransport = class {
1590
1743
  });
1591
1744
  applyAuthMiddleware(this.state);
1592
1745
  applyScopeEnforcementMiddleware(this.state);
1746
+ if (this.state.config.metricsExport === "prometheus") {
1747
+ this.state.app.get("/metrics", (_req, res) => {
1748
+ res.set("Content-Type", "text/plain");
1749
+ res.send(metrics.toPrometheus());
1750
+ });
1751
+ }
1593
1752
  const oauthEnabled = this.state.config.oauth?.enabled ?? false;
1594
1753
  let lastNoAuthWarning = 0;
1595
1754
  this.state.app.use((req, _res, next) => {
@@ -1617,7 +1776,7 @@ var HttpTransport = class {
1617
1776
  if (this.state.config.stateless) {
1618
1777
  await setupStatelessEndpoints(this.state);
1619
1778
  } else {
1620
- setupStatefulEndpoints(this.state);
1779
+ this.sweepTimer = setupStatefulEndpoints(this.state);
1621
1780
  }
1622
1781
  if (!this.state.config.stateless) {
1623
1782
  setupLegacySSEEndpoints(this.state);
@@ -1642,7 +1801,7 @@ var HttpTransport = class {
1642
1801
  throw new DbMcpError(
1643
1802
  "Transport not initialized. Call initialize() first.",
1644
1803
  ERROR_CODES.SERVER.START_FAILED.full,
1645
- "internal" /* INTERNAL */
1804
+ ErrorCategory.INTERNAL
1646
1805
  );
1647
1806
  }
1648
1807
  return new Promise((resolve, reject) => {
@@ -1682,6 +1841,10 @@ var HttpTransport = class {
1682
1841
  * Stop the server and close all active sessions
1683
1842
  */
1684
1843
  async stop() {
1844
+ if (this.sweepTimer) {
1845
+ clearInterval(this.sweepTimer);
1846
+ this.sweepTimer = null;
1847
+ }
1685
1848
  for (const [sessionId, transport] of this.state.transports) {
1686
1849
  try {
1687
1850
  logger11.debug("Closing transport", {
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-LLIAIJPO.js';
2
+ export { DatabaseAdapter } from './chunk-27C5EE6U.js';
3
+ export { NAME, VERSION } from './chunk-2TYICG7B.js';
4
+ export { ALL_TOOL_GROUPS, AuthenticationError, AuthorizationError, ConnectionError, DbMcpError, META_GROUPS, QueryError, TOOL_GROUPS, ValidationError, filterTools, getFilterSummary, getToolFilterFromEnv, isToolEnabled, parseToolFilter } from './chunk-XLIYO3YA.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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/observability/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK/C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;CACf;AA+ED,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,UAAU,CAA+C;IAEjE,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAMrC,OAAO,CAAC,cAAc;IAsCtB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,SAAS;IAiCjB,KAAK,IAAI,IAAI;IAQb,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,MAAM,SAAI,GACT,IAAI;IASP,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IASrC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAkBrC,YAAY,IAAI,MAAM;CAwCvB;AAGD,eAAO,MAAM,OAAO,iBAAwB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Database } from "better-sqlite3";
2
+ export interface SystemDbConfig {
3
+ dbPath: string;
4
+ }
5
+ export declare class SystemDb {
6
+ private db;
7
+ private readonly config;
8
+ constructor(config: SystemDbConfig);
9
+ init(): Promise<void>;
10
+ getDb(): Database;
11
+ close(): void;
12
+ }
13
+ //# sourceMappingURL=system-db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-db.d.ts","sourceRoot":"","sources":["../../src/observability/system-db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAM/C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;gBAE5B,MAAM,EAAE,cAAc;IAI5B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmF3B,KAAK,IAAI,QAAQ;IAOjB,KAAK,IAAI,IAAI;CAMd"}
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import type { McpServerConfig, DatabaseConfig } from "../types/index.js";
8
8
  import type { DatabaseAdapter } from "../adapters/database-adapter.js";
9
+ import { SubscriptionManager } from "./subscription-manager.js";
9
10
  /**
10
11
  * Main db-mcp server class
11
12
  *
@@ -18,8 +19,10 @@ export declare class DbMcpServer {
18
19
  private config;
19
20
  private auditLogger;
20
21
  private backupManager;
22
+ private systemDb;
21
23
  private auditInterceptor;
22
24
  private auditInitPromise;
25
+ readonly subscriptionManager: SubscriptionManager;
23
26
  constructor(config: McpServerConfig);
24
27
  /**
25
28
  * Register a database adapter
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/server/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAyEvE;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,gBAAgB,CAA8B;gBAE1C,MAAM,EAAE,eAAe;IAkFnC;;OAEG;IACG,eAAe,CACnB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAqDhB;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI1D;;OAEG;IACH,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAI3C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B;;OAEG;YACW,UAAU;IAiBxB;;OAEG;YACW,SAAS;IAsDvB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC/B;;;OAGG;YACW,eAAe;CAmC9B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CAEjE;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,eAAe,CAKnD,CAAC"}
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/server/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAwCvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AA+ChE;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,gBAAgB,CAA8B;IACtD,SAAgB,mBAAmB,EAAE,mBAAmB,CAAC;gBAE7C,MAAM,EAAE,eAAe;IAyLnC;;OAEG;IACG,eAAe,CACnB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAiEhB;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI1D;;OAEG;IACH,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAI3C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B;;OAEG;YACW,UAAU;IAiBxB;;OAEG;YACW,SAAS;IAyDvB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC/B;;;OAGG;YACW,eAAe;CA8C9B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CAEjE;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,eAAe,CAKnD,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /**
3
+ * Register administrative tools
4
+ */
5
+ export declare function registerAdminTools(server: McpServer): void;
6
+ //# sourceMappingURL=admin-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-tools.d.ts","sourceRoot":"","sources":["../../../src/server/registration/admin-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkL1D"}
@@ -0,0 +1,8 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DatabaseAdapter } from "../../../adapters/database-adapter.js";
3
+ import type { BackupManager } from "../../../audit/backup-manager.js";
4
+ /**
5
+ * Register audit backup tools for snapshot management.
6
+ */
7
+ export declare function registerAuditBackupTools(server: McpServer, backupManager: BackupManager | null, adaptersMap: Map<string, DatabaseAdapter>): void;
8
+ //# sourceMappingURL=backup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../../../src/server/registration/audit-tools/backup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAqBtE;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,aAAa,EAAE,aAAa,GAAG,IAAI,EACnC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GACxC,IAAI,CAkoBN"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Force redaction of SQL string literals to prevent secret exposure
3
+ * in audit logs and backups, regardless of operator configuration.
4
+ */
5
+ export declare function redactSqlLiterals(text: string): string;
6
+ /**
7
+ * Validate DDL to prevent execution of unauthorized or destructive statements
8
+ * during restore operations from tampered backups.
9
+ */
10
+ export declare function validateDdl(sql: string): void;
11
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/server/registration/audit-tools/helpers.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAqB7C"}
@@ -0,0 +1,4 @@
1
+ export { registerAuditResource } from "./resource.js";
2
+ export { registerAuditBackupTools } from "./backup.js";
3
+ export { registerAuditSearchTool } from "./search.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/registration/audit-tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { BackupManager } from "../../../audit/backup-manager.js";
3
+ import type { AuditLogger } from "../../../audit/logger.js";
4
+ /**
5
+ * Register the sqlite://audit resource for agent access to audit log.
6
+ */
7
+ export declare function registerAuditResource(server: McpServer, auditLogger: AuditLogger | null, backupManager: BackupManager | null): void;
8
+ //# sourceMappingURL=resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../../../src/server/registration/audit-tools/resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAI5D;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,WAAW,GAAG,IAAI,EAC/B,aAAa,EAAE,aAAa,GAAG,IAAI,GAClC,IAAI,CAuCN"}
@@ -0,0 +1,7 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { AuditLogger } from "../../../audit/logger.js";
3
+ /**
4
+ * Register the sqlite_audit_search tool.
5
+ */
6
+ export declare function registerAuditSearchTool(server: McpServer, auditLogger: AuditLogger | null): void;
7
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/server/registration/audit-tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAe5D;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,WAAW,GAAG,IAAI,GAC9B,IAAI,CA6EN"}
@@ -1 +1 @@
1
- {"version":3,"file":"help-resources.d.ts","sourceRoot":"","sources":["../../../src/server/registration/help-resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,sBAAsB,CAAC;AAKxE;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,gBAAgB,GAC3B,IAAI,CAiFN"}
1
+ {"version":3,"file":"help-resources.d.ts","sourceRoot":"","sources":["../../../src/server/registration/help-resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,sBAAsB,CAAC;AAMxE;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,gBAAgB,GAC3B,IAAI,CAuFN"}