db-mcp 1.0.2 → 1.1.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 (241) hide show
  1. package/.gitattributes +2 -0
  2. package/LICENSE +1 -1
  3. package/README.md +244 -518
  4. package/dist/chunk-4IA3DB5C.js +135 -0
  5. package/dist/chunk-AOUL5SHS.js +930 -0
  6. package/dist/chunk-DWJXQEFA.js +13759 -0
  7. package/dist/chunk-DZQLDEQS.js +879 -0
  8. package/dist/chunk-S5IDDSSB.js +74 -0
  9. package/dist/chunk-Z2GFQU3G.js +363 -0
  10. package/dist/cli.d.ts +0 -7
  11. package/dist/cli.js +227 -183
  12. package/dist/http-VSB7DBJR.js +1541 -0
  13. package/dist/index.d.ts +842 -10
  14. package/dist/index.js +5 -17
  15. package/dist/sqlite-VHBA4ABV.js +600 -0
  16. package/dist/sqlite-native-D2LH5ZT7.js +2498 -0
  17. package/dist/worker-script.d.ts +2 -0
  18. package/dist/worker-script.js +126 -0
  19. package/package.json +26 -16
  20. package/playwright.config.ts +101 -0
  21. package/scripts/generate-server-instructions.ts +111 -0
  22. package/server.json +5 -6
  23. package/test-server/README.md +118 -0
  24. package/test-server/code-map.md +409 -0
  25. package/test-server/fixtures/sample.csv +6 -0
  26. package/test-server/reset-database.ps1 +373 -0
  27. package/test-server/sample.csv +11 -0
  28. package/test-server/test-agent-experience.md +243 -0
  29. package/test-server/test-database.sql +388 -0
  30. package/test-server/test-group-tools.md +861 -0
  31. package/test-server/test-help-resources.mjs +238 -0
  32. package/test-server/test-preflight.md +53 -0
  33. package/test-server/test-prompts.md +354 -0
  34. package/test-server/test-resources.md +245 -0
  35. package/test-server/test-tool-annotations.mjs +157 -0
  36. package/test-server/test-tools-advanced-1.md +517 -0
  37. package/test-server/test-tools-advanced-2.md +487 -0
  38. package/test-server/test-tools-codemode.md +629 -0
  39. package/test-server/test-tools.md +176 -0
  40. package/test-server/tool-reference.md +236 -0
  41. package/tsconfig.test.json +9 -0
  42. package/dist/adapters/DatabaseAdapter.d.ts +0 -141
  43. package/dist/adapters/DatabaseAdapter.d.ts.map +0 -1
  44. package/dist/adapters/DatabaseAdapter.js +0 -131
  45. package/dist/adapters/DatabaseAdapter.js.map +0 -1
  46. package/dist/adapters/sqlite/SchemaManager.d.ts +0 -58
  47. package/dist/adapters/sqlite/SchemaManager.d.ts.map +0 -1
  48. package/dist/adapters/sqlite/SchemaManager.js +0 -187
  49. package/dist/adapters/sqlite/SchemaManager.js.map +0 -1
  50. package/dist/adapters/sqlite/SqliteAdapter.d.ts +0 -161
  51. package/dist/adapters/sqlite/SqliteAdapter.d.ts.map +0 -1
  52. package/dist/adapters/sqlite/SqliteAdapter.js +0 -741
  53. package/dist/adapters/sqlite/SqliteAdapter.js.map +0 -1
  54. package/dist/adapters/sqlite/index.d.ts +0 -9
  55. package/dist/adapters/sqlite/index.d.ts.map +0 -1
  56. package/dist/adapters/sqlite/index.js +0 -8
  57. package/dist/adapters/sqlite/index.js.map +0 -1
  58. package/dist/adapters/sqlite/json-utils.d.ts +0 -100
  59. package/dist/adapters/sqlite/json-utils.d.ts.map +0 -1
  60. package/dist/adapters/sqlite/json-utils.js +0 -274
  61. package/dist/adapters/sqlite/json-utils.js.map +0 -1
  62. package/dist/adapters/sqlite/output-schemas.d.ts +0 -1187
  63. package/dist/adapters/sqlite/output-schemas.d.ts.map +0 -1
  64. package/dist/adapters/sqlite/output-schemas.js +0 -1337
  65. package/dist/adapters/sqlite/output-schemas.js.map +0 -1
  66. package/dist/adapters/sqlite/prompts.d.ts +0 -13
  67. package/dist/adapters/sqlite/prompts.d.ts.map +0 -1
  68. package/dist/adapters/sqlite/prompts.js +0 -605
  69. package/dist/adapters/sqlite/prompts.js.map +0 -1
  70. package/dist/adapters/sqlite/resources.d.ts +0 -13
  71. package/dist/adapters/sqlite/resources.d.ts.map +0 -1
  72. package/dist/adapters/sqlite/resources.js +0 -251
  73. package/dist/adapters/sqlite/resources.js.map +0 -1
  74. package/dist/adapters/sqlite/tools/admin.d.ts +0 -14
  75. package/dist/adapters/sqlite/tools/admin.d.ts.map +0 -1
  76. package/dist/adapters/sqlite/tools/admin.js +0 -788
  77. package/dist/adapters/sqlite/tools/admin.js.map +0 -1
  78. package/dist/adapters/sqlite/tools/core.d.ts +0 -25
  79. package/dist/adapters/sqlite/tools/core.d.ts.map +0 -1
  80. package/dist/adapters/sqlite/tools/core.js +0 -359
  81. package/dist/adapters/sqlite/tools/core.js.map +0 -1
  82. package/dist/adapters/sqlite/tools/fts.d.ts +0 -13
  83. package/dist/adapters/sqlite/tools/fts.d.ts.map +0 -1
  84. package/dist/adapters/sqlite/tools/fts.js +0 -347
  85. package/dist/adapters/sqlite/tools/fts.js.map +0 -1
  86. package/dist/adapters/sqlite/tools/geo.d.ts +0 -14
  87. package/dist/adapters/sqlite/tools/geo.d.ts.map +0 -1
  88. package/dist/adapters/sqlite/tools/geo.js +0 -252
  89. package/dist/adapters/sqlite/tools/geo.js.map +0 -1
  90. package/dist/adapters/sqlite/tools/index.d.ts +0 -30
  91. package/dist/adapters/sqlite/tools/index.d.ts.map +0 -1
  92. package/dist/adapters/sqlite/tools/index.js +0 -61
  93. package/dist/adapters/sqlite/tools/index.js.map +0 -1
  94. package/dist/adapters/sqlite/tools/json-helpers.d.ts +0 -14
  95. package/dist/adapters/sqlite/tools/json-helpers.d.ts.map +0 -1
  96. package/dist/adapters/sqlite/tools/json-helpers.js +0 -477
  97. package/dist/adapters/sqlite/tools/json-helpers.js.map +0 -1
  98. package/dist/adapters/sqlite/tools/json-operations.d.ts +0 -14
  99. package/dist/adapters/sqlite/tools/json-operations.d.ts.map +0 -1
  100. package/dist/adapters/sqlite/tools/json-operations.js +0 -839
  101. package/dist/adapters/sqlite/tools/json-operations.js.map +0 -1
  102. package/dist/adapters/sqlite/tools/stats.d.ts +0 -15
  103. package/dist/adapters/sqlite/tools/stats.d.ts.map +0 -1
  104. package/dist/adapters/sqlite/tools/stats.js +0 -1219
  105. package/dist/adapters/sqlite/tools/stats.js.map +0 -1
  106. package/dist/adapters/sqlite/tools/text.d.ts +0 -14
  107. package/dist/adapters/sqlite/tools/text.d.ts.map +0 -1
  108. package/dist/adapters/sqlite/tools/text.js +0 -1141
  109. package/dist/adapters/sqlite/tools/text.js.map +0 -1
  110. package/dist/adapters/sqlite/tools/vector.d.ts +0 -14
  111. package/dist/adapters/sqlite/tools/vector.d.ts.map +0 -1
  112. package/dist/adapters/sqlite/tools/vector.js +0 -613
  113. package/dist/adapters/sqlite/tools/vector.js.map +0 -1
  114. package/dist/adapters/sqlite/tools/virtual.d.ts +0 -13
  115. package/dist/adapters/sqlite/tools/virtual.d.ts.map +0 -1
  116. package/dist/adapters/sqlite/tools/virtual.js +0 -930
  117. package/dist/adapters/sqlite/tools/virtual.js.map +0 -1
  118. package/dist/adapters/sqlite/types.d.ts +0 -207
  119. package/dist/adapters/sqlite/types.d.ts.map +0 -1
  120. package/dist/adapters/sqlite/types.js +0 -186
  121. package/dist/adapters/sqlite/types.js.map +0 -1
  122. package/dist/adapters/sqlite-native/NativeSqliteAdapter.d.ts +0 -163
  123. package/dist/adapters/sqlite-native/NativeSqliteAdapter.d.ts.map +0 -1
  124. package/dist/adapters/sqlite-native/NativeSqliteAdapter.js +0 -748
  125. package/dist/adapters/sqlite-native/NativeSqliteAdapter.js.map +0 -1
  126. package/dist/adapters/sqlite-native/index.d.ts +0 -11
  127. package/dist/adapters/sqlite-native/index.d.ts.map +0 -1
  128. package/dist/adapters/sqlite-native/index.js +0 -11
  129. package/dist/adapters/sqlite-native/index.js.map +0 -1
  130. package/dist/adapters/sqlite-native/tools/spatialite.d.ts +0 -19
  131. package/dist/adapters/sqlite-native/tools/spatialite.d.ts.map +0 -1
  132. package/dist/adapters/sqlite-native/tools/spatialite.js +0 -628
  133. package/dist/adapters/sqlite-native/tools/spatialite.js.map +0 -1
  134. package/dist/adapters/sqlite-native/tools/transactions.d.ts +0 -12
  135. package/dist/adapters/sqlite-native/tools/transactions.d.ts.map +0 -1
  136. package/dist/adapters/sqlite-native/tools/transactions.js +0 -255
  137. package/dist/adapters/sqlite-native/tools/transactions.js.map +0 -1
  138. package/dist/adapters/sqlite-native/tools/window.d.ts +0 -12
  139. package/dist/adapters/sqlite-native/tools/window.d.ts.map +0 -1
  140. package/dist/adapters/sqlite-native/tools/window.js +0 -370
  141. package/dist/adapters/sqlite-native/tools/window.js.map +0 -1
  142. package/dist/auth/AuthorizationServerDiscovery.d.ts +0 -90
  143. package/dist/auth/AuthorizationServerDiscovery.d.ts.map +0 -1
  144. package/dist/auth/AuthorizationServerDiscovery.js +0 -204
  145. package/dist/auth/AuthorizationServerDiscovery.js.map +0 -1
  146. package/dist/auth/OAuthResourceServer.d.ts +0 -65
  147. package/dist/auth/OAuthResourceServer.d.ts.map +0 -1
  148. package/dist/auth/OAuthResourceServer.js +0 -121
  149. package/dist/auth/OAuthResourceServer.js.map +0 -1
  150. package/dist/auth/TokenValidator.d.ts +0 -60
  151. package/dist/auth/TokenValidator.d.ts.map +0 -1
  152. package/dist/auth/TokenValidator.js +0 -235
  153. package/dist/auth/TokenValidator.js.map +0 -1
  154. package/dist/auth/errors.d.ts +0 -74
  155. package/dist/auth/errors.d.ts.map +0 -1
  156. package/dist/auth/errors.js +0 -133
  157. package/dist/auth/errors.js.map +0 -1
  158. package/dist/auth/index.d.ts +0 -13
  159. package/dist/auth/index.d.ts.map +0 -1
  160. package/dist/auth/index.js +0 -15
  161. package/dist/auth/index.js.map +0 -1
  162. package/dist/auth/middleware.d.ts +0 -81
  163. package/dist/auth/middleware.d.ts.map +0 -1
  164. package/dist/auth/middleware.js +0 -291
  165. package/dist/auth/middleware.js.map +0 -1
  166. package/dist/auth/scopes.d.ts +0 -136
  167. package/dist/auth/scopes.d.ts.map +0 -1
  168. package/dist/auth/scopes.js +0 -349
  169. package/dist/auth/scopes.js.map +0 -1
  170. package/dist/auth/types.d.ts +0 -257
  171. package/dist/auth/types.d.ts.map +0 -1
  172. package/dist/auth/types.js +0 -8
  173. package/dist/auth/types.js.map +0 -1
  174. package/dist/cli.d.ts.map +0 -1
  175. package/dist/cli.js.map +0 -1
  176. package/dist/constants/ServerInstructions.d.ts +0 -45
  177. package/dist/constants/ServerInstructions.d.ts.map +0 -1
  178. package/dist/constants/ServerInstructions.js +0 -356
  179. package/dist/constants/ServerInstructions.js.map +0 -1
  180. package/dist/filtering/ToolConstants.d.ts +0 -34
  181. package/dist/filtering/ToolConstants.d.ts.map +0 -1
  182. package/dist/filtering/ToolConstants.js +0 -174
  183. package/dist/filtering/ToolConstants.js.map +0 -1
  184. package/dist/filtering/ToolFilter.d.ts +0 -82
  185. package/dist/filtering/ToolFilter.d.ts.map +0 -1
  186. package/dist/filtering/ToolFilter.js +0 -296
  187. package/dist/filtering/ToolFilter.js.map +0 -1
  188. package/dist/index.d.ts.map +0 -1
  189. package/dist/index.js.map +0 -1
  190. package/dist/server/McpServer.d.ts +0 -61
  191. package/dist/server/McpServer.d.ts.map +0 -1
  192. package/dist/server/McpServer.js +0 -270
  193. package/dist/server/McpServer.js.map +0 -1
  194. package/dist/transports/http.d.ts +0 -134
  195. package/dist/transports/http.d.ts.map +0 -1
  196. package/dist/transports/http.js +0 -516
  197. package/dist/transports/http.js.map +0 -1
  198. package/dist/transports/index.d.ts +0 -5
  199. package/dist/transports/index.d.ts.map +0 -1
  200. package/dist/transports/index.js +0 -5
  201. package/dist/transports/index.js.map +0 -1
  202. package/dist/types/index.d.ts +0 -380
  203. package/dist/types/index.d.ts.map +0 -1
  204. package/dist/types/index.js +0 -68
  205. package/dist/types/index.js.map +0 -1
  206. package/dist/utils/annotations.d.ts +0 -44
  207. package/dist/utils/annotations.d.ts.map +0 -1
  208. package/dist/utils/annotations.js +0 -77
  209. package/dist/utils/annotations.js.map +0 -1
  210. package/dist/utils/errors.d.ts +0 -155
  211. package/dist/utils/errors.d.ts.map +0 -1
  212. package/dist/utils/errors.js +0 -329
  213. package/dist/utils/errors.js.map +0 -1
  214. package/dist/utils/identifiers.d.ts +0 -121
  215. package/dist/utils/identifiers.d.ts.map +0 -1
  216. package/dist/utils/identifiers.js +0 -319
  217. package/dist/utils/identifiers.js.map +0 -1
  218. package/dist/utils/index.d.ts +0 -7
  219. package/dist/utils/index.d.ts.map +0 -1
  220. package/dist/utils/index.js +0 -7
  221. package/dist/utils/index.js.map +0 -1
  222. package/dist/utils/insightsManager.d.ts +0 -39
  223. package/dist/utils/insightsManager.d.ts.map +0 -1
  224. package/dist/utils/insightsManager.js +0 -63
  225. package/dist/utils/insightsManager.js.map +0 -1
  226. package/dist/utils/logger.d.ts +0 -189
  227. package/dist/utils/logger.d.ts.map +0 -1
  228. package/dist/utils/logger.js +0 -394
  229. package/dist/utils/logger.js.map +0 -1
  230. package/dist/utils/progress-utils.d.ts +0 -54
  231. package/dist/utils/progress-utils.d.ts.map +0 -1
  232. package/dist/utils/progress-utils.js +0 -74
  233. package/dist/utils/progress-utils.js.map +0 -1
  234. package/dist/utils/resourceAnnotations.d.ts +0 -36
  235. package/dist/utils/resourceAnnotations.d.ts.map +0 -1
  236. package/dist/utils/resourceAnnotations.js +0 -57
  237. package/dist/utils/resourceAnnotations.js.map +0 -1
  238. package/dist/utils/where-clause.d.ts +0 -41
  239. package/dist/utils/where-clause.d.ts.map +0 -1
  240. package/dist/utils/where-clause.js +0 -116
  241. package/dist/utils/where-clause.js.map +0 -1
@@ -0,0 +1,879 @@
1
+ import { READ_ONLY, SERVER_ICONS } from './chunk-S5IDDSSB.js';
2
+ import { parseToolFilter, getToolFilterFromEnv, logger, getFilterSummary, DbMcpError } from './chunk-AOUL5SHS.js';
3
+ import { createRequire } from 'module';
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
+
7
+ var _require = createRequire(import.meta.url);
8
+ var pkg = _require("../package.json");
9
+ var VERSION = pkg.version;
10
+ var NAME = pkg.name;
11
+
12
+ // src/constants/server-instructions.ts
13
+ var INSTRUCTIONS = `# db-mcp (SQLite MCP Server)
14
+
15
+ ## Quick Access
16
+
17
+ | Purpose | Action |
18
+ | --------------- | -------------------------- |
19
+ | Health check | \`server_health\` tool |
20
+ | Server info | \`server_info\` tool |
21
+ | Database schema | \`sqlite://schema\` resource |
22
+ | Tool help | \`sqlite://help\` resource |
23
+
24
+ ## Built-in Tools
25
+
26
+ \`server_info\`, \`server_health\`, \`list_adapters\` \u2014 always available.
27
+
28
+ ## Help Resources
29
+
30
+ Read \`sqlite://help\` for gotchas and critical usage patterns.
31
+ Read \`sqlite://help/{group}\` for group-specific tool reference (json, text, stats, vector, geo, admin, introspection, migration).
32
+ Only help resources for your enabled tool groups are registered.`;
33
+ var HELP_CONTENT = /* @__PURE__ */ new Map([
34
+ [
35
+ "admin",
36
+ `# db-mcp Help \u2014 Database Administration (33 Native / 26 WASM)
37
+
38
+ ## Transactions (7 tools, Native only)
39
+
40
+ \`\`\`javascript
41
+ // Atomic multi-statement execution (preferred for simple cases)
42
+ sqlite_transaction_execute({ statements: ["UPDATE a SET x=1", "UPDATE b SET y=2"] });
43
+
44
+ // Manual transaction control
45
+ sqlite_transaction_begin({ mode: "immediate" }); // or "deferred", "exclusive"
46
+ sqlite_transaction_savepoint({ name: "checkpoint" });
47
+ sqlite_transaction_rollback_to({ name: "checkpoint" });
48
+ sqlite_transaction_release({ name: "checkpoint" });
49
+ sqlite_transaction_commit();
50
+ sqlite_transaction_rollback();
51
+ \`\`\`
52
+
53
+ ## Maintenance
54
+
55
+ \`\`\`javascript
56
+ sqlite_integrity_check({ maxErrors: 10 }); // check for corruption
57
+ sqlite_optimize({ analyze: true, reindex: true }); // optimize performance
58
+ sqlite_vacuum(); // reclaim space
59
+ sqlite_analyze({ table: "orders" }); // update statistics for query planner
60
+ sqlite_dbstat({ summarize: true }); // storage stats (\u26A0\uFE0F summarize native-only; WASM returns counts only)
61
+ \`\`\`
62
+
63
+ ## Backup/Restore (Native only)
64
+
65
+ \`\`\`javascript
66
+ sqlite_backup({ targetPath: "/path/to/backup.db" });
67
+ sqlite_verify_backup({ backupPath: "/path/to/backup.db" }); // check integrity without restoring
68
+ sqlite_restore({ sourcePath: "/path/to/backup.db" }); // \u26A0\uFE0F WARNING: Replaces current database
69
+ \`\`\`
70
+
71
+ ## PRAGMA
72
+
73
+ \`\`\`javascript
74
+ sqlite_pragma_settings({ pragma: "journal_mode" }); // get value
75
+ sqlite_pragma_settings({ pragma: "cache_size", value: 10000 }); // set value
76
+ sqlite_pragma_table_info({ table: "users" }); // column details
77
+ sqlite_pragma_compile_options({ filter: "FTS" }); // \u26A0\uFE0F WASM may show FTS3, not FTS5
78
+ sqlite_pragma_database_list(); // list attached databases
79
+ sqlite_pragma_optimize(); // run PRAGMA optimize
80
+ \`\`\`
81
+
82
+ ## Index & Stats
83
+
84
+ - \`sqlite_index_stats({ table: "orders" })\` \u2014 stats for explicit indexes
85
+
86
+ ## Views
87
+
88
+ \`\`\`javascript
89
+ sqlite_create_view({ viewName: "active_orders", selectQuery: "SELECT * FROM orders WHERE status = 'active'" });
90
+ sqlite_create_view({ viewName: "v", selectQuery: "...", replace: true }); // CREATE OR REPLACE
91
+ sqlite_list_views(); // list all views
92
+ sqlite_drop_view({ viewName: "active_orders" });
93
+ \`\`\`
94
+
95
+ ## Virtual Tables
96
+
97
+ \`\`\`javascript
98
+ sqlite_list_virtual_tables(); // list FTS5, R-Tree, CSV tables
99
+ sqlite_virtual_table_info({ tableName: "articles_fts" }); // module and column info
100
+ sqlite_drop_virtual_table({ tableName: "old_fts", ifExists: true });
101
+ \`\`\`
102
+
103
+ ## Generate Series (pure JS)
104
+
105
+ \`\`\`javascript
106
+ sqlite_generate_series({ start: 1, stop: 100, step: 5 }); // returns array of values
107
+ // \u26A0\uFE0F Creates a REGULAR table (not virtual) \u2014 use sqlite_drop_table to remove
108
+ sqlite_create_series_table({ tableName: "numbers", start: 1, stop: 1000 });
109
+ \`\`\`
110
+
111
+ ## R-Tree (Native only)
112
+
113
+ \`\`\`javascript
114
+ sqlite_create_rtree_table({ tableName: "locations_idx", dimensions: 2 }); // 2D: minX, maxX, minY, maxY
115
+ // Returns graceful error with wasmLimitation: true in WASM
116
+ \`\`\`
117
+
118
+ ## CSV Virtual Tables (Native only)
119
+
120
+ \u26A0\uFE0F Requires ABSOLUTE file paths
121
+
122
+ \`\`\`javascript
123
+ sqlite_analyze_csv_schema({ filePath: "/absolute/path/to/data.csv" }); // analyze CSV structure
124
+ sqlite_create_csv_table({ tableName: "csv_data", filePath: "/absolute/path/to/data.csv" });
125
+ \`\`\`
126
+
127
+ ## Business Insights
128
+
129
+ \`\`\`javascript
130
+ sqlite_append_insight({ insight: "Q4 revenue increased 23% YoY" }); // add to memo://insights
131
+ \`\`\``
132
+ ],
133
+ [
134
+ "geo",
135
+ `# db-mcp Help \u2014 Geospatial Operations (4 basic + 7 SpatiaLite)
136
+
137
+ ## Basic Geo (always available \u2014 Haversine formula)
138
+
139
+ \`\`\`javascript
140
+ sqlite_geo_distance({ lat1: 40.7128, lon1: -74.006, lat2: 34.0522, lon2: -118.2437 }); // returns km
141
+ sqlite_geo_bounding_box({
142
+ table: "stores", latColumn: "lat", lonColumn: "lon",
143
+ minLat: 40, maxLat: 41, minLon: -75, maxLon: -73,
144
+ });
145
+ sqlite_geo_nearby({
146
+ table: "stores", latColumn: "lat", lonColumn: "lon",
147
+ centerLat: 40.7, centerLon: -74, radius: 10, unit: "km",
148
+ });
149
+ sqlite_geo_cluster({ table: "customers", latColumn: "lat", lonColumn: "lon", gridSize: 0.1 });
150
+ \`\`\`
151
+
152
+ ## SpatiaLite (7 tools, Native only)
153
+
154
+ \`\`\`javascript
155
+ // Load extension first
156
+ sqlite_spatialite_load(); // \u26A0\uFE0F Required before using other spatial tools
157
+
158
+ // Create spatial table with geometry column
159
+ sqlite_spatialite_create_table({ tableName: "places", geometryColumn: "geom", geometryType: "POINT", srid: 4326 });
160
+
161
+ // Import data (WKT or GeoJSON)
162
+ sqlite_spatialite_import({ tableName: "places", format: "wkt", data: "POINT(-73.99 40.75)", additionalData: { name: "NYC" } });
163
+ sqlite_spatialite_import({ tableName: "places", format: "geojson", data: '{"type":"Point","coordinates":[-73.99,40.75]}' });
164
+
165
+ // Spatial queries (SELECT only)
166
+ sqlite_spatialite_query({ query: "SELECT name, AsText(geom) FROM places WHERE ST_Within(geom, ...)" });
167
+
168
+ // Spatial analysis
169
+ // analysisType: "spatial_extent" | "point_in_polygon" | "nearest_neighbor" | "distance_matrix"
170
+ // \u26A0\uFE0F nearest_neighbor/distance_matrix return CARTESIAN distance (degrees), not geodetic (km/miles)
171
+ // For same source/target table, use excludeSelf: true to avoid self-matches
172
+ sqlite_spatialite_analyze({ analysisType: "spatial_extent", sourceTable: "places", geometryColumn: "geom" });
173
+ sqlite_spatialite_analyze({ analysisType: "nearest_neighbor", sourceTable: "pts", targetTable: "pts", excludeSelf: true });
174
+
175
+ // Geometry transforms
176
+ // buffer: 'distance' = radius; simplify: 'distance' = tolerance (0.0001 for lat/lon)
177
+ // \u26A0\uFE0F Buffer auto-simplifies output by default (tolerance=0.0001). Use simplifyTolerance: 0 to disable
178
+ sqlite_spatialite_transform({ operation: "buffer", geometry1: "POINT(-73.99 40.75)", distance: 0.01 });
179
+ sqlite_spatialite_transform({ operation: "simplify", geometry1: "...", distance: 0.001 });
180
+
181
+ // Spatial index (R-Tree)
182
+ sqlite_spatialite_index({ tableName: "places", geometryColumn: "geom", action: "create" }); // create, drop, or check
183
+ \`\`\``
184
+ ],
185
+ [
186
+ "gotchas",
187
+ `# db-mcp Help \u2014 Gotchas & Code Mode
188
+
189
+ ## \u26A0\uFE0F Critical Gotchas
190
+
191
+ 1. **sqlite_write_query**: \u26D4 Only INSERT/UPDATE/DELETE \u2014 use \`sqlite_read_query\` for SELECT
192
+ 2. **Regex patterns**: Double-escape backslashes (\`\\\\\\\\\`) when passing through JSON/MCP
193
+ 3. **FTS5 virtual tables**: \`*_fts\` and shadow tables \`*_fts_*\` are hidden from \`sqlite_list_tables\` for cleaner output
194
+ 4. **FTS5 boolean logic**: Uses AND by default \u2014 \`"machine learning"\` = rows with BOTH words. Use OR explicitly: \`"machine OR learning"\`
195
+ 5. **FTS5 rebuild**: After \`sqlite_fts_create\`, must call \`sqlite_fts_rebuild\` to populate index with existing data
196
+ 6. **json_each row multiplication**: Expands arrays to rows \u2014 use \`limit\` param for large arrays
197
+ 7. **json_group_object without groupByColumn**: Each row creates a key-value pair; duplicate keys result if key values aren't unique
198
+ 8. **allowExpressions**: For column extraction ONLY (e.g., \`json_extract\`), NOT aggregate functions \u2014 use \`aggregateFunction\` param instead
199
+ 9. **sqlite_json_normalize_column**: Defaults to \`preserve\` (maintains original format); use \`outputFormat: 'text'\` to force text
200
+ 10. **Fuzzy matching tokenization**: Matches WORD TOKENS by default \u2014 \`"laptop"\` matches \`"Laptop Pro 15"\` (distance 0 on first token). Use \`tokenize: false\` for full-string matching
201
+ 11. **SpatiaLite distances**: \`nearest_neighbor\`/\`distance_matrix\` return CARTESIAN distance (degrees), not geodetic (km/miles)
202
+ 12. **SpatiaLite buffer**: Auto-simplifies output by default (tolerance=0.0001). Use \`simplifyTolerance: 0\` to disable
203
+ 13. **sqlite_stats_top_n**: Auto-excludes long-content columns (description, body, notes, etc.) when \`selectColumns\` is omitted. Use \`selectColumns\` to override
204
+ 14. **CSV virtual tables**: Require ABSOLUTE file paths
205
+ 15. **sqlite_create_series_table**: Creates a REGULAR table (not virtual) \u2014 use \`sqlite_drop_table\` to remove
206
+ 16. **sqlite_dbstat**: \`summarize\` only works in native; WASM returns counts only
207
+ 17. **PRAGMA compile options**: WASM may show FTS3, not FTS5
208
+
209
+ ## WASM vs Native
210
+
211
+ | Feature | Native | WASM | Fallback |
212
+ | ------------------------------------------------- | --------------------- | ----------- | ---------------- |
213
+ | FTS5 full-text search | \u2705 | \u274C | None |
214
+ | Transactions (7 tools) | \u2705 | \u274C | None |
215
+ | Window functions (6 tools in stats group) | \u2705 | \u274C | None |
216
+ | SpatiaLite GIS (7 tools; 4 basic geo always work) | \u2705 | \u274C | None |
217
+ | Backup/Restore (3 tools) | \u2705 | \u274C | Graceful error |
218
+ | R-Tree spatial indexing | \u2705 | \u274C | Graceful error |
219
+ | CSV virtual tables | \u2705 | \u274C | Graceful error |
220
+ | generate_series | JS fallback | JS fallback | \u2014 |
221
+ | dbstat | \u2705 native (per-table) | \u274C | JS (counts only) |
222
+ | soundex() | \u2705 native | \u274C | JS |
223
+
224
+ ## Code Mode (1 tool)
225
+
226
+ | Tool | Description |
227
+ | --------------------- | ----------------------------------------------------------------- |
228
+ | \`sqlite_execute_code\` | Execute JavaScript in a sandboxed environment with \`sqlite.*\` API |
229
+
230
+ **Usage**: \`sqlite_execute_code({ code: "const tables = await sqlite.core.listTables(); return tables;" })\`
231
+ **Discover**: \`sqlite.help()\` for all groups, \`sqlite.<group>.help()\` for methods.
232
+ **Groups**: \`sqlite.core\`, \`sqlite.json\`, \`sqlite.text\`, \`sqlite.stats\`, \`sqlite.vector\`, \`sqlite.admin\`, \`sqlite.geo\`, \`sqlite.introspection\`, \`sqlite.migration\`
233
+
234
+ ## Code Mode API Mapping
235
+
236
+ \`sqlite_group_action\` \u2192 \`sqlite.group.action()\` (group prefixes dropped: \`sqlite_json_insert\` \u2192 \`sqlite.json.insert()\`)
237
+
238
+ **Positional args work**: \`sqlite.core.readQuery("SELECT...")\`, \`sqlite.json.insert("docs", "data", {...})\`
239
+
240
+ **Discovery**: \`sqlite.help()\` returns all groups and methods. \`sqlite.core.help()\`, \`sqlite.json.help()\` for group-specific methods.`
241
+ ],
242
+ [
243
+ "introspection",
244
+ `# db-mcp Help \u2014 Schema Introspection (9 tools)
245
+
246
+ All introspection tools are **read-only** \u2014 they query PRAGMAs and sqlite_master, never modify data.
247
+
248
+ ## Graph Analysis (3 tools)
249
+
250
+ \`\`\`javascript
251
+ // Build FK dependency graph \u2014 nodesOnly: true for lightweight response (nodes without edges)
252
+ sqlite_dependency_graph({ includeRowCounts: true, excludeSystemTables: true });
253
+ sqlite_dependency_graph({ nodesOnly: true }); // lighter payload
254
+
255
+ // Safe DDL execution order \u2014 "create" = parents first (default), "drop" = children first
256
+ sqlite_topological_sort({ direction: "create", excludeSystemTables: true });
257
+ sqlite_topological_sort({ direction: "drop" }); // safe DROP order
258
+
259
+ // Simulate DELETE/DROP/TRUNCATE impact \u2014 shows affected tables, cascade paths, severity scoring
260
+ sqlite_cascade_simulator({ table: "users", operation: "delete" });
261
+ sqlite_cascade_simulator({ table: "users", operation: "drop", compact: true }); // compact omits path arrays
262
+ \`\`\`
263
+
264
+ ## Schema Analysis (3 tools)
265
+
266
+ \`\`\`javascript
267
+ // Full schema in one call \u2014 compact: true omits column details, sections limits scope
268
+ sqlite_schema_snapshot({ sections: ["tables", "indexes"], excludeSystemTables: true });
269
+ sqlite_schema_snapshot({ compact: true }); // lighter payload
270
+
271
+ // Find constraint health issues \u2014 missing PKs, nullable FKs, unindexed FKs
272
+ sqlite_constraint_analysis({ excludeSystemTables: true });
273
+ sqlite_constraint_analysis({ table: "orders", checks: ["missing_pk", "unindexed_fk"] }); // limit scope
274
+
275
+ // Analyze DDL for SQLite-specific risks \u2014 does NOT execute the statements
276
+ sqlite_migration_risks({ statements: ["ALTER TABLE users ADD COLUMN email TEXT", "DROP TABLE old_logs"] });
277
+ \`\`\`
278
+
279
+ ## Diagnostics (3 tools)
280
+
281
+ \`\`\`javascript
282
+ // Fragmentation, per-table size breakdown, optimization recommendations
283
+ sqlite_storage_analysis({ includeTableDetails: true, excludeSystemTables: true });
284
+ sqlite_storage_analysis({ limit: 10 }); // top 10 tables only
285
+
286
+ // Audit index effectiveness \u2014 find redundant, missing FK, unindexed large tables
287
+ sqlite_index_audit({ excludeSystemTables: true });
288
+ sqlite_index_audit({ table: "orders", minSeverity: "warning" }); // reduce payload
289
+
290
+ // EXPLAIN QUERY PLAN with scan-type classification and optimization suggestions (SELECT/WITH only)
291
+ sqlite_query_plan({ sql: "SELECT * FROM orders WHERE status = 'active'" });
292
+ \`\`\`
293
+
294
+ ## \u26A0\uFE0F Gotchas
295
+
296
+ - \`excludeSystemTables\` defaults to \`true\` \u2014 SpatiaLite system tables are hidden for cleaner output. Pass \`false\` to include them
297
+ - \`sqlite_migration_risks\` analyzes DDL text statically \u2014 it does NOT execute the statements`
298
+ ],
299
+ [
300
+ "json",
301
+ `# db-mcp Help \u2014 JSON Operations (23 tools)
302
+
303
+ ## Collection & CRUD
304
+
305
+ - \`sqlite_create_json_collection({ tableName, indexes: [{ path: "$.type" }, { path: "$.author" }] })\` \u2014 creates table with JSON indexes
306
+ - \`sqlite_json_insert({ table, column, data: { type: "article", title: "Hello", tags: ["news"] } })\` \u2014 insert JSON document
307
+ - \`sqlite_json_select({ table, column, extractPaths? })\` \u2014 select rows, optionally extract specific JSON paths
308
+ - \`sqlite_json_update({ table, column, path, value, whereClause })\` \u2014 update value at JSON path
309
+ - \`sqlite_json_query({ table, column, filterPaths: { "$.type": "article" }, selectPaths: ["$.title"] })\` \u2014 query with path-based filters and projections
310
+
311
+ ## Path Operations
312
+
313
+ - \`sqlite_json_extract({ table, column, path: "$.title" })\` \u2014 extract value at path. Returns null if path doesn't exist
314
+ - \`sqlite_json_set({ table, column, path: "$.views", value: 100, whereClause: "id = 1" })\` \u2014 set value at path (creates if missing)
315
+ - \`sqlite_json_merge({ table, column, mergeData: { featured: true }, whereClause: "id = 1" })\` \u2014 merge object into existing JSON
316
+ - \`sqlite_json_remove({ table, column, path, whereClause })\` \u2014 remove key at path
317
+ - \`sqlite_json_validate_path({ path: "$.store.books[0].title" })\` \u2014 validate JSON path syntax without executing a query
318
+ - \`sqlite_json_type({ table, column, path })\` \u2014 get JSON type (null, true, false, integer, real, text, array, object)
319
+
320
+ ## Array Operations
321
+
322
+ \u26A0\uFE0F \`json_each\` multiplies output rows \u2014 use \`limit\` param for large arrays
323
+
324
+ - \`sqlite_json_array_append({ table, column, path: "$.tags", value: "featured", whereClause: "id = 1" })\` \u2014 append to array
325
+ - \`sqlite_json_array_length({ table, column, path })\` \u2014 get array length
326
+ - \`sqlite_json_each({ table, column, path: "$.tags", limit: 50 })\` \u2014 expand array to rows
327
+
328
+ ## Aggregation & Analysis
329
+
330
+ \`\`\`javascript
331
+ // Regular tables: use column names directly
332
+ sqlite_json_group_array({ table: "events", valueColumn: "user_id", groupByColumn: "event_type" });
333
+
334
+ // JSON collections: use allowExpressions with json_extract for both columns
335
+ // \u26A0\uFE0F allowExpressions is for column extraction ONLY, NOT aggregate functions
336
+ // \u26A0\uFE0F Without groupByColumn, each row creates a key-value pair; duplicate keys if values aren't unique
337
+ sqlite_json_group_array({
338
+ table: "docs",
339
+ valueColumn: "json_extract(data, '$.author')",
340
+ groupByColumn: "json_extract(data, '$.type')",
341
+ allowExpressions: true,
342
+ });
343
+
344
+ // For aggregate values (COUNT, SUM, AVG), use aggregateFunction parameter instead
345
+ sqlite_json_group_object({ table: "events", keyColumn: "event_type", aggregateFunction: "COUNT(*)" });
346
+ sqlite_json_group_object({ table: "orders", keyColumn: "status", aggregateFunction: "SUM(total)" });
347
+ \`\`\`
348
+
349
+ - \`sqlite_json_keys({ table, column, path? })\` \u2014 get distinct keys of JSON objects
350
+ - \`sqlite_json_pretty({ table, column, whereClause? })\` \u2014 format JSON with indentation
351
+ - \`sqlite_json_valid({ table, column })\` \u2014 check if values are valid JSON
352
+ - \`sqlite_json_analyze_schema({ table, column })\` \u2014 infer schema types
353
+
354
+ ## JSONB Optimization (SQLite 3.45+)
355
+
356
+ - \`sqlite_json_storage_info({ table, column })\` \u2014 check text vs JSONB format
357
+ - \`sqlite_jsonb_convert({ table, column })\` \u2014 convert to JSONB for faster queries
358
+ - \`sqlite_json_normalize_column({ table, column, outputFormat? })\` \u2014 normalize JSON (sort keys, compact). \u26A0\uFE0F Defaults to \`"preserve"\` (maintains original format); use \`outputFormat: "text"\` to force text output`
359
+ ],
360
+ [
361
+ "migration",
362
+ `# db-mcp Help \u2014 Migration Tracking (6 tools)
363
+
364
+ \u26A0\uFE0F Must call \`sqlite_migration_init()\` before using any other migration tool \u2014 it creates the tracking table.
365
+
366
+ \`\`\`javascript
367
+ // Initialize tracking table (idempotent \u2014 safe to call multiple times)
368
+ sqlite_migration_init();
369
+
370
+ // Apply migration: executes SQL and records atomically. If SQL fails, no record is created
371
+ // SHA-256 dedup \u2014 submitting the same SQL twice is rejected as a duplicate
372
+ sqlite_migration_apply({
373
+ version: "2024-01-15-add-users",
374
+ description: "Create users table",
375
+ migrationSql: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE)",
376
+ rollbackSql: "DROP TABLE users",
377
+ sourceSystem: "agent",
378
+ appliedBy: "claude",
379
+ });
380
+
381
+ // Record externally-applied migration (does NOT execute the SQL)
382
+ sqlite_migration_record({
383
+ version: "2024-01-10-initial",
384
+ description: "Initial schema (pre-existing)",
385
+ migrationSql: "CREATE TABLE orders (...)",
386
+ sourceSystem: "manual",
387
+ });
388
+
389
+ // Rollback by ID or version \u2014 requires rollbackSql to have been recorded
390
+ sqlite_migration_rollback({ version: "2024-01-15-add-users" });
391
+ sqlite_migration_rollback({ id: 3, dryRun: true }); // preview SQL without executing
392
+
393
+ // Query history with filters and pagination
394
+ sqlite_migration_history({ status: "applied", limit: 10 });
395
+ sqlite_migration_history({ sourceSystem: "agent", compact: true }); // compact omits hash and source system
396
+
397
+ // Summary: latest version, counts by status, unique source systems
398
+ sqlite_migration_status();
399
+ \`\`\`
400
+
401
+ ## \u26A0\uFE0F Gotchas
402
+
403
+ - Rollback requires \`rollbackSql\` to have been provided when the migration was recorded/applied
404
+ - Migration group is **opt-in** \u2014 not included in any shortcut except \`dev-schema\` and \`full\``
405
+ ],
406
+ [
407
+ "stats",
408
+ `# db-mcp Help \u2014 Statistical Analysis (13 core + 6 window)
409
+
410
+ ## Core Statistics (always available)
411
+
412
+ \`\`\`javascript
413
+ sqlite_stats_basic({ table: "employees", column: "salary" }); // count, sum, avg, min, max
414
+ sqlite_stats_count({ table: "orders", column: "status", distinct: true }); // count rows, optionally distinct
415
+ sqlite_stats_group_by({ table: "orders", column: "total", groupBy: "status" }); // aggregate by group
416
+ sqlite_stats_percentile({ table: "sales", column: "revenue", percentiles: [25, 50, 75, 90] });
417
+ sqlite_stats_histogram({ table: "products", column: "price", buckets: 10 });
418
+ sqlite_stats_correlation({ table: "data", column1: "x", column2: "y" }); // Pearson coefficient
419
+ sqlite_stats_distinct({ table: "orders", column: "status" }); // distinct values
420
+ sqlite_stats_summary({ table: "data", columns: ["price", "quantity", "discount"] }); // multi-column summary
421
+ sqlite_stats_frequency({ table: "orders", column: "status" }); // frequency distribution
422
+ sqlite_stats_regression({ table: "data", xColumn: "year", yColumn: "revenue" }); // linear
423
+ sqlite_stats_regression({ table: "data", xColumn: "year", yColumn: "revenue", degree: 2 }); // quadratic
424
+ sqlite_stats_outliers({ table: "sales", column: "amount", method: "iqr" }); // or "zscore". Use maxOutliers to limit payload
425
+ sqlite_stats_hypothesis({ table: "samples", column: "value", testType: "ttest_one", expectedMean: 100 });
426
+ \`\`\`
427
+
428
+ \u26A0\uFE0F \`sqlite_stats_top_n\` \u2014 always use \`selectColumns\` to avoid returning all columns (large payloads with text fields):
429
+
430
+ \`\`\`javascript
431
+ sqlite_stats_top_n({
432
+ table: "products",
433
+ column: "price",
434
+ n: 10,
435
+ selectColumns: ["id", "name", "price"],
436
+ });
437
+ \`\`\`
438
+
439
+ ## Window Functions (6 tools, Native only)
440
+
441
+ \`\`\`javascript
442
+ sqlite_window_row_number({ table: "employees", orderBy: "hire_date", partitionBy: "department" });
443
+ sqlite_window_rank({ table: "sales", orderBy: "revenue DESC", partitionBy: "region", rankType: "dense_rank" });
444
+ sqlite_window_lag_lead({ table: "sales", orderBy: "date", column: "revenue", partitionBy: "region" }); // access previous/next row values
445
+ sqlite_window_running_total({ table: "transactions", column: "amount", orderBy: "date" });
446
+ sqlite_window_moving_avg({ table: "stock_prices", column: "close_price", orderBy: "date", windowSize: 7 });
447
+ sqlite_window_ntile({ table: "employees", orderBy: "salary DESC", buckets: 4, partitionBy: "department" }); // quartiles
448
+ \`\`\``
449
+ ],
450
+ [
451
+ "text",
452
+ `# db-mcp Help \u2014 Text Processing & FTS5
453
+
454
+ ## Full-Text Search / FTS5 (4 tools, Native only)
455
+
456
+ \`\`\`javascript
457
+ // Create FTS5 table with triggers for auto-sync on future changes
458
+ sqlite_fts_create({ tableName: "articles_fts", sourceTable: "articles", columns: ["title", "content"] });
459
+ sqlite_fts_rebuild({ table: "articles_fts" }); // \u26A0\uFE0F Required: populate index with existing data
460
+
461
+ // FTS5 uses AND by default: "machine learning" = rows containing BOTH words
462
+ // Use OR explicitly: "machine OR learning" for rows containing EITHER word
463
+ sqlite_fts_search({ table: "articles_fts", query: "machine learning", limit: 10 });
464
+ sqlite_fts_match_info({ table: "articles_fts", query: "machine learning" }); // bm25 ranking info
465
+ \`\`\`
466
+
467
+ \u26A0\uFE0F FTS5 virtual tables (\`*_fts\`) and shadow tables (\`*_fts_*\`) are hidden from \`sqlite_list_tables\` for cleaner output
468
+
469
+ ## Text Processing (13 tools)
470
+
471
+ \`\`\`javascript
472
+ // Regex patterns: \u26A0\uFE0F Double-escape backslashes (\\\\) when passing through JSON/MCP
473
+ sqlite_regex_match({ table: "logs", column: "message", pattern: "ERROR:\\\\\\\\s+(\\\\\\\\w+)" });
474
+ sqlite_regex_extract({ table: "users", column: "email", pattern: "@([a-zA-Z0-9.-]+)", groupIndex: 1 });
475
+
476
+ // Text manipulation
477
+ sqlite_text_split({ table: "users", column: "email", delimiter: "@" }); // split into parts array
478
+ sqlite_text_concat({ table: "users", columns: ["first_name", "last_name"], separator: " " });
479
+ sqlite_text_replace({ table: "docs", column: "content", search: "old", replacement: "new" });
480
+ sqlite_text_trim({ table: "users", column: "name" }); // trim whitespace
481
+ sqlite_text_case({ table: "products", column: "name", mode: "upper" }); // or "lower"
482
+ sqlite_text_substring({ table: "codes", column: "value", start: 1, length: 3 }); // extract substring
483
+ sqlite_text_normalize({ table: "docs", column: "content", mode: "strip_accents" }); // or nfc, nfd, nfkc, nfkd
484
+
485
+ // Validation patterns: email, phone, url, uuid, ipv4, custom
486
+ sqlite_text_validate({ table: "users", column: "email", pattern: "email" });
487
+ sqlite_text_validate({ table: "data", column: "field", pattern: "custom", customPattern: "^[A-Z]{2}[0-9]{4}$" });
488
+
489
+ // Fuzzy matching \u2014 matches WORD TOKENS by default (not entire value)
490
+ // "laptop" matches "Laptop Pro 15" (distance 0 on first token). Use tokenize: false for full-string matching.
491
+ sqlite_fuzzy_match({ table: "products", column: "name", search: "laptop", maxDistance: 2 });
492
+ sqlite_fuzzy_match({ table: "products", column: "name", search: "laptob", maxDistance: 2, tokenize: false }); // full value
493
+
494
+ // Phonetic matching \u2014 finds words that sound alike (matches against any word in value)
495
+ // Use includeRowData: false for lighter payloads when only matching values are needed
496
+ sqlite_phonetic_match({ table: "products", column: "name", search: "laptop", algorithm: "soundex" });
497
+ sqlite_phonetic_match({ table: "products", column: "name", search: "laptop", includeRowData: false }); // lighter
498
+
499
+ // Advanced search \u2014 combines exact, fuzzy, and phonetic techniques
500
+ // fuzzyThreshold: 0.3-0.4 = loose matching (more results), 0.6-0.8 = strict matching (fewer results)
501
+ sqlite_advanced_search({
502
+ table: "products", column: "name", searchTerm: "laptop",
503
+ techniques: ["exact", "fuzzy", "phonetic"], fuzzyThreshold: 0.4,
504
+ });
505
+ \`\`\``
506
+ ],
507
+ [
508
+ "vector",
509
+ `# db-mcp Help \u2014 Vector/Semantic Search (11 tools)
510
+
511
+ \`\`\`javascript
512
+ // Create vector table with metadata columns
513
+ sqlite_vector_create_table({ tableName: "docs", dimensions: 384, additionalColumns: [{ name: "content", type: "TEXT" }] });
514
+
515
+ // Store vectors (single and batch)
516
+ sqlite_vector_store({ table: "docs", idColumn: "id", vectorColumn: "emb", id: 1, vector: [...] });
517
+ sqlite_vector_batch_store({ table: "docs", idColumn: "id", vectorColumn: "emb", items: [{ id: 1, vector: [...] }, { id: 2, vector: [...] }] });
518
+
519
+ // Search vectors (returnColumns omits vector data from results for smaller payloads)
520
+ sqlite_vector_search({ table: "docs", vectorColumn: "emb", queryVector: [...], limit: 10, returnColumns: ["id", "title"] });
521
+
522
+ // Retrieve and delete vectors
523
+ // Note: sqlite_vector_get returns parsed 'vector' array + raw JSON string in 'metadata' for flexibility
524
+ sqlite_vector_get({ table: "docs", idColumn: "id", vectorColumn: "emb", id: 1 });
525
+ sqlite_vector_delete({ table: "docs", idColumn: "id", ids: [1, 2, 3] });
526
+
527
+ // Vector metadata
528
+ sqlite_vector_count({ table: "docs" }); // or with dimensions filter: { table: "docs", dimensions: 384 }
529
+ sqlite_vector_dimensions({ table: "docs", vectorColumn: "emb" });
530
+ sqlite_vector_stats({ table: "docs", vectorColumn: "emb" }); // magnitude min/max/avg
531
+
532
+ // Utility tools for preprocessing
533
+ sqlite_vector_normalize({ vector: [3, 4, 0, 0] }); // returns unit vector [0.6, 0.8, 0, 0]
534
+ sqlite_vector_distance({ vector1: [...], vector2: [...], metric: "cosine" }); // or "euclidean", "dot"
535
+ \`\`\``
536
+ ]
537
+ ]);
538
+
539
+ // src/server/mcp-server.ts
540
+ var DbMcpServer = class {
541
+ server;
542
+ adapters = /* @__PURE__ */ new Map();
543
+ toolFilter;
544
+ config;
545
+ constructor(config) {
546
+ this.config = config;
547
+ this.toolFilter = config.toolFilter ? parseToolFilter(config.toolFilter) : getToolFilterFromEnv();
548
+ this.server = new McpServer(
549
+ {
550
+ name: config.name,
551
+ version: config.version
552
+ },
553
+ {
554
+ capabilities: {
555
+ logging: {}
556
+ },
557
+ instructions: INSTRUCTIONS
558
+ }
559
+ );
560
+ logger.info(getFilterSummary(this.toolFilter), { module: "FILTER" });
561
+ logger.info("MCP Server initialized", {
562
+ module: "SERVER",
563
+ name: config.name,
564
+ version: config.version,
565
+ toolFilter: config.toolFilter ?? "none",
566
+ capabilities: ["logging"]
567
+ });
568
+ this.registerBuiltInTools();
569
+ this.registerHelpResources();
570
+ }
571
+ /**
572
+ * Register a database adapter
573
+ */
574
+ async registerAdapter(adapter, config) {
575
+ const adapterId = `${adapter.type}:${config.connectionString ?? "default"}`;
576
+ await adapter.connect(config);
577
+ this.adapters.set(adapterId, adapter);
578
+ adapter.registerTools(this.server, this.toolFilter);
579
+ adapter.registerResources(this.server);
580
+ adapter.registerPrompts(this.server);
581
+ logger.info(`Registered adapter: ${adapter.name} (${adapterId})`, {
582
+ module: "SERVER"
583
+ });
584
+ }
585
+ /**
586
+ * Get an adapter by ID
587
+ */
588
+ getAdapter(adapterId) {
589
+ return this.adapters.get(adapterId);
590
+ }
591
+ /**
592
+ * Get all registered adapters
593
+ */
594
+ getAdapters() {
595
+ return this.adapters;
596
+ }
597
+ /**
598
+ * Register built-in server tools (health, info, etc.)
599
+ */
600
+ registerBuiltInTools() {
601
+ const serverInfoOpts = {
602
+ title: "Server Info",
603
+ description: "Get information about the db-mcp server and registered adapters",
604
+ icons: SERVER_ICONS,
605
+ annotations: READ_ONLY
606
+ };
607
+ this.server.registerTool(
608
+ "server_info",
609
+ serverInfoOpts,
610
+ () => {
611
+ const adapterInfo = [];
612
+ for (const [id, adapter] of this.adapters) {
613
+ adapterInfo.push({
614
+ id,
615
+ ...adapter.getInfo()
616
+ });
617
+ }
618
+ return {
619
+ content: [
620
+ {
621
+ type: "text",
622
+ text: JSON.stringify(
623
+ {
624
+ name: this.config.name,
625
+ version: this.config.version,
626
+ transport: this.config.transport,
627
+ adapters: adapterInfo,
628
+ toolFilter: {
629
+ raw: this.toolFilter.raw,
630
+ enabledGroups: [...this.toolFilter.enabledGroups]
631
+ }
632
+ },
633
+ null,
634
+ 2
635
+ )
636
+ }
637
+ ]
638
+ };
639
+ }
640
+ );
641
+ const healthOpts = {
642
+ title: "Server Health",
643
+ description: "Check health status of all database connections",
644
+ icons: SERVER_ICONS,
645
+ annotations: READ_ONLY
646
+ };
647
+ this.server.registerTool(
648
+ "server_health",
649
+ healthOpts,
650
+ async () => {
651
+ const health = {
652
+ server: "healthy",
653
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
654
+ adapters: {}
655
+ };
656
+ for (const [id, adapter] of this.adapters) {
657
+ try {
658
+ const adapterHealth = await adapter.getHealth();
659
+ health["adapters"][id] = adapterHealth;
660
+ } catch (error) {
661
+ health["adapters"][id] = {
662
+ connected: false,
663
+ error: error instanceof Error ? error.message : "Unknown error"
664
+ };
665
+ }
666
+ }
667
+ return {
668
+ content: [
669
+ {
670
+ type: "text",
671
+ text: JSON.stringify(health, null, 2)
672
+ }
673
+ ]
674
+ };
675
+ }
676
+ );
677
+ const listAdaptersOpts = {
678
+ title: "List Adapters",
679
+ description: "List all registered database adapters",
680
+ icons: SERVER_ICONS,
681
+ annotations: READ_ONLY
682
+ };
683
+ this.server.registerTool(
684
+ "list_adapters",
685
+ listAdaptersOpts,
686
+ () => {
687
+ const adapters = [];
688
+ for (const [id, adapter] of this.adapters) {
689
+ adapters.push({
690
+ id,
691
+ type: adapter.type,
692
+ name: adapter.name,
693
+ version: adapter.version,
694
+ connected: adapter.isConnected()
695
+ });
696
+ }
697
+ return {
698
+ content: [
699
+ {
700
+ type: "text",
701
+ text: JSON.stringify(adapters, null, 2)
702
+ }
703
+ ]
704
+ };
705
+ }
706
+ );
707
+ }
708
+ /**
709
+ * Register sqlite://help resources for on-demand reference documentation.
710
+ * Always registers sqlite://help (gotchas). Group-specific help is filtered
711
+ * by the tool filter configuration.
712
+ */
713
+ registerHelpResources() {
714
+ const gotchasContent = HELP_CONTENT.get("gotchas");
715
+ if (gotchasContent) {
716
+ this.server.registerResource(
717
+ "sqlite_help",
718
+ "sqlite://help",
719
+ {
720
+ description: "Critical gotchas, WASM vs Native comparison, and Code Mode API reference",
721
+ mimeType: "text/markdown"
722
+ },
723
+ () => ({
724
+ contents: [
725
+ {
726
+ uri: "sqlite://help",
727
+ mimeType: "text/markdown",
728
+ text: gotchasContent
729
+ }
730
+ ]
731
+ })
732
+ );
733
+ }
734
+ const groupHelpKeys = [
735
+ { group: "json", key: "json" },
736
+ { group: "text", key: "text" },
737
+ { group: "stats", key: "stats" },
738
+ { group: "vector", key: "vector" },
739
+ { group: "geo", key: "geo" },
740
+ { group: "admin", key: "admin" },
741
+ { group: "introspection", key: "introspection" },
742
+ { group: "migration", key: "migration" }
743
+ ];
744
+ for (const { group, key } of groupHelpKeys) {
745
+ if (!this.toolFilter.enabledGroups.has(group)) continue;
746
+ const content = HELP_CONTENT.get(key);
747
+ if (!content) continue;
748
+ this.server.registerResource(
749
+ `sqlite_help_${key}`,
750
+ `sqlite://help/${key}`,
751
+ {
752
+ description: `Tool reference for the ${group} tool group`,
753
+ mimeType: "text/markdown"
754
+ },
755
+ () => ({
756
+ contents: [
757
+ {
758
+ uri: `sqlite://help/${key}`,
759
+ mimeType: "text/markdown",
760
+ text: content
761
+ }
762
+ ]
763
+ })
764
+ );
765
+ }
766
+ const registeredHelp = ["sqlite://help"];
767
+ for (const { group, key } of groupHelpKeys) {
768
+ if (this.toolFilter.enabledGroups.has(group)) {
769
+ registeredHelp.push(`sqlite://help/${key}`);
770
+ }
771
+ }
772
+ logger.info(`Help resources: ${registeredHelp.join(", ")}`, {
773
+ module: "SERVER"
774
+ });
775
+ }
776
+ /**
777
+ * Start the server with the configured transport
778
+ */
779
+ async start() {
780
+ switch (this.config.transport) {
781
+ case "stdio":
782
+ await this.startStdio();
783
+ break;
784
+ case "http":
785
+ await this.startHttp();
786
+ break;
787
+ default:
788
+ throw new DbMcpError(
789
+ `Unsupported transport: ${this.config.transport}`,
790
+ "SERVER_START_FAILED",
791
+ "config" /* CONFIGURATION */
792
+ );
793
+ }
794
+ }
795
+ /**
796
+ * Start server with stdio transport
797
+ */
798
+ async startStdio() {
799
+ const transport = new StdioServerTransport();
800
+ await this.server.connect(transport);
801
+ logger.info(`db-mcp server started (stdio transport)`, {
802
+ module: "SERVER"
803
+ });
804
+ }
805
+ /**
806
+ * Start server with HTTP transport (Streamable HTTP with SSE support)
807
+ */
808
+ async startHttp() {
809
+ const { HttpTransport } = await import('./http-VSB7DBJR.js');
810
+ const oauthConfig = {
811
+ enabled: this.config.oauth?.enabled ?? false,
812
+ authorizationServerUrl: this.config.oauth?.authorizationServerUrl ?? "",
813
+ audience: this.config.oauth?.audience ?? this.config.name
814
+ };
815
+ if (this.config.oauth?.issuer !== void 0) {
816
+ oauthConfig.issuer = this.config.oauth.issuer;
817
+ }
818
+ if (this.config.oauth?.jwksUri !== void 0) {
819
+ oauthConfig.jwksUri = this.config.oauth.jwksUri;
820
+ }
821
+ if (this.config.oauth?.clockTolerance !== void 0) {
822
+ oauthConfig.clockTolerance = this.config.oauth.clockTolerance;
823
+ }
824
+ if (this.config.oauth?.publicPaths !== void 0) {
825
+ oauthConfig.publicPaths = this.config.oauth.publicPaths;
826
+ }
827
+ const transport = new HttpTransport({
828
+ port: this.config.port ?? 3e3,
829
+ ...this.config.host !== void 0 && { host: this.config.host },
830
+ ...this.config.authToken !== void 0 && {
831
+ authToken: this.config.authToken
832
+ },
833
+ ...this.config.enableHSTS !== void 0 && {
834
+ enableHSTS: this.config.enableHSTS
835
+ },
836
+ oauth: oauthConfig,
837
+ stateless: this.config.statelessHttp ?? false
838
+ });
839
+ await transport.initialize(this.server);
840
+ await transport.start();
841
+ const mode = this.config.statelessHttp ? "stateless" : "stateful";
842
+ const host = this.config.host ?? "0.0.0.0";
843
+ const port = String(this.config.port ?? 3e3);
844
+ logger.info(
845
+ `db-mcp server started (HTTP transport on ${host}:${port}, ${mode} mode)`,
846
+ { module: "TRANSPORT", mode }
847
+ );
848
+ }
849
+ /**
850
+ * Gracefully shut down the server
851
+ */
852
+ async shutdown() {
853
+ logger.info("Shutting down db-mcp server...", { module: "SERVER" });
854
+ for (const [id, adapter] of this.adapters) {
855
+ try {
856
+ await adapter.disconnect();
857
+ logger.info(`Disconnected adapter: ${id}`, { module: "SERVER" });
858
+ } catch (error) {
859
+ logger.error(`Error disconnecting adapter ${id}`, {
860
+ module: "SERVER",
861
+ error: error instanceof Error ? error : void 0
862
+ });
863
+ }
864
+ }
865
+ await this.server.close();
866
+ logger.info("Server shutdown complete", { module: "SERVER" });
867
+ }
868
+ };
869
+ function createServer(config) {
870
+ return new DbMcpServer(config);
871
+ }
872
+ var DEFAULT_CONFIG = {
873
+ name: NAME,
874
+ version: VERSION,
875
+ transport: "stdio",
876
+ databases: []
877
+ };
878
+
879
+ export { DEFAULT_CONFIG, DbMcpServer, NAME, VERSION, createServer };