db-mcp 4.0.0 → 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 (138) hide show
  1. package/README.md +30 -25
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/adapters/database-adapter.d.ts +9 -0
  4. package/dist/adapters/database-adapter.d.ts.map +1 -1
  5. package/dist/adapters/sqlite/query-executor.d.ts.map +1 -1
  6. package/dist/adapters/sqlite/read-write-lock.d.ts +49 -0
  7. package/dist/adapters/sqlite/read-write-lock.d.ts.map +1 -0
  8. package/dist/adapters/sqlite/schemas/admin.d.ts +5 -5
  9. package/dist/adapters/sqlite/schemas/admin.d.ts.map +1 -1
  10. package/dist/adapters/sqlite/schemas/core.d.ts +94 -0
  11. package/dist/adapters/sqlite/schemas/core.d.ts.map +1 -1
  12. package/dist/adapters/sqlite/schemas/introspection.d.ts +8 -7
  13. package/dist/adapters/sqlite/schemas/introspection.d.ts.map +1 -1
  14. package/dist/adapters/sqlite/schemas/migration.d.ts +2 -2
  15. package/dist/adapters/sqlite/schemas/migration.d.ts.map +1 -1
  16. package/dist/adapters/sqlite/sqlite-adapter.d.ts +6 -0
  17. package/dist/adapters/sqlite/sqlite-adapter.d.ts.map +1 -1
  18. package/dist/adapters/sqlite/tools/admin/backup/create.d.ts.map +1 -1
  19. package/dist/adapters/sqlite/tools/admin/backup/dump.d.ts.map +1 -1
  20. package/dist/adapters/sqlite/tools/admin/backup/restore.d.ts.map +1 -1
  21. package/dist/adapters/sqlite/tools/admin/pragma.d.ts.map +1 -1
  22. package/dist/adapters/sqlite/tools/admin/verify.d.ts.map +1 -1
  23. package/dist/adapters/sqlite/tools/codemode.d.ts.map +1 -1
  24. package/dist/adapters/sqlite/tools/core/convenience.d.ts.map +1 -1
  25. package/dist/adapters/sqlite/tools/core/index.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/versioning.d.ts +19 -0
  28. package/dist/adapters/sqlite/tools/core/versioning.d.ts.map +1 -0
  29. package/dist/adapters/sqlite/tools/introspection/graph/tools.d.ts.map +1 -1
  30. package/dist/adapters/sqlite/tools/json-operations/crud.d.ts.map +1 -1
  31. package/dist/adapters/sqlite/tools/migration/helpers.d.ts.map +1 -1
  32. package/dist/adapters/sqlite/tools/vector/metadata.d.ts.map +1 -1
  33. package/dist/adapters/sqlite/tools/vector/search.d.ts.map +1 -1
  34. package/dist/adapters/sqlite/tools/vector/storage.d.ts.map +1 -1
  35. package/dist/adapters/sqlite/tools/virtual/vtable/analyze-csv.d.ts.map +1 -1
  36. package/dist/adapters/sqlite/tools/virtual/vtable/csv.d.ts.map +1 -1
  37. package/dist/adapters/sqlite/tools/virtual/vtable/info.d.ts.map +1 -1
  38. package/dist/adapters/sqlite/types.d.ts +1 -1
  39. package/dist/adapters/sqlite/types.d.ts.map +1 -1
  40. package/dist/adapters/sqlite-native/index.d.ts +1 -1
  41. package/dist/adapters/sqlite-native/index.d.ts.map +1 -1
  42. package/dist/adapters/sqlite-native/tools/window/helpers.d.ts +52 -0
  43. package/dist/adapters/sqlite-native/tools/window/helpers.d.ts.map +1 -0
  44. package/dist/adapters/sqlite-native/tools/window/index.d.ts +7 -0
  45. package/dist/adapters/sqlite-native/tools/window/index.d.ts.map +1 -0
  46. package/dist/adapters/sqlite-native/tools/window/lag-lead.d.ts +7 -0
  47. package/dist/adapters/sqlite-native/tools/window/lag-lead.d.ts.map +1 -0
  48. package/dist/adapters/sqlite-native/tools/window/moving-average.d.ts +7 -0
  49. package/dist/adapters/sqlite-native/tools/window/moving-average.d.ts.map +1 -0
  50. package/dist/adapters/sqlite-native/tools/window/ntile.d.ts +7 -0
  51. package/dist/adapters/sqlite-native/tools/window/ntile.d.ts.map +1 -0
  52. package/dist/adapters/sqlite-native/tools/window/rank.d.ts +7 -0
  53. package/dist/adapters/sqlite-native/tools/window/rank.d.ts.map +1 -0
  54. package/dist/adapters/sqlite-native/tools/window/row-number.d.ts +7 -0
  55. package/dist/adapters/sqlite-native/tools/window/row-number.d.ts.map +1 -0
  56. package/dist/adapters/sqlite-native/tools/window/running-total.d.ts +7 -0
  57. package/dist/adapters/sqlite-native/tools/window/running-total.d.ts.map +1 -0
  58. package/dist/adapters/sqlite-native/tools/window/schemas.d.ts +159 -0
  59. package/dist/adapters/sqlite-native/tools/window/schemas.d.ts.map +1 -0
  60. package/dist/adapters/sqlite-native/transaction-methods.d.ts.map +1 -1
  61. package/dist/audit/logger.d.ts.map +1 -1
  62. package/dist/auth/authorization-server-discovery.d.ts.map +1 -1
  63. package/dist/auth/scopes/mapping.d.ts.map +1 -1
  64. package/dist/auth/token-validator.d.ts.map +1 -1
  65. package/dist/{chunk-EQF3WZHX.js → chunk-27C5EE6U.js} +15 -2
  66. package/dist/{chunk-R5M4WKDM.js → chunk-2TYICG7B.js} +381 -185
  67. package/dist/{chunk-NIC5Z2CA.js → chunk-LLIAIJPO.js} +394 -381
  68. package/dist/{chunk-TGE7LFAR.js → chunk-UE7GVOBV.js} +1069 -355
  69. package/dist/{chunk-Y57WFKAP.js → chunk-XLIYO3YA.js} +178 -72
  70. package/dist/cli.js +18 -6
  71. package/dist/codemode/api-constants.d.ts.map +1 -1
  72. package/dist/codemode/api.d.ts.map +1 -1
  73. package/dist/codemode/sandbox-factory.d.ts.map +1 -1
  74. package/dist/codemode/sandbox.d.ts +0 -3
  75. package/dist/codemode/sandbox.d.ts.map +1 -1
  76. package/dist/codemode/security.d.ts.map +1 -1
  77. package/dist/codemode/types.d.ts +2 -0
  78. package/dist/codemode/types.d.ts.map +1 -1
  79. package/dist/constants/server-instructions.d.ts.map +1 -1
  80. package/dist/filtering/tool-constants.d.ts +5 -5
  81. package/dist/filtering/tool-constants.d.ts.map +1 -1
  82. package/dist/{http-2WGR3E5K.js → http-ZDMK46QU.js} +183 -32
  83. package/dist/index.js +4 -4
  84. package/dist/observability/system-db.d.ts.map +1 -1
  85. package/dist/server/mcp-server.d.ts.map +1 -1
  86. package/dist/server/registration/admin-tools.d.ts.map +1 -1
  87. package/dist/server/registration/audit-tools/backup.d.ts +8 -0
  88. package/dist/server/registration/audit-tools/backup.d.ts.map +1 -0
  89. package/dist/server/registration/audit-tools/helpers.d.ts +11 -0
  90. package/dist/server/registration/audit-tools/helpers.d.ts.map +1 -0
  91. package/dist/server/registration/audit-tools/index.d.ts +4 -0
  92. package/dist/server/registration/audit-tools/index.d.ts.map +1 -0
  93. package/dist/server/registration/audit-tools/resource.d.ts +8 -0
  94. package/dist/server/registration/audit-tools/resource.d.ts.map +1 -0
  95. package/dist/server/registration/audit-tools/search.d.ts +7 -0
  96. package/dist/server/registration/audit-tools/search.d.ts.map +1 -0
  97. package/dist/server/registration/index.d.ts +1 -1
  98. package/dist/server/registration/index.d.ts.map +1 -1
  99. package/dist/{sqlite-D4WCNPU4.js → sqlite-XWZPEZJO.js} +192 -19
  100. package/dist/{sqlite-native-DLVS2T52.js → sqlite-native-5GQ3WKCZ.js} +156 -117
  101. package/dist/transports/http/middleware.d.ts.map +1 -1
  102. package/dist/transports/http/oauth.d.ts.map +1 -1
  103. package/dist/transports/http/sessions/legacy-sse.d.ts.map +1 -1
  104. package/dist/transports/http/sessions/stateful.d.ts +5 -1
  105. package/dist/transports/http/sessions/stateful.d.ts.map +1 -1
  106. package/dist/transports/http/transport.d.ts +2 -0
  107. package/dist/transports/http/transport.d.ts.map +1 -1
  108. package/dist/transports/http/types.d.ts +9 -0
  109. package/dist/transports/http/types.d.ts.map +1 -1
  110. package/dist/types/auth.d.ts +4 -0
  111. package/dist/types/auth.d.ts.map +1 -1
  112. package/dist/types/server.d.ts +3 -0
  113. package/dist/types/server.d.ts.map +1 -1
  114. package/dist/utils/annotations.d.ts +8 -0
  115. package/dist/utils/annotations.d.ts.map +1 -1
  116. package/dist/utils/errors/categories.d.ts +16 -11
  117. package/dist/utils/errors/categories.d.ts.map +1 -1
  118. package/dist/utils/errors/classes.d.ts +37 -0
  119. package/dist/utils/errors/classes.d.ts.map +1 -1
  120. package/dist/utils/errors/format.d.ts +2 -2
  121. package/dist/utils/errors/format.d.ts.map +1 -1
  122. package/dist/utils/errors/index.d.ts +1 -1
  123. package/dist/utils/errors/index.d.ts.map +1 -1
  124. package/dist/utils/errors/suggestions.d.ts +1 -0
  125. package/dist/utils/errors/suggestions.d.ts.map +1 -1
  126. package/dist/utils/index.d.ts +2 -0
  127. package/dist/utils/index.d.ts.map +1 -1
  128. package/dist/utils/security-utils.d.ts +29 -0
  129. package/dist/utils/security-utils.d.ts.map +1 -0
  130. package/dist/utils/stream-utils.d.ts +14 -0
  131. package/dist/utils/stream-utils.d.ts.map +1 -0
  132. package/dist/utils/where-clause.d.ts +0 -13
  133. package/dist/utils/where-clause.d.ts.map +1 -1
  134. package/package.json +35 -38
  135. package/dist/adapters/sqlite-native/tools/window.d.ts +0 -7
  136. package/dist/adapters/sqlite-native/tools/window.d.ts.map +0 -1
  137. package/dist/server/registration/audit-tools.d.ts +0 -17
  138. package/dist/server/registration/audit-tools.d.ts.map +0 -1
@@ -1,13 +1,306 @@
1
- import { ValidationError, SCOPES } from './chunk-Y57WFKAP.js';
1
+ import { ConfigurationError, SCOPES, ValidationError, DbMcpError, ErrorCategory } from './chunk-XLIYO3YA.js';
2
2
  import { createRequire } from 'module';
3
- import { dirname, resolve, basename, normalize, relative } from 'path';
4
- import { realpathSync } from 'fs';
3
+ import { resolve, parse, dirname, relative, join, sep, isAbsolute, basename, normalize } from 'path';
4
+ import { realpathSync, lstatSync, existsSync } from 'fs';
5
5
  import { z } from 'zod';
6
6
 
7
7
  var _require = createRequire(import.meta.url);
8
8
  var pkg = _require("../package.json");
9
9
  var VERSION = pkg.version;
10
10
  var NAME = pkg.name;
11
+ var IoPathError = class extends DbMcpError {
12
+ constructor(message) {
13
+ super(message, "SECURITY_ERROR", ErrorCategory.VALIDATION, {
14
+ suggestion: "Check that the target path is within the allowed IO roots.",
15
+ recoverable: false
16
+ });
17
+ this.name = "IoPathError";
18
+ }
19
+ };
20
+ function assertSafeIoPath(targetPath, allowedRoots, validateExtension = true) {
21
+ if (targetPath.includes("\0")) {
22
+ throw new IoPathError("Security: path must not contain null bytes.");
23
+ }
24
+ if (targetPath.startsWith("file:") || targetPath.includes("?")) {
25
+ throw new IoPathError(
26
+ "Security: SQLite URIs and query parameters are not allowed."
27
+ );
28
+ }
29
+ const normalized = targetPath.replace(/\\/g, "/");
30
+ const segments = normalized.split("/");
31
+ if (segments.some((s) => s === "..")) {
32
+ throw new IoPathError("Security: Path traversal (..) detected.");
33
+ }
34
+ const base = segments[segments.length - 1];
35
+ if (!base) {
36
+ throw new IoPathError("Security: Invalid path structure.");
37
+ }
38
+ if (base.startsWith(".")) {
39
+ throw new IoPathError("Security: Cannot access hidden files or dotfiles.");
40
+ }
41
+ if (validateExtension) {
42
+ const validExtensions = [
43
+ ".db",
44
+ ".sqlite",
45
+ ".sqlite3",
46
+ ".sql",
47
+ ".csv",
48
+ ".tsv"
49
+ ];
50
+ const hasValidExt = validExtensions.some(
51
+ (ext) => base.toLowerCase().endsWith(ext)
52
+ );
53
+ if (!hasValidExt) {
54
+ throw new IoPathError(
55
+ `Security: Invalid file extension. Allowed extensions are: ${validExtensions.join(", ")}`
56
+ );
57
+ }
58
+ }
59
+ const resolved = resolve(targetPath);
60
+ let currentDir = resolved;
61
+ let existingRealPath = "";
62
+ while (currentDir !== parse(currentDir).root) {
63
+ try {
64
+ existingRealPath = realpathSync(currentDir);
65
+ break;
66
+ } catch {
67
+ currentDir = dirname(currentDir);
68
+ }
69
+ }
70
+ if (!existingRealPath) {
71
+ try {
72
+ existingRealPath = realpathSync(currentDir);
73
+ } catch {
74
+ existingRealPath = currentDir;
75
+ }
76
+ }
77
+ const remainder = relative(currentDir, resolved);
78
+ const finalTargetPath = remainder ? join(existingRealPath, remainder) : existingRealPath;
79
+ if (allowedRoots.length === 0) {
80
+ throw new IoPathError(
81
+ "No allowed input/output roots configured for sandbox boundary. Please configure ALLOWED_IO_ROOTS env variable or pass --allowed-io-roots with absolute paths to enable filesystem operations."
82
+ );
83
+ }
84
+ const safeRoots = [];
85
+ for (const root of allowedRoots) {
86
+ try {
87
+ safeRoots.push(realpathSync(resolve(root)));
88
+ } catch {
89
+ safeRoots.push(resolve(root));
90
+ }
91
+ }
92
+ const isAllowed = safeRoots.some((root) => {
93
+ const rel = relative(root, finalTargetPath);
94
+ return rel !== ".." && !rel.startsWith(".." + sep) && !isAbsolute(rel);
95
+ });
96
+ if (!isAllowed) {
97
+ throw new IoPathError(
98
+ `Directory path escapes allowed sandbox boundaries: ${targetPath}`
99
+ );
100
+ }
101
+ let isSymlink = false;
102
+ try {
103
+ const stats = lstatSync(resolved);
104
+ if (stats.isSymbolicLink()) {
105
+ isSymlink = true;
106
+ }
107
+ } catch {
108
+ }
109
+ if (isSymlink) {
110
+ throw new IoPathError(
111
+ `Symlinks are strictly forbidden for file operations: ${targetPath}`
112
+ );
113
+ }
114
+ }
115
+ function parseAllowedIoRoots(raw) {
116
+ if (!raw) return void 0;
117
+ if (raw.length > 51200) {
118
+ throw new ConfigurationError(
119
+ "ALLOWED_IO_ROOTS configuration exceeds size limit (50KB)"
120
+ );
121
+ }
122
+ let paths;
123
+ try {
124
+ if (raw.trim().startsWith("[")) {
125
+ const parsed = JSON.parse(raw);
126
+ if (Array.isArray(parsed) && parsed.every((p) => typeof p === "string" && isAbsolute(p))) {
127
+ paths = parsed;
128
+ } else {
129
+ throw new ConfigurationError("Must be an array of absolute paths");
130
+ }
131
+ } else {
132
+ paths = raw.split(",").map((s) => s.trim()).filter(Boolean);
133
+ if (paths.some((p) => !isAbsolute(p))) {
134
+ throw new ConfigurationError("All paths must be absolute");
135
+ }
136
+ }
137
+ } catch (e) {
138
+ const errName = e instanceof Error ? e.message : String(e);
139
+ throw new ConfigurationError(
140
+ `Invalid ALLOWED_IO_ROOTS configuration: ${errName}`,
141
+ "CONFIG_ERROR",
142
+ {
143
+ cause: e instanceof Error ? e : void 0
144
+ }
145
+ );
146
+ }
147
+ for (const p of paths) {
148
+ try {
149
+ if (!existsSync(p)) {
150
+ console.warn(`
151
+ [WARN] ALLOWED_IO_ROOTS path does not exist: ${p}
152
+ `);
153
+ }
154
+ } catch {
155
+ }
156
+ }
157
+ return paths;
158
+ }
159
+
160
+ // src/utils/annotations.ts
161
+ var READ_ONLY = {
162
+ readOnlyHint: true,
163
+ destructiveHint: false,
164
+ openWorldHint: false,
165
+ sensitiveHint: false
166
+ };
167
+ var WRITE = {
168
+ readOnlyHint: false,
169
+ destructiveHint: false,
170
+ openWorldHint: false,
171
+ sensitiveHint: false
172
+ };
173
+ var DESTRUCTIVE = {
174
+ readOnlyHint: false,
175
+ destructiveHint: true,
176
+ openWorldHint: false,
177
+ sensitiveHint: false
178
+ };
179
+ var IDEMPOTENT = {
180
+ readOnlyHint: false,
181
+ destructiveHint: false,
182
+ idempotentHint: true,
183
+ openWorldHint: false,
184
+ sensitiveHint: false
185
+ };
186
+ var ADMIN = {
187
+ readOnlyHint: false,
188
+ destructiveHint: true,
189
+ openWorldHint: false,
190
+ sensitiveHint: true
191
+ // System maintenance may expose internal db structures
192
+ };
193
+ function readOnly(title) {
194
+ return { title, ...READ_ONLY };
195
+ }
196
+ function write(title) {
197
+ return { title, ...WRITE };
198
+ }
199
+ function destructive(title) {
200
+ return { title, ...DESTRUCTIVE };
201
+ }
202
+ function idempotent(title) {
203
+ return { title, ...IDEMPOTENT };
204
+ }
205
+ function admin(title) {
206
+ return { title, ...ADMIN };
207
+ }
208
+ var ADMIN_FS = {
209
+ readOnlyHint: false,
210
+ destructiveHint: true,
211
+ openWorldHint: true,
212
+ sensitiveHint: true
213
+ };
214
+ var WRITE_FS = {
215
+ readOnlyHint: false,
216
+ destructiveHint: false,
217
+ openWorldHint: true,
218
+ sensitiveHint: true
219
+ };
220
+ function adminFs(title) {
221
+ return { title, ...ADMIN_FS };
222
+ }
223
+ function writeFs(title) {
224
+ return { title, ...WRITE_FS };
225
+ }
226
+ function toSDK(annotations) {
227
+ return annotations;
228
+ }
229
+
230
+ // src/utils/icons.ts
231
+ var MDI_BASE = "https://cdn.jsdelivr.net/npm/@mdi/svg@7.4.47/svg";
232
+ var SERVER_ICONS = [
233
+ {
234
+ src: `${MDI_BASE}/server.svg`,
235
+ mimeType: "image/svg+xml"
236
+ }
237
+ ];
238
+ var TOOL_GROUP_ICONS = {
239
+ core: [{ src: `${MDI_BASE}/database.svg`, mimeType: "image/svg+xml" }],
240
+ json: [{ src: `${MDI_BASE}/code-json.svg`, mimeType: "image/svg+xml" }],
241
+ text: [{ src: `${MDI_BASE}/format-text.svg`, mimeType: "image/svg+xml" }],
242
+ stats: [{ src: `${MDI_BASE}/chart-bar.svg`, mimeType: "image/svg+xml" }],
243
+ vector: [
244
+ { src: `${MDI_BASE}/vector-polyline.svg`, mimeType: "image/svg+xml" }
245
+ ],
246
+ admin: [{ src: `${MDI_BASE}/cog.svg`, mimeType: "image/svg+xml" }],
247
+ transactions: [
248
+ { src: `${MDI_BASE}/swap-horizontal.svg`, mimeType: "image/svg+xml" }
249
+ ],
250
+ geo: [{ src: `${MDI_BASE}/earth.svg`, mimeType: "image/svg+xml" }],
251
+ introspection: [
252
+ { src: `${MDI_BASE}/graph-outline.svg`, mimeType: "image/svg+xml" }
253
+ ],
254
+ migration: [
255
+ { src: `${MDI_BASE}/source-branch.svg`, mimeType: "image/svg+xml" }
256
+ ],
257
+ codemode: [{ src: `${MDI_BASE}/code-braces.svg`, mimeType: "image/svg+xml" }]
258
+ };
259
+ function getToolGroupIcon(group) {
260
+ return TOOL_GROUP_ICONS[group];
261
+ }
262
+
263
+ // src/utils/redaction.ts
264
+ var SENSITIVE_KEY_PATTERN = /(?:sk-|Bearer |token\s*[:=]\s*|password\s*[:=]\s*|secret\s*[:=]\s*|apikey\s*[:=]\s*|api_key\s*[:=]\s*|AWS_SECRET_ACCESS_KEY\s*[:=]\s*|GITHUB_TOKEN\s*[:=]\s*|ghp_|gho_|ghu_|ghs_|xoxb-|xoxp-|xoxs-|AZURE_[A-Z_]*\s*[:=]\s*|DATABASE_URL\s*[:=]\s*|AKIA|sk-ant-api[a-zA-Z0-9_-]+|sk_live_[a-zA-Z0-9_]+|rk_live_[a-zA-Z0-9_]+|SG\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+|npm_[a-zA-Z0-9]{30,}|dpl_[a-zA-Z0-9]{30,}|hvs\.[a-zA-Z0-9_-]+)[^\s'",;)}\]]{2,}/i;
265
+ var SENSITIVE_VALUE_REGEX = new RegExp(SENSITIVE_KEY_PATTERN.source, "gi");
266
+ var SENSITIVE_KEY_REGEX = /^(password|passwd|token|secret|authorization|api_?key|credential|private_?key|access_?token|refresh_?token|database_url)$/i;
267
+ function redactObject(obj, depth = 0, maxDepth = 15) {
268
+ if (depth > maxDepth || obj === null || obj === void 0) {
269
+ return obj;
270
+ }
271
+ if (typeof obj === "string") {
272
+ return obj.replace(SENSITIVE_VALUE_REGEX, "[REDACTED]");
273
+ }
274
+ if (typeof obj !== "object") {
275
+ return obj;
276
+ }
277
+ if (Array.isArray(obj)) {
278
+ return obj.map((item) => redactObject(item, depth + 1, maxDepth));
279
+ }
280
+ const redacted = {};
281
+ for (const [key, value] of Object.entries(obj)) {
282
+ if (SENSITIVE_KEY_REGEX.test(key)) {
283
+ redacted[key] = "[REDACTED]";
284
+ } else {
285
+ redacted[key] = redactObject(value, depth + 1, maxDepth);
286
+ }
287
+ }
288
+ return redacted;
289
+ }
290
+
291
+ // src/auth/scope-map.ts
292
+ var toolScopeMap = /* @__PURE__ */ new Map();
293
+ function registerToolScope(toolName, scope) {
294
+ toolScopeMap.set(toolName, scope);
295
+ if (!toolName.startsWith("sqlite_")) {
296
+ toolScopeMap.set(`sqlite_${toolName}`, scope);
297
+ } else {
298
+ toolScopeMap.set(toolName.slice(7), scope);
299
+ }
300
+ }
301
+ function getRequiredScope(toolName) {
302
+ return toolScopeMap.get(toolName) ?? SCOPES.ADMIN;
303
+ }
11
304
 
12
305
  // src/utils/where-clause.ts
13
306
  var UnsafeWhereClauseError = class extends Error {
@@ -265,7 +558,7 @@ function buildWhereClause(conditions, whereClause) {
265
558
  ]);
266
559
  for (const cond of conditions) {
267
560
  if (!allowedOperators.has(cond.operator.toUpperCase())) {
268
- throw new Error(`Invalid operator: ${cond.operator}`);
561
+ throw new ValidationError(`Invalid operator: ${cond.operator}`);
269
562
  }
270
563
  const col = `"${cond.column.replace(/"/g, '""')}"`;
271
564
  if (cond.operator.toUpperCase() === "IN" && Array.isArray(cond.value)) {
@@ -334,6 +627,65 @@ function sanitizeIdentifiers(names) {
334
627
  function createColumnList(columns) {
335
628
  return sanitizeIdentifiers(columns).join(", ");
336
629
  }
630
+
631
+ // src/utils/tokens.ts
632
+ function estimateTokens(text, contentType = "text") {
633
+ const bytes = Buffer.byteLength(text, "utf8");
634
+ switch (contentType) {
635
+ case "json":
636
+ return Math.ceil(bytes / 3);
637
+ case "sql":
638
+ return Math.ceil(bytes / 3.5);
639
+ case "text":
640
+ default:
641
+ return Math.ceil(bytes / 4);
642
+ }
643
+ }
644
+
645
+ // src/utils/progress-utils.ts
646
+ function buildProgressContext(ctx) {
647
+ if (ctx?.server === void 0 || ctx.progressToken === void 0) {
648
+ return void 0;
649
+ }
650
+ return {
651
+ server: ctx.server,
652
+ progressToken: ctx.progressToken
653
+ };
654
+ }
655
+ async function sendProgress(ctx, progress, total, message) {
656
+ if (ctx === void 0) return;
657
+ if (ctx.progressToken === void 0) return;
658
+ try {
659
+ const notification = {
660
+ method: "notifications/progress",
661
+ params: {
662
+ progressToken: ctx.progressToken,
663
+ progress,
664
+ ...total !== void 0 && { total },
665
+ ...message !== void 0 && message !== "" && { message }
666
+ }
667
+ };
668
+ await ctx.server.notification(notification);
669
+ } catch {
670
+ }
671
+ }
672
+
673
+ // src/utils/stream-utils.ts
674
+ var STREAM_CHUNK_SIZE = 10;
675
+ async function streamResultRows(ctx, rows, chunkSize = STREAM_CHUNK_SIZE) {
676
+ if (rows.length === 0) {
677
+ return 0;
678
+ }
679
+ const effectiveChunkSize = Math.max(1, chunkSize);
680
+ const totalChunks = Math.ceil(rows.length / effectiveChunkSize);
681
+ for (let i = 0; i < totalChunks; i++) {
682
+ const start = i * effectiveChunkSize;
683
+ const end = Math.min(start + effectiveChunkSize, rows.length);
684
+ const chunk = rows.slice(start, end);
685
+ await sendProgress(ctx, i + 1, totalChunks, JSON.stringify(chunk));
686
+ }
687
+ return totalChunks;
688
+ }
337
689
  function validateSameDirPath(targetPath, dbPath) {
338
690
  if (targetPath.includes("\0")) {
339
691
  return {
@@ -479,180 +831,6 @@ function validateAggregateFunction(fn) {
479
831
  );
480
832
  }
481
833
  }
482
-
483
- // src/utils/tokens.ts
484
- function estimateTokens(text, contentType = "text") {
485
- const bytes = Buffer.byteLength(text, "utf8");
486
- switch (contentType) {
487
- case "json":
488
- return Math.ceil(bytes / 3);
489
- case "sql":
490
- return Math.ceil(bytes / 3.5);
491
- case "text":
492
- default:
493
- return Math.ceil(bytes / 4);
494
- }
495
- }
496
-
497
- // src/utils/icons.ts
498
- var MDI_BASE = "https://cdn.jsdelivr.net/npm/@mdi/svg@7.4.47/svg";
499
- var SERVER_ICONS = [
500
- {
501
- src: `${MDI_BASE}/server.svg`,
502
- mimeType: "image/svg+xml"
503
- }
504
- ];
505
- var TOOL_GROUP_ICONS = {
506
- core: [{ src: `${MDI_BASE}/database.svg`, mimeType: "image/svg+xml" }],
507
- json: [{ src: `${MDI_BASE}/code-json.svg`, mimeType: "image/svg+xml" }],
508
- text: [{ src: `${MDI_BASE}/format-text.svg`, mimeType: "image/svg+xml" }],
509
- stats: [{ src: `${MDI_BASE}/chart-bar.svg`, mimeType: "image/svg+xml" }],
510
- vector: [
511
- { src: `${MDI_BASE}/vector-polyline.svg`, mimeType: "image/svg+xml" }
512
- ],
513
- admin: [{ src: `${MDI_BASE}/cog.svg`, mimeType: "image/svg+xml" }],
514
- transactions: [
515
- { src: `${MDI_BASE}/swap-horizontal.svg`, mimeType: "image/svg+xml" }
516
- ],
517
- geo: [{ src: `${MDI_BASE}/earth.svg`, mimeType: "image/svg+xml" }],
518
- introspection: [
519
- { src: `${MDI_BASE}/graph-outline.svg`, mimeType: "image/svg+xml" }
520
- ],
521
- migration: [
522
- { src: `${MDI_BASE}/source-branch.svg`, mimeType: "image/svg+xml" }
523
- ],
524
- codemode: [{ src: `${MDI_BASE}/code-braces.svg`, mimeType: "image/svg+xml" }]
525
- };
526
- function getToolGroupIcon(group) {
527
- return TOOL_GROUP_ICONS[group];
528
- }
529
-
530
- // src/utils/annotations.ts
531
- var READ_ONLY = {
532
- readOnlyHint: true,
533
- destructiveHint: false,
534
- openWorldHint: false,
535
- sensitiveHint: false
536
- };
537
- var WRITE = {
538
- readOnlyHint: false,
539
- destructiveHint: false,
540
- openWorldHint: false,
541
- sensitiveHint: false
542
- };
543
- var DESTRUCTIVE = {
544
- readOnlyHint: false,
545
- destructiveHint: true,
546
- openWorldHint: false,
547
- sensitiveHint: false
548
- };
549
- var IDEMPOTENT = {
550
- readOnlyHint: false,
551
- destructiveHint: false,
552
- idempotentHint: true,
553
- openWorldHint: false,
554
- sensitiveHint: false
555
- };
556
- var ADMIN = {
557
- readOnlyHint: false,
558
- destructiveHint: true,
559
- openWorldHint: false,
560
- sensitiveHint: true
561
- // System maintenance may expose internal db structures
562
- };
563
- function readOnly(title) {
564
- return { title, ...READ_ONLY };
565
- }
566
- function write(title) {
567
- return { title, ...WRITE };
568
- }
569
- function destructive(title) {
570
- return { title, ...DESTRUCTIVE };
571
- }
572
- function idempotent(title) {
573
- return { title, ...IDEMPOTENT };
574
- }
575
- function admin(title) {
576
- return { title, ...ADMIN };
577
- }
578
- var ADMIN_FS = {
579
- readOnlyHint: false,
580
- destructiveHint: true,
581
- openWorldHint: true,
582
- sensitiveHint: true
583
- };
584
- var WRITE_FS = {
585
- readOnlyHint: false,
586
- destructiveHint: false,
587
- openWorldHint: true,
588
- sensitiveHint: true
589
- };
590
- function adminFs(title) {
591
- return { title, ...ADMIN_FS };
592
- }
593
- function writeFs(title) {
594
- return { title, ...WRITE_FS };
595
- }
596
-
597
- // src/utils/redaction.ts
598
- var SENSITIVE_KEY_PATTERN = /(?:sk-|Bearer |token\s*[:=]\s*|password\s*[:=]\s*|secret\s*[:=]\s*|apikey\s*[:=]\s*|api_key\s*[:=]\s*|AWS_SECRET_ACCESS_KEY\s*[:=]\s*|GITHUB_TOKEN\s*[:=]\s*|ghp_|gho_|ghu_|ghs_|xoxb-|xoxp-|xoxs-|AZURE_[A-Z_]*\s*[:=]\s*|DATABASE_URL\s*[:=]\s*|AKIA|sk-ant-api[a-zA-Z0-9_-]+|sk_live_[a-zA-Z0-9_]+|rk_live_[a-zA-Z0-9_]+|SG\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+|npm_[a-zA-Z0-9]{30,}|dpl_[a-zA-Z0-9]{30,}|hvs\.[a-zA-Z0-9_-]+)[^\s'",;)}\]]{2,}/i;
599
- var SENSITIVE_VALUE_REGEX = new RegExp(SENSITIVE_KEY_PATTERN.source, "gi");
600
- var SENSITIVE_KEY_REGEX = /^(password|passwd|token|secret|authorization|api_?key|credential|private_?key|access_?token|refresh_?token|database_url)$/i;
601
- function redactObject(obj, depth = 0, maxDepth = 15) {
602
- if (depth > maxDepth || obj === null || obj === void 0) {
603
- return obj;
604
- }
605
- if (typeof obj === "string") {
606
- return obj.replace(SENSITIVE_VALUE_REGEX, "[REDACTED]");
607
- }
608
- if (typeof obj !== "object") {
609
- return obj;
610
- }
611
- if (Array.isArray(obj)) {
612
- return obj.map((item) => redactObject(item, depth + 1, maxDepth));
613
- }
614
- const redacted = {};
615
- for (const [key, value] of Object.entries(obj)) {
616
- if (SENSITIVE_KEY_REGEX.test(key)) {
617
- redacted[key] = "[REDACTED]";
618
- } else {
619
- redacted[key] = redactObject(value, depth + 1, maxDepth);
620
- }
621
- }
622
- return redacted;
623
- }
624
-
625
- // src/auth/scope-map.ts
626
- var toolScopeMap = /* @__PURE__ */ new Map();
627
- function registerToolScope(toolName, scope) {
628
- toolScopeMap.set(toolName, scope);
629
- if (!toolName.startsWith("sqlite_")) {
630
- toolScopeMap.set(`sqlite_${toolName}`, scope);
631
- } else {
632
- toolScopeMap.set(toolName.slice(7), scope);
633
- }
634
- }
635
- function getRequiredScope(toolName) {
636
- return toolScopeMap.get(toolName) ?? SCOPES.ADMIN;
637
- }
638
-
639
- // src/utils/resource-annotations.ts
640
- var HIGH_PRIORITY = {
641
- audience: ["user", "assistant"],
642
- priority: 0.9
643
- };
644
- var MEDIUM_PRIORITY = {
645
- audience: ["user", "assistant"],
646
- priority: 0.6
647
- };
648
- var LOW_PRIORITY = {
649
- audience: ["user", "assistant"],
650
- priority: 0.4
651
- };
652
- var ASSISTANT_FOCUSED = {
653
- audience: ["assistant"],
654
- priority: 0.5
655
- };
656
834
  var ErrorResponseFields = z.object({
657
835
  error: z.string().optional().describe("Error message (human-readable)"),
658
836
  code: z.string().optional().describe("Error code (e.g. VALIDATION_ERROR, QUERY_ERROR)"),
@@ -719,7 +897,7 @@ var PragmaCompileOptionsSchema = z.object({
719
897
  "Optional filter pattern (case-insensitive substring match) to limit returned options"
720
898
  )
721
899
  });
722
- var PragmaDatabaseListSchema = z.object({});
900
+ var PragmaDatabaseListSchema = z.object({}).strict();
723
901
  z.object({
724
902
  analyze: z.boolean().optional().default(true).describe("Run ANALYZE after VACUUM")
725
903
  });
@@ -768,7 +946,7 @@ var AuditSearchSchema = z.object({
768
946
  toTimestamp: z.string().optional().describe("Filter by end timestamp (ISO 8601)"),
769
947
  limit: z.preprocess(
770
948
  coerceNumber,
771
- z.number().int().min(1).max(1e3).optional().default(50).describe("Maximum number of entries to return (default 50)")
949
+ z.number().int().min(1).max(1e3).optional().default(10).describe("Maximum number of entries to return (default 10)")
772
950
  ),
773
951
  offset: z.preprocess(
774
952
  coerceNumber,
@@ -782,14 +960,14 @@ var SqlDumpSchema = z.object({
782
960
  });
783
961
  var AuditListBackupsOutputSchema = z.object({
784
962
  success: z.boolean(),
785
- snapshots: z.array(z.any()).optional(),
963
+ snapshots: z.array(z.unknown()).optional(),
786
964
  count: z.number().optional(),
787
965
  totalCount: z.number().optional(),
788
966
  _meta: z.object({ tokenEstimate: z.number() }).optional()
789
967
  }).extend(ErrorResponseFields.shape);
790
968
  var AuditGetBackupOutputSchema = z.object({
791
969
  success: z.boolean(),
792
- metadata: z.any().optional(),
970
+ metadata: z.unknown().optional(),
793
971
  ddl: z.string().optional(),
794
972
  data: z.string().optional()
795
973
  }).extend(ErrorResponseFields.shape);
@@ -800,7 +978,7 @@ var AuditCleanupOutputSchema = z.object({
800
978
  }).extend(ErrorResponseFields.shape);
801
979
  var AuditDiffBackupOutputSchema = z.object({
802
980
  success: z.boolean(),
803
- diffs: z.array(z.any()).optional(),
981
+ diffs: z.array(z.unknown()).optional(),
804
982
  snapshotTimestamp: z.string().optional(),
805
983
  snapshotTarget: z.string().optional()
806
984
  }).extend(ErrorResponseFields.shape);
@@ -813,7 +991,7 @@ var AuditRestoreBackupOutputSchema = z.object({
813
991
  }).extend(ErrorResponseFields.shape);
814
992
  var AuditSearchOutputSchema = z.object({
815
993
  success: z.boolean(),
816
- entries: z.array(z.any()).optional(),
994
+ entries: z.array(z.unknown()).optional(),
817
995
  count: z.number().optional(),
818
996
  totalCount: z.number().optional()
819
997
  }).extend(ErrorResponseFields.shape);
@@ -984,4 +1162,22 @@ var WalOutputSchema = z.object({
984
1162
  checkpointedPages: z.number().optional()
985
1163
  }).extend(ErrorResponseFields.shape);
986
1164
 
987
- export { ASSISTANT_FOCUSED, AnalyzeOutputSchema, AnalyzeSchema, AttachDatabaseOutputSchema, AttachDatabaseSchema, AuditCleanupOutputSchema, AuditDiffBackupOutputSchema, AuditGetBackupOutputSchema, AuditListBackupsOutputSchema, AuditListBackupsSchema, AuditRestoreBackupOutputSchema, AuditSearchOutputSchema, AuditSearchSchema, BackupOutputSchema, BackupSchema, DetachDatabaseOutputSchema, DetachDatabaseSchema, ErrorResponseFields, HIGH_PRIORITY, IndexStatsOutputSchema, IndexStatsSchema, IntegrityCheckOutputSchema, IntegrityCheckSchema, LOW_PRIORITY, MEDIUM_PRIORITY, NAME, OptimizeOutputSchema, OptimizeSchema, PragmaCompileOptionsOutputSchema, PragmaCompileOptionsSchema, PragmaDatabaseListOutputSchema, PragmaDatabaseListSchema, PragmaOptimizeOutputSchema, PragmaOptimizeSchema, PragmaSettingsOutputSchema, PragmaSettingsSchema, PragmaTableInfoOutputSchema, PragmaTableInfoSchema, READ_ONLY, ReindexOutputSchema, ReindexSchema, RestoreOutputSchema, RestoreSchema, SENSITIVE_KEY_PATTERN, SERVER_ICONS, SqlDumpOutputSchema, SqlDumpSchema, VERSION, VacuumIntoCopyOutputSchema, VacuumIntoCopySchema, VacuumOutputSchema, VerifyBackupOutputSchema, VerifyBackupSchema, WalOutputSchema, WalSchema, admin, adminFs, buildWhereClause, createColumnList, destructive, estimateTokens, getRequiredScope, getToolGroupIcon, idempotent, readOnly, redactObject, registerToolScope, sanitizeIdentifier, sanitizeWhereClause, validateAggregateFunction, validateIdentifier, validateJsonPath, validateSameDirPath, write, writeFs };
1165
+ // src/utils/resource-annotations.ts
1166
+ var HIGH_PRIORITY = {
1167
+ audience: ["user", "assistant"],
1168
+ priority: 0.9
1169
+ };
1170
+ var MEDIUM_PRIORITY = {
1171
+ audience: ["user", "assistant"],
1172
+ priority: 0.6
1173
+ };
1174
+ var LOW_PRIORITY = {
1175
+ audience: ["user", "assistant"],
1176
+ priority: 0.4
1177
+ };
1178
+ var ASSISTANT_FOCUSED = {
1179
+ audience: ["assistant"],
1180
+ priority: 0.5
1181
+ };
1182
+
1183
+ export { ASSISTANT_FOCUSED, AnalyzeOutputSchema, AnalyzeSchema, AttachDatabaseOutputSchema, AttachDatabaseSchema, AuditCleanupOutputSchema, AuditDiffBackupOutputSchema, AuditGetBackupOutputSchema, AuditListBackupsOutputSchema, AuditListBackupsSchema, AuditRestoreBackupOutputSchema, AuditSearchOutputSchema, AuditSearchSchema, BackupOutputSchema, BackupSchema, DetachDatabaseOutputSchema, DetachDatabaseSchema, ErrorResponseFields, HIGH_PRIORITY, IndexStatsOutputSchema, IndexStatsSchema, IntegrityCheckOutputSchema, IntegrityCheckSchema, LOW_PRIORITY, MEDIUM_PRIORITY, NAME, OptimizeOutputSchema, OptimizeSchema, PragmaCompileOptionsOutputSchema, PragmaCompileOptionsSchema, PragmaDatabaseListOutputSchema, PragmaDatabaseListSchema, PragmaOptimizeOutputSchema, PragmaOptimizeSchema, PragmaSettingsOutputSchema, PragmaSettingsSchema, PragmaTableInfoOutputSchema, PragmaTableInfoSchema, READ_ONLY, ReindexOutputSchema, ReindexSchema, RestoreOutputSchema, RestoreSchema, SENSITIVE_KEY_PATTERN, SERVER_ICONS, SqlDumpOutputSchema, SqlDumpSchema, VERSION, VacuumIntoCopyOutputSchema, VacuumIntoCopySchema, VacuumOutputSchema, VerifyBackupOutputSchema, VerifyBackupSchema, WalOutputSchema, WalSchema, admin, adminFs, assertSafeIoPath, buildProgressContext, buildWhereClause, createColumnList, destructive, estimateTokens, getRequiredScope, getToolGroupIcon, idempotent, parseAllowedIoRoots, readOnly, redactObject, registerToolScope, sanitizeIdentifier, sanitizeWhereClause, sendProgress, streamResultRows, toSDK, validateAggregateFunction, validateIdentifier, validateJsonPath, validateSameDirPath, write, writeFs };