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
@@ -36,7 +36,11 @@ var TOOL_GROUPS = {
36
36
  "list_constraints",
37
37
  "date_add",
38
38
  "date_diff",
39
- "alter_table"
39
+ "alter_table",
40
+ "enable_versioning",
41
+ "disable_versioning",
42
+ "check_version",
43
+ "conditional_update"
40
44
  ],
41
45
  json: [
42
46
  // CRUD + Query + Collection (8: crud.ts, query.ts, write.ts)
@@ -71,7 +75,7 @@ var TOOL_GROUPS = {
71
75
  "json_diff"
72
76
  ],
73
77
  text: [
74
- // Text Tools (14 WASM)
78
+ // Text Tools (15 WASM)
75
79
  "regex_extract",
76
80
  "regex_match",
77
81
  "text_split",
@@ -85,6 +89,7 @@ var TOOL_GROUPS = {
85
89
  "text_normalize",
86
90
  "text_validate",
87
91
  "advanced_search",
92
+ "hybrid_search",
88
93
  "text_sentiment",
89
94
  // FTS5 Tools (5 Native-only)
90
95
  "fts_create",
@@ -94,7 +99,7 @@ var TOOL_GROUPS = {
94
99
  "fts_headline"
95
100
  ],
96
101
  stats: [
97
- // Stats Tools (16 WASM)
102
+ // Stats Tools (13 WASM)
98
103
  "stats_basic",
99
104
  "stats_count",
100
105
  "stats_group_by",
@@ -136,7 +141,7 @@ var TOOL_GROUPS = {
136
141
  "vector_distance"
137
142
  ],
138
143
  admin: [
139
- // Admin Tools (15: backup.ts, verify.ts, pragma.ts, reindex.ts, wal.ts)
144
+ // Admin Tools (12: backup.ts, verify.ts, pragma.ts)
140
145
  "backup",
141
146
  "analyze",
142
147
  "integrity_check",
@@ -149,7 +154,6 @@ var TOOL_GROUPS = {
149
154
  "pragma_optimize",
150
155
  "pragma_settings",
151
156
  "pragma_table_info",
152
- "append_insight",
153
157
  // Virtual Table Tools (13: views.ts, vtable.ts, extensions.ts, analysis.ts)
154
158
  "generate_series",
155
159
  "create_view",
@@ -164,7 +168,7 @@ var TOOL_GROUPS = {
164
168
  "analyze_csv_schema",
165
169
  "create_rtree_table",
166
170
  "create_series_table",
167
- // Database management (5: pragma.ts, backup/create.ts, reindex.ts, wal.ts)
171
+ // Database management (6: pragma.ts, backup/create.ts, dump.ts, reindex.ts, wal.ts)
168
172
  "attach_database",
169
173
  "detach_database",
170
174
  "vacuum_into",
@@ -223,19 +227,19 @@ var TOOL_GROUPS = {
223
227
  codemode: ["execute_code"]
224
228
  };
225
229
  var META_GROUPS = {
226
- // General development - Core + JSON + Text (60 WASM / 65 Native)
230
+ // General development - Core + JSON + Text (65 WASM / 70 Native)
227
231
  starter: ["core", "json", "text", "codemode"],
228
- // Data analysis - Core + JSON + Stats (63 WASM / 69 Native)
232
+ // Data analysis - Core + JSON + Stats (67 WASM / 73 Native)
229
233
  analytics: ["core", "json", "stats", "codemode"],
230
- // Search workloads - Core + Text + Vector (46 WASM / 51 Native)
234
+ // Search workloads - Core + Text + Vector (51 WASM / 56 Native)
231
235
  search: ["core", "text", "vector", "codemode"],
232
- // Geospatial workloads - Core + Geo + Vector (36 WASM / 43 Native)
236
+ // Geospatial workloads - Core + Geo + Vector (40 WASM / 47 Native)
233
237
  spatial: ["core", "geo", "vector", "codemode"],
234
- // Schema development - Core + Introspection + Migration (37 tools)
238
+ // Schema development - Core + Introspection + Migration (41 tools)
235
239
  "dev-schema": ["core", "introspection", "migration", "codemode"],
236
- // Bare minimum - Core (21 tools)
240
+ // Bare minimum - Core (25 tools)
237
241
  minimal: ["core", "codemode"],
238
- // All group tools enabled (166 Native / 139 WASM — see TOOL COUNT TAXONOMY above)
242
+ // All group tools enabled (171 Native / 144 WASM — see TOOL COUNT TAXONOMY above)
239
243
  full: [
240
244
  "core",
241
245
  "json",
@@ -742,227 +746,270 @@ if (envLevel && envLevel in LEVEL_PRIORITY_CHECK) {
742
746
  logger.setLevel(envLevel);
743
747
  }
744
748
 
749
+ // src/utils/errors/categories.ts
750
+ var ErrorCategory = {
751
+ /** Input validation failures (invalid names, paths, types) */
752
+ VALIDATION: "validation",
753
+ /** Database connection issues */
754
+ CONNECTION: "connection",
755
+ /** SQL execution errors */
756
+ QUERY: "query",
757
+ /** Authorization/permission failures */
758
+ PERMISSION: "permission",
759
+ /** Configuration/setup issues */
760
+ CONFIGURATION: "config",
761
+ /** Missing resources (tables, columns, views) */
762
+ RESOURCE: "resource",
763
+ /** Authentication failures (invalid credentials, expired tokens) */
764
+ AUTHENTICATION: "authentication",
765
+ /** Authorization failures (insufficient scope/permissions) */
766
+ AUTHORIZATION: "authorization",
767
+ /** Unexpected internal errors */
768
+ INTERNAL: "internal",
769
+ /** Execution timeout errors */
770
+ TIMEOUT: "timeout",
771
+ /** Rate limit enforcement errors */
772
+ RATE_LIMIT: "rate_limit"
773
+ };
774
+
745
775
  // src/utils/errors/suggestions.ts
746
776
  var ERROR_SUGGESTIONS = [
747
777
  // Validation errors
748
778
  {
749
779
  pattern: /invalid table name/i,
750
780
  suggestion: "Table names must start with a letter or underscore, followed by letters, numbers, or underscores only.",
751
- category: "validation" /* VALIDATION */
781
+ category: ErrorCategory.VALIDATION
752
782
  },
753
783
  {
754
784
  pattern: /invalid column name/i,
755
785
  suggestion: "Column names must start with a letter or underscore, followed by letters, numbers, or underscores only.",
756
- category: "validation" /* VALIDATION */
786
+ category: ErrorCategory.VALIDATION
757
787
  },
758
788
  {
759
789
  pattern: /invalid (view|index) name/i,
760
790
  suggestion: "Names must start with a letter or underscore, followed by alphanumeric characters only.",
761
- category: "validation" /* VALIDATION */
791
+ category: ErrorCategory.VALIDATION
762
792
  },
763
793
  {
764
794
  pattern: /json path must start with \$/i,
765
795
  suggestion: "JSON paths use $ as the root. Example: $.name, $.items[0], $.nested.property",
766
- category: "validation" /* VALIDATION */
796
+ category: ErrorCategory.VALIDATION
767
797
  },
768
798
  {
769
799
  pattern: /vector dimensions must match/i,
770
800
  suggestion: "All vectors in comparison must have the same number of dimensions.",
771
- category: "validation" /* VALIDATION */
801
+ category: ErrorCategory.VALIDATION
772
802
  },
773
803
  {
774
804
  pattern: /insufficient data/i,
775
805
  suggestion: "Not enough data points for the requested analysis. Add more data or reduce the degree.",
776
- category: "validation" /* VALIDATION */
806
+ category: ErrorCategory.VALIDATION
777
807
  },
778
808
  // Resource errors — specific codes for table/column not found
779
809
  {
780
810
  pattern: /no such table[:\s]*(['"]?)([\w.]+)\1/i,
781
811
  suggestion: "Table not found. Run sqlite_list_tables to see available tables.",
782
- category: "resource" /* RESOURCE */,
812
+ category: ErrorCategory.RESOURCE,
783
813
  code: "TABLE_NOT_FOUND"
784
814
  },
785
815
  {
786
816
  pattern: /no such column[:\s]*(['"]?)([\w.]+)\1/i,
787
817
  suggestion: "Column not found. Use sqlite_describe_table to see available columns.",
788
- category: "resource" /* RESOURCE */,
818
+ category: ErrorCategory.RESOURCE,
789
819
  code: "COLUMN_NOT_FOUND"
790
820
  },
791
821
  {
792
- pattern: /has no column named/i,
822
+ pattern: /has no column named\s+(['"]?)([\w.]+)\1/i,
793
823
  suggestion: "Column not found in target table. Use sqlite_describe_table to verify column names before INSERT or UPDATE.",
794
- category: "resource" /* RESOURCE */,
824
+ category: ErrorCategory.RESOURCE,
795
825
  code: "COLUMN_NOT_FOUND"
796
826
  },
797
827
  {
798
828
  pattern: /no such view[:\s]*(['"]?)([\w.]+)\1/i,
799
829
  suggestion: "View not found. Run sqlite_list_views to see available views.",
800
- category: "resource" /* RESOURCE */,
830
+ category: ErrorCategory.RESOURCE,
801
831
  code: "VIEW_NOT_FOUND"
802
832
  },
803
833
  {
804
834
  pattern: /filename.*does not exist/i,
805
835
  suggestion: "File not found. Verify the absolute path exists and is readable.",
806
- category: "resource" /* RESOURCE */,
836
+ category: ErrorCategory.RESOURCE,
807
837
  code: "FILE_NOT_FOUND"
808
838
  },
809
839
  {
810
840
  pattern: /table .* already exists/i,
811
841
  suggestion: "Table already exists. Use CREATE TABLE IF NOT EXISTS or drop the existing table first.",
812
- category: "resource" /* RESOURCE */,
842
+ category: ErrorCategory.RESOURCE,
813
843
  code: "TABLE_ALREADY_EXISTS"
814
844
  },
815
845
  {
816
846
  pattern: /index .* already exists/i,
817
847
  suggestion: "Index already exists. Use CREATE INDEX IF NOT EXISTS or drop the existing index first.",
818
- category: "resource" /* RESOURCE */,
848
+ category: ErrorCategory.RESOURCE,
819
849
  code: "INDEX_ALREADY_EXISTS"
820
850
  },
821
851
  // JSON-specific errors — often caused by wrong column name
822
852
  {
823
853
  pattern: /malformed JSON/i,
824
854
  suggestion: "The JSON data is malformed. This commonly occurs when the column name is incorrect \u2014 SQLite treats the unresolved identifier as a literal string. Verify the column exists with sqlite_describe_table.",
825
- category: "query" /* QUERY */,
855
+ category: ErrorCategory.QUERY,
826
856
  code: "MALFORMED_JSON"
827
857
  },
828
858
  // Query errors
829
859
  {
830
860
  pattern: /syntax error/i,
831
861
  suggestion: "Check SQL syntax. Common issues: missing quotes, commas, parentheses, or reserved word conflicts.",
832
- category: "query" /* QUERY */
862
+ category: ErrorCategory.QUERY
833
863
  },
834
864
  {
835
865
  pattern: /UNIQUE constraint failed/i,
836
866
  suggestion: "A row with this value already exists. Use UPDATE to modify existing data or check for duplicates.",
837
- category: "query" /* QUERY */,
867
+ category: ErrorCategory.QUERY,
838
868
  code: "CONSTRAINT_VIOLATION"
839
869
  },
840
870
  {
841
871
  pattern: /FOREIGN KEY constraint failed/i,
842
872
  suggestion: "The referenced row does not exist. Ensure the parent record exists before inserting.",
843
- category: "query" /* QUERY */,
873
+ category: ErrorCategory.QUERY,
844
874
  code: "CONSTRAINT_VIOLATION"
845
875
  },
846
876
  {
847
877
  pattern: /NOT NULL constraint failed/i,
848
878
  suggestion: "A required column is missing a value. Provide a value or set a default.",
849
- category: "query" /* QUERY */,
879
+ category: ErrorCategory.QUERY,
850
880
  code: "CONSTRAINT_VIOLATION"
851
881
  },
852
882
  {
853
883
  pattern: /CHECK constraint failed/i,
854
884
  suggestion: "The value does not meet the column's check constraint requirements.",
855
- category: "query" /* QUERY */,
885
+ category: ErrorCategory.QUERY,
856
886
  code: "CONSTRAINT_VIOLATION"
857
887
  },
858
888
  {
859
889
  pattern: /incomplete input/i,
860
890
  suggestion: "SQL statement is incomplete. Check for missing clauses, closing parentheses, or semicolons.",
861
- category: "query" /* QUERY */
891
+ category: ErrorCategory.QUERY
862
892
  },
863
893
  {
864
894
  pattern: /more than one statement/i,
865
895
  suggestion: "Only one SQL statement per call is allowed. Split multiple statements into separate calls or use sqlite_execute_code for multi-step operations.",
866
- category: "query" /* QUERY */
896
+ category: ErrorCategory.QUERY
867
897
  },
868
898
  {
869
899
  pattern: /too few parameter/i,
870
900
  suggestion: "Not enough parameter values provided for the prepared statement placeholders (?). Ensure params array matches the number of ? placeholders in the query.",
871
- category: "query" /* QUERY */
901
+ category: ErrorCategory.QUERY
872
902
  },
873
903
  // Connection errors
874
904
  {
875
905
  pattern: /not connected/i,
876
906
  suggestion: "Database connection not established. Ensure the database is configured and connected.",
877
- category: "connection" /* CONNECTION */
907
+ category: ErrorCategory.CONNECTION
878
908
  },
879
909
  {
880
910
  pattern: /cannot start a transaction within a transaction/i,
881
911
  suggestion: "A transaction is already active. Commit or rollback the current transaction first, or use sqlite_transaction_execute for atomic multi-statement operations.",
882
- category: "query" /* QUERY */,
912
+ category: ErrorCategory.QUERY,
883
913
  code: "TRANSACTION_CONFLICT"
884
914
  },
885
915
  {
886
916
  pattern: /no transaction is active/i,
887
917
  suggestion: "No transaction is active. Start a transaction using sqlite_transaction_begin first.",
888
- category: "query" /* QUERY */,
918
+ category: ErrorCategory.QUERY,
889
919
  code: "TRANSACTION_NOT_ACTIVE"
890
920
  },
891
921
  {
892
922
  pattern: /no such savepoint/i,
893
923
  suggestion: "The specified savepoint does not exist. Verify the savepoint name and ensure it hasn't already been released or rolled back.",
894
- category: "query" /* QUERY */,
924
+ category: ErrorCategory.QUERY,
895
925
  code: "SAVEPOINT_NOT_FOUND"
896
926
  },
897
927
  {
898
928
  pattern: /database is locked/i,
899
929
  suggestion: "Database is being used by another process. Wait and retry, or check for long-running transactions.",
900
- category: "connection" /* CONNECTION */
930
+ category: ErrorCategory.CONNECTION
901
931
  },
902
932
  // Permission errors
903
933
  {
904
934
  pattern: /readonly database/i,
905
935
  suggestion: "Database is in read-only mode. Check file permissions or connection settings.",
906
- category: "permission" /* PERMISSION */
936
+ category: ErrorCategory.PERMISSION
907
937
  },
908
938
  {
909
939
  pattern: /attempt to write a readonly/i,
910
940
  suggestion: "Write operations are not allowed. Check database configuration.",
911
- category: "permission" /* PERMISSION */
941
+ category: ErrorCategory.PERMISSION
912
942
  },
913
943
  // Codemode errors
914
944
  {
915
945
  pattern: /code validation failed/i,
916
946
  suggestion: "Check for blocked patterns: require(), process., eval(), Function(), import(). Use sqlite.* API instead.",
917
- category: "validation" /* VALIDATION */
947
+ category: ErrorCategory.VALIDATION
918
948
  },
919
949
  {
920
950
  pattern: /rate limit exceeded/i,
921
951
  suggestion: "Wait before retrying. Combine multiple operations into fewer execute_code calls.",
922
- category: "permission" /* PERMISSION */
952
+ category: ErrorCategory.RATE_LIMIT
923
953
  },
924
954
  {
925
955
  pattern: /execution timed out/i,
926
956
  suggestion: "Reduce code complexity or increase timeout (max 30s). Break into smaller operations.",
927
- category: "query" /* QUERY */
957
+ category: ErrorCategory.TIMEOUT
928
958
  },
929
959
  {
930
960
  pattern: /sandbox.*not initialized/i,
931
961
  suggestion: "Internal sandbox error. Retry the operation.",
932
- category: "internal" /* INTERNAL */
962
+ category: ErrorCategory.INTERNAL
933
963
  },
934
964
  // Extension errors
935
965
  {
936
966
  pattern: /extension.*not (available|installed|loaded|found)/i,
937
967
  suggestion: "Extension is not available. Check CLI flags, environment variables, or platform compatibility.",
938
- category: "config" /* CONFIGURATION */,
968
+ category: ErrorCategory.CONFIGURATION,
939
969
  code: "EXTENSION_MISSING"
940
970
  },
941
971
  // Custom JS errors mapped from tools
942
972
  {
943
973
  pattern: /invalid identifier/i,
944
974
  suggestion: "Identifiers must start with a letter or underscore and contain only alphanumeric characters or underscores. Ensure the name follows SQLite identifier rules.",
945
- category: "validation" /* VALIDATION */,
975
+ category: ErrorCategory.VALIDATION,
946
976
  code: "INVALID_IDENTIFIER"
947
977
  },
948
978
  {
949
979
  pattern: /(expected property name|unexpected token|in JSON at position|Expected double-quoted property name)/i,
950
980
  suggestion: "The JSON data provided is malformed. Ensure the input string is valid JSON.",
951
- category: "validation" /* VALIDATION */,
981
+ category: ErrorCategory.VALIDATION,
952
982
  code: "MALFORMED_JSON"
953
983
  }
954
984
  ];
985
+ var suggestionCache = /* @__PURE__ */ new Map();
986
+ var MAX_CACHE_SIZE = 1e3;
955
987
  function findSuggestion(message) {
988
+ const cached = suggestionCache.get(message);
989
+ if (cached) {
990
+ suggestionCache.delete(message);
991
+ suggestionCache.set(message, cached);
992
+ return cached;
993
+ }
994
+ let result = null;
956
995
  for (const entry of ERROR_SUGGESTIONS) {
957
- if (entry.pattern.test(message)) {
958
- return {
996
+ const match = entry.pattern.exec(message);
997
+ if (match) {
998
+ result = {
959
999
  suggestion: entry.suggestion,
960
1000
  category: entry.category,
961
- code: entry.code
1001
+ code: entry.code,
1002
+ match
962
1003
  };
1004
+ break;
963
1005
  }
964
1006
  }
965
- return null;
1007
+ if (suggestionCache.size >= MAX_CACHE_SIZE) {
1008
+ const firstKey = suggestionCache.keys().next().value;
1009
+ if (firstKey) suggestionCache.delete(firstKey);
1010
+ }
1011
+ suggestionCache.set(message, result);
1012
+ return result;
966
1013
  }
967
1014
 
968
1015
  // src/utils/errors/base.ts
@@ -1014,7 +1061,7 @@ var DbMcpError = class extends Error {
1014
1061
  // src/utils/errors/classes.ts
1015
1062
  var ValidationError = class extends DbMcpError {
1016
1063
  constructor(message, code = "VALIDATION_ERROR", options) {
1017
- super(message, code, "validation" /* VALIDATION */, {
1064
+ super(message, code, ErrorCategory.VALIDATION, {
1018
1065
  ...options,
1019
1066
  recoverable: false
1020
1067
  });
@@ -1022,7 +1069,7 @@ var ValidationError = class extends DbMcpError {
1022
1069
  };
1023
1070
  var ConnectionError = class extends DbMcpError {
1024
1071
  constructor(message, code = "CONNECTION_ERROR", options) {
1025
- super(message, code, "connection" /* CONNECTION */, {
1072
+ super(message, code, ErrorCategory.CONNECTION, {
1026
1073
  ...options,
1027
1074
  recoverable: true
1028
1075
  // Connection errors are often transient
@@ -1031,7 +1078,7 @@ var ConnectionError = class extends DbMcpError {
1031
1078
  };
1032
1079
  var QueryError = class extends DbMcpError {
1033
1080
  constructor(message, code = "QUERY_ERROR", options) {
1034
- super(message, code, "query" /* QUERY */, {
1081
+ super(message, code, ErrorCategory.QUERY, {
1035
1082
  ...options,
1036
1083
  details: {
1037
1084
  ...options?.details,
@@ -1043,7 +1090,7 @@ var QueryError = class extends DbMcpError {
1043
1090
  };
1044
1091
  var ResourceNotFoundError = class extends DbMcpError {
1045
1092
  constructor(message, code = "RESOURCE_NOT_FOUND", options) {
1046
- super(message, code, "resource" /* RESOURCE */, {
1093
+ super(message, code, ErrorCategory.RESOURCE, {
1047
1094
  ...options,
1048
1095
  details: {
1049
1096
  ...options?.details,
@@ -1056,7 +1103,15 @@ var ResourceNotFoundError = class extends DbMcpError {
1056
1103
  };
1057
1104
  var ConfigurationError = class extends DbMcpError {
1058
1105
  constructor(message, code = "CONFIG_ERROR", options) {
1059
- super(message, code, "config" /* CONFIGURATION */, {
1106
+ super(message, code, ErrorCategory.CONFIGURATION, {
1107
+ ...options,
1108
+ recoverable: false
1109
+ });
1110
+ }
1111
+ };
1112
+ var InternalError = class extends DbMcpError {
1113
+ constructor(message, code = "INTERNAL_ERROR", options) {
1114
+ super(message, code, ErrorCategory.INTERNAL, {
1060
1115
  ...options,
1061
1116
  recoverable: false
1062
1117
  });
@@ -1064,7 +1119,7 @@ var ConfigurationError = class extends DbMcpError {
1064
1119
  };
1065
1120
  var AuthenticationError = class extends DbMcpError {
1066
1121
  constructor(message, code = "AUTHENTICATION_ERROR", options) {
1067
- super(message, code, "authentication" /* AUTHENTICATION */, {
1122
+ super(message, code, ErrorCategory.AUTHENTICATION, {
1068
1123
  ...options,
1069
1124
  recoverable: false
1070
1125
  });
@@ -1072,7 +1127,7 @@ var AuthenticationError = class extends DbMcpError {
1072
1127
  };
1073
1128
  var AuthorizationError = class extends DbMcpError {
1074
1129
  constructor(message, code = "AUTHORIZATION_ERROR", options) {
1075
- super(message, code, "authorization" /* AUTHORIZATION */, {
1130
+ super(message, code, ErrorCategory.AUTHORIZATION, {
1076
1131
  ...options,
1077
1132
  recoverable: false
1078
1133
  });
@@ -1083,7 +1138,7 @@ var ExtensionNotAvailableError = class extends DbMcpError {
1083
1138
  const isWasm = options?.wasmLimitation ?? options?.details?.["wasmLimitation"] ?? false;
1084
1139
  const baseMessage = `Extension '${extensionName}' is not installed or available`;
1085
1140
  const message = isWasm === true ? `${baseMessage} in WASM mode` : baseMessage;
1086
- super(message, "EXTENSION_MISSING", "config" /* CONFIGURATION */, {
1141
+ super(message, "EXTENSION_MISSING", ErrorCategory.CONFIGURATION, {
1087
1142
  suggestion: options?.suggestion ?? `Install or enable the '${extensionName}' extension. Check environment variable or CLI flag configuration.`,
1088
1143
  details: {
1089
1144
  extension: extensionName,
@@ -1095,10 +1150,53 @@ var ExtensionNotAvailableError = class extends DbMcpError {
1095
1150
  });
1096
1151
  }
1097
1152
  };
1153
+ var TimeoutError = class extends DbMcpError {
1154
+ constructor(message, code = "TIMEOUT_ERROR", options) {
1155
+ super(message, code, ErrorCategory.TIMEOUT, {
1156
+ ...options,
1157
+ details: {
1158
+ ...options?.details,
1159
+ timeoutMs: options?.timeoutMs
1160
+ },
1161
+ recoverable: true
1162
+ // Timeouts are retriable with increased timeout or simplified logic
1163
+ });
1164
+ }
1165
+ };
1166
+ var RateLimitError = class extends DbMcpError {
1167
+ constructor(message, code = "RATE_LIMIT_ERROR", options) {
1168
+ super(message, code, ErrorCategory.RATE_LIMIT, {
1169
+ ...options,
1170
+ details: {
1171
+ ...options?.details,
1172
+ retryAfterMs: options?.retryAfterMs,
1173
+ limit: options?.limit
1174
+ },
1175
+ recoverable: true
1176
+ // Rate limits are transient — retry after backoff
1177
+ });
1178
+ }
1179
+ };
1180
+ var ConflictError = class extends DbMcpError {
1181
+ constructor(message, code = "CONFLICT_ERROR", options) {
1182
+ super(message, code, ErrorCategory.QUERY, {
1183
+ ...options,
1184
+ details: {
1185
+ ...options?.details,
1186
+ conflictType: options?.conflictType
1187
+ },
1188
+ recoverable: true
1189
+ // Conflicts are retriable after re-reading current state
1190
+ });
1191
+ }
1192
+ };
1098
1193
 
1099
1194
  // src/utils/errors/format.ts
1100
1195
  function sanitizeErrorMessage(msg) {
1101
1196
  if (!msg || typeof msg !== "string") return msg;
1197
+ if (!msg.includes(":") && !msg.includes("/") && !msg.includes("\\") && !msg.includes("=")) {
1198
+ return msg;
1199
+ }
1102
1200
  return msg.replace(/[a-zA-Z]:\\[^:\n]*\\/g, "<redacted_path>\\").replace(/(file:|sqlite:|\/)[^:\s]+(\/[^:\s]*)/g, "<redacted_path>").replace(
1103
1201
  /([a-zA-Z0-9+.-]+:\/\/[^:]+:)[^@\s]+(@)/g,
1104
1202
  "$1<redacted_credential>$2"
@@ -1111,15 +1209,17 @@ function sanitizeErrorMessage(msg) {
1111
1209
  );
1112
1210
  }
1113
1211
  var CATEGORY_DEFAULT_CODES = {
1114
- ["validation" /* VALIDATION */]: "VALIDATION_ERROR",
1115
- ["connection" /* CONNECTION */]: "CONNECTION_ERROR",
1116
- ["query" /* QUERY */]: "QUERY_ERROR",
1117
- ["permission" /* PERMISSION */]: "PERMISSION_ERROR",
1118
- ["config" /* CONFIGURATION */]: "CONFIG_ERROR",
1119
- ["resource" /* RESOURCE */]: "RESOURCE_ERROR",
1120
- ["authentication" /* AUTHENTICATION */]: "AUTHENTICATION_ERROR",
1121
- ["authorization" /* AUTHORIZATION */]: "AUTHORIZATION_ERROR",
1122
- ["internal" /* INTERNAL */]: "UNKNOWN_ERROR"
1212
+ [ErrorCategory.VALIDATION]: "VALIDATION_ERROR",
1213
+ [ErrorCategory.CONNECTION]: "CONNECTION_ERROR",
1214
+ [ErrorCategory.QUERY]: "QUERY_ERROR",
1215
+ [ErrorCategory.PERMISSION]: "PERMISSION_ERROR",
1216
+ [ErrorCategory.CONFIGURATION]: "CONFIG_ERROR",
1217
+ [ErrorCategory.RESOURCE]: "RESOURCE_ERROR",
1218
+ [ErrorCategory.AUTHENTICATION]: "AUTHENTICATION_ERROR",
1219
+ [ErrorCategory.AUTHORIZATION]: "AUTHORIZATION_ERROR",
1220
+ [ErrorCategory.INTERNAL]: "UNKNOWN_ERROR",
1221
+ [ErrorCategory.TIMEOUT]: "TIMEOUT_ERROR",
1222
+ [ErrorCategory.RATE_LIMIT]: "RATE_LIMIT_ERROR"
1123
1223
  };
1124
1224
  function formatZodError(error) {
1125
1225
  if (!("issues" in error) || !Array.isArray(error["issues"])) {
@@ -1144,7 +1244,7 @@ function formatHandlerError(error, _context) {
1144
1244
  success: false,
1145
1245
  error: sanitizeErrorMessage(zodMessage),
1146
1246
  code: "VALIDATION_ERROR",
1147
- category: "validation" /* VALIDATION */,
1247
+ category: ErrorCategory.VALIDATION,
1148
1248
  suggestion: void 0,
1149
1249
  recoverable: false,
1150
1250
  details: void 0
@@ -1153,7 +1253,7 @@ function formatHandlerError(error, _context) {
1153
1253
  }
1154
1254
  if (error instanceof Error) {
1155
1255
  const match = findSuggestion(error.message);
1156
- const category = match?.category ?? "internal" /* INTERNAL */;
1256
+ const category = match?.category ?? ErrorCategory.INTERNAL;
1157
1257
  return {
1158
1258
  success: false,
1159
1259
  error: sanitizeErrorMessage(error.message),
@@ -1168,12 +1268,230 @@ function formatHandlerError(error, _context) {
1168
1268
  success: false,
1169
1269
  error: sanitizeErrorMessage(String(error)),
1170
1270
  code: "UNKNOWN_ERROR",
1171
- category: "internal" /* INTERNAL */,
1271
+ category: ErrorCategory.INTERNAL,
1172
1272
  suggestion: void 0,
1173
1273
  recoverable: false,
1174
1274
  details: void 0
1175
1275
  };
1176
1276
  }
1277
+
1278
+ // src/observability/metrics.ts
1279
+ var MAX_SAMPLES = 1e3;
1280
+ var ToolMetric = class {
1281
+ calls = 0;
1282
+ errors = 0;
1283
+ tokens = 0;
1284
+ // Circular buffer for latency samples
1285
+ samples = new Array(MAX_SAMPLES).fill(0);
1286
+ sampleIndex = 0;
1287
+ sampleCount = 0;
1288
+ record(durationMs, success, tokens = 0) {
1289
+ this.calls++;
1290
+ if (!success) this.errors++;
1291
+ this.tokens += tokens;
1292
+ this.samples[this.sampleIndex] = durationMs;
1293
+ this.sampleIndex = (this.sampleIndex + 1) % MAX_SAMPLES;
1294
+ if (this.sampleCount < MAX_SAMPLES) {
1295
+ this.sampleCount++;
1296
+ }
1297
+ }
1298
+ getSummary() {
1299
+ if (this.sampleCount === 0) {
1300
+ return {
1301
+ calls: this.calls,
1302
+ errors: this.errors,
1303
+ tokens: this.tokens,
1304
+ p50: 0,
1305
+ p95: 0,
1306
+ p99: 0
1307
+ };
1308
+ }
1309
+ const activeSamples = this.samples.slice(0, this.sampleCount).sort((a, b) => a - b);
1310
+ return {
1311
+ calls: this.calls,
1312
+ errors: this.errors,
1313
+ tokens: this.tokens,
1314
+ p50: this.getPercentile(activeSamples, 0.5),
1315
+ p95: this.getPercentile(activeSamples, 0.95),
1316
+ p99: this.getPercentile(activeSamples, 0.99)
1317
+ };
1318
+ }
1319
+ getPercentile(sorted, p) {
1320
+ if (sorted.length === 0) return 0;
1321
+ const idx = (sorted.length - 1) * p;
1322
+ const base = Math.floor(idx);
1323
+ const rest = idx - base;
1324
+ const v0 = sorted[base] ?? 0;
1325
+ const v1 = sorted[base + 1];
1326
+ if (v1 !== void 0) {
1327
+ return Math.round(v0 + rest * (v1 - v0));
1328
+ } else {
1329
+ return v0;
1330
+ }
1331
+ }
1332
+ };
1333
+ var ResourceMetric = class {
1334
+ reads = 0;
1335
+ record() {
1336
+ this.reads++;
1337
+ }
1338
+ getSummary() {
1339
+ return { reads: this.reads };
1340
+ }
1341
+ };
1342
+ var MetricsRegistry = class {
1343
+ tools = /* @__PURE__ */ new Map();
1344
+ resources = /* @__PURE__ */ new Map();
1345
+ systemDb = null;
1346
+ flushTimer = null;
1347
+ setSystemDb(systemDb) {
1348
+ this.systemDb = systemDb;
1349
+ this.loadHistorical();
1350
+ this.startFlushTimer();
1351
+ }
1352
+ loadHistorical() {
1353
+ if (!this.systemDb) return;
1354
+ try {
1355
+ const db = this.systemDb.getDb();
1356
+ const rows = db.prepare(
1357
+ `
1358
+ SELECT tool, MAX(calls) as max_calls, MAX(errors) as max_errors, MAX(tokens) as max_tokens
1359
+ FROM metrics_snapshots
1360
+ GROUP BY tool
1361
+ `
1362
+ ).all();
1363
+ for (const row of rows) {
1364
+ const metric = new ToolMetric();
1365
+ metric.calls = row.max_calls;
1366
+ metric.errors = row.max_errors;
1367
+ metric.tokens = row.max_tokens;
1368
+ this.tools.set(row.tool, metric);
1369
+ }
1370
+ logger.info(`Loaded historical metrics for ${rows.length} tools`, {
1371
+ module: "METRICS"
1372
+ });
1373
+ } catch (err) {
1374
+ logger.warning("Failed to load historical metrics", {
1375
+ module: "METRICS",
1376
+ error: err instanceof Error ? err : new Error(String(err))
1377
+ });
1378
+ }
1379
+ }
1380
+ startFlushTimer() {
1381
+ if (this.flushTimer) clearInterval(this.flushTimer);
1382
+ this.flushTimer = setInterval(
1383
+ () => {
1384
+ this.flushToDb();
1385
+ },
1386
+ 5 * 60 * 1e3
1387
+ );
1388
+ this.flushTimer.unref();
1389
+ }
1390
+ flushToDb() {
1391
+ if (!this.systemDb) return;
1392
+ try {
1393
+ const db = this.systemDb.getDb();
1394
+ const stmt = db.prepare(`
1395
+ INSERT INTO metrics_snapshots (timestamp, tool, calls, errors, p50, p95, p99, tokens)
1396
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
1397
+ `);
1398
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1399
+ const transaction = db.transaction(() => {
1400
+ for (const [name, metric] of this.tools.entries()) {
1401
+ const summary = metric.getSummary();
1402
+ stmt.run(
1403
+ timestamp,
1404
+ name,
1405
+ summary.calls,
1406
+ summary.errors,
1407
+ summary.p50,
1408
+ summary.p95,
1409
+ summary.p99,
1410
+ summary.tokens
1411
+ );
1412
+ }
1413
+ });
1414
+ transaction();
1415
+ } catch (err) {
1416
+ logger.warning("Failed to flush metrics to db", {
1417
+ module: "METRICS",
1418
+ error: err instanceof Error ? err : new Error(String(err))
1419
+ });
1420
+ }
1421
+ }
1422
+ close() {
1423
+ if (this.flushTimer) {
1424
+ clearInterval(this.flushTimer);
1425
+ this.flushTimer = null;
1426
+ }
1427
+ this.flushToDb();
1428
+ }
1429
+ recordToolCall(toolName, durationMs, success, tokens = 0) {
1430
+ let metric = this.tools.get(toolName);
1431
+ if (!metric) {
1432
+ metric = new ToolMetric();
1433
+ this.tools.set(toolName, metric);
1434
+ }
1435
+ metric.record(durationMs, success, tokens);
1436
+ }
1437
+ recordResourceRead(uri) {
1438
+ let metric = this.resources.get(uri);
1439
+ if (!metric) {
1440
+ metric = new ResourceMetric();
1441
+ this.resources.set(uri, metric);
1442
+ }
1443
+ metric.record();
1444
+ }
1445
+ getSummary() {
1446
+ const toolsSummary = {};
1447
+ for (const [name, metric] of this.tools.entries()) {
1448
+ toolsSummary[name] = metric.getSummary();
1449
+ }
1450
+ const resourcesSummary = {};
1451
+ for (const [uri, metric] of this.resources.entries()) {
1452
+ resourcesSummary[uri] = metric.getSummary();
1453
+ }
1454
+ return {
1455
+ tools: toolsSummary,
1456
+ resources: resourcesSummary,
1457
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1458
+ };
1459
+ }
1460
+ toPrometheus() {
1461
+ const lines = [];
1462
+ lines.push("# HELP db_mcp_tool_calls_total Total tool calls");
1463
+ lines.push("# TYPE db_mcp_tool_calls_total counter");
1464
+ lines.push("# HELP db_mcp_tool_errors_total Total tool errors");
1465
+ lines.push("# TYPE db_mcp_tool_errors_total counter");
1466
+ lines.push("# HELP db_mcp_tool_tokens_total Total tokens estimated");
1467
+ lines.push("# TYPE db_mcp_tool_tokens_total counter");
1468
+ lines.push("# HELP db_mcp_tool_latency_ms_p50 P50 Latency (ms)");
1469
+ lines.push("# TYPE db_mcp_tool_latency_ms_p50 gauge");
1470
+ lines.push("# HELP db_mcp_tool_latency_ms_p95 P95 Latency (ms)");
1471
+ lines.push("# TYPE db_mcp_tool_latency_ms_p95 gauge");
1472
+ lines.push("# HELP db_mcp_tool_latency_ms_p99 P99 Latency (ms)");
1473
+ lines.push("# TYPE db_mcp_tool_latency_ms_p99 gauge");
1474
+ for (const [name, metric] of this.tools.entries()) {
1475
+ const summary = metric.getSummary();
1476
+ const labels = `{tool="${name}"}`;
1477
+ lines.push(`db_mcp_tool_calls_total${labels} ${summary.calls}`);
1478
+ lines.push(`db_mcp_tool_errors_total${labels} ${summary.errors}`);
1479
+ lines.push(`db_mcp_tool_tokens_total${labels} ${summary.tokens}`);
1480
+ lines.push(`db_mcp_tool_latency_ms_p50${labels} ${summary.p50}`);
1481
+ lines.push(`db_mcp_tool_latency_ms_p95${labels} ${summary.p95}`);
1482
+ lines.push(`db_mcp_tool_latency_ms_p99${labels} ${summary.p99}`);
1483
+ }
1484
+ lines.push("# HELP db_mcp_resource_reads_total Total resource reads");
1485
+ lines.push("# TYPE db_mcp_resource_reads_total counter");
1486
+ for (const [uri, metric] of this.resources.entries()) {
1487
+ const summary = metric.getSummary();
1488
+ const labels = `{resource="${uri}"}`;
1489
+ lines.push(`db_mcp_resource_reads_total${labels} ${summary.reads}`);
1490
+ }
1491
+ return lines.join("\n") + "\n";
1492
+ }
1493
+ };
1494
+ var metrics = new MetricsRegistry();
1177
1495
  var authContextStorage = new AsyncLocalStorage();
1178
1496
  function runWithAuthContext(context, fn) {
1179
1497
  return authContextStorage.run(context, fn);
@@ -1247,8 +1565,12 @@ adminToolNames.push(
1247
1565
  "sqlite_audit_cleanup",
1248
1566
  "sqlite_audit_diff_backup",
1249
1567
  "sqlite_audit_restore_backup",
1250
- "drop_table"
1568
+ "drop_table",
1251
1569
  // explicitly admin since it is destructive, despite being in core
1570
+ "enable_versioning",
1571
+ // admin scope needed for DDL
1572
+ "disable_versioning"
1573
+ // admin scope needed for DDL
1252
1574
  );
1253
1575
  withSqlitePrefix(adminToolNames);
1254
1576
  var READ_ONLY_TOOLS = withSqlitePrefix([
@@ -1263,6 +1585,7 @@ var READ_ONLY_TOOLS = withSqlitePrefix([
1263
1585
  "list_constraints",
1264
1586
  "date_add",
1265
1587
  "date_diff",
1588
+ "check_version",
1266
1589
  // JSON read operations
1267
1590
  "json_valid",
1268
1591
  "json_extract",
@@ -1359,6 +1682,7 @@ var WRITE_TOOLS = withSqlitePrefix([
1359
1682
  "create_trigger",
1360
1683
  "drop_trigger",
1361
1684
  "alter_table",
1685
+ "conditional_update",
1362
1686
  // JSON write operations
1363
1687
  "json_insert",
1364
1688
  "json_update",
@@ -1457,7 +1781,7 @@ var OAuthError = class extends DbMcpError {
1457
1781
  /** WWW-Authenticate header value */
1458
1782
  wwwAuthenticate;
1459
1783
  constructor(message, code, httpStatus, details, wwwAuthenticate) {
1460
- super(message, code, "authentication" /* AUTHENTICATION */, { details });
1784
+ super(message, code, ErrorCategory.AUTHENTICATION, { details });
1461
1785
  this.name = "OAuthError";
1462
1786
  this.httpStatus = httpStatus;
1463
1787
  this.wwwAuthenticate = wwwAuthenticate;
@@ -1555,4 +1879,4 @@ function isOAuthError(error) {
1555
1879
  return error instanceof OAuthError;
1556
1880
  }
1557
1881
 
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 };
1882
+ export { ALL_TOOL_GROUPS, AuthServerDiscoveryError, AuthenticationError, AuthorizationError, BASE_SCOPES, ConfigurationError, ConflictError, ConnectionError, DbMcpError, ERROR_CODES, ErrorCategory, ExtensionNotAvailableError, InsufficientScopeError, InternalError, InvalidSignatureError, InvalidTokenError, JwksFetchError, META_GROUPS, QueryError, RateLimitError, ResourceNotFoundError, SCOPES, SUPPORTED_SCOPES, TOOL_GROUPS, TimeoutError, TokenExpiredError, TokenMissingError, ValidationError, createModuleLogger, filterTools, findSuggestion, formatHandlerError, getAuthContext, getFilterSummary, getToolFilterFromEnv, hasAdminScope, hasReadScope, isOAuthError, isToolEnabled, logger, metrics, parseScopes, parseToolFilter, registerToolScopes, runWithAuthContext, sanitizeErrorMessage, scopesGrantToolAccess };