db-mcp 1.1.1 → 2.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 (84) hide show
  1. package/.gitleaks.toml +9 -0
  2. package/.trivyignore +8 -0
  3. package/README.md +193 -120
  4. package/dist/{chunk-TVIZ3XJH.js → chunk-5Y42NPBP.js} +4168 -2411
  5. package/dist/{chunk-AOUL5SHS.js → chunk-645ZEFLA.js} +70 -20
  6. package/dist/chunk-OKOVZ5QE.js +28 -0
  7. package/dist/chunk-SFJQCNG7.js +131 -0
  8. package/dist/{chunk-FW7UCRLN.js → chunk-VIDSICEL.js} +3 -0
  9. package/dist/chunk-WBER5YY4.js +2053 -0
  10. package/dist/{chunk-4IA3DB5C.js → chunk-X3MUUOWM.js} +19 -2
  11. package/dist/{chunk-Z2GFQU3G.js → chunk-Z7C2TM4L.js} +114 -21
  12. package/dist/cli.js +79 -5
  13. package/dist/{http-VSB7DBJR.js → http-6KF4ULDI.js} +199 -77
  14. package/dist/index.d.ts +231 -8
  15. package/dist/index.js +6 -5
  16. package/dist/{sqlite-26V3Y4MK.js → sqlite-U5KSYQXK.js} +62 -138
  17. package/dist/{sqlite-native-5O7FZJGB.js → sqlite-native-JXMCFQBA.js} +575 -113
  18. package/dist/worker-script.js +34 -10
  19. package/logs/.gitkeep +1 -0
  20. package/mcp-config-example.json +83 -0
  21. package/package.json +9 -8
  22. package/playwright.config.ts +1 -1
  23. package/scripts/update-badges.ts +99 -0
  24. package/server.json +7 -5
  25. package/test-server/README.md +20 -23
  26. package/test-server/code-map.md +45 -33
  27. package/test-server/reset-database.ps1 +59 -17
  28. package/test-server/scripts/README.md +27 -0
  29. package/test-server/{test-help-resources.mjs → scripts/test-help-resources.mjs} +12 -5
  30. package/test-server/scripts/test-prompts.mjs +251 -0
  31. package/test-server/{test-tool-annotations.mjs → scripts/test-tool-annotations.mjs} +9 -4
  32. package/test-server/test-advanced/README.md +70 -0
  33. package/test-server/test-advanced/test-codemode-advanced-admin.md +174 -0
  34. package/test-server/test-advanced/test-codemode-advanced-core.md +193 -0
  35. package/test-server/test-advanced/test-codemode-advanced-geo.md +157 -0
  36. package/test-server/test-advanced/test-codemode-advanced-introspection.md +171 -0
  37. package/test-server/test-advanced/test-codemode-advanced-json.md +169 -0
  38. package/test-server/test-advanced/test-codemode-advanced-migration.md +160 -0
  39. package/test-server/test-advanced/test-codemode-advanced-stats.md +185 -0
  40. package/test-server/test-advanced/test-codemode-advanced-text.md +183 -0
  41. package/test-server/test-advanced/test-codemode-advanced-transactions.md +136 -0
  42. package/test-server/test-advanced/test-codemode-advanced-vector.md +141 -0
  43. package/test-server/test-codemode/README.md +121 -0
  44. package/test-server/test-codemode/test-codemode-admin.md +223 -0
  45. package/test-server/test-codemode/test-codemode-core.md +286 -0
  46. package/test-server/test-codemode/test-codemode-geo.md +177 -0
  47. package/test-server/test-codemode/test-codemode-introspection.md +190 -0
  48. package/test-server/test-codemode/test-codemode-json.md +237 -0
  49. package/test-server/test-codemode/test-codemode-migration.md +278 -0
  50. package/test-server/test-codemode/test-codemode-sandbox.md +413 -0
  51. package/test-server/test-codemode/test-codemode-stats.md +232 -0
  52. package/test-server/test-codemode/test-codemode-text.md +237 -0
  53. package/test-server/test-codemode/test-codemode-transactions.md +236 -0
  54. package/test-server/test-codemode/test-codemode-vector.md +244 -0
  55. package/test-server/test-codemode/test-codemode-wasm-degradation.md +394 -0
  56. package/test-server/test-database.sql +37 -1
  57. package/test-server/test-resources.md +43 -16
  58. package/test-server/test-tool-groups/README.md +100 -0
  59. package/test-server/test-tool-groups/test-admin-core.md +165 -0
  60. package/test-server/test-tool-groups/test-admin-extensions.md +133 -0
  61. package/test-server/{test-tools.md → test-tool-groups/test-core-data.md} +103 -17
  62. package/test-server/test-tool-groups/test-core-schema.md +240 -0
  63. package/test-server/test-tool-groups/test-geo-haversine.md +130 -0
  64. package/test-server/test-tool-groups/test-geo-spatialite.md +110 -0
  65. package/test-server/test-tool-groups/test-introspection-diagnostics.md +123 -0
  66. package/test-server/test-tool-groups/test-introspection-schema.md +133 -0
  67. package/test-server/test-tool-groups/test-json-read.md +219 -0
  68. package/test-server/test-tool-groups/test-json-write.md +157 -0
  69. package/test-server/test-tool-groups/test-migration.md +193 -0
  70. package/test-server/test-tool-groups/test-stats-advanced.md +118 -0
  71. package/test-server/test-tool-groups/test-stats-basic.md +156 -0
  72. package/test-server/test-tool-groups/test-text-advanced.md +169 -0
  73. package/test-server/test-tool-groups/test-text-basic.md +177 -0
  74. package/test-server/test-tool-groups/test-transactions.md +179 -0
  75. package/test-server/test-tool-groups/test-vector-read.md +130 -0
  76. package/test-server/test-tool-groups/test-vector-write.md +115 -0
  77. package/test-server/tool-reference.md +79 -58
  78. package/tsconfig.build.json +6 -0
  79. package/dist/chunk-RHVEZ42P.js +0 -873
  80. package/test-server/test-agent-experience.md +0 -243
  81. package/test-server/test-group-tools.md +0 -861
  82. package/test-server/test-tools-advanced-1.md +0 -517
  83. package/test-server/test-tools-advanced-2.md +0 -487
  84. package/test-server/test-tools-codemode.md +0 -629
@@ -1,7 +1,7 @@
1
+ import { transformAutoReturn } from './chunk-OKOVZ5QE.js';
1
2
  import { workerData, parentPort } from 'worker_threads';
2
3
  import vm from 'vm';
3
4
 
4
- // src/codemode/worker-script.ts
5
5
  function buildSqliteProxy(bindings, rpcPort) {
6
6
  const pending = /* @__PURE__ */ new Map();
7
7
  let nextId = 0;
@@ -9,8 +9,12 @@ function buildSqliteProxy(bindings, rpcPort) {
9
9
  const p = pending.get(msg.id);
10
10
  if (p) {
11
11
  pending.delete(msg.id);
12
- if (msg.error) {
13
- p.reject(new Error(msg.error));
12
+ if (msg.error !== void 0) {
13
+ const err = new Error(msg.error || "Empty error message");
14
+ if (msg.errorDetails) {
15
+ Object.assign(err, msg.errorDetails);
16
+ }
17
+ p.reject(err);
14
18
  } else {
15
19
  p.resolve(msg.result);
16
20
  }
@@ -40,9 +44,19 @@ function buildSqliteProxy(bindings, rpcPort) {
40
44
  if (topLevel) {
41
45
  for (const method of topLevel) {
42
46
  if (method === "help") {
43
- sqlite["help"] = () => ({
44
- groups: groupNames
45
- });
47
+ sqlite["help"] = () => {
48
+ let totalMethods = 0;
49
+ for (const k of groupNames) {
50
+ totalMethods += (bindings[k] ?? []).filter(
51
+ (m) => m !== "help"
52
+ ).length;
53
+ }
54
+ return {
55
+ groups: groupNames,
56
+ totalMethods,
57
+ usage: "Use sqlite.<group>.help() for group details. Example: sqlite.core.help()"
58
+ };
59
+ };
46
60
  } else {
47
61
  sqlite[method] = (...args) => new Promise((resolve, reject) => {
48
62
  const id = nextId++;
@@ -58,9 +72,19 @@ function buildSqliteProxy(bindings, rpcPort) {
58
72
  }
59
73
  }
60
74
  if (sqlite["help"] === void 0) {
61
- sqlite["help"] = () => ({
62
- groups: groupNames
63
- });
75
+ sqlite["help"] = () => {
76
+ let totalMethods = 0;
77
+ for (const k of groupNames) {
78
+ totalMethods += (bindings[k] ?? []).filter(
79
+ (m) => m !== "help"
80
+ ).length;
81
+ }
82
+ return {
83
+ groups: groupNames,
84
+ totalMethods,
85
+ usage: "Use sqlite.<group>.help() for group details. Example: sqlite.core.help()"
86
+ };
87
+ };
64
88
  }
65
89
  return sqlite;
66
90
  }
@@ -97,7 +121,7 @@ async function executeInWorker() {
97
121
  const context = vm.createContext(sandbox, {
98
122
  name: "worker-sandbox"
99
123
  });
100
- const wrappedCode = `(async () => { ${code} })()`;
124
+ const wrappedCode = `(async () => { ${transformAutoReturn(code)} })()`;
101
125
  const script = new vm.Script(wrappedCode, {
102
126
  filename: "user-code.js"
103
127
  });
package/logs/.gitkeep ADDED
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,83 @@
1
+ {
2
+ "mcpServers": {
3
+ "db-mcp": {
4
+ "command": "docker",
5
+ "args": [
6
+ "run",
7
+ "--rm",
8
+ "-i",
9
+ "-v",
10
+ "./data:/app/data",
11
+ "-e",
12
+ "MCP_HOST",
13
+ "-e",
14
+ "LOG_LEVEL",
15
+ "-e",
16
+ "METADATA_CACHE_TTL_MS",
17
+ "-e",
18
+ "CODEMODE_ISOLATION",
19
+ "-e",
20
+ "MCP_RATE_LIMIT_MAX",
21
+ "-e",
22
+ "SQLITE_DATABASE",
23
+ "-e",
24
+ "DB_MCP_TOOL_FILTER",
25
+ "-e",
26
+ "CSV_EXTENSION_PATH",
27
+ "-e",
28
+ "SPATIALITE_PATH",
29
+ "-e",
30
+ "MCP_AUTH_TOKEN",
31
+ "-e",
32
+ "OAUTH_ENABLED",
33
+ "-e",
34
+ "OAUTH_ISSUER",
35
+ "-e",
36
+ "OAUTH_AUDIENCE",
37
+ "-e",
38
+ "OAUTH_JWKS_URI",
39
+ "-e",
40
+ "OAUTH_CLOCK_TOLERANCE",
41
+ "-e",
42
+ "AUDIT_BACKUP",
43
+ "-e",
44
+ "AUDIT_REDACT",
45
+ "-e",
46
+ "AUDIT_READS",
47
+ "-e",
48
+ "AUDIT_BACKUP_DATA",
49
+ "-e",
50
+ "AUDIT_LOG",
51
+ "writenotenow/db-mcp:latest",
52
+ "--sqlite-native",
53
+ "/app/data/my-database.db",
54
+ "--tool-filter",
55
+ "codemode",
56
+ "--audit-log",
57
+ "/tmp/db-mcp-logs/audit.jsonl"
58
+ ],
59
+ "env": {
60
+ "MCP_HOST": "0.0.0.0",
61
+ "LOG_LEVEL": "info",
62
+ "METADATA_CACHE_TTL_MS": "5000",
63
+ "CODEMODE_ISOLATION": "worker",
64
+ "MCP_RATE_LIMIT_MAX": "100",
65
+ "SQLITE_DATABASE": "",
66
+ "DB_MCP_TOOL_FILTER": "",
67
+ "CSV_EXTENSION_PATH": "",
68
+ "SPATIALITE_PATH": "",
69
+ "MCP_AUTH_TOKEN": "",
70
+ "OAUTH_ENABLED": "false",
71
+ "OAUTH_ISSUER": "",
72
+ "OAUTH_AUDIENCE": "",
73
+ "OAUTH_JWKS_URI": "",
74
+ "OAUTH_CLOCK_TOLERANCE": "60",
75
+ "AUDIT_BACKUP": "false",
76
+ "AUDIT_REDACT": "false",
77
+ "AUDIT_READS": "false",
78
+ "AUDIT_BACKUP_DATA": "false",
79
+ "AUDIT_LOG": ""
80
+ }
81
+ }
82
+ }
83
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "db-mcp",
3
- "version": "1.1.1",
3
+ "version": "2.0.0",
4
4
  "description": "SQLite MCP server with OAuth 2.1 authentication, HTTP/SSE transport, and smart tool filtering",
5
5
  "mcpName": "io.github.neverinfamous/db-mcp",
6
6
  "type": "module",
@@ -22,8 +22,8 @@
22
22
  "check": "npm run lint && npm run typecheck",
23
23
  "test": "vitest run",
24
24
  "test:watch": "vitest",
25
- "test:coverage": "vitest run --coverage",
26
- "test:e2e": "playwright test",
25
+ "test:coverage": "vitest run --coverage && tsx scripts/update-badges.ts",
26
+ "test:e2e": "playwright test && tsx scripts/update-badges.ts",
27
27
  "bench": "vitest bench --run",
28
28
  "bench:verbose": "vitest bench --run --reporter=verbose",
29
29
  "clean": "rimraf dist",
@@ -73,8 +73,8 @@
73
73
  "globals": "^17.4.0",
74
74
  "rimraf": "^6.1.3",
75
75
  "tsup": "^8.5.1",
76
- "tsx": "^4.21.0",
77
- "typescript": "^5.9.3",
76
+ "tsx": "^4.22.1",
77
+ "typescript": "^6.0.3",
78
78
  "typescript-eslint": "^8.57.1",
79
79
  "vitest": "^4.0.17"
80
80
  },
@@ -85,9 +85,10 @@
85
85
  "better-sqlite3": "^12.8.0"
86
86
  },
87
87
  "overrides": {
88
- "diff": "8.0.3",
88
+ "diff": "9.0.0",
89
89
  "@isaacs/brace-expansion": "5.0.1",
90
- "tar": "7.5.11",
91
- "minimatch": "10.2.4"
90
+ "tar": "7.5.15",
91
+ "minimatch": "10.2.5",
92
+ "brace-expansion": "5.0.6"
92
93
  }
93
94
  }
@@ -8,7 +8,7 @@ export default defineConfig({
8
8
  // MCP SDK McpServer only supports one active transport at a time.
9
9
  // Parallel workers create competing SSE connections that steal each other's transport.
10
10
  workers: 1,
11
- reporter: "list",
11
+ reporter: [["list"], ["json", { outputFile: "playwright-results.json" }]],
12
12
  use: {
13
13
  trace: "on-first-retry",
14
14
  // 60s timeout — allows slow operations (vector stats, code mode ETL)
@@ -0,0 +1,99 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+ const ROOT_DIR = path.resolve(__dirname, "..");
8
+
9
+ function getBadgeColor(percentage: number): string {
10
+ if (percentage >= 95) return "brightgreen";
11
+ if (percentage >= 85) return "green";
12
+ if (percentage >= 75) return "yellowgreen";
13
+ if (percentage >= 65) return "yellow";
14
+ if (percentage >= 50) return "orange";
15
+ return "red";
16
+ }
17
+
18
+ function updateBadges() {
19
+ const summaryPath = path.join(ROOT_DIR, "coverage/coverage-summary.json");
20
+ const playwrightPath = path.join(ROOT_DIR, "playwright-results.json");
21
+
22
+ let linesPct = 0;
23
+ let coverageColor = "red";
24
+ let hasCoverage = false;
25
+
26
+ if (fs.existsSync(summaryPath)) {
27
+ const summary = JSON.parse(fs.readFileSync(summaryPath, "utf-8"));
28
+ linesPct = summary.total.lines.pct;
29
+ coverageColor = getBadgeColor(linesPct);
30
+ hasCoverage = true;
31
+ } else {
32
+ console.warn(`Coverage summary not found at ${summaryPath}`);
33
+ }
34
+
35
+ let e2ePassing = 0;
36
+ let e2eSkipped = 0;
37
+ let hasE2e = false;
38
+
39
+ if (fs.existsSync(playwrightPath)) {
40
+ const pw = JSON.parse(fs.readFileSync(playwrightPath, "utf-8"));
41
+ e2ePassing = pw.stats.expected || 0;
42
+ e2eSkipped = pw.stats.skipped || 0;
43
+ hasE2e = true;
44
+ } else {
45
+ console.warn(`Playwright results not found at ${playwrightPath}`);
46
+ }
47
+
48
+ // ![Coverage](https://img.shields.io/badge/Coverage-96.7%25-brightgreen.svg)
49
+ const covRegex =
50
+ /!\[Coverage\]\(https:\/\/img\.shields\.io\/badge\/Coverage-[0-9.]+.*?\.svg\)/g;
51
+ const newCovBadge = `![Coverage](https://img.shields.io/badge/Coverage-${linesPct}%25-${coverageColor}.svg)`;
52
+
53
+ // ![E2E](https://img.shields.io/badge/E2E-179%20tests%20%C2%B7%20224%20tools-blue.svg)
54
+ const e2eRegex =
55
+ /!\[E2E\]\(https:\/\/img\.shields\.io\/badge\/E2E-[a-zA-Z0-9%.-]+.*?\.svg\)/g;
56
+ const newE2eBadge = `![E2E](https://img.shields.io/badge/E2E-${e2ePassing}%20passing%20%C2%B7%20${e2eSkipped}%20skipped-blue.svg)`;
57
+
58
+ const filesToUpdate = ["README.md", "DOCKER_README.md"];
59
+
60
+ for (const file of filesToUpdate) {
61
+ const filePath = path.join(ROOT_DIR, file);
62
+ try {
63
+ let content = fs.readFileSync(filePath, "utf-8");
64
+ let changed = false;
65
+
66
+ if (hasCoverage) {
67
+ covRegex.lastIndex = 0;
68
+ if (covRegex.test(content)) {
69
+ covRegex.lastIndex = 0;
70
+ content = content.replace(covRegex, newCovBadge);
71
+ changed = true;
72
+ console.log(`Updated coverage badge in ${file} to ${linesPct}%`);
73
+ }
74
+ }
75
+
76
+ if (hasE2e) {
77
+ e2eRegex.lastIndex = 0;
78
+ if (e2eRegex.test(content)) {
79
+ e2eRegex.lastIndex = 0;
80
+ content = content.replace(e2eRegex, newE2eBadge);
81
+ changed = true;
82
+ console.log(
83
+ `Updated E2E badge in ${file} to ${e2ePassing} passing, ${e2eSkipped} skipped`,
84
+ );
85
+ }
86
+ }
87
+
88
+ if (changed) {
89
+ fs.writeFileSync(filePath, content, "utf-8");
90
+ } else {
91
+ console.log(`No badges found to update in ${file}.`);
92
+ }
93
+ } catch (err) {
94
+ console.warn(`Skipped updating ${file}: File not found or unreadable.`);
95
+ }
96
+ }
97
+ }
98
+
99
+ updateBadges();
package/server.json CHANGED
@@ -2,20 +2,20 @@
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.neverinfamous/db-mcp",
4
4
  "title": "db-mcp (SQLite MCP Server)",
5
- "description": "SQLite MCP server with OAuth 2.1, HTTP/SSE, 139 tools, and smart tool filtering",
6
- "version": "1.1.1",
5
+ "description": "SQLite MCP server with OAuth 2.1, HTTP/SSE, audit logging, 151 tools, and smart tool filtering",
6
+ "version": "2.0.0",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "db-mcp",
11
- "version": "1.1.1",
11
+ "version": "2.0.0",
12
12
  "transport": {
13
13
  "type": "stdio"
14
14
  }
15
15
  },
16
16
  {
17
17
  "registryType": "oci",
18
- "identifier": "docker.io/writenotenow/db-mcp:v1.1.1",
18
+ "identifier": "docker.io/writenotenow/db-mcp:v2.0.0",
19
19
  "transport": {
20
20
  "type": "stdio"
21
21
  }
@@ -36,7 +36,9 @@
36
36
  "vector-search",
37
37
  "geospatial",
38
38
  "spatialite",
39
- "statistical-analysis"
39
+ "statistical-analysis",
40
+ "audit-logging",
41
+ "token-estimation"
40
42
  ],
41
43
  "author": {
42
44
  "name": "Chris LeRoux",
@@ -4,22 +4,20 @@
4
4
 
5
5
  ## Files
6
6
 
7
- | File | Size | Purpose | When to Read |
8
- | ---------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
9
- | `test-tools.md` | ~12KB | **Entry-point protocol** — schema reference, error pattern docs, reporting format, cleanup rules. Paste a group checklist from `test-group-tools.md` at the bottom. | Always read first (Step 1 says read help resources, Step 2 is the testing) |
10
- | `test-group-tools.md` | ~54KB | Per-group **deterministic checklists** (core, json, text, stats, vector, admin, geo, introspection, migration). Copy the relevant section into `test-tools.md`. | When running a specific tool group |
11
- | `test-tools-advanced-1.md` | ~28KB | **Second-pass stress tests (Part 1)** — boundary values, state pollution, error message quality, WASM parity. | After basic checklist passes |
12
- | `test-tools-advanced-2.md` | ~32KB | **Second-pass stress tests (Part 2)** cross-group integration. Self-contained. | After basic checklist passes |
13
- | `test-resources.md` | ~6KB | Resource testing plan (8 data + 7 help resources via `read_resource`) | When testing resources |
14
- | `test-preflight.md` | ~2KB | **Pre-flight check** validates slim instructions, help resources, data resources, and tool-filter alignment in 5 steps | Before any test pass |
15
- | `test-agent-experience.md` | ~9KB | **Agent experience test** — 29 open-ended scenarios across 7 passes validating help resource sufficiency | After help resource changes |
16
- | `test-prompts.md` | ~10KB | Prompt testing plan (10 prompts, tested manually since agents typically don't invoke prompts) | When testing prompts |
17
- | `tool-groups-list.md` | | **Canonical tool inventory** — all 9 groups + codemode, 139 Native / 115 WASM tools. Source of truth for tool counts. | Reference / auditing |
18
- | `tool-reference.md` | ~18KB | **Complete Tool Reference** Detailed list of all 139 Native / 115 WASM tools organized by group. | Reference |
19
- | [`code-map.md`](code-map.md) | ~12KB | **Source Code Map** Directory tree, handler→tool mapping, type/schema locations, error hierarchy, constants, architecture patterns. | When debugging source code or making changes |
20
- | `reset-database.ps1` | ~11KB | PowerShell script to delete + re-seed `test.db` from `test-database.sql`. Verifies row counts. | After migration group testing or if data is polluted |
21
- | `test-database.sql` | ~21KB | Seed SQL (DDL + DML) for all `test_*` tables | Reference only — reset script consumes this |
22
- | `sample.csv` | <1KB | CSV fixture for `sqlite_create_csv_table` / `sqlite_analyze_csv_schema` testing | Used by admin group checklist |
7
+ | File | Size | Purpose | When to Read |
8
+ | ---------------------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
9
+ | `test-tool-groups/` | | **10 self-contained test prompts** — one per tool group. Each is a complete, standalone prompt (paste directly). See `test-tool-groups/README.md` for details. | **Primary testing method** use instead of `test-tools.md` + `test-group-tools.md` |
10
+ | `test-codemode/` | | **10 self-contained Code Mode test prompts** one per tool group. Tests via `sqlite_execute_code` only. See `test-codemode/README.md`. | **Primary Code Mode testing method** |
11
+ | `test-advanced/` | | **10 self-contained advanced stress test prompts** — one per tool group. Second-pass edge cases via Code Mode. See `test-advanced/README.md`. | **Primary advanced testing method** |
12
+ | `test-resources.md` | ~6KB | Resource testing plan (8 data + 7 help resources via `read_resource`) | When testing resources |
13
+ | `test-preflight.md` | ~2KB | **Pre-flight check** validates slim instructions, help resources, data resources, and tool-filter alignment in 5 steps | Before any test pass |
14
+ | `test-prompts.md` | ~10KB | Prompt testing plan (10 prompts, tested manually since agents typically don't invoke prompts) | When testing prompts |
15
+ | `tool-groups-list.md` | | **Canonical tool inventory** — all 10 groups + codemode, 151 Native / 125 WASM tools. Source of truth for tool counts. | Reference / auditing |
16
+ | `tool-reference.md` | ~18KB | **Complete Tool Reference** Detailed list of all 151 Native / 125 WASM tools organized by group. | Reference |
17
+ | [`code-map.md`](code-map.md) | ~12KB | **Source Code Map** — Directory tree, handler→tool mapping, type/schema locations, error hierarchy, constants, architecture patterns. | When debugging source code or making changes |
18
+ | `reset-database.ps1` | ~11KB | PowerShell script to delete + re-seed `test.db` from `test-database.sql`. Verifies row counts. | After migration group testing or if data is polluted |
19
+ | `test-database.sql` | ~21KB | Seed SQL (DDL + DML) for all `test_*` tables | Reference only reset script consumes this |
20
+ | `sample.csv` | <1KB | CSV fixture for `sqlite_create_csv_table` / `sqlite_analyze_csv_schema` testing | Used by admin group checklist |
23
21
 
24
22
  ## Test Database Schema
25
23
 
@@ -59,7 +57,7 @@
59
57
  To validate WASM mode produces identical results for shared tools:
60
58
 
61
59
  1. **Configure for WASM**: Set `--sqlite` (not `--sqlite-native`) in your MCP client config
62
- 2. **Expected tool count**: 115 WASM vs 139 Native (24 fewer: 4 FTS5, 6 window, 7 transaction, 7 SpatiaLite)
60
+ 2. **Expected tool count**: 115 WASM vs 140 Native (25 fewer: 4 FTS5, 6 window, 8 transaction, 7 SpatiaLite)
63
61
  3. **Run the same checklists**: Use `test-group-tools.md` but skip items marked `[NATIVE ONLY]`
64
62
  4. **Verify shared tools**: All non-`[NATIVE ONLY]` items should produce identical output in both backends
65
63
  5. **Verify absent tools**: Calling a Native-only tool in WASM mode should return a structured error (not crash)
@@ -110,9 +108,8 @@ node test-server/test-tool-annotations.mjs
110
108
  ## Agent Workflow
111
109
 
112
110
  1. Read `sqlite://help` resource (or `view_file` on `src/constants/server-instructions/gotchas.md`).
113
- 2. Read `test-tools.md` for protocol and schema details.
114
- 3. Access `test-group-tools.md` and copy the target group checklist.
115
- 4. Execute via direct MCP tool calls to test logic. Run both happy-path and error-path tests.
116
- 5. Clean up any temporary tables generated during execution.
117
- 6. Report findings using the designated reporting convention.
118
- 7. (Optional) Run stress tests from `test-tools-advanced-1.md` or `test-tools-advanced-2.md`.
111
+ 2. Open the target group prompt from `test-tool-groups/` (e.g., `test-admin-core.md`). Each file is self-contained.
112
+ 3. Execute via direct MCP tool calls to test logic. Run both happy-path and error-path tests.
113
+ 4. Clean up any temporary tables generated during execution.
114
+ 5. Report findings using the designated reporting convention.
115
+ 6. (Optional) Run stress tests from `test-advanced/` folder.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **Agent-optimized navigation reference.** Read this before searching the codebase. Covers directory layout, handler→tool mapping, type/schema locations, error hierarchy, and key constants.
4
4
  >
5
- > Last updated: March 18, 2026
5
+ > Last updated: May 16, 2026
6
6
 
7
7
  ---
8
8
 
@@ -81,6 +81,13 @@ src/
81
81
  │ ├── errors.ts # OAuth-specific error classes
82
82
  │ └── types.ts # OAuth TypeScript types
83
83
 
84
+ ├── audit/ # Audit logging subsystem
85
+ │ ├── types.ts # AuditEntry, AuditConfig, BackupConfig, SnapshotMetadata types
86
+ │ ├── logger.ts # AuditLogger — async-buffered JSONL writer with rotation
87
+ │ ├── interceptor.ts # createAuditInterceptor() — wraps tool handlers with around(), reads OAuth identity from AsyncLocalStorage
88
+ │ ├── backup-manager.ts # BackupManager — pre-mutation DDL snapshots (gzip)
89
+ │ └── index.ts # Barrel
90
+
84
91
  ├── transports/
85
92
  │ └── http/
86
93
  │ ├── transport.ts # HTTP/SSE transport (Streamable HTTP + legacy SSE)
@@ -94,6 +101,7 @@ src/
94
101
  ├── codemode/ # Code Mode sandbox (secure JS execution)
95
102
  │ ├── sandbox.ts # SandboxPool lifecycle manager
96
103
  │ ├── sandbox-factory.ts # Sandbox creation factory
104
+ │ ├── auto-return.ts # Last-expression auto-return transform (IIFE helper)
97
105
  │ ├── worker-sandbox.ts # Worker thread sandbox (MessagePort RPC bridge)
98
106
  │ ├── worker-script.ts # Worker thread entry point (runs inside vm)
99
107
  │ ├── api.ts # sqlite.* API bridge (exposes tools to sandbox)
@@ -113,7 +121,7 @@ src/
113
121
  │ │ ├── schema-manager.ts # Schema cache + metadata (TTL-based)
114
122
  │ │ ├── json-utils.ts # JSON column detection and normalization
115
123
  │ │ ├── types.ts # WASM-specific Zod schemas + TS types
116
- │ │ ├── resources.ts # 8 data MCP resources (schema, tables, indexes, etc.)
124
+ │ │ ├── resources.ts # 10 data MCP resources (schema, tables, indexes, compile_options, etc.)
117
125
  │ │ ├── index.ts # Barrel
118
126
  │ │ ├── output-schemas/ # Zod outputSchema definitions per group (see § below)
119
127
  │ │ ├── prompts/ # 10 MCP prompts (see § below)
@@ -144,6 +152,7 @@ Each file below registers tools with `group` labels. Native-only tools are marke
144
152
  | ----------------- | ----------------------------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------- |
145
153
  | **codemode** | `codemode.ts` | 1 | `sqlite_execute_code` |
146
154
  | **core** | `core/queries.ts` | 2 | `sqlite_read_query`, `sqlite_write_query` |
155
+ | | `core/convenience.ts` | 5 | `sqlite_upsert`, `sqlite_batch_insert`, `sqlite_count`, `sqlite_exists`, `sqlite_truncate` |
147
156
  | | `core/tables.ts` | 4 | `create_table`, `list_tables`, `describe_table`, `drop_table` |
148
157
  | | `core/indexes.ts` | 3 | `get_indexes`, `create_index`, `drop_index` |
149
158
  | **json** | `json-operations/crud.ts` | 3 | `json_insert`, `json_update`, `json_select` |
@@ -155,9 +164,12 @@ Each file below registers tools with `group` labels. Native-only tools are marke
155
164
  | | `text/formatting.ts` | 6 | `text_split`, `text_concat`, `text_replace`, `text_trim`, `text_case`, `text_substring` |
156
165
  | | `text/search.ts` | 3 | `fuzzy_match`, `phonetic_match`, `advanced_search` |
157
166
  | | `text/validate.ts` | 2 | `text_normalize`, `text_validate` |
158
- | **text** (FTS5) | `fts.ts` | 4 | `fts_create`, `fts_search`, `fts_rebuild`, `fts_match_info` |
167
+ | | `text/sentiment.ts` | 1 | `text_sentiment` |
168
+ | **text** (FTS5) | `fts.ts` | 5 | `fts_create`, `fts_search`, `fts_rebuild`, `fts_match_info`, `fts_headline` |
159
169
  | **stats** | `stats/basic.ts` | 7 | `stats_basic`, `stats_count`, `stats_group_by`, `stats_histogram`, `stats_percentile`, `stats_correlation`, `stats_top_n` |
160
170
  | | `stats/advanced.ts` | 6 | `stats_distinct`, `stats_summary`, `stats_frequency`, `stats_outliers`, `stats_regression`, `stats_hypothesis` |
171
+ | | `stats/anomaly-detection.ts` | 2 | `stats_detect_anomalies`, `stats_detect_bloat` |
172
+ | | `stats/schema-risks.ts` | 1 | `stats_detect_schema_risks` |
161
173
  | **vector** | `vector/storage.ts` | 4 | `vector_create_table`, `vector_store`, `vector_batch_store`, `vector_delete` |
162
174
  | | `vector/search.ts` | 2 | `vector_search`, `vector_get` |
163
175
  | | `vector/metadata.ts` | 5 | `vector_count`, `vector_stats`, `vector_dimensions`, `vector_normalize`, `vector_distance` |
@@ -189,12 +201,12 @@ Each file below registers tools with `group` labels. Native-only tools are marke
189
201
 
190
202
  ### Native-Only Handlers (`src/adapters/sqlite-native/tools/`)
191
203
 
192
- | Group | Handler File | Tools | Notes |
193
- | ------------------------ | ------------------------ | ----- | ------------------------------------------------------------------------------------------------------------------ |
194
- | **stats** (window) | `window.ts` | 6 | `window_row_number`, `window_rank`, `window_lag_lead`, `window_running_total`, `window_moving_avg`, `window_ntile` |
195
- | **admin** (transactions) | `transactions.ts` | 7 | `transaction_begin/commit/rollback/savepoint/release/rollback_to/execute` |
196
- | **geo** (SpatiaLite) | `spatialite/tools.ts` | 4 | `spatialite_load/create_table/query/index` |
197
- | | `spatialite/analysis.ts` | 3 | `spatialite_analyze/transform/import` |
204
+ | Group | Handler File | Tools | Notes |
205
+ | -------------------- | ------------------------ | ----- | ------------------------------------------------------------------------------------------------------------------ |
206
+ | **stats** (window) | `window.ts` | 6 | `window_row_number`, `window_rank`, `window_lag_lead`, `window_running_total`, `window_moving_avg`, `window_ntile` |
207
+ | **transactions** | `transactions.ts` | 8 | `transaction_begin/status/commit/rollback/savepoint/release/rollback_to/execute` |
208
+ | **geo** (SpatiaLite) | `spatialite/tools.ts` | 4 | `spatialite_load/create_table/query/index` |
209
+ | | `spatialite/analysis.ts` | 3 | `spatialite_analyze/transform/import` |
198
210
 
199
211
  ### Utility Files (no tools, shared helpers)
200
212
 
@@ -241,7 +253,7 @@ Zod schemas that define the `outputSchema` for MCP tool responses. All output sc
241
253
  | `introspection.ts` | Introspection group output schemas (9 schemas: DependencyGraph, TopologicalSort, CascadeSimulator, SchemaSnapshot, ConstraintAnalysis, MigrationRisks, StorageAnalysis, IndexAudit, QueryPlan) |
242
254
  | `migration.ts` | Migration group output schemas (7 schemas: MigrationInit, MigrationRecord, MigrationApply, MigrationRollback, MigrationHistory, MigrationStatus + MigrationRecordEntry) |
243
255
  | `virtual.ts` | Virtual table output schemas (7 schemas: ListVirtualTables, VirtualTableInfo, DropVirtualTable, CreateCsvTable, AnalyzeCsvSchema, CreateRtreeTable, CreateSeriesTable) |
244
- | `native.ts` | Native-only output schemas (transactions — 7 schemas, window functions — 6 schemas) |
256
+ | `native.ts` | Native-only output schemas (transactions — 8 schemas, window functions — 6 schemas) |
245
257
  | `spatialite.ts` | SpatiaLite output schemas (7 tools — native only) |
246
258
  | `server.ts` | Type aliases for core output schemas (built-in tools use `content` pattern, not `structuredContent`) |
247
259
  | `index.ts` | Barrel re-export |
@@ -269,15 +281,17 @@ The `DbMcpError` constructor auto-refines generic codes (`DB_QUERY_FAILED`, `DB_
269
281
 
270
282
  ```
271
283
  DbMcpError (base.ts)
272
- ├── ValidationError code: VALIDATION_ERROR category: validation
273
- ├── ConnectionError code: CONNECTION_ERROR category: connection recoverable: true
274
- ├── QueryError code: QUERY_ERROR category: query accepts: sql option
275
- ├── PermissionError code: PERMISSION_ERROR category: permission
276
- ├── ResourceNotFoundError code: RESOURCE_NOT_FOUND category: resource accepts: resourceType, resourceName
277
- ├── ConfigurationError code: CONFIG_ERROR category: config
278
- ├── InternalError code: INTERNAL_ERROR category: internal
279
- ├── AuthenticationError code: AUTHENTICATION_ERROR category: authentication
280
- └── AuthorizationError code: AUTHORIZATION_ERROR category: authorization
284
+ ├── ValidationError code: VALIDATION_ERROR category: validation
285
+ ├── ConnectionError code: CONNECTION_ERROR category: connection recoverable: true
286
+ ├── QueryError code: QUERY_ERROR category: query accepts: sql option
287
+ ├── PermissionError code: PERMISSION_ERROR category: permission
288
+ ├── ResourceNotFoundError code: RESOURCE_NOT_FOUND category: resource accepts: resourceType, resourceName
289
+ ├── ConfigurationError code: CONFIG_ERROR category: config
290
+ ├── InternalError code: INTERNAL_ERROR category: internal
291
+ ├── AuthenticationError code: AUTHENTICATION_ERROR category: authentication
292
+ ├── AuthorizationError code: AUTHORIZATION_ERROR category: authorization
293
+ ├── TransactionError code: TRANSACTION_ERROR category: query recoverable: true
294
+ └── ExtensionNotAvailableError code: EXTENSION_MISSING category: config accepts: extensionName
281
295
  ```
282
296
 
283
297
  **Usage pattern** — all tool handlers:
@@ -308,14 +322,14 @@ catch (error) {
308
322
 
309
323
  ## Key Constants & Config
310
324
 
311
- | What | Where | Notes |
312
- | ---------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------------------------------- |
313
- | Server instructions (agent prompt) | `src/constants/server-instructions.ts` | Generated: slim `INSTRUCTIONS` (~680 chars) + `HELP_CONTENT` map. Source: `server-instructions/*.md` |
314
- | Tool group arrays | `src/filtering/tool-constants.ts` | `TOOL_GROUPS` map, `META_GROUPS` shortcuts |
315
- | Tool filter logic | `src/filtering/tool-filter.ts` | `ToolFilter` class |
316
- | JSON-RPC constants | `src/codemode/api-constants.ts` | Error codes, method names for sandbox RPC |
317
- | Logger error codes | `src/utils/logger/error-codes.ts` | Module-prefixed codes (`DB_`, `AUTH_`, etc.) |
318
- | Version SSoT | `src/version.ts` | Reads from `package.json` at build time |
325
+ | What | Where | Notes |
326
+ | ---------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
327
+ | Server instructions (agent prompt) | `src/constants/server-instructions.ts` | Generated: slim `INSTRUCTIONS` (~680 chars) + `HELP_CONTENT` map. Source: `server-instructions/*.md` |
328
+ | Tool group arrays | `src/filtering/tool-constants.ts` | `TOOL_GROUPS` map, `META_GROUPS` shortcuts |
329
+ | Tool filter logic | `src/filtering/tool-filter.ts` | `ToolFilter` class |
330
+ | JSON-RPC constants | `src/codemode/api-constants.ts` | Error codes, method names for sandbox RPC |
331
+ | Logger error codes | `src/utils/logger/error-codes.ts` | Module-prefixed codes (`DB_`, `AUTH_`, etc.) |
332
+ | Version SSoT | `src/version.ts` | Reads from `package.json` at runtime. Both adapters `import { VERSION }` — **never hardcode version strings** |
319
333
 
320
334
  ---
321
335
 
@@ -356,13 +370,11 @@ catch (error) {
356
370
  | `test-server/README.md` | Agent testing orchestration doc |
357
371
  | `test-server/test-database.sql` | Seed DDL+DML (10 tables, ~400 rows) |
358
372
  | `test-server/reset-database.ps1` | Reset script — drops + re-seeds `test.db` |
359
- | `test-server/tool-reference.md` | Complete 139/115 tool inventory with descriptions |
373
+ | `test-server/tool-reference.md` | Complete 151/125 tool inventory with descriptions |
360
374
  | `test-server/test-preflight.md` | Pre-test verification checklist |
361
- | `test-server/test-tools.md` | Entry-point protocol (schema ref, reporting format) |
362
- | `test-server/test-group-tools.md` | Per-group deterministic checklists |
363
- | `test-server/test-tools-advanced-1.md` | Advanced stress test prompts (part 1) |
364
- | `test-server/test-tools-advanced-2.md` | Advanced stress test prompts (part 2) |
365
- | `test-server/test-tools-codemode.md` | Code mode specific test prompts |
375
+ | `test-server/test-tool-groups/` | 10 self-contained test prompts one per tool group. Direct calls only. |
376
+ | `test-server/test-codemode/` | 10 self-contained test prompts — one per tool group. Code Mode execution only. |
377
+ | `test-server/test-advanced/` | 10 self-contained advanced stress test prompts one per tool group. |
366
378
  | `test-server/test-resources.md` | MCP resource verification prompts |
367
379
  | `test-server/test-prompts.md` | MCP prompt verification prompts |
368
380
  | `test-server/test-agent-experience.md` | 20 open-ended scenarios — validates help resource sufficiency |