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.
- package/.gitattributes +2 -0
- package/LICENSE +1 -1
- package/README.md +244 -518
- package/dist/chunk-4IA3DB5C.js +135 -0
- package/dist/chunk-AOUL5SHS.js +930 -0
- package/dist/chunk-DWJXQEFA.js +13759 -0
- package/dist/chunk-DZQLDEQS.js +879 -0
- package/dist/chunk-S5IDDSSB.js +74 -0
- package/dist/chunk-Z2GFQU3G.js +363 -0
- package/dist/cli.d.ts +0 -7
- package/dist/cli.js +227 -183
- package/dist/http-VSB7DBJR.js +1541 -0
- package/dist/index.d.ts +842 -10
- package/dist/index.js +5 -17
- package/dist/sqlite-VHBA4ABV.js +600 -0
- package/dist/sqlite-native-D2LH5ZT7.js +2498 -0
- package/dist/worker-script.d.ts +2 -0
- package/dist/worker-script.js +126 -0
- package/package.json +26 -16
- package/playwright.config.ts +101 -0
- package/scripts/generate-server-instructions.ts +111 -0
- package/server.json +5 -6
- package/test-server/README.md +118 -0
- package/test-server/code-map.md +409 -0
- package/test-server/fixtures/sample.csv +6 -0
- package/test-server/reset-database.ps1 +373 -0
- package/test-server/sample.csv +11 -0
- package/test-server/test-agent-experience.md +243 -0
- package/test-server/test-database.sql +388 -0
- package/test-server/test-group-tools.md +861 -0
- package/test-server/test-help-resources.mjs +238 -0
- package/test-server/test-preflight.md +53 -0
- package/test-server/test-prompts.md +354 -0
- package/test-server/test-resources.md +245 -0
- package/test-server/test-tool-annotations.mjs +157 -0
- package/test-server/test-tools-advanced-1.md +517 -0
- package/test-server/test-tools-advanced-2.md +487 -0
- package/test-server/test-tools-codemode.md +629 -0
- package/test-server/test-tools.md +176 -0
- package/test-server/tool-reference.md +236 -0
- package/tsconfig.test.json +9 -0
- package/dist/adapters/DatabaseAdapter.d.ts +0 -141
- package/dist/adapters/DatabaseAdapter.d.ts.map +0 -1
- package/dist/adapters/DatabaseAdapter.js +0 -131
- package/dist/adapters/DatabaseAdapter.js.map +0 -1
- package/dist/adapters/sqlite/SchemaManager.d.ts +0 -58
- package/dist/adapters/sqlite/SchemaManager.d.ts.map +0 -1
- package/dist/adapters/sqlite/SchemaManager.js +0 -187
- package/dist/adapters/sqlite/SchemaManager.js.map +0 -1
- package/dist/adapters/sqlite/SqliteAdapter.d.ts +0 -161
- package/dist/adapters/sqlite/SqliteAdapter.d.ts.map +0 -1
- package/dist/adapters/sqlite/SqliteAdapter.js +0 -741
- package/dist/adapters/sqlite/SqliteAdapter.js.map +0 -1
- package/dist/adapters/sqlite/index.d.ts +0 -9
- package/dist/adapters/sqlite/index.d.ts.map +0 -1
- package/dist/adapters/sqlite/index.js +0 -8
- package/dist/adapters/sqlite/index.js.map +0 -1
- package/dist/adapters/sqlite/json-utils.d.ts +0 -100
- package/dist/adapters/sqlite/json-utils.d.ts.map +0 -1
- package/dist/adapters/sqlite/json-utils.js +0 -274
- package/dist/adapters/sqlite/json-utils.js.map +0 -1
- package/dist/adapters/sqlite/output-schemas.d.ts +0 -1187
- package/dist/adapters/sqlite/output-schemas.d.ts.map +0 -1
- package/dist/adapters/sqlite/output-schemas.js +0 -1337
- package/dist/adapters/sqlite/output-schemas.js.map +0 -1
- package/dist/adapters/sqlite/prompts.d.ts +0 -13
- package/dist/adapters/sqlite/prompts.d.ts.map +0 -1
- package/dist/adapters/sqlite/prompts.js +0 -605
- package/dist/adapters/sqlite/prompts.js.map +0 -1
- package/dist/adapters/sqlite/resources.d.ts +0 -13
- package/dist/adapters/sqlite/resources.d.ts.map +0 -1
- package/dist/adapters/sqlite/resources.js +0 -251
- package/dist/adapters/sqlite/resources.js.map +0 -1
- package/dist/adapters/sqlite/tools/admin.d.ts +0 -14
- package/dist/adapters/sqlite/tools/admin.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/admin.js +0 -788
- package/dist/adapters/sqlite/tools/admin.js.map +0 -1
- package/dist/adapters/sqlite/tools/core.d.ts +0 -25
- package/dist/adapters/sqlite/tools/core.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/core.js +0 -359
- package/dist/adapters/sqlite/tools/core.js.map +0 -1
- package/dist/adapters/sqlite/tools/fts.d.ts +0 -13
- package/dist/adapters/sqlite/tools/fts.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/fts.js +0 -347
- package/dist/adapters/sqlite/tools/fts.js.map +0 -1
- package/dist/adapters/sqlite/tools/geo.d.ts +0 -14
- package/dist/adapters/sqlite/tools/geo.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/geo.js +0 -252
- package/dist/adapters/sqlite/tools/geo.js.map +0 -1
- package/dist/adapters/sqlite/tools/index.d.ts +0 -30
- package/dist/adapters/sqlite/tools/index.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/index.js +0 -61
- package/dist/adapters/sqlite/tools/index.js.map +0 -1
- package/dist/adapters/sqlite/tools/json-helpers.d.ts +0 -14
- package/dist/adapters/sqlite/tools/json-helpers.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/json-helpers.js +0 -477
- package/dist/adapters/sqlite/tools/json-helpers.js.map +0 -1
- package/dist/adapters/sqlite/tools/json-operations.d.ts +0 -14
- package/dist/adapters/sqlite/tools/json-operations.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/json-operations.js +0 -839
- package/dist/adapters/sqlite/tools/json-operations.js.map +0 -1
- package/dist/adapters/sqlite/tools/stats.d.ts +0 -15
- package/dist/adapters/sqlite/tools/stats.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/stats.js +0 -1219
- package/dist/adapters/sqlite/tools/stats.js.map +0 -1
- package/dist/adapters/sqlite/tools/text.d.ts +0 -14
- package/dist/adapters/sqlite/tools/text.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/text.js +0 -1141
- package/dist/adapters/sqlite/tools/text.js.map +0 -1
- package/dist/adapters/sqlite/tools/vector.d.ts +0 -14
- package/dist/adapters/sqlite/tools/vector.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/vector.js +0 -613
- package/dist/adapters/sqlite/tools/vector.js.map +0 -1
- package/dist/adapters/sqlite/tools/virtual.d.ts +0 -13
- package/dist/adapters/sqlite/tools/virtual.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/virtual.js +0 -930
- package/dist/adapters/sqlite/tools/virtual.js.map +0 -1
- package/dist/adapters/sqlite/types.d.ts +0 -207
- package/dist/adapters/sqlite/types.d.ts.map +0 -1
- package/dist/adapters/sqlite/types.js +0 -186
- package/dist/adapters/sqlite/types.js.map +0 -1
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.d.ts +0 -163
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.js +0 -748
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.js.map +0 -1
- package/dist/adapters/sqlite-native/index.d.ts +0 -11
- package/dist/adapters/sqlite-native/index.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/index.js +0 -11
- package/dist/adapters/sqlite-native/index.js.map +0 -1
- package/dist/adapters/sqlite-native/tools/spatialite.d.ts +0 -19
- package/dist/adapters/sqlite-native/tools/spatialite.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/tools/spatialite.js +0 -628
- package/dist/adapters/sqlite-native/tools/spatialite.js.map +0 -1
- package/dist/adapters/sqlite-native/tools/transactions.d.ts +0 -12
- package/dist/adapters/sqlite-native/tools/transactions.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/tools/transactions.js +0 -255
- package/dist/adapters/sqlite-native/tools/transactions.js.map +0 -1
- package/dist/adapters/sqlite-native/tools/window.d.ts +0 -12
- package/dist/adapters/sqlite-native/tools/window.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/tools/window.js +0 -370
- package/dist/adapters/sqlite-native/tools/window.js.map +0 -1
- package/dist/auth/AuthorizationServerDiscovery.d.ts +0 -90
- package/dist/auth/AuthorizationServerDiscovery.d.ts.map +0 -1
- package/dist/auth/AuthorizationServerDiscovery.js +0 -204
- package/dist/auth/AuthorizationServerDiscovery.js.map +0 -1
- package/dist/auth/OAuthResourceServer.d.ts +0 -65
- package/dist/auth/OAuthResourceServer.d.ts.map +0 -1
- package/dist/auth/OAuthResourceServer.js +0 -121
- package/dist/auth/OAuthResourceServer.js.map +0 -1
- package/dist/auth/TokenValidator.d.ts +0 -60
- package/dist/auth/TokenValidator.d.ts.map +0 -1
- package/dist/auth/TokenValidator.js +0 -235
- package/dist/auth/TokenValidator.js.map +0 -1
- package/dist/auth/errors.d.ts +0 -74
- package/dist/auth/errors.d.ts.map +0 -1
- package/dist/auth/errors.js +0 -133
- package/dist/auth/errors.js.map +0 -1
- package/dist/auth/index.d.ts +0 -13
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js +0 -15
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/middleware.d.ts +0 -81
- package/dist/auth/middleware.d.ts.map +0 -1
- package/dist/auth/middleware.js +0 -291
- package/dist/auth/middleware.js.map +0 -1
- package/dist/auth/scopes.d.ts +0 -136
- package/dist/auth/scopes.d.ts.map +0 -1
- package/dist/auth/scopes.js +0 -349
- package/dist/auth/scopes.js.map +0 -1
- package/dist/auth/types.d.ts +0 -257
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js +0 -8
- package/dist/auth/types.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/constants/ServerInstructions.d.ts +0 -45
- package/dist/constants/ServerInstructions.d.ts.map +0 -1
- package/dist/constants/ServerInstructions.js +0 -356
- package/dist/constants/ServerInstructions.js.map +0 -1
- package/dist/filtering/ToolConstants.d.ts +0 -34
- package/dist/filtering/ToolConstants.d.ts.map +0 -1
- package/dist/filtering/ToolConstants.js +0 -174
- package/dist/filtering/ToolConstants.js.map +0 -1
- package/dist/filtering/ToolFilter.d.ts +0 -82
- package/dist/filtering/ToolFilter.d.ts.map +0 -1
- package/dist/filtering/ToolFilter.js +0 -296
- package/dist/filtering/ToolFilter.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/server/McpServer.d.ts +0 -61
- package/dist/server/McpServer.d.ts.map +0 -1
- package/dist/server/McpServer.js +0 -270
- package/dist/server/McpServer.js.map +0 -1
- package/dist/transports/http.d.ts +0 -134
- package/dist/transports/http.d.ts.map +0 -1
- package/dist/transports/http.js +0 -516
- package/dist/transports/http.js.map +0 -1
- package/dist/transports/index.d.ts +0 -5
- package/dist/transports/index.d.ts.map +0 -1
- package/dist/transports/index.js +0 -5
- package/dist/transports/index.js.map +0 -1
- package/dist/types/index.d.ts +0 -380
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -68
- package/dist/types/index.js.map +0 -1
- package/dist/utils/annotations.d.ts +0 -44
- package/dist/utils/annotations.d.ts.map +0 -1
- package/dist/utils/annotations.js +0 -77
- package/dist/utils/annotations.js.map +0 -1
- package/dist/utils/errors.d.ts +0 -155
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -329
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/identifiers.d.ts +0 -121
- package/dist/utils/identifiers.d.ts.map +0 -1
- package/dist/utils/identifiers.js +0 -319
- package/dist/utils/identifiers.js.map +0 -1
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -7
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/insightsManager.d.ts +0 -39
- package/dist/utils/insightsManager.d.ts.map +0 -1
- package/dist/utils/insightsManager.js +0 -63
- package/dist/utils/insightsManager.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -189
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -394
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/progress-utils.d.ts +0 -54
- package/dist/utils/progress-utils.d.ts.map +0 -1
- package/dist/utils/progress-utils.js +0 -74
- package/dist/utils/progress-utils.js.map +0 -1
- package/dist/utils/resourceAnnotations.d.ts +0 -36
- package/dist/utils/resourceAnnotations.d.ts.map +0 -1
- package/dist/utils/resourceAnnotations.js +0 -57
- package/dist/utils/resourceAnnotations.js.map +0 -1
- package/dist/utils/where-clause.d.ts +0 -41
- package/dist/utils/where-clause.d.ts.map +0 -1
- package/dist/utils/where-clause.js +0 -116
- package/dist/utils/where-clause.js.map +0 -1
|
@@ -0,0 +1,861 @@
|
|
|
1
|
+
## core Group-Specific Testing (Native and WASM are identical)
|
|
2
|
+
|
|
3
|
+
> **Instructions**: Execute every numbered checklist item with the exact inputs shown. Compare responses against the expected results. Report any deviation. These are the minimum-bar tests that must pass every run — freeform testing comes after.
|
|
4
|
+
|
|
5
|
+
### Built-in Tools (3)
|
|
6
|
+
|
|
7
|
+
1. server_info
|
|
8
|
+
2. server_health
|
|
9
|
+
3. list_adapters
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### core Group Tools (10)
|
|
14
|
+
|
|
15
|
+
4. sqlite_read_query
|
|
16
|
+
5. sqlite_write_query
|
|
17
|
+
6. sqlite_create_table
|
|
18
|
+
7. sqlite_list_tables
|
|
19
|
+
8. sqlite_describe_table
|
|
20
|
+
9. sqlite_drop_table
|
|
21
|
+
10. sqlite_get_indexes
|
|
22
|
+
11. sqlite_create_index
|
|
23
|
+
12. sqlite_drop_index
|
|
24
|
+
13. sqlite_execute_code
|
|
25
|
+
|
|
26
|
+
**Checklist:**
|
|
27
|
+
|
|
28
|
+
1. `server_info` → verify server name, version, adapter info present
|
|
29
|
+
2. `server_health` → verify healthy status
|
|
30
|
+
3. `list_adapters` → verify at least one adapter listed
|
|
31
|
+
4. `sqlite_read_query({query: "SELECT COUNT(*) AS n FROM test_products"})` → `{rows: [{n: 16}]}`
|
|
32
|
+
5. `sqlite_read_query({query: "SELECT name, price FROM test_products WHERE price > 500"})` → 1 result: `Laptop Pro 15` (1299.99)
|
|
33
|
+
6. `sqlite_read_query({query: "SELECT COUNT(*) AS n FROM test_orders WHERE status = 'completed'"})` → `{rows: [{n: 8}]}`
|
|
34
|
+
7. `sqlite_list_tables` → verify `test_products`, `test_orders`, `test_jsonb_docs`, `test_articles`, `test_users`, `test_measurements`, `test_embeddings`, `test_locations`, `test_categories`, `test_events` all present
|
|
35
|
+
8. `sqlite_describe_table({table: "test_products"})` → verify columns include `id` (INTEGER), `name` (TEXT), `price` (REAL), `category` (TEXT)
|
|
36
|
+
9. `sqlite_get_indexes({table: "test_orders"})` → verify `idx_orders_status` and `idx_orders_date` present
|
|
37
|
+
10. `sqlite_create_table({table: "temp_core_test", columns: [{name: "id", type: "INTEGER", primaryKey: true}, {name: "name", type: "TEXT"}, {name: "value", type: "REAL"}]})` → success
|
|
38
|
+
11. `sqlite_write_query({query: "INSERT INTO temp_core_test (id, name, value) VALUES (1, 'alpha', 10.5), (2, 'beta', 20.0)"})` → `{rowsAffected: 2}`
|
|
39
|
+
12. `sqlite_read_query({query: "SELECT * FROM temp_core_test"})` → 2 rows
|
|
40
|
+
13. `sqlite_create_index({table: "temp_core_test", columns: ["name"], indexName: "idx_temp_core_name"})` → success
|
|
41
|
+
14. `sqlite_drop_table({table: "temp_core_test"})` → success
|
|
42
|
+
|
|
43
|
+
**Code mode testing:**
|
|
44
|
+
|
|
45
|
+
15. `sqlite_execute_code({code: "const tables = await sqlite.core.listTables(); return tables;"})` → returns list of tables including `test_products`, `test_orders`, etc.
|
|
46
|
+
16. `sqlite_execute_code({code: "const result = await sqlite.core.readQuery('SELECT COUNT(*) AS n FROM test_products'); return result;", readonly: true})` → `{rows: [{n: 16}]}` (verify readonly mode works)
|
|
47
|
+
17. `sqlite_execute_code({code: "const result = await sqlite.core.writeQuery('INSERT INTO test_products VALUES (999, \"x\", \"x\", 0, \"x\", \"x\")'); return result;", readonly: true})` → `result` contains `{success: false, code: "CODEMODE_READONLY_VIOLATION"}` (code mode returns errors as values, not thrown exceptions)
|
|
48
|
+
|
|
49
|
+
**Error path testing:**
|
|
50
|
+
|
|
51
|
+
🔴 18. `sqlite_describe_table({table: "nonexistent_table_xyz"})` → structured error response, NOT a raw MCP exception
|
|
52
|
+
🔴 19. `sqlite_read_query({query: "SELECT * FROM nonexistent_table_xyz"})` → structured error mentioning table name
|
|
53
|
+
🔴 20. `sqlite_get_indexes({table: "nonexistent_table_xyz"})` → report behavior (structured error or empty result)
|
|
54
|
+
🔴 21. `sqlite_drop_table({table: "nonexistent_table_xyz"})` → structured error or `{existed: false}` style response
|
|
55
|
+
|
|
56
|
+
**Zod validation sweep** — call each tool with `{}` (empty params). Every response must be a handler error (`{success: false, error: "Validation error: ..."}`) — NOT a raw MCP error frame:
|
|
57
|
+
|
|
58
|
+
🔴 22. `sqlite_read_query({})` → handler error
|
|
59
|
+
🔴 23. `sqlite_write_query({})` → handler error
|
|
60
|
+
🔴 24. `sqlite_create_table({})` → handler error
|
|
61
|
+
🔴 25. `sqlite_describe_table({})` → handler error
|
|
62
|
+
🔴 26. `sqlite_drop_table({})` → handler error
|
|
63
|
+
🔴 27. `sqlite_get_indexes({})` → handler error
|
|
64
|
+
🔴 28. `sqlite_create_index({})` → handler error
|
|
65
|
+
🔴 29. `sqlite_drop_index({})` → handler error
|
|
66
|
+
🔴 30. `sqlite_execute_code({})` → handler error (has required `code` param)
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## json Group-Specific Testing (Native and WASM are identical)
|
|
71
|
+
|
|
72
|
+
> **Instructions**: Execute every numbered checklist item with the exact inputs shown. Compare responses against the expected results. Report any deviation. These are the minimum-bar tests that must pass every run — freeform testing comes after.
|
|
73
|
+
|
|
74
|
+
### Built-in Tools (3)
|
|
75
|
+
|
|
76
|
+
1. server_info
|
|
77
|
+
2. server_health
|
|
78
|
+
3. list_adapters
|
|
79
|
+
|
|
80
|
+
### json Group Tools (24)
|
|
81
|
+
|
|
82
|
+
4. sqlite_json_valid
|
|
83
|
+
5. sqlite_json_extract
|
|
84
|
+
6. sqlite_json_set
|
|
85
|
+
7. sqlite_json_remove
|
|
86
|
+
8. sqlite_json_type
|
|
87
|
+
9. sqlite_json_array_length
|
|
88
|
+
10. sqlite_json_array_append
|
|
89
|
+
11. sqlite_json_keys
|
|
90
|
+
12. sqlite_json_each
|
|
91
|
+
13. sqlite_json_group_array
|
|
92
|
+
14. sqlite_json_group_object
|
|
93
|
+
15. sqlite_json_pretty
|
|
94
|
+
16. sqlite_jsonb_convert
|
|
95
|
+
17. sqlite_json_storage_info
|
|
96
|
+
18. sqlite_json_normalize_column
|
|
97
|
+
19. sqlite_json_insert
|
|
98
|
+
20. sqlite_json_update
|
|
99
|
+
21. sqlite_json_select
|
|
100
|
+
22. sqlite_json_query
|
|
101
|
+
23. sqlite_json_validate_path
|
|
102
|
+
24. sqlite_json_merge
|
|
103
|
+
25. sqlite_json_analyze_schema
|
|
104
|
+
26. sqlite_create_json_collection
|
|
105
|
+
27. sqlite_execute_code
|
|
106
|
+
|
|
107
|
+
**Test data reference (test_jsonb_docs):**
|
|
108
|
+
|
|
109
|
+
| id | doc.type | doc.author | doc.views | metadata.source | tags |
|
|
110
|
+
| --- | -------- | ---------- | --------- | --------------- | ------------------------------------ |
|
|
111
|
+
| 1 | article | Alice | 1250 | blog | ["database","tutorial","beginner"] |
|
|
112
|
+
| 2 | article | Bob | 890 | docs | ["json","advanced","sqlite"] |
|
|
113
|
+
| 3 | video | Carol | 5400 | youtube | ["mcp","protocol","ai"] |
|
|
114
|
+
| 4 | article | David | 670 | wiki | ["fts5","search","indexing"] |
|
|
115
|
+
| 5 | podcast | Eve | — | spotify | ["performance","tips","podcast"] |
|
|
116
|
+
| 6 | article | Frank | 2100 | medium | ["vector","embeddings","similarity"] |
|
|
117
|
+
|
|
118
|
+
Row 4 has nested path: `doc → nested → level1 → level2 = "deep value"`
|
|
119
|
+
|
|
120
|
+
**Checklist:**
|
|
121
|
+
|
|
122
|
+
1. `sqlite_json_extract({table: "test_jsonb_docs", column: "doc", path: "$.author", whereClause: "id = 1"})` → result contains `"Alice"`
|
|
123
|
+
2. `sqlite_json_extract({table: "test_jsonb_docs", column: "doc", path: "$.nested.level1.level2", whereClause: "id = 4"})` → result contains `"deep value"`
|
|
124
|
+
3. `sqlite_json_keys({table: "test_jsonb_docs", column: "doc", whereClause: "id = 1"})` → keys include `type`, `title`, `author`, `views`, `rating`
|
|
125
|
+
4. `sqlite_json_type({table: "test_jsonb_docs", column: "tags", whereClause: "id = 1"})` → `"array"`
|
|
126
|
+
5. `sqlite_json_type({table: "test_jsonb_docs", column: "doc", whereClause: "id = 1"})` → `"object"`
|
|
127
|
+
6. `sqlite_json_array_length({table: "test_jsonb_docs", column: "tags", whereClause: "id = 1"})` → `3`
|
|
128
|
+
7. `sqlite_json_valid({json: "{\"type\":\"article\",\"title\":\"Getting Started with SQLite\",\"author\":\"Alice\",\"views\":1250,\"rating\":4.5}"})` → `{valid: true}`
|
|
129
|
+
8. `sqlite_json_validate_path({path: "$.author"})` → valid
|
|
130
|
+
9. `sqlite_json_pretty({json: "{\"type\":\"article\",\"author\":\"Alice\",\"views\":1250}"})` → formatted JSON with indentation
|
|
131
|
+
10. `sqlite_json_each({table: "test_jsonb_docs", column: "tags", whereClause: "id = 1"})` → 3 expanded rows: `database`, `tutorial`, `beginner`
|
|
132
|
+
11. `sqlite_json_analyze_schema({table: "test_jsonb_docs", column: "doc"})` → inferred schema with `type`, `author`, etc.
|
|
133
|
+
12. `sqlite_json_merge({table: "test_jsonb_docs", column: "doc", mergeData: {"featured": true}, whereClause: "id = 999"})` → `{rowsAffected: 0}` (no matching rows, non-destructive test)
|
|
134
|
+
13. `sqlite_json_select({table: "test_jsonb_docs", column: "doc", paths: ["$.author", "$.views"]})` → rows with author and views columns
|
|
135
|
+
14. `sqlite_json_query({table: "test_jsonb_docs", column: "doc", filterPaths: {"$.type": "article"}})` → 4 rows (rows 1,2,4,6)
|
|
136
|
+
15. `sqlite_json_storage_info({table: "test_jsonb_docs", column: "doc"})` → storage analysis
|
|
137
|
+
16. `sqlite_json_group_array({table: "test_jsonb_docs", valueColumn: "json_extract(doc, '$.author')", allowExpressions: true})` → array of all authors `["Alice","Bob","Carol","David","Eve","Frank"]`
|
|
138
|
+
17. `sqlite_json_group_object({table: "test_jsonb_docs", keyColumn: "json_extract(doc, '$.author')", valueColumn: "json_extract(doc, '$.views')", allowExpressions: true})` → object mapping authors to view counts
|
|
139
|
+
18. `sqlite_jsonb_convert({table: "test_jsonb_docs", column: "doc", whereClause: "id = 1"})` → JSONB binary conversion result
|
|
140
|
+
19. `sqlite_json_normalize_column({table: "test_jsonb_docs", column: "doc"})` → normalization report for the doc column
|
|
141
|
+
|
|
142
|
+
**Write operations (use temp tables):**
|
|
143
|
+
|
|
144
|
+
20. `sqlite_create_json_collection({tableName: "temp_json_test"})` → creates table with JSON columns
|
|
145
|
+
21. `sqlite_json_set` on `temp_json_test` → modify a JSON value
|
|
146
|
+
22. `sqlite_json_update` on `temp_json_test` → update an existing key's value (distinct from json_set: update requires key to exist)
|
|
147
|
+
23. `sqlite_json_insert` on `temp_json_test` → insert new key
|
|
148
|
+
24. `sqlite_json_remove` on `temp_json_test` → remove a key
|
|
149
|
+
25. `sqlite_json_array_append` on `temp_json_test` → add to array
|
|
150
|
+
26. Cleanup: drop `temp_json_test`
|
|
151
|
+
|
|
152
|
+
**Code mode testing:**
|
|
153
|
+
|
|
154
|
+
27. `sqlite_execute_code({code: "const result = await sqlite.json.extract({table: 'test_jsonb_docs', column: 'doc', path: '$.author', whereClause: 'id = 1'}); return result;"})` → result contains `"Alice"`
|
|
155
|
+
28. `sqlite_execute_code({code: "const keys = await sqlite.json.keys({table: 'test_jsonb_docs', column: 'doc', whereClause: 'id = 1'}); return keys;"})` → keys include `type`, `title`, `author`
|
|
156
|
+
|
|
157
|
+
**Error path testing:**
|
|
158
|
+
|
|
159
|
+
🔴 29. `sqlite_json_extract({table: "nonexistent_table_xyz", column: "doc", path: "$.x"})` → structured error
|
|
160
|
+
🔴 30. `sqlite_json_extract({table: "test_jsonb_docs", column: "nonexistent_col", path: "$.x"})` → report behavior
|
|
161
|
+
🔴 31. `sqlite_json_validate_path({path: "invalid path !@#"})` → report behavior
|
|
162
|
+
|
|
163
|
+
**Zod validation sweep** — call each tool with `{}` (empty params). Must return handler error, NOT raw MCP error:
|
|
164
|
+
|
|
165
|
+
🔴 32. `sqlite_json_valid({})` → handler error
|
|
166
|
+
🔴 33. `sqlite_json_extract({})` → handler error
|
|
167
|
+
🔴 34. `sqlite_json_set({})` → handler error
|
|
168
|
+
🔴 35. `sqlite_json_remove({})` → handler error
|
|
169
|
+
🔴 36. `sqlite_json_type({})` → handler error
|
|
170
|
+
🔴 37. `sqlite_json_array_length({})` → handler error
|
|
171
|
+
🔴 38. `sqlite_json_array_append({})` → handler error
|
|
172
|
+
🔴 39. `sqlite_json_keys({})` → handler error
|
|
173
|
+
🔴 40. `sqlite_json_each({})` → handler error
|
|
174
|
+
🔴 41. `sqlite_json_group_array({})` → handler error
|
|
175
|
+
🔴 42. `sqlite_json_group_object({})` → handler error
|
|
176
|
+
🔴 43. `sqlite_json_pretty({})` → handler error
|
|
177
|
+
🔴 44. `sqlite_jsonb_convert({})` → handler error
|
|
178
|
+
🔴 45. `sqlite_json_storage_info({})` → handler error
|
|
179
|
+
🔴 46. `sqlite_json_normalize_column({})` → handler error
|
|
180
|
+
🔴 47. `sqlite_json_insert({})` → handler error
|
|
181
|
+
🔴 48. `sqlite_json_update({})` → handler error
|
|
182
|
+
🔴 49. `sqlite_json_select({})` → handler error
|
|
183
|
+
🔴 50. `sqlite_json_query({})` → handler error
|
|
184
|
+
🔴 51. `sqlite_json_validate_path({})` → handler error
|
|
185
|
+
🔴 52. `sqlite_json_merge({})` → handler error
|
|
186
|
+
🔴 53. `sqlite_json_analyze_schema({})` → handler error
|
|
187
|
+
🔴 54. `sqlite_create_json_collection({})` → handler error
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## text Group-Specific Testing (Native- 18 Tools)
|
|
192
|
+
|
|
193
|
+
> **Instructions**: Execute every numbered checklist item with the exact inputs shown. Compare responses against the expected results. Report any deviation. These are the minimum-bar tests that must pass every run — freeform testing comes after.
|
|
194
|
+
|
|
195
|
+
> **FTS Testing Notes:** After `sqlite_fts_create`, always call `sqlite_fts_rebuild` before searching. `test_articles` searchable terms: `SQLite`, `database`, `JSON`, `FTS`, `vector`, `API`, `search`, `MCP`.
|
|
196
|
+
|
|
197
|
+
### Built-in Tools (3)
|
|
198
|
+
|
|
199
|
+
1. server_info
|
|
200
|
+
2. server_health
|
|
201
|
+
3. list_adapters
|
|
202
|
+
|
|
203
|
+
### text Group Tools
|
|
204
|
+
|
|
205
|
+
4. sqlite_regex_extract
|
|
206
|
+
5. sqlite_regex_match
|
|
207
|
+
6. sqlite_text_split
|
|
208
|
+
7. sqlite_text_concat
|
|
209
|
+
8. sqlite_text_replace
|
|
210
|
+
9. sqlite_text_trim
|
|
211
|
+
10. sqlite_text_case
|
|
212
|
+
11. sqlite_text_substring
|
|
213
|
+
12. sqlite_fuzzy_match
|
|
214
|
+
13. sqlite_phonetic_match
|
|
215
|
+
14. sqlite_text_normalize
|
|
216
|
+
15. sqlite_text_validate
|
|
217
|
+
16. sqlite_advanced_search
|
|
218
|
+
17. sqlite_fts_create `[NATIVE ONLY]`
|
|
219
|
+
18. sqlite_fts_search `[NATIVE ONLY]`
|
|
220
|
+
19. sqlite_fts_rebuild `[NATIVE ONLY]`
|
|
221
|
+
20. sqlite_fts_match_info `[NATIVE ONLY]`
|
|
222
|
+
21. sqlite_execute_code
|
|
223
|
+
|
|
224
|
+
### text Group Tools (WASM- 14 Tools)
|
|
225
|
+
|
|
226
|
+
Same as Native minus the 4 FTS5 tools (items 17-20). WASM mode excludes FTS5 tools entirely.
|
|
227
|
+
|
|
228
|
+
**Test data reference:**
|
|
229
|
+
|
|
230
|
+
- `test_articles` (8 rows): FTS5 searchable terms: `SQLite`, `database`, `JSON`, `FTS`, `vector`, `API`, `search`, `MCP`
|
|
231
|
+
- `test_users` (9 rows): Emails include `@example.com`, `@company.org`, `@gmail.com`, etc. One user (`testuser`) has `test.user@gmail.com`. Phone formats: `+1-555-0101`, `+44-20-7123-4567`, `+82-2-1234-5678`
|
|
232
|
+
- `test_products` row 16: `name = 'Café Décor Light'` — has accented characters for `strip_accents` testing
|
|
233
|
+
|
|
234
|
+
**Checklist:**
|
|
235
|
+
|
|
236
|
+
1. `sqlite_regex_match({table: "test_users", column: "email", pattern: "@gmail\\.com$"})` → at least 1 result (`test.user@gmail.com`)
|
|
237
|
+
2. `sqlite_regex_extract({table: "test_users", column: "email", pattern: "@([^.]+)\\.", groupIndex: 1})` → extract domain parts (example, company, startup, etc.)
|
|
238
|
+
3. `sqlite_fuzzy_match({table: "test_products", column: "name", search: "Laptp", maxDistance: 3})` → results include `Laptop Pro 15`
|
|
239
|
+
4. `sqlite_phonetic_match({table: "test_products", column: "name", search: "Labtop"})` → should find `Laptop Pro 15` via Soundex (both produce L131)
|
|
240
|
+
5. `sqlite_text_validate({table: "test_users", column: "email", pattern: "email"})` → all 9 rows should be valid emails
|
|
241
|
+
6. `sqlite_text_validate({table: "test_users", column: "phone", pattern: "phone"})` → report valid/invalid counts (one user has NULL phone)
|
|
242
|
+
7. `sqlite_text_case({table: "test_users", column: "username", mode: "upper"})` → all usernames uppercased
|
|
243
|
+
8. `sqlite_text_normalize({table: "test_products", column: "name", mode: "strip_accents"})` → `Café Décor Light` becomes `Cafe Decor Light`
|
|
244
|
+
9. `sqlite_text_split({table: "test_users", column: "email", delimiter: "@"})` → each email split into local + domain parts
|
|
245
|
+
10. `sqlite_text_concat({table: "test_users", columns: ["username", "email"], separator: " - "})` → concatenated strings
|
|
246
|
+
11. `sqlite_text_replace({table: "test_users", column: "email", searchPattern: "@example.com", replaceWith: "@test.org", whereClause: "email LIKE '%@example.com'"})` → 1 row affected (write operation — revert with `searchPattern: "@test.org", replaceWith: "@example.com", whereClause: "email LIKE '%@test.org'"` afterward)
|
|
247
|
+
12. `sqlite_text_trim({table: "test_users", column: "bio"})` → trimmed bios
|
|
248
|
+
13. `sqlite_text_substring({table: "test_users", column: "username", start: 1, length: 4})` → first 4 chars of each username
|
|
249
|
+
14. `sqlite_advanced_search({table: "test_products", column: "name", searchTerm: "keyboard", techniques: ["exact", "fuzzy", "phonetic"]})` → should find `Mechanical Keyboard`
|
|
250
|
+
|
|
251
|
+
**FTS5 tools `[NATIVE ONLY]`:**
|
|
252
|
+
|
|
253
|
+
15. `sqlite_fts_create({sourceTable: "test_users", columns: ["username", "bio"], ftsTable: "temp_users_fts"})` → FTS5 virtual table created
|
|
254
|
+
16. `sqlite_fts_rebuild({table: "temp_users_fts"})` → rebuild index before searching
|
|
255
|
+
17. `sqlite_fts_search({table: "temp_users_fts", query: "test*"})` → verify results from test_users data (prefix query needed since no standalone "test" token exists)
|
|
256
|
+
18. Cleanup: `sqlite_drop_table({table: "temp_users_fts"})` (drop the temp FTS table)
|
|
257
|
+
19. `sqlite_fts_search({table: "test_articles_fts", query: "SQLite"})` → at least 1 result (article 1: "Introduction to SQLite")
|
|
258
|
+
20. `sqlite_fts_search({table: "test_articles_fts", query: "MCP protocol"})` → matches article 3: "The Model Context Protocol Explained"
|
|
259
|
+
21. `sqlite_fts_search({table: "test_articles_fts", query: "nonexistent_term_xyz"})` → 0 results
|
|
260
|
+
22. `sqlite_fts_match_info({table: "test_articles_fts", query: "database"})` → match info with scoring data
|
|
261
|
+
23. `sqlite_fts_rebuild({table: "test_articles_fts"})` → success
|
|
262
|
+
|
|
263
|
+
**Code mode testing:**
|
|
264
|
+
|
|
265
|
+
24. `sqlite_execute_code({code: "const result = await sqlite.text.fuzzyMatch({table: 'test_products', column: 'name', search: 'Laptp', maxDistance: 3}); return result;"})` → results include `Laptop Pro 15`
|
|
266
|
+
25. `sqlite_execute_code({code: "const result = await sqlite.text.regexMatch({table: 'test_users', column: 'email', pattern: '@gmail\\\\.com$'}); return result;"})` → at least 1 result
|
|
267
|
+
|
|
268
|
+
**Error path testing:**
|
|
269
|
+
|
|
270
|
+
🔴 26. `sqlite_regex_match({table: "nonexistent_table_xyz", column: "x", pattern: "."})` → structured error
|
|
271
|
+
🔴 27. `sqlite_fuzzy_match({table: "test_users", column: "nonexistent_col", search: "test"})` → structured error with code `COLUMN_NOT_FOUND`
|
|
272
|
+
🔴 28. `sqlite_fts_search({table: "nonexistent_fts_xyz", query: "test"})` `[NATIVE ONLY]` → structured error
|
|
273
|
+
|
|
274
|
+
**Zod validation sweep** — call each tool with `{}` (empty params). Must return handler error, NOT raw MCP error:
|
|
275
|
+
|
|
276
|
+
🔴 29. `sqlite_regex_extract({})` → handler error
|
|
277
|
+
🔴 30. `sqlite_regex_match({})` → handler error
|
|
278
|
+
🔴 31. `sqlite_text_split({})` → handler error
|
|
279
|
+
🔴 32. `sqlite_text_concat({})` → handler error
|
|
280
|
+
🔴 33. `sqlite_text_replace({})` → handler error
|
|
281
|
+
🔴 34. `sqlite_text_trim({})` → handler error
|
|
282
|
+
🔴 35. `sqlite_text_case({})` → handler error
|
|
283
|
+
🔴 36. `sqlite_text_substring({})` → handler error
|
|
284
|
+
🔴 37. `sqlite_fuzzy_match({})` → handler error
|
|
285
|
+
🔴 38. `sqlite_phonetic_match({})` → handler error
|
|
286
|
+
🔴 39. `sqlite_text_normalize({})` → handler error
|
|
287
|
+
🔴 40. `sqlite_text_validate({})` → handler error
|
|
288
|
+
🔴 41. `sqlite_advanced_search({})` → handler error
|
|
289
|
+
🔴 42. `sqlite_fts_create({})` `[NATIVE ONLY]` → handler error
|
|
290
|
+
🔴 43. `sqlite_fts_search({})` `[NATIVE ONLY]` → handler error
|
|
291
|
+
🔴 44. `sqlite_fts_rebuild({})` `[NATIVE ONLY]` → handler error
|
|
292
|
+
🔴 45. `sqlite_fts_match_info({})` `[NATIVE ONLY]` → handler error
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## stats Group-Specific Testing
|
|
297
|
+
|
|
298
|
+
> **Instructions**: Execute every numbered checklist item with the exact inputs shown. Compare responses against the expected results. Report any deviation. These are the minimum-bar tests that must pass every run — freeform testing comes after.
|
|
299
|
+
|
|
300
|
+
### Built-in Tools (3)
|
|
301
|
+
|
|
302
|
+
1. server_info
|
|
303
|
+
2. server_health
|
|
304
|
+
3. list_adapters
|
|
305
|
+
|
|
306
|
+
### stats Group Tools — (Native- 20 Tools)
|
|
307
|
+
|
|
308
|
+
4. sqlite_stats_basic
|
|
309
|
+
5. sqlite_stats_count
|
|
310
|
+
6. sqlite_stats_group_by
|
|
311
|
+
7. sqlite_stats_histogram
|
|
312
|
+
8. sqlite_stats_percentile
|
|
313
|
+
9. sqlite_stats_correlation
|
|
314
|
+
10. sqlite_stats_top_n
|
|
315
|
+
11. sqlite_stats_distinct
|
|
316
|
+
12. sqlite_stats_summary
|
|
317
|
+
13. sqlite_stats_frequency
|
|
318
|
+
14. sqlite_stats_outliers
|
|
319
|
+
15. sqlite_stats_regression
|
|
320
|
+
16. sqlite_stats_hypothesis
|
|
321
|
+
17. sqlite_window_row_number `[NATIVE ONLY]`
|
|
322
|
+
18. sqlite_window_rank `[NATIVE ONLY]`
|
|
323
|
+
19. sqlite_window_lag_lead `[NATIVE ONLY]`
|
|
324
|
+
20. sqlite_window_running_total `[NATIVE ONLY]`
|
|
325
|
+
21. sqlite_window_moving_avg `[NATIVE ONLY]`
|
|
326
|
+
22. sqlite_window_ntile `[NATIVE ONLY]`
|
|
327
|
+
23. sqlite_execute_code
|
|
328
|
+
|
|
329
|
+
### stats Group Tools (WASM- 14 Tools)
|
|
330
|
+
|
|
331
|
+
Same as Native minus the 6 window function tools (items 17-22).
|
|
332
|
+
|
|
333
|
+
**Test data:** `test_measurements` (200 rows, sensor_id 1-5, columns: temperature, humidity, pressure, measured_at). `test_products` (16 rows, price column). `test_events` (100 rows, event_type column: page_view, click, purchase, login, search).
|
|
334
|
+
|
|
335
|
+
**Checklist:**
|
|
336
|
+
|
|
337
|
+
1. `sqlite_stats_basic({table: "test_measurements", column: "temperature"})` → verify `count: 200`, `min`, `max`, `avg` present
|
|
338
|
+
2. `sqlite_stats_count({table: "test_products"})` → `{count: 16}`
|
|
339
|
+
3. `sqlite_stats_count({table: "test_products", column: "category", distinct: true})` → distinct category count (electronics, accessories, office = 3)
|
|
340
|
+
4. `sqlite_stats_group_by({table: "test_measurements", groupByColumn: "sensor_id", valueColumn: "temperature", stat: "avg"})` → 5 groups (sensor_id 1-5) with average temperatures
|
|
341
|
+
5. `sqlite_stats_histogram({table: "test_measurements", column: "temperature", buckets: 5})` → 5 buckets
|
|
342
|
+
6. `sqlite_stats_percentile({table: "test_measurements", column: "temperature", percentiles: [25, 50, 75, 90]})` → 4 percentile values
|
|
343
|
+
7. `sqlite_stats_correlation({table: "test_measurements", column1: "temperature", column2: "humidity"})` → correlation value between -1 and 1
|
|
344
|
+
8. `sqlite_stats_top_n({table: "test_products", column: "price", n: 3, orderDirection: "desc"})` → top 3 most expensive products (Laptop Pro 15 at 1299.99 should be #1)
|
|
345
|
+
9. `sqlite_stats_distinct({table: "test_locations", column: "city"})` → distinct city count (New York, Paris, London, Tokyo, Sydney, San Francisco = 6)
|
|
346
|
+
10. `sqlite_stats_summary({table: "test_measurements", columns: ["temperature", "humidity", "pressure"]})` → summaries array with 3 entries
|
|
347
|
+
11. `sqlite_stats_frequency({table: "test_events", column: "event_type"})` → distribution of page_view, click, purchase, login, search (each ~20)
|
|
348
|
+
12. `sqlite_stats_outliers({table: "test_measurements", column: "temperature"})` → outlier detection result
|
|
349
|
+
13. `sqlite_stats_regression({table: "test_measurements", xColumn: "temperature", yColumn: "humidity", degree: 1})` → regression coefficients
|
|
350
|
+
14. `sqlite_stats_hypothesis({table: "test_measurements", column: "temperature", testType: "ttest_one", expectedMean: 25})` → verify `statistic` and `pValue` present
|
|
351
|
+
|
|
352
|
+
**Window functions `[NATIVE ONLY]`:**
|
|
353
|
+
|
|
354
|
+
15. `sqlite_window_row_number({table: "test_products", orderBy: "price DESC"})` → products ranked by price
|
|
355
|
+
16. `sqlite_window_rank({table: "test_products", orderBy: "price DESC"})` → rank with ties
|
|
356
|
+
17. `sqlite_window_running_total({table: "test_orders", valueColumn: "total_price", orderBy: "order_date"})` → cumulative totals
|
|
357
|
+
18. `sqlite_window_moving_avg({table: "test_measurements", valueColumn: "temperature", windowSize: 5, orderBy: "measured_at"})` → moving averages
|
|
358
|
+
19. `sqlite_window_lag_lead({table: "test_orders", column: "total_price", direction: "lag", orderBy: "order_date"})` → lag/lead values
|
|
359
|
+
20. `sqlite_window_ntile({table: "test_products", buckets: 4, orderBy: "price"})` → quartile assignments
|
|
360
|
+
|
|
361
|
+
**Code mode testing:**
|
|
362
|
+
|
|
363
|
+
21. `sqlite_execute_code({code: "const result = await sqlite.stats.statsBasic({table: 'test_measurements', column: 'temperature'}); return result;"})` → verify `count: 200`, `min`, `max`, `avg` present
|
|
364
|
+
22. `sqlite_execute_code({code: "const result = await sqlite.stats.statsPercentile({table: 'test_measurements', column: 'temperature', percentiles: [50]}); return result;"})` → median value
|
|
365
|
+
|
|
366
|
+
**Error path testing:**
|
|
367
|
+
|
|
368
|
+
🔴 23. `sqlite_stats_basic({table: "nonexistent_table_xyz", column: "x"})` → structured error
|
|
369
|
+
🔴 24. `sqlite_stats_basic({table: "test_products", column: "nonexistent_col"})` → report behavior
|
|
370
|
+
🔴 25. `sqlite_stats_correlation({table: "test_products", column1: "name", column2: "description"})` → error about non-numeric columns
|
|
371
|
+
|
|
372
|
+
**Zod validation sweep** — call each tool with `{}` (empty params). Must return handler error, NOT raw MCP error:
|
|
373
|
+
|
|
374
|
+
🔴 26. `sqlite_stats_basic({})` → handler error
|
|
375
|
+
🔴 27. `sqlite_stats_count({})` → handler error
|
|
376
|
+
🔴 28. `sqlite_stats_group_by({})` → handler error
|
|
377
|
+
🔴 29. `sqlite_stats_histogram({})` → handler error
|
|
378
|
+
🔴 30. `sqlite_stats_percentile({})` → handler error
|
|
379
|
+
🔴 31. `sqlite_stats_correlation({})` → handler error
|
|
380
|
+
🔴 32. `sqlite_stats_top_n({})` → handler error
|
|
381
|
+
🔴 33. `sqlite_stats_distinct({})` → handler error
|
|
382
|
+
🔴 34. `sqlite_stats_summary({})` → handler error
|
|
383
|
+
🔴 35. `sqlite_stats_frequency({})` → handler error
|
|
384
|
+
🔴 36. `sqlite_stats_outliers({})` → handler error
|
|
385
|
+
🔴 37. `sqlite_stats_regression({})` → handler error
|
|
386
|
+
🔴 38. `sqlite_stats_hypothesis({})` → handler error
|
|
387
|
+
🔴 39. `sqlite_window_row_number({})` `[NATIVE ONLY]` → handler error
|
|
388
|
+
🔴 40. `sqlite_window_rank({})` `[NATIVE ONLY]` → handler error
|
|
389
|
+
🔴 41. `sqlite_window_lag_lead({})` `[NATIVE ONLY]` → handler error
|
|
390
|
+
🔴 42. `sqlite_window_running_total({})` `[NATIVE ONLY]` → handler error
|
|
391
|
+
🔴 43. `sqlite_window_moving_avg({})` `[NATIVE ONLY]` → handler error
|
|
392
|
+
🔴 44. `sqlite_window_ntile({})` `[NATIVE ONLY]` → handler error
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## vector Group-Specific Testing (Native and WASM are identical)
|
|
397
|
+
|
|
398
|
+
> **Instructions**: Execute every numbered checklist item with the exact inputs shown. Compare responses against the expected results. Report any deviation. These are the minimum-bar tests that must pass every run — freeform testing comes after.
|
|
399
|
+
|
|
400
|
+
> **Note:** Vector tools use pure JS computations (cosine, euclidean, dot product) with JSON-stored vectors — no native SQLite extension required. All 12 tools work identically in both WASM and Native modes.
|
|
401
|
+
|
|
402
|
+
### Built-in Tools (3)
|
|
403
|
+
|
|
404
|
+
1. server_info
|
|
405
|
+
2. server_health
|
|
406
|
+
3. list_adapters
|
|
407
|
+
|
|
408
|
+
### vector Group Tools (12 Tools)
|
|
409
|
+
|
|
410
|
+
4. sqlite_vector_create_table
|
|
411
|
+
5. sqlite_vector_store
|
|
412
|
+
6. sqlite_vector_batch_store
|
|
413
|
+
7. sqlite_vector_search
|
|
414
|
+
8. sqlite_vector_get
|
|
415
|
+
9. sqlite_vector_delete
|
|
416
|
+
10. sqlite_vector_count
|
|
417
|
+
11. sqlite_vector_stats
|
|
418
|
+
12. sqlite_vector_dimensions
|
|
419
|
+
13. sqlite_vector_normalize
|
|
420
|
+
14. sqlite_vector_distance
|
|
421
|
+
15. sqlite_execute_code
|
|
422
|
+
|
|
423
|
+
**Test data:** `test_embeddings` (20 rows, 8-dim vectors, categories: tech, database, food, fitness, travel). Row 1: content="Machine learning fundamentals", embedding=[0.12, 0.45, -0.23, 0.78, 0.34, -0.56, 0.89, 0.01].
|
|
424
|
+
|
|
425
|
+
**Checklist:**
|
|
426
|
+
|
|
427
|
+
1. `sqlite_vector_count({table: "test_embeddings"})` → `{count: 20}`
|
|
428
|
+
2. `sqlite_vector_dimensions({table: "test_embeddings"})` → `{dimensions: 8}`
|
|
429
|
+
3. `sqlite_vector_get({table: "test_embeddings", idColumn: "id", vectorColumn: "embedding", id: 1})` → verify content="Machine learning fundamentals", category="tech", embedding has 8 dimensions
|
|
430
|
+
4. `sqlite_vector_search({table: "test_embeddings", vectorColumn: "embedding", queryVector: [0.12, 0.45, -0.23, 0.78, 0.34, -0.56, 0.89, 0.01], metric: "cosine", limit: 3})` → top result should be row 1 (exact match, \_similarity ≈ 1)
|
|
431
|
+
5. `sqlite_vector_search({table: "test_embeddings", vectorColumn: "embedding", queryVector: [0.12, 0.45, -0.23, 0.78, 0.34, -0.56, 0.89, 0.01], metric: "cosine", limit: 3, whereClause: "category = 'database'"})` → only database category results
|
|
432
|
+
6. `sqlite_vector_distance({vector1: [1, 0, 0], vector2: [0, 1, 0], metric: "cosine"})` → distance ≈ 1.0 (orthogonal vectors)
|
|
433
|
+
7. `sqlite_vector_distance({vector1: [3, 4], vector2: [0, 0], metric: "euclidean"})` → distance = 5.0
|
|
434
|
+
8. `sqlite_vector_normalize({vector: [3, 4]})` → `{normalized: [0.6, 0.8], originalMagnitude: 5}`
|
|
435
|
+
9. `sqlite_vector_stats({table: "test_embeddings", vectorColumn: "embedding"})` → verify min/max/avg magnitude
|
|
436
|
+
|
|
437
|
+
**Write operations (use temp tables):**
|
|
438
|
+
|
|
439
|
+
10. `sqlite_vector_create_table({tableName: "temp_vector_test", dimensions: 8, additionalColumns: [{name: "content", type: "TEXT"}, {name: "category", type: "TEXT"}]})` → success
|
|
440
|
+
11. `sqlite_vector_store({table: "temp_vector_test", idColumn: "id", vectorColumn: "vector", id: 1, vector: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]})` → success (note: additional columns like content/category cannot be set via this tool)
|
|
441
|
+
12. `sqlite_vector_batch_store({table: "temp_vector_test", idColumn: "id", vectorColumn: "vector", items: [{id: 2, vector: [0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 0.77, 0.88]}, {id: 3, vector: [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2]}]})` → `{stored: 2}`
|
|
442
|
+
13. `sqlite_vector_count({table: "temp_vector_test"})` → `{count: 3}`
|
|
443
|
+
14. `sqlite_vector_delete({table: "temp_vector_test", idColumn: "id", ids: [1]})` → success
|
|
444
|
+
15. `sqlite_vector_count({table: "temp_vector_test"})` → `{count: 2}`
|
|
445
|
+
16. Cleanup: `sqlite_drop_table({table: "temp_vector_test"})` (via core tools if needed)
|
|
446
|
+
|
|
447
|
+
**Code mode testing:**
|
|
448
|
+
|
|
449
|
+
17. `sqlite_execute_code({code: "const result = await sqlite.vector.count({table: 'test_embeddings'}); return result;"})` → `{count: 20}`
|
|
450
|
+
18. `sqlite_execute_code({code: "const result = await sqlite.vector.distance({vector1: [3, 4], vector2: [0, 0], metric: 'euclidean'}); return result;"})` → distance = 5.0
|
|
451
|
+
|
|
452
|
+
**Error path testing:**
|
|
453
|
+
|
|
454
|
+
🔴 19. `sqlite_vector_search({table: "nonexistent_table_xyz", vectorColumn: "embedding", queryVector: [1,2,3], metric: "cosine"})` → structured error
|
|
455
|
+
🔴 20. `sqlite_vector_distance({vector1: [1, 2, 3], vector2: [1, 2], metric: "cosine"})` → error about dimension mismatch
|
|
456
|
+
|
|
457
|
+
**Zod validation sweep** — call each tool with `{}` (empty params). Must return handler error, NOT raw MCP error:
|
|
458
|
+
|
|
459
|
+
🔴 21. `sqlite_vector_create_table({})` → handler error
|
|
460
|
+
🔴 22. `sqlite_vector_store({})` → handler error
|
|
461
|
+
🔴 23. `sqlite_vector_batch_store({})` → handler error
|
|
462
|
+
🔴 24. `sqlite_vector_search({})` → handler error
|
|
463
|
+
🔴 25. `sqlite_vector_get({})` → handler error
|
|
464
|
+
🔴 26. `sqlite_vector_delete({})` → handler error
|
|
465
|
+
🔴 27. `sqlite_vector_count({})` → handler error
|
|
466
|
+
🔴 28. `sqlite_vector_stats({})` → handler error
|
|
467
|
+
🔴 29. `sqlite_vector_dimensions({})` → handler error
|
|
468
|
+
🔴 30. `sqlite_vector_normalize({})` → handler error
|
|
469
|
+
🔴 31. `sqlite_vector_distance({})` → handler error
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
## admin Group-Specific Testing
|
|
474
|
+
|
|
475
|
+
> **Instructions**: Execute every numbered checklist item with the exact inputs shown. Compare responses against the expected results. Report any deviation. These are the minimum-bar tests that must pass every run — freeform testing comes after.
|
|
476
|
+
|
|
477
|
+
> **CSV Testing Note:** Use `test-server/sample.csv` (columns: id, name, category, price, quantity, created_at) with **absolute paths** for CSV tool testing — relative paths resolve from IDE CWD.
|
|
478
|
+
|
|
479
|
+
### Built-in Tools (3)
|
|
480
|
+
|
|
481
|
+
1. server_info
|
|
482
|
+
2. server_health
|
|
483
|
+
3. list_adapters
|
|
484
|
+
|
|
485
|
+
### admin Group Tools (Native- 34 Tools)
|
|
486
|
+
|
|
487
|
+
4. sqlite_generate_series
|
|
488
|
+
5. sqlite_create_view
|
|
489
|
+
6. sqlite_list_views
|
|
490
|
+
7. sqlite_drop_view
|
|
491
|
+
8. sqlite_dbstat
|
|
492
|
+
9. sqlite_vacuum
|
|
493
|
+
10. sqlite_list_virtual_tables
|
|
494
|
+
11. sqlite_virtual_table_info
|
|
495
|
+
12. sqlite_drop_virtual_table
|
|
496
|
+
13. sqlite_create_csv_table
|
|
497
|
+
14. sqlite_analyze_csv_schema
|
|
498
|
+
15. sqlite_create_rtree_table
|
|
499
|
+
16. sqlite_create_series_table
|
|
500
|
+
17. sqlite_backup
|
|
501
|
+
18. sqlite_analyze
|
|
502
|
+
19. sqlite_integrity_check
|
|
503
|
+
20. sqlite_optimize
|
|
504
|
+
21. sqlite_restore
|
|
505
|
+
22. sqlite_verify_backup
|
|
506
|
+
23. sqlite_index_stats
|
|
507
|
+
24. sqlite_pragma_compile_options
|
|
508
|
+
25. sqlite_pragma_database_list
|
|
509
|
+
26. sqlite_pragma_optimize
|
|
510
|
+
27. sqlite_pragma_settings
|
|
511
|
+
28. sqlite_pragma_table_info
|
|
512
|
+
29. sqlite_append_insight
|
|
513
|
+
30. sqlite_transaction_begin
|
|
514
|
+
31. sqlite_transaction_commit
|
|
515
|
+
32. sqlite_transaction_rollback
|
|
516
|
+
33. sqlite_transaction_savepoint
|
|
517
|
+
34. sqlite_transaction_release
|
|
518
|
+
35. sqlite_transaction_rollback_to
|
|
519
|
+
36. sqlite_transaction_execute
|
|
520
|
+
37. sqlite_execute_code
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
### admin Group Tools (WASM- 27 Tools)
|
|
525
|
+
|
|
526
|
+
Same as Native minus the 7 transaction management tools (items 30-36).
|
|
527
|
+
|
|
528
|
+
**Checklist — Pragma & Inspection:**
|
|
529
|
+
|
|
530
|
+
1. `sqlite_pragma_database_list` → verify database path matches `test.db`
|
|
531
|
+
2. `sqlite_pragma_compile_options` → verify list of compile options returned
|
|
532
|
+
3. `sqlite_pragma_compile_options({filter: "FTS"})` → filtered subset containing FTS-related options (`ENABLE_FTS3`, `ENABLE_FTS4`, `ENABLE_FTS5`)
|
|
533
|
+
4. `sqlite_pragma_settings({pragma: "journal_mode"})` → `{value: "wal"}`
|
|
534
|
+
5. `sqlite_pragma_table_info({table: "test_products"})` → verify columns: id, name, description, price, category, created_at
|
|
535
|
+
6. `sqlite_index_stats` → verify index statistics for test database
|
|
536
|
+
7. `sqlite_integrity_check` → `ok` result
|
|
537
|
+
8. `sqlite_analyze` → success
|
|
538
|
+
9. `sqlite_dbstat({summarize: true})` → per-table storage metrics
|
|
539
|
+
|
|
540
|
+
**Checklist — View Management:**
|
|
541
|
+
|
|
542
|
+
10. `sqlite_create_view({viewName: "temp_view_orders", selectQuery: "SELECT product_id, COUNT(*) as order_count, SUM(total_price) as revenue FROM test_orders GROUP BY product_id"})` → success
|
|
543
|
+
11. `sqlite_list_views` → verify `temp_view_orders` present
|
|
544
|
+
12. `sqlite_drop_view({viewName: "temp_view_orders"})` → success
|
|
545
|
+
|
|
546
|
+
**Checklist — Virtual Tables:**
|
|
547
|
+
|
|
548
|
+
13. `sqlite_list_virtual_tables` → verify `test_articles_fts` present (Native) or report behavior (WASM)
|
|
549
|
+
14. `sqlite_virtual_table_info({tableName: "test_articles_fts"})` → verify module and column info (Native)
|
|
550
|
+
15. `sqlite_generate_series({start: 1, stop: 5, step: 1})` → 5 values
|
|
551
|
+
16. `sqlite_create_rtree_table({tableName: "temp_rtree_test", dimensions: 2})` → R-Tree virtual table created with 2D bounding box columns
|
|
552
|
+
17. `sqlite_create_series_table({tableName: "temp_series_test", start: 1, stop: 10})` → regular table created with 10 rows (not a virtual table — see gotcha #15)
|
|
553
|
+
18. Cleanup: `sqlite_drop_virtual_table({tableName: "temp_rtree_test"})` and `sqlite_drop_table({table: "temp_series_test"})` (series is a regular table — use `sqlite_drop_table`)
|
|
554
|
+
|
|
555
|
+
**Checklist — Backup/Restore:**
|
|
556
|
+
|
|
557
|
+
19. `sqlite_backup({targetPath: "<absolute-path>/test-server/test-backup.db"})` → success with backup file info (⚠️ use absolute path — relative paths resolve from IDE CWD)
|
|
558
|
+
20. `sqlite_verify_backup({backupPath: "<absolute-path>/test-server/test-backup.db"})` → integrity verified
|
|
559
|
+
21. `sqlite_restore({sourcePath: "<absolute-path>/test-server/test-backup.db"})` → restore from backup, verify success
|
|
560
|
+
22. Cleanup: note backup file location for manual removal if desired
|
|
561
|
+
|
|
562
|
+
**Checklist — Optimization:**
|
|
563
|
+
|
|
564
|
+
23. `sqlite_vacuum` → success
|
|
565
|
+
24. `sqlite_optimize` → success with optimization details
|
|
566
|
+
25. `sqlite_pragma_optimize` → success (note: distinct from `sqlite_optimize` — this runs `PRAGMA optimize`)
|
|
567
|
+
|
|
568
|
+
**Checklist — Transaction Management `[NATIVE ONLY]`:**
|
|
569
|
+
|
|
570
|
+
26. `sqlite_transaction_begin` → capture transaction ID
|
|
571
|
+
27. `sqlite_transaction_rollback` → rollback entire transaction, verify success
|
|
572
|
+
28. `sqlite_transaction_begin` → start a new transaction for savepoint tests
|
|
573
|
+
29. `sqlite_transaction_savepoint({name: "sp1"})` → success
|
|
574
|
+
30. `sqlite_transaction_rollback_to({name: "sp1"})` → success
|
|
575
|
+
31. `sqlite_transaction_release({name: "sp1"})` → success (released savepoints cannot be rolled back to)
|
|
576
|
+
32. `sqlite_transaction_commit` → success
|
|
577
|
+
33. `sqlite_transaction_execute({statements: ["SELECT 1 AS test", "SELECT 2 AS test2"]})` → success with 2 statements executed
|
|
578
|
+
|
|
579
|
+
**Checklist — CSV:**
|
|
580
|
+
|
|
581
|
+
34. `sqlite_analyze_csv_schema({filePath: "<absolute-path>/test-server/sample.csv"})` → inferred column types (⚠️ CSV requires absolute paths — see gotcha #14)
|
|
582
|
+
35. `sqlite_create_csv_table({tableName: "temp_csv_test", filePath: "<absolute-path>/test-server/sample.csv"})` → virtual table created
|
|
583
|
+
36. Cleanup: `sqlite_drop_virtual_table({tableName: "temp_csv_test"})`
|
|
584
|
+
|
|
585
|
+
**Checklist — Insights:**
|
|
586
|
+
|
|
587
|
+
37. `sqlite_append_insight({insight: "Test insight for verification"})` → success
|
|
588
|
+
|
|
589
|
+
**Code mode testing:**
|
|
590
|
+
|
|
591
|
+
38. `sqlite_execute_code({code: "const result = await sqlite.admin.integrityCheck(); return result;"})` → `ok` result
|
|
592
|
+
39. `sqlite_execute_code({code: "const result = await sqlite.admin.pragmaSettings({pragma: 'journal_mode'}); return result;"})` → `{pragma: "journal_mode", value: "wal"}`
|
|
593
|
+
|
|
594
|
+
**Error path testing:**
|
|
595
|
+
|
|
596
|
+
🔴 40. `sqlite_pragma_table_info({table: "nonexistent_table_xyz"})` → report behavior
|
|
597
|
+
🔴 41. `sqlite_virtual_table_info({tableName: "nonexistent_table_xyz"})` → structured error
|
|
598
|
+
🔴 42. `sqlite_verify_backup({backupPath: "nonexistent_file.db"})` → structured error
|
|
599
|
+
🔴 43. `sqlite_transaction_execute({statements: ["INSERT INTO nonexistent_table VALUES (1)"]})` `[NATIVE ONLY]` → structured error with rollback info
|
|
600
|
+
|
|
601
|
+
**Zod validation sweep** — call each tool with `{}` (empty params). Must return handler error, NOT raw MCP error:
|
|
602
|
+
|
|
603
|
+
🔴 44. `sqlite_backup({})` → handler error
|
|
604
|
+
🔴 45. `sqlite_restore({})` → handler error
|
|
605
|
+
🔴 46. `sqlite_verify_backup({})` → handler error
|
|
606
|
+
🔴 47. `sqlite_pragma_table_info({})` → handler error
|
|
607
|
+
🔴 48. `sqlite_pragma_settings({})` → handler error (has required `pragma` param)
|
|
608
|
+
🔴 49. `sqlite_append_insight({})` → handler error
|
|
609
|
+
🔴 50. `sqlite_create_view({})` → handler error
|
|
610
|
+
🔴 51. `sqlite_drop_view({})` → handler error
|
|
611
|
+
🔴 52. `sqlite_virtual_table_info({})` → handler error
|
|
612
|
+
🔴 53. `sqlite_drop_virtual_table({})` → handler error
|
|
613
|
+
🔴 54. `sqlite_create_csv_table({})` → handler error
|
|
614
|
+
🔴 55. `sqlite_analyze_csv_schema({})` → handler error
|
|
615
|
+
🔴 56. `sqlite_create_rtree_table({})` → handler error
|
|
616
|
+
🔴 57. `sqlite_create_series_table({})` → handler error
|
|
617
|
+
🔴 58. `sqlite_generate_series({})` → handler error
|
|
618
|
+
🔴 59. `sqlite_dbstat({})` → handler error (or success if no required params)
|
|
619
|
+
🔴 60. `sqlite_transaction_begin({})` `[NATIVE ONLY]` → handler error (or success if no required params)
|
|
620
|
+
🔴 61. `sqlite_transaction_execute({})` `[NATIVE ONLY]` → handler error
|
|
621
|
+
🔴 62. `sqlite_transaction_savepoint({})` `[NATIVE ONLY]` → handler error
|
|
622
|
+
🔴 63. `sqlite_transaction_release({})` `[NATIVE ONLY]` → handler error
|
|
623
|
+
🔴 64. `sqlite_transaction_rollback_to({})` `[NATIVE ONLY]` → handler error
|
|
624
|
+
|
|
625
|
+
---
|
|
626
|
+
|
|
627
|
+
## geo Group-Specific Testing
|
|
628
|
+
|
|
629
|
+
> **Instructions**: Execute every numbered checklist item with the exact inputs shown. Compare responses against the expected results. Report any deviation. These are the minimum-bar tests that must pass every run — freeform testing comes after.
|
|
630
|
+
|
|
631
|
+
### Built-in Tools (3)
|
|
632
|
+
|
|
633
|
+
1. server_info
|
|
634
|
+
2. server_health
|
|
635
|
+
3. list_adapters
|
|
636
|
+
|
|
637
|
+
### geo Group Tools (Native- 12 Tools)
|
|
638
|
+
|
|
639
|
+
4. sqlite_geo_distance
|
|
640
|
+
5. sqlite_geo_nearby
|
|
641
|
+
6. sqlite_geo_bounding_box
|
|
642
|
+
7. sqlite_geo_cluster
|
|
643
|
+
8. sqlite_spatialite_load `[NATIVE ONLY]`
|
|
644
|
+
9. sqlite_spatialite_create_table `[NATIVE ONLY]`
|
|
645
|
+
10. sqlite_spatialite_query `[NATIVE ONLY]`
|
|
646
|
+
11. sqlite_spatialite_analyze `[NATIVE ONLY]`
|
|
647
|
+
12. sqlite_spatialite_index `[NATIVE ONLY]`
|
|
648
|
+
13. sqlite_spatialite_transform `[NATIVE ONLY]`
|
|
649
|
+
14. sqlite_spatialite_import `[NATIVE ONLY]`
|
|
650
|
+
15. sqlite_execute_code
|
|
651
|
+
|
|
652
|
+
### geo Group Tools — WASM (5)
|
|
653
|
+
|
|
654
|
+
Only the Haversine-based tools: items 4-7 and code mode. SpatiaLite tools (items 8-14) are Native only.
|
|
655
|
+
|
|
656
|
+
**Test data:** `test_locations` (15 rows). Key coordinates:
|
|
657
|
+
|
|
658
|
+
| Name | City | Lat | Lng |
|
|
659
|
+
| ------------------ | ------------- | -------- | --------- |
|
|
660
|
+
| Central Park | New York | 40.7829 | -73.9654 |
|
|
661
|
+
| Eiffel Tower | Paris | 48.8584 | 2.2945 |
|
|
662
|
+
| Big Ben | London | 51.5007 | -0.1246 |
|
|
663
|
+
| Tokyo Tower | Tokyo | 35.6586 | 139.7454 |
|
|
664
|
+
| Sydney Opera House | Sydney | -33.8568 | 151.2153 |
|
|
665
|
+
| Golden Gate Bridge | San Francisco | 37.8199 | -122.4783 |
|
|
666
|
+
|
|
667
|
+
**Checklist (Haversine tools — Native & WASM):**
|
|
668
|
+
|
|
669
|
+
1. `sqlite_geo_distance({lat1: 40.7829, lon1: -73.9654, lat2: 48.8584, lon2: 2.2945})` → NYC to Paris ≈ 5,837 km (verify within ±50 km)
|
|
670
|
+
2. `sqlite_geo_distance({lat1: 40.7829, lon1: -73.9654, lat2: 37.8199, lon2: -122.4783})` → NYC to SF ≈ 4,130 km
|
|
671
|
+
3. `sqlite_geo_nearby({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", centerLat: 40.7580, centerLon: -73.9855, radius: 10})` → should find NYC locations (Central Park, Empire State Building, Times Square) — 3 results
|
|
672
|
+
4. `sqlite_geo_nearby({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", centerLat: 48.8584, centerLon: 2.2945, radius: 10})` → should find Paris locations (Eiffel Tower, Louvre, Notre-Dame) — 3 results
|
|
673
|
+
5. `sqlite_geo_bounding_box({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", minLat: 35, maxLat: 55, minLon: -130, maxLon: -70})` → US locations (NYC 3 + SF 1 = 4)
|
|
674
|
+
6. `sqlite_geo_cluster({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", gridSize: 5})` → ~5 clusters grouping by city proximity
|
|
675
|
+
|
|
676
|
+
**SpatiaLite tools `[NATIVE ONLY]`:**
|
|
677
|
+
|
|
678
|
+
7. `sqlite_spatialite_load` → load SpatiaLite extension, verify version
|
|
679
|
+
8. `sqlite_spatialite_create_table({tableName: "temp_spatial_test", geometryColumn: "geom", geometryType: "POINT", srid: 4326, additionalColumns: [{name: "name", type: "TEXT"}]})` → success
|
|
680
|
+
9. `sqlite_spatialite_import({tableName: "temp_spatial_test", format: "wkt", data: "POINT(-73.9654 40.7829)", additionalData: {name: "Test Point"}})` → success
|
|
681
|
+
10. `sqlite_spatialite_query({query: "SELECT name, AsText(geom) as geom_text FROM temp_spatial_test"})` → WKT geometry returned
|
|
682
|
+
11. `sqlite_spatialite_transform({operation: "buffer", geometry1: "POINT(-73.9654 40.7829)", distance: 0.01, srid: 4326})` → buffered polygon
|
|
683
|
+
12. `sqlite_spatialite_index({tableName: "temp_spatial_test", geometryColumn: "geom", action: "create"})` → R-Tree index created
|
|
684
|
+
13. `sqlite_spatialite_analyze({analysisType: "spatial_extent", sourceTable: "temp_spatial_test", geometryColumn: "geom"})` → spatial extent
|
|
685
|
+
14. Cleanup: drop `temp_spatial_test`
|
|
686
|
+
|
|
687
|
+
**Code mode testing:**
|
|
688
|
+
|
|
689
|
+
15. `sqlite_execute_code({code: "const result = await sqlite.geo.distance({lat1: 40.7829, lon1: -73.9654, lat2: 48.8584, lon2: 2.2945}); return result;"})` → NYC to Paris ≈ 5,837 km
|
|
690
|
+
16. `sqlite_execute_code({code: "const result = await sqlite.geo.nearby({table: 'test_locations', latColumn: 'latitude', lonColumn: 'longitude', centerLat: 40.758, centerLon: -73.9855, radius: 10}); return result;"})` → NYC locations
|
|
691
|
+
|
|
692
|
+
**Error path testing:**
|
|
693
|
+
|
|
694
|
+
🔴 17. `sqlite_geo_nearby({table: "nonexistent_table_xyz", latColumn: "lat", lonColumn: "lng", centerLat: 0, centerLon: 0, radius: 100})` → structured error
|
|
695
|
+
🔴 18. `sqlite_geo_distance({lat1: 91, lon1: 0, lat2: 0, lon2: 0})` → must return `{success: false, error: "Invalid lat1: 91. Must be between -90 and 90."}` — structured handler error, NOT a raw MCP error. If this returns a raw MCP `-32602`, it is a Zod `.min()/.max()` refinement leak bug (see `test-tools.md` refinement leak pattern).
|
|
696
|
+
|
|
697
|
+
**Zod validation sweep** — call each tool with `{}` (empty params). Must return handler error, NOT raw MCP error:
|
|
698
|
+
|
|
699
|
+
🔴 19. `sqlite_geo_distance({})` → handler error
|
|
700
|
+
🔴 20. `sqlite_geo_nearby({})` → handler error
|
|
701
|
+
🔴 21. `sqlite_geo_bounding_box({})` → handler error
|
|
702
|
+
🔴 22. `sqlite_geo_cluster({})` → handler error
|
|
703
|
+
🔴 23. `sqlite_spatialite_create_table({})` `[NATIVE ONLY]` → handler error
|
|
704
|
+
🔴 24. `sqlite_spatialite_query({})` `[NATIVE ONLY]` → handler error
|
|
705
|
+
🔴 25. `sqlite_spatialite_analyze({})` `[NATIVE ONLY]` → handler error
|
|
706
|
+
🔴 26. `sqlite_spatialite_index({})` `[NATIVE ONLY]` → handler error
|
|
707
|
+
🔴 27. `sqlite_spatialite_transform({})` `[NATIVE ONLY]` → handler error
|
|
708
|
+
🔴 28. `sqlite_spatialite_import({})` `[NATIVE ONLY]` → handler error
|
|
709
|
+
|
|
710
|
+
---
|
|
711
|
+
|
|
712
|
+
## introspection Group-Specific Testing (Native and WASM are identical)
|
|
713
|
+
|
|
714
|
+
> **Instructions**: Execute every numbered checklist item with the exact inputs shown. Compare responses against the expected results. Report any deviation. These are the minimum-bar tests that must pass every run — freeform testing comes after.
|
|
715
|
+
|
|
716
|
+
> **Note:** All introspection tools are **read-only**. The test database has one FK relationship (`test_orders.product_id → test_products.id`) and a deliberately redundant index (`idx_orders_status` is a prefix of `idx_orders_status_date`) for audit testing.
|
|
717
|
+
|
|
718
|
+
### Built-in Tools (3)
|
|
719
|
+
|
|
720
|
+
1. server_info
|
|
721
|
+
2. server_health
|
|
722
|
+
3. list_adapters
|
|
723
|
+
|
|
724
|
+
### introspection Group Tools (10)
|
|
725
|
+
|
|
726
|
+
4. sqlite_dependency_graph
|
|
727
|
+
5. sqlite_topological_sort
|
|
728
|
+
6. sqlite_cascade_simulator
|
|
729
|
+
7. sqlite_schema_snapshot
|
|
730
|
+
8. sqlite_constraint_analysis
|
|
731
|
+
9. sqlite_migration_risks
|
|
732
|
+
10. sqlite_storage_analysis
|
|
733
|
+
11. sqlite_index_audit
|
|
734
|
+
12. sqlite_query_plan
|
|
735
|
+
13. sqlite_execute_code
|
|
736
|
+
|
|
737
|
+
**Checklist — Graph Analysis:**
|
|
738
|
+
|
|
739
|
+
1. `sqlite_dependency_graph({})` → nodes ≥ 2, edges includes `test_orders → test_products` (FK); stats.totalRelationships ≥ 1
|
|
740
|
+
2. `sqlite_topological_sort({})` → order array with `test_products` before `test_orders` (FK dependency); hasCycles = false
|
|
741
|
+
3. `sqlite_cascade_simulator({table: "test_products"})` → affectedTables includes `test_orders` (FK dependent)
|
|
742
|
+
4. `sqlite_cascade_simulator({table: "test_measurements"})` → affectedTables is empty (no tables reference it via FK)
|
|
743
|
+
5. `sqlite_cascade_simulator({table: "nonexistent_table_xyz"})` → `{success: false, error: "..."}`
|
|
744
|
+
|
|
745
|
+
**Checklist — Schema Analysis:**
|
|
746
|
+
|
|
747
|
+
6. `sqlite_schema_snapshot({})` → snapshot.tables ≥ 11 (10 test\_ tables + FTS virtual); stats.indexes ≥ 4; generatedAt present
|
|
748
|
+
7. `sqlite_constraint_analysis({})` → findings array; summary.totalFindings ≥ 0; summary.byType and bySeverity objects present
|
|
749
|
+
8. `sqlite_migration_risks({statements: ["DROP TABLE test_products"]})` → risks array non-empty; risk category includes data_loss or destructive
|
|
750
|
+
9. `sqlite_migration_risks({statements: ["ALTER TABLE test_users ADD COLUMN age INTEGER"]})` → low risk
|
|
751
|
+
10. `sqlite_migration_risks({statements: ["CREATE TABLE new_table (id INTEGER PRIMARY KEY)", "DROP TABLE test_products"]})` → summary.totalStatements = 2; summary.highestRisk ≥ "high"
|
|
752
|
+
|
|
753
|
+
**Checklist — Diagnostics:**
|
|
754
|
+
|
|
755
|
+
11. `sqlite_storage_analysis({})` → database.pageSize > 0, database.totalPages > 0, database.totalSizeBytes = pageSize × totalPages; recommendations array present
|
|
756
|
+
12. `sqlite_storage_analysis({})` → tables array contains "test_measurements" (largest by row count); verify each entry has name, sizeBytes, rowCount
|
|
757
|
+
13. `sqlite_index_audit({})` → findings array present; summary has redundant, missingFk, total fields
|
|
758
|
+
14. `sqlite_index_audit({})` → findings includes type="redundant" for `idx_orders_status` (prefix of `idx_orders_status_date`)
|
|
759
|
+
15. `sqlite_query_plan({sql: "SELECT * FROM test_products WHERE category = 'electronics'"})` → plan array non-empty; analysis.fullScans may or may not include test_products (idx_products_category exists)
|
|
760
|
+
16. `sqlite_query_plan({sql: "SELECT * FROM test_orders WHERE status = 'completed'"})` → analysis.indexScans present (idx_orders_status exists)
|
|
761
|
+
17. `sqlite_query_plan({sql: "SELECT * FROM test_products WHERE name = 'Laptop Pro 15'"})` → analysis.fullScans includes test_products (no index on name); suggestions non-empty
|
|
762
|
+
18. `sqlite_query_plan({sql: "WITH recent AS (SELECT * FROM test_orders ORDER BY order_date DESC LIMIT 5) SELECT * FROM recent"})` → plan contains CTE-related entries
|
|
763
|
+
|
|
764
|
+
**Code mode testing (params only accessible via code mode):**
|
|
765
|
+
|
|
766
|
+
19. `sqlite_execute_code({code: "const result = await sqlite.introspection.schemaSnapshot({}); return { tableCount: result.snapshot.tables.length, hasStats: !!result.stats };"})` → tableCount ≥ 11, hasStats = true
|
|
767
|
+
20. `sqlite_execute_code({code: "const result = await sqlite.introspection.queryPlan({sql: 'SELECT * FROM test_products WHERE category = \u0027electronics\u0027'}); return result;"})` → plan array present
|
|
768
|
+
21. `sqlite_execute_code({code: "const result = await sqlite.introspection.schemaSnapshot({sections: ['tables']}); return { hasTables: !!result.snapshot.tables, hasViews: !!result.snapshot.views, hasIndexes: !!result.snapshot.indexes };"})` → hasTables=true, hasViews=false, hasIndexes=false
|
|
769
|
+
22. `sqlite_execute_code({code: "const result = await sqlite.introspection.schemaSnapshot({compact: true}); const t = result.snapshot.tables[0]; return { name: t.name, hasColumns: !!t.columns };"})` → hasColumns=false (compact omits columns)
|
|
770
|
+
23. `sqlite_execute_code({code: "const result = await sqlite.introspection.constraintAnalysis({table: 'test_orders'}); return { count: result.findings.length, allTestOrders: result.findings.every(f => f.table === 'test_orders') };"})` → allTestOrders=true
|
|
771
|
+
24. `sqlite_execute_code({code: "const result = await sqlite.introspection.constraintAnalysis({checks: ['unindexed_fk']}); return { count: result.findings.length, allUnindexedFk: result.findings.every(f => f.type === 'unindexed_fk') };"})` → allUnindexedFk=true
|
|
772
|
+
25. `sqlite_execute_code({code: "const result = await sqlite.introspection.storageAnalysis({includeTableDetails: false}); return { hasTables: !!result.tables, hasDatabase: !!result.database };"})` → hasTables=false, hasDatabase=true
|
|
773
|
+
26. `sqlite_execute_code({code: "const result = await sqlite.introspection.indexAudit({table: 'test_orders'}); return { count: result.findings.length, allTestOrders: result.findings.every(f => f.table === 'test_orders') };"})` → allTestOrders=true
|
|
774
|
+
27. `sqlite_execute_code({code: "const result = await sqlite.introspection.topologicalSort({direction: 'drop'}); return { direction: result.direction, first: result.order[0], last: result.order[result.order.length - 1] };"})` → direction="drop", test_orders before test_products in order
|
|
775
|
+
|
|
776
|
+
**Error path testing:**
|
|
777
|
+
|
|
778
|
+
🔴 28. `sqlite_query_plan({sql: "DELETE FROM test_products WHERE id = 1"})` → `{success: false, error: "...only SELECT..."}` (non-SELECT rejected)
|
|
779
|
+
🔴 29. `sqlite_query_plan({})` → Zod validation error (missing required `sql`). Must be handler error, NOT raw MCP error.
|
|
780
|
+
🔴 30. `sqlite_cascade_simulator({})` → Zod validation error (missing required `table`)
|
|
781
|
+
🔴 31. `sqlite_migration_risks({statements: []})` → report behavior for empty array
|
|
782
|
+
🔴 32. `sqlite_execute_code({code: "return await sqlite.introspection.storageAnalysis({limit: 0});", readonly: true})` → Zod validation error (min: 1) — `limit` param only accessible via code mode
|
|
783
|
+
|
|
784
|
+
**Zod validation sweep** — call each tool with `{}` (empty params). Must return handler error, NOT raw MCP error:
|
|
785
|
+
|
|
786
|
+
🔴 33. `sqlite_dependency_graph({})` → handler error (or success if no required params)
|
|
787
|
+
🔴 34. `sqlite_topological_sort({})` → handler error (or success if no required params)
|
|
788
|
+
🔴 35. `sqlite_cascade_simulator({})` → handler error
|
|
789
|
+
🔴 36. `sqlite_schema_snapshot({})` → handler error (or success if no required params)
|
|
790
|
+
🔴 37. `sqlite_constraint_analysis({})` → handler error (or success if no required params)
|
|
791
|
+
🔴 38. `sqlite_migration_risks({})` → handler error
|
|
792
|
+
🔴 39. `sqlite_storage_analysis({})` → handler error (or success if no required params)
|
|
793
|
+
🔴 40. `sqlite_index_audit({})` → handler error (or success if no required params)
|
|
794
|
+
🔴 41. `sqlite_query_plan({})` → handler error
|
|
795
|
+
|
|
796
|
+
---
|
|
797
|
+
|
|
798
|
+
## migration Group-Specific Testing (Native and WASM are identical)
|
|
799
|
+
|
|
800
|
+
> **Instructions**: Execute every numbered checklist item with the exact inputs shown. Compare responses against the expected results. Report any deviation. These are the minimum-bar tests that must pass every run — freeform testing comes after.
|
|
801
|
+
|
|
802
|
+
> **Note:** Migration tools write a `_mcp_migrations` tracking table. Use `temp_*` naming for test migrations. Attempt to remove all `temp_*` tables upon completion. If DROP fails due to a database lock, note the leftover tables and move on — they are inert and will be cleaned up on next database regeneration
|
|
803
|
+
|
|
804
|
+
### Built-in Tools (3)
|
|
805
|
+
|
|
806
|
+
1. server_info
|
|
807
|
+
2. server_health
|
|
808
|
+
3. list_adapters
|
|
809
|
+
|
|
810
|
+
### migration Group Tools (7)
|
|
811
|
+
|
|
812
|
+
4. sqlite_migration_init
|
|
813
|
+
5. sqlite_migration_record
|
|
814
|
+
6. sqlite_migration_apply
|
|
815
|
+
7. sqlite_migration_rollback
|
|
816
|
+
8. sqlite_migration_history
|
|
817
|
+
9. sqlite_migration_status
|
|
818
|
+
10. sqlite_execute_code
|
|
819
|
+
|
|
820
|
+
**Checklist — Full Lifecycle:**
|
|
821
|
+
|
|
822
|
+
> **Note**: `sqlite_migration_record` is for **externally-applied** migrations — it records them as `applied` immediately without executing the SQL. `sqlite_migration_apply` **executes SQL AND records** the migration atomically. They are NOT a two-step record→apply workflow.
|
|
823
|
+
|
|
824
|
+
1. `sqlite_migration_init({})` → success; creates `_mcp_migrations` table
|
|
825
|
+
2. `sqlite_migration_status({})` → initialized state, zero counts
|
|
826
|
+
3. `sqlite_migration_apply({version: "001_create_temp_table", migrationSql: "CREATE TABLE temp_migration_test (id INTEGER PRIMARY KEY, value TEXT)", rollbackSql: "DROP TABLE IF EXISTS temp_migration_test", description: "Create temp table for migration testing", sourceSystem: "agent", appliedBy: "antigravity"})` → migration executed and recorded as applied; verify `temp_migration_test` exists via `sqlite_list_tables`
|
|
827
|
+
4. `sqlite_migration_status({})` → shows 1 applied migration, latestVersion = "001_create_temp_table"
|
|
828
|
+
5. `sqlite_migration_record({version: "002_external_change", migrationSql: "ALTER TABLE temp_migration_test ADD COLUMN extra TEXT", description: "Record external schema change", sourceSystem: "agent", appliedBy: "antigravity"})` → migration recorded as applied (SQL NOT executed — record-only)
|
|
829
|
+
6. `sqlite_migration_history({})` → shows both migrations with `applied` status, ordered by id DESC
|
|
830
|
+
7. `sqlite_migration_rollback({version: "001_create_temp_table"})` → rollback executed; `temp_migration_test` dropped; status = "rolled_back"
|
|
831
|
+
8. `sqlite_migration_history({})` → shows 001=rolled_back, 002=applied
|
|
832
|
+
9. `sqlite_migration_status({})` → verify overall state: 1 applied, 1 rolled_back
|
|
833
|
+
10. `sqlite_migration_apply({version: "003_duplicate_test", migrationSql: "CREATE TABLE temp_migration_test (id INTEGER PRIMARY KEY, value TEXT)"})` → duplicate SQL detection (same hash as 001) → `{success: false, error: "Duplicate migration: ..."}`
|
|
834
|
+
|
|
835
|
+
**Code mode testing:**
|
|
836
|
+
|
|
837
|
+
11. `sqlite_execute_code({code: "const result = await sqlite.migration.migrationStatus(); return result;"})` → current migration state
|
|
838
|
+
12. `sqlite_execute_code({code: "const result = await sqlite.migration.migrationHistory(); return result;"})` → migration history list
|
|
839
|
+
|
|
840
|
+
**Error path testing:**
|
|
841
|
+
|
|
842
|
+
🔴 13. `sqlite_migration_apply({version: "fail_test", migrationSql: "CREATE TABLE nonexistent_xyz.bad (id INT)"})` → structured error (SQL execution fails; recorded as status=failed)
|
|
843
|
+
🔴 14. `sqlite_migration_record({})` → Zod validation error (missing required params) — must be handler error, NOT raw MCP error
|
|
844
|
+
🔴 15. `sqlite_migration_rollback({version: "nonexistent_migration_xyz"})` → structured error `{success: false, error: "Migration not found: ..."}`
|
|
845
|
+
🔴 16. `sqlite_migration_rollback({version: "002_external_change"})` → structured error (no rollback SQL was recorded with this migration)
|
|
846
|
+
|
|
847
|
+
**Zod validation sweep** — call each tool with `{}` (empty params). Must return handler error, NOT raw MCP error:
|
|
848
|
+
|
|
849
|
+
🔴 17. `sqlite_migration_init({})` → handler error (or success if no required params)
|
|
850
|
+
🔴 18. `sqlite_migration_record({})` → handler error
|
|
851
|
+
🔴 19. `sqlite_migration_apply({})` → handler error
|
|
852
|
+
🔴 20. `sqlite_migration_rollback({})` → handler error
|
|
853
|
+
🔴 21. `sqlite_migration_history({})` → handler error (or success if no required params)
|
|
854
|
+
🔴 22. `sqlite_migration_status({})` → handler error (or success if no required params)
|
|
855
|
+
|
|
856
|
+
**Cleanup:**
|
|
857
|
+
|
|
858
|
+
23. Drop `_mcp_migrations` table: `sqlite_drop_table({table: "_mcp_migrations"})` (writeQuery rejects DROP TABLE)
|
|
859
|
+
24. Drop `temp_migration_test` if still exists: `sqlite_drop_table({table: "temp_migration_test"})`
|
|
860
|
+
25. Verify cleanup via `sqlite_list_tables`
|
|
861
|
+
26. Attempt to remove all `temp_*` tables. If DROP fails due to a database lock, move on — they are inert and will be cleaned up on next database regeneration
|