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,487 @@
|
|
|
1
|
+
# Advanced Stress Test — db-mcp (SQLite) — Part 2
|
|
2
|
+
|
|
3
|
+
**Ignore Native content. Test WASM Mode Only**
|
|
4
|
+
|
|
5
|
+
**Step 1:** Read `server-instructions.ts` and `src/constants/server-instructions/gotchas.md` using `view_file` (not grep or search) to understand documented behaviors, edge cases, and response structures.
|
|
6
|
+
|
|
7
|
+
**Step 2:** Execute each numbered stress test below using `sqlite_execute_code` (code mode), not with a browser, scripts, or terminal.
|
|
8
|
+
|
|
9
|
+
**Note** If temp tables are present from a previous test pass, it's because the database is locked. Ignore and work around them.
|
|
10
|
+
|
|
11
|
+
## Code Mode Execution
|
|
12
|
+
|
|
13
|
+
All tests should be executed via `sqlite_execute_code` code mode. Tests are written in direct tool call syntax for readability — translate to code mode:
|
|
14
|
+
|
|
15
|
+
| Direct Tool Call | Code Mode Equivalent |
|
|
16
|
+
| --------------------------------------------------------- | ------------------------------------------------------------- |
|
|
17
|
+
| `sqlite_read_query({query: "..."})` | `sqlite.core.readQuery({query: "..."})` |
|
|
18
|
+
| `sqlite_write_query({query: "..."})` | `sqlite.core.writeQuery({query: "..."})` |
|
|
19
|
+
| `sqlite_create_table({tableName: "...", columns: [...]})` | `sqlite.core.createTable({tableName: "...", columns: [...]})` |
|
|
20
|
+
| `sqlite_describe_table({tableName: "..."})` | `sqlite.core.describeTable({tableName: "..."})` |
|
|
21
|
+
| `sqlite_drop_table({tableName: "..."})` | `sqlite.core.dropTable({tableName: "..."})` |
|
|
22
|
+
| `sqlite_create_index({...})` | `sqlite.core.createIndex({...})` |
|
|
23
|
+
| `sqlite_get_indexes({tableName: "..."})` | `sqlite.core.getIndexes({tableName: "..."})` |
|
|
24
|
+
| `sqlite_json_*({...})` | `sqlite.json.*({...})` |
|
|
25
|
+
| `sqlite_text_*` / `sqlite_regex_*` / etc. | `sqlite.text.*` |
|
|
26
|
+
| `sqlite_stats_*` / `sqlite_window_*` | `sqlite.stats.*` |
|
|
27
|
+
| `sqlite_vector_*` | `sqlite.vector.*` |
|
|
28
|
+
| `sqlite_fts_*` | `sqlite.text.*` (FTS tools are in the text group) |
|
|
29
|
+
| `sqlite_create_view` / `sqlite_drop_view` / etc. | `sqlite.admin.*` |
|
|
30
|
+
| `sqlite_geo_*` / `sqlite_spatialite_*` | `sqlite.geo.*` |
|
|
31
|
+
| `sqlite_dependency_graph` / `sqlite_index_audit` / etc. | `sqlite.introspection.*` |
|
|
32
|
+
| `sqlite_migration_*` | `sqlite.migration.*` |
|
|
33
|
+
|
|
34
|
+
**Key rules:**
|
|
35
|
+
|
|
36
|
+
- Use `sqlite.<group>.help()` to discover method names and parameters for each group
|
|
37
|
+
- State **persists** across `sqlite_execute_code` calls — create a table in one call, query it in the next
|
|
38
|
+
- Do **NOT** pass `readonly: true` when tests need to create/write/drop objects
|
|
39
|
+
- Group multiple related tests into a single code mode call when practical
|
|
40
|
+
|
|
41
|
+
## Test Database Schema
|
|
42
|
+
|
|
43
|
+
Same as `test-tools.md` — refer to that file for the full schema reference. Key tables: `test_products` (16 rows), `test_orders` (20), `test_jsonb_docs` (6), `test_articles` (8), `test_users` (9), `test_measurements` (200), `test_embeddings` (20), `test_locations` (15), `test_categories` (17), `test_events` (100).
|
|
44
|
+
|
|
45
|
+
## Naming & Cleanup
|
|
46
|
+
|
|
47
|
+
- **Temporary tables**: Prefix with `stress_` (e.g., `stress_empty_table`)
|
|
48
|
+
- **Temporary indexes**: Prefix with `stress_idx_`
|
|
49
|
+
- **Temporary views**: Prefix with `stress_view_`
|
|
50
|
+
- **Cleanup**: Attempt to remove all `temp_*` tables. 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
|
|
51
|
+
|
|
52
|
+
## Reporting Format
|
|
53
|
+
|
|
54
|
+
- ❌ Fail: Tool errors or produces incorrect results (include error message)
|
|
55
|
+
- ⚠️ Issue: Unexpected behavior or improvement opportunity
|
|
56
|
+
- 📦 Payload: Unnecessarily large response that should be optimized — **blocking, equally important as ❌ bugs**. Oversized payloads waste LLM context window tokens and degrade downstream tool-calling quality. Report the response size in KB and suggest a concrete optimization (e.g., filter system tables, add `compact` option, omit empty arrays).
|
|
57
|
+
- ✅ Confirmed: Edge case handled correctly (use only inline during testing; omit from Final Summary)
|
|
58
|
+
|
|
59
|
+
### Error Code Consistency
|
|
60
|
+
|
|
61
|
+
When rating errors, flag any generic code (`RESOURCE_ERROR`, `UNKNOWN_ERROR`) that should be a specific code (e.g., `TABLE_NOT_FOUND`, `COLUMN_NOT_FOUND`, `VALIDATION_ERROR`). These are fixable in `src/utils/errors/` (see `suggestions.ts` and `classes.ts`) by adding a `code` override to the matching error class. Treat as ⚠️ Issue and include in fix plan.
|
|
62
|
+
|
|
63
|
+
## Post-Test Procedures
|
|
64
|
+
|
|
65
|
+
At the end, confirm cleanup of all `stress_*` objects, then **fix every finding** — not just ❌ Fails, but also ⚠️ Issues (behavioral improvements, missing warnings, error code consistency) and 📦 Payload problems (responses that should be truncated or offer a `limit` param). Create a plan covering all findings; if the plan does not require important decision choices, proceed with implementation. When complete, run the full test suite and fix any broken tests, run lint and typecheck and fix any issues, run prettier, update the changelog (being careful not to create duplicate headers), and commit without pushing. Then re-test your fixes with code mode calls.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## admin Group Advanced Tests
|
|
70
|
+
|
|
71
|
+
### Built-in Tools (3)
|
|
72
|
+
|
|
73
|
+
1. server_info
|
|
74
|
+
2. server_health
|
|
75
|
+
3. list_adapters
|
|
76
|
+
|
|
77
|
+
### admin Group Tools — Native (33)
|
|
78
|
+
|
|
79
|
+
4. sqlite_generate_series
|
|
80
|
+
5. sqlite_create_view
|
|
81
|
+
6. sqlite_list_views
|
|
82
|
+
7. sqlite_drop_view
|
|
83
|
+
8. sqlite_dbstat
|
|
84
|
+
9. sqlite_vacuum
|
|
85
|
+
10. sqlite_list_virtual_tables
|
|
86
|
+
11. sqlite_virtual_table_info
|
|
87
|
+
12. sqlite_drop_virtual_table
|
|
88
|
+
13. sqlite_create_csv_table
|
|
89
|
+
14. sqlite_analyze_csv_schema
|
|
90
|
+
15. sqlite_create_rtree_table
|
|
91
|
+
16. sqlite_create_series_table
|
|
92
|
+
17. sqlite_backup
|
|
93
|
+
18. sqlite_analyze
|
|
94
|
+
19. sqlite_integrity_check
|
|
95
|
+
20. sqlite_optimize
|
|
96
|
+
21. sqlite_restore
|
|
97
|
+
22. sqlite_verify_backup
|
|
98
|
+
23. sqlite_index_stats
|
|
99
|
+
24. sqlite_pragma_compile_options
|
|
100
|
+
25. sqlite_pragma_database_list
|
|
101
|
+
26. sqlite_pragma_optimize
|
|
102
|
+
27. sqlite_pragma_settings
|
|
103
|
+
28. sqlite_pragma_table_info
|
|
104
|
+
29. sqlite_append_insight
|
|
105
|
+
30. sqlite_transaction_begin
|
|
106
|
+
31. sqlite_transaction_commit
|
|
107
|
+
32. sqlite_transaction_rollback
|
|
108
|
+
33. sqlite_transaction_savepoint
|
|
109
|
+
34. sqlite_transaction_release
|
|
110
|
+
35. sqlite_transaction_rollback_to
|
|
111
|
+
36. sqlite_transaction_execute
|
|
112
|
+
|
|
113
|
+
### admin Group Tools — WASM (26)
|
|
114
|
+
|
|
115
|
+
Same as Native minus the 7 transaction management tools (items 30-36).
|
|
116
|
+
|
|
117
|
+
### Category 1: View Lifecycle Stress
|
|
118
|
+
|
|
119
|
+
1. `sqlite_create_view({viewName: "stress_view_orders", selectQuery: "SELECT product_id, COUNT(*) as cnt FROM test_orders GROUP BY product_id"})` → success
|
|
120
|
+
2. `sqlite_list_views` → verify `stress_view_orders` present
|
|
121
|
+
3. `sqlite_drop_view({viewName: "stress_view_orders"})` → success
|
|
122
|
+
4. `sqlite_drop_view({viewName: "stress_view_orders"})` → expect structured error or "not found" (not raw crash)
|
|
123
|
+
5. `sqlite_create_view({viewName: "stress_view_orders", selectQuery: "SELECT product_id, COUNT(*) as cnt FROM test_orders GROUP BY product_id"})` → recreate success
|
|
124
|
+
|
|
125
|
+
### Category 2: Virtual Table Edge Cases
|
|
126
|
+
|
|
127
|
+
6. `sqlite_create_rtree_table({tableName: "stress_rtree_test", dimensions: 2})` → success
|
|
128
|
+
7. `sqlite_list_virtual_tables` → verify `stress_rtree_test` present alongside `test_articles_fts` (Native)
|
|
129
|
+
8. `sqlite_virtual_table_info({tableName: "stress_rtree_test"})` → correct module and column info
|
|
130
|
+
9. `sqlite_drop_virtual_table({tableName: "stress_rtree_test"})` → success
|
|
131
|
+
10. `sqlite_virtual_table_info({tableName: "nonexistent_vtable_xyz"})` → structured error
|
|
132
|
+
|
|
133
|
+
### Category 3: Backup/Restore Integrity
|
|
134
|
+
|
|
135
|
+
11. `sqlite_backup({targetPath: "test-server/stress-backup.db"})` → success
|
|
136
|
+
12. `sqlite_verify_backup({backupPath: "test-server/stress-backup.db"})` → integrity verified
|
|
137
|
+
13. `sqlite_verify_backup({backupPath: "nonexistent_file.db"})` → structured error
|
|
138
|
+
14. Cleanup: note backup file for manual removal
|
|
139
|
+
|
|
140
|
+
### Category 4: Transaction Edge Cases `[NATIVE ONLY]`
|
|
141
|
+
|
|
142
|
+
**4.1 Aborted Transaction Recovery**
|
|
143
|
+
|
|
144
|
+
15. `sqlite_transaction_begin` → get transaction ID
|
|
145
|
+
16. `sqlite_transaction_execute({statements: ["INSERT INTO nonexistent_table VALUES (1)"]})` → should fail
|
|
146
|
+
17. Start new transaction → verify it works normally (no lingering aborted state)
|
|
147
|
+
|
|
148
|
+
**4.2 Savepoint Stress Test**
|
|
149
|
+
|
|
150
|
+
18. `sqlite_transaction_begin` → get transaction ID
|
|
151
|
+
19. Create savepoint `sp1`
|
|
152
|
+
20. `sqlite_write_query` → INSERT a row into a temp table (within transaction)
|
|
153
|
+
21. Create savepoint `sp2`
|
|
154
|
+
22. `sqlite_write_query` → INSERT another row
|
|
155
|
+
23. `sqlite_transaction_rollback_to({name: "sp2"})` → should undo sp2's insert
|
|
156
|
+
24. `sqlite_transaction_rollback_to({name: "sp1"})` → should undo all inserts
|
|
157
|
+
25. `sqlite_transaction_commit` → only pre-sp1 state persists
|
|
158
|
+
|
|
159
|
+
**4.3 Transaction Execute Mixed Statements**
|
|
160
|
+
|
|
161
|
+
26. `sqlite_transaction_execute({statements: ["CREATE TABLE stress_tx_test (id INTEGER PRIMARY KEY, name TEXT)", "INSERT INTO stress_tx_test VALUES (1, 'alpha')", "INSERT INTO stress_tx_test VALUES (2, 'beta')"]})` → success, 3 statements executed
|
|
162
|
+
27. Verify `stress_tx_test` exists with 2 rows
|
|
163
|
+
|
|
164
|
+
**4.4 Transaction Execute Failure Rollback**
|
|
165
|
+
|
|
166
|
+
28. `sqlite_transaction_execute({statements: ["CREATE TABLE stress_tx_fail (id INT)", "INSERT INTO nonexistent_xyz VALUES (1)", "CREATE TABLE stress_tx_fail2 (id INT)"]})` → failure
|
|
167
|
+
29. Verify: `stress_tx_fail` does NOT exist (atomic rollback worked)
|
|
168
|
+
|
|
169
|
+
### Category 5: Pragma Edge Cases
|
|
170
|
+
|
|
171
|
+
30. `sqlite_pragma_compile_options({filter: "THREAD"})` → filtered result subset
|
|
172
|
+
31. `sqlite_pragma_settings` → verify key settings structure
|
|
173
|
+
32. `sqlite_pragma_table_info({tableName: "nonexistent_table_xyz"})` → report behavior
|
|
174
|
+
|
|
175
|
+
### Category 6: Error Message Quality
|
|
176
|
+
|
|
177
|
+
33. `sqlite_drop_view({viewName: "nonexistent_view_xyz"})` → structured error
|
|
178
|
+
34. `sqlite_create_csv_table({tableName: "stress_csv", filePath: "nonexistent_file.csv"})` → structured error
|
|
179
|
+
35. `sqlite_verify_backup({backupPath: "nonexistent_backup.db"})` → structured error
|
|
180
|
+
|
|
181
|
+
### Category 7: WASM Boundary Verification
|
|
182
|
+
|
|
183
|
+
For WASM testing only:
|
|
184
|
+
|
|
185
|
+
36. Confirm transaction tools are NOT present in the tool list
|
|
186
|
+
37. All 26 non-transaction admin tools should work identically in WASM and Native
|
|
187
|
+
|
|
188
|
+
### Final Cleanup
|
|
189
|
+
|
|
190
|
+
Drop all `stress_*` tables and views. Confirm `test_products` (16 rows) and `test_orders` (20 rows) are unchanged.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## geo Group Advanced Tests
|
|
195
|
+
|
|
196
|
+
### Built-in Tools (3)
|
|
197
|
+
|
|
198
|
+
1. server_info
|
|
199
|
+
2. server_health
|
|
200
|
+
3. list_adapters
|
|
201
|
+
|
|
202
|
+
### geo Group Tools — Native (11)
|
|
203
|
+
|
|
204
|
+
4. sqlite_geo_distance
|
|
205
|
+
5. sqlite_geo_nearby
|
|
206
|
+
6. sqlite_geo_bounding_box
|
|
207
|
+
7. sqlite_geo_cluster
|
|
208
|
+
8. sqlite_spatialite_load `[NATIVE ONLY]`
|
|
209
|
+
9. sqlite_spatialite_create_table `[NATIVE ONLY]`
|
|
210
|
+
10. sqlite_spatialite_query `[NATIVE ONLY]`
|
|
211
|
+
11. sqlite_spatialite_analyze `[NATIVE ONLY]`
|
|
212
|
+
12. sqlite_spatialite_index `[NATIVE ONLY]`
|
|
213
|
+
13. sqlite_spatialite_transform `[NATIVE ONLY]`
|
|
214
|
+
14. sqlite_spatialite_import `[NATIVE ONLY]`
|
|
215
|
+
|
|
216
|
+
### geo Group Tools — WASM (4)
|
|
217
|
+
|
|
218
|
+
Only the Haversine-based tools: items 4-7.
|
|
219
|
+
|
|
220
|
+
### Category 1: Haversine Boundary Conditions
|
|
221
|
+
|
|
222
|
+
1. `sqlite_geo_distance({lat1: 0, lon1: 0, lat2: 0, lon2: 0})` → distance = 0 (same point)
|
|
223
|
+
2. `sqlite_geo_distance({lat1: 90, lon1: 0, lat2: -90, lon2: 0})` → antipodal distance ≈ 20,015 km (half Earth circumference)
|
|
224
|
+
3. `sqlite_geo_distance({lat1: 0, lon1: -180, lat2: 0, lon2: 180})` → distance ≈ 0 (same point, opposite notation)
|
|
225
|
+
4. `sqlite_geo_distance({lat1: 91, lon1: 0, lat2: 0, lon2: 0})` → report behavior for out-of-bounds latitude (>90°)
|
|
226
|
+
5. `sqlite_geo_distance({lat1: 0, lon1: 181, lat2: 0, lon2: 0})` → report behavior for out-of-bounds longitude (>180°)
|
|
227
|
+
|
|
228
|
+
### Category 2: Nearby Search Edge Cases
|
|
229
|
+
|
|
230
|
+
6. `sqlite_geo_nearby({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", centerLat: 40.7829, centerLon: -73.9654, radius: 0.1, unit: "km"})` → very small radius — should find only Central Park (within 100m)
|
|
231
|
+
7. `sqlite_geo_nearby({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", centerLat: 40.7829, centerLon: -73.9654, radius: 50000, unit: "km"})` → very large radius — should find ALL 15 locations
|
|
232
|
+
8. `sqlite_geo_nearby({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", centerLat: 0, centerLon: 0, radius: 100, unit: "km"})` → no locations near (0,0) — 0 results (not error)
|
|
233
|
+
|
|
234
|
+
### Category 3: Bounding Box Edge Cases
|
|
235
|
+
|
|
236
|
+
9. `sqlite_geo_bounding_box({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", minLat: -90, maxLat: 90, minLon: -180, maxLon: 180})` → all 15 locations (global bounding box)
|
|
237
|
+
10. `sqlite_geo_bounding_box({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", minLat: 0, maxLat: 0, minLon: 0, maxLon: 0})` → 0 results (point bounding box)
|
|
238
|
+
11. `sqlite_geo_bounding_box({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", minLat: 50, maxLat: 52, minLon: -1, maxLon: 1})` → London locations (Big Ben, Tower Bridge, Buckingham Palace)
|
|
239
|
+
|
|
240
|
+
### Category 4: Clustering Edge Cases
|
|
241
|
+
|
|
242
|
+
12. `sqlite_geo_cluster({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", gridSize: 180})` → single cluster with all 15 points (huge grid)
|
|
243
|
+
13. `sqlite_geo_cluster({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", gridSize: 0.001})` → ~15 clusters (tiny grid, one per location)
|
|
244
|
+
14. `sqlite_geo_cluster({table: "test_locations", latColumn: "latitude", lonColumn: "longitude", gridSize: 0.1})` → approximately one cluster per city
|
|
245
|
+
|
|
246
|
+
### Category 5: SpatiaLite Integration `[NATIVE ONLY]`
|
|
247
|
+
|
|
248
|
+
15. `sqlite_spatialite_load` → verify version string returned
|
|
249
|
+
16. `sqlite_spatialite_create_table({tableName: "stress_geo_spatial", geometryColumn: "geom", geometryType: "POINT", srid: 4326, additionalColumns: [{name: "name", type: "TEXT"}, {name: "type", type: "TEXT"}]})` → success
|
|
250
|
+
17. Import 3 points (NYC, Paris, Tokyo) via `sqlite_spatialite_import`
|
|
251
|
+
18. `sqlite_spatialite_query({query: "SELECT name, AsText(geom) FROM stress_geo_spatial"})` → 3 rows with WKT
|
|
252
|
+
19. `sqlite_spatialite_transform({operation: "buffer", geometry1: "POINT(-73.9654 40.7829)", distance: 0.01})` → buffered polygon
|
|
253
|
+
20. `sqlite_spatialite_transform({operation: "centroid", geometry1: "POLYGON((-74 40, -74 41, -73 41, -73 40, -74 40))"})` → centroid point
|
|
254
|
+
21. `sqlite_spatialite_index({tableName: "stress_geo_spatial", geometryColumn: "geom", action: "create"})` → R-Tree index
|
|
255
|
+
22. `sqlite_spatialite_index({tableName: "stress_geo_spatial", geometryColumn: "geom", action: "check"})` → index integrity
|
|
256
|
+
23. `sqlite_spatialite_analyze({analysisType: "spatial_extent", sourceTable: "stress_geo_spatial", geometryColumn: "geom"})` → spatial extent
|
|
257
|
+
|
|
258
|
+
### Category 6: Error Message Quality
|
|
259
|
+
|
|
260
|
+
24. `sqlite_geo_nearby({table: "nonexistent_table_xyz", latColumn: "lat", lonColumn: "lon", centerLat: 0, centerLon: 0, radius: 100, unit: "km"})` → structured error
|
|
261
|
+
25. `sqlite_geo_nearby({table: "test_locations", latColumn: "nonexistent_col", lonColumn: "longitude", centerLat: 0, centerLon: 0, radius: 100, unit: "km"})` → structured error about column
|
|
262
|
+
26. `sqlite_spatialite_query({query: "SELECT * FROM nonexistent_table_xyz"})` `[NATIVE ONLY]` → structured error
|
|
263
|
+
|
|
264
|
+
### Category 7: WASM Boundary Verification
|
|
265
|
+
|
|
266
|
+
For WASM testing only:
|
|
267
|
+
|
|
268
|
+
27. Confirm SpatiaLite tools (items 8-14) are NOT present in the tool list
|
|
269
|
+
28. All 4 Haversine tools should produce identical results in WASM and Native
|
|
270
|
+
|
|
271
|
+
### Final Cleanup
|
|
272
|
+
|
|
273
|
+
Drop `stress_geo_spatial` (if created). Confirm `test_locations` count is still 15.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## introspection Group Advanced Tests
|
|
278
|
+
|
|
279
|
+
> **Note:** All introspection tools are **read-only**. The test database has **one FK** (`test_orders.product_id → test_products.id`) and a **deliberately redundant index** (`idx_orders_status` is a prefix of `idx_orders_status_date`).
|
|
280
|
+
|
|
281
|
+
> **Code Mode Required:** Several optional params (`table`, `direction`, `sections`, `compact`, `checks`, `includeTableDetails`, `limit`) are defined in tool schemas but NOT exposed in MCP tool definitions. Use `sqlite_execute_code` to test these params via `sqlite.introspection.*` API.
|
|
282
|
+
|
|
283
|
+
### Built-in Tools (3)
|
|
284
|
+
|
|
285
|
+
1. server_info
|
|
286
|
+
2. server_health
|
|
287
|
+
3. list_adapters
|
|
288
|
+
|
|
289
|
+
### introspection Group Tools (9)
|
|
290
|
+
|
|
291
|
+
4. sqlite_dependency_graph
|
|
292
|
+
5. sqlite_topological_sort
|
|
293
|
+
6. sqlite_cascade_simulator
|
|
294
|
+
7. sqlite_schema_snapshot
|
|
295
|
+
8. sqlite_constraint_analysis
|
|
296
|
+
9. sqlite_migration_risks
|
|
297
|
+
10. sqlite_storage_analysis
|
|
298
|
+
11. sqlite_index_audit
|
|
299
|
+
12. sqlite_query_plan
|
|
300
|
+
|
|
301
|
+
### Category 1: Graph Analysis Edge Cases
|
|
302
|
+
|
|
303
|
+
**1.1 Full Dependency Graph**
|
|
304
|
+
|
|
305
|
+
1. `sqlite_dependency_graph({})` → full graph. Verify edge `test_orders → test_products` present in edges array.
|
|
306
|
+
2. `sqlite_dependency_graph({includeRowCounts: false})` → verify rowCount is omitted from node entries.
|
|
307
|
+
3. `sqlite_dependency_graph({})` → verify `stats.rootTables` and `stats.leafTables` are populated and disjoint.
|
|
308
|
+
|
|
309
|
+
**1.2 Topological Sort Direction Stress**
|
|
310
|
+
|
|
311
|
+
4. `sqlite_topological_sort({direction: "create"})` → `test_products` appears BEFORE `test_orders` (dependency order)
|
|
312
|
+
5. `sqlite_topological_sort({direction: "drop"})` → `test_orders` appears BEFORE `test_products` (reverse)
|
|
313
|
+
6. Verify both directions list the same set of tables (just reordered)
|
|
314
|
+
|
|
315
|
+
**1.3 Cascade Chains**
|
|
316
|
+
|
|
317
|
+
7. `sqlite_cascade_simulator({table: "test_products"})` → affectedTables includes `test_orders` with action from FK definition (CASCADE)
|
|
318
|
+
8. `sqlite_cascade_simulator({table: "test_measurements"})` → affectedTables is empty (leaf table, nothing references it)
|
|
319
|
+
9. `sqlite_cascade_simulator({table: "test_orders"})` → verify behavior: nothing references `test_orders` via FK, so affectedTables should be empty even though it has outgoing FKs
|
|
320
|
+
|
|
321
|
+
### Category 2: Schema Snapshot Completeness
|
|
322
|
+
|
|
323
|
+
10. `sqlite_schema_snapshot({})` → full snapshot. Verify:
|
|
324
|
+
- tables ≥ 11 (10 regular + FTS virtual)
|
|
325
|
+
- indexes ≥ 4 (`idx_orders_status`, `idx_orders_date`, `idx_products_category`, `idx_orders_status_date`)
|
|
326
|
+
- generatedAt is a valid ISO timestamp
|
|
327
|
+
11. `sqlite_schema_snapshot({sections: ["indexes"]})` → only indexes section populated. Verify table section is absent/empty.
|
|
328
|
+
12. `sqlite_schema_snapshot({sections: ["tables", "indexes"]})` → both sections present
|
|
329
|
+
13. `sqlite_schema_snapshot({compact: true})` → verify tables exist but columns arrays are absent from each table entry
|
|
330
|
+
14. `sqlite_schema_snapshot({compact: false})` → verify column details (name, type, nullable, pk) are present for each table
|
|
331
|
+
|
|
332
|
+
### Category 3: Constraint Analysis Stress
|
|
333
|
+
|
|
334
|
+
15. `sqlite_constraint_analysis({})` → all tables analyzed. Verify summary.byType keys and summary.bySeverity keys.
|
|
335
|
+
16. `sqlite_constraint_analysis({checks: ["unindexed_fk"]})` → only unindexed FK findings. The `test_orders.product_id` FK may or may not be flagged depending on whether `idx_orders_status` counts as a covering index.
|
|
336
|
+
17. `sqlite_constraint_analysis({table: "test_users"})` → only findings for `test_users`. Verify no findings reference other tables.
|
|
337
|
+
18. `sqlite_constraint_analysis({table: "nonexistent_table_xyz"})` → report behavior: empty findings, or structured error?
|
|
338
|
+
|
|
339
|
+
### Category 4: Storage Analysis & Index Audit Depth
|
|
340
|
+
|
|
341
|
+
**4.1 Storage Analysis Verification**
|
|
342
|
+
|
|
343
|
+
19. `sqlite_storage_analysis({})` → verify database.totalSizeBytes = database.pageSize × database.totalPages (arithmetic check)
|
|
344
|
+
20. `sqlite_storage_analysis({})` → verify tables array is sorted by size descending (or largest tables first)
|
|
345
|
+
21. `sqlite_storage_analysis({includeTableDetails: false})` → tables property is absent. Database-level metrics still present.
|
|
346
|
+
22. `sqlite_storage_analysis({limit: 3})` → only top 3 tables returned (if limit parameter is supported)
|
|
347
|
+
23. `sqlite_storage_analysis({})` → verify database.fragmentationPct is a number between 0 and 100. Check database.journalMode and database.autoVacuum are non-empty strings.
|
|
348
|
+
|
|
349
|
+
**4.2 Index Audit Cross-Validation**
|
|
350
|
+
|
|
351
|
+
24. `sqlite_index_audit({})` → should flag `idx_orders_status` as `type: "redundant"` (prefix of `idx_orders_status_date`). Note: the field name is `index` (not `indexName`).
|
|
352
|
+
25. `sqlite_index_audit({})` → verify `redundantOf` field points to `idx_orders_status_date` (the superset index)
|
|
353
|
+
26. `sqlite_index_audit({})` → check for `missing_fk_index` on `test_orders.product_id` (FK column without dedicated index)
|
|
354
|
+
27. `sqlite_index_audit({table: "test_products"})` → filtered findings. Only `test_products` findings returned. Verify `idx_products_category` is NOT flagged as redundant (it's the only index on that table).
|
|
355
|
+
28. `sqlite_index_audit({table: "test_measurements"})` → table with 200 rows and no secondary indexes. Note: `unindexed_large_table` threshold is 1000 rows, so no finding expected here.
|
|
356
|
+
|
|
357
|
+
### Category 5: Query Plan Deep Analysis
|
|
358
|
+
|
|
359
|
+
29. `sqlite_query_plan({sql: "SELECT * FROM test_orders WHERE status = 'completed'"})` → should use `idx_orders_status`. Verify `analysis.indexScans` includes a reference.
|
|
360
|
+
30. `sqlite_query_plan({sql: "SELECT * FROM test_products WHERE name = 'Laptop Pro 15'"})` → full scan (no index on `name`). Verify:
|
|
361
|
+
- `analysis.fullScans` includes `test_products`
|
|
362
|
+
- `suggestions` array is non-empty with index creation recommendation
|
|
363
|
+
31. `sqlite_query_plan({sql: "SELECT p.name, o.quantity FROM test_products p JOIN test_orders o ON o.product_id = p.id WHERE o.status = 'completed'"})` → join plan. Verify plan has multiple entries and analysis reflects join strategy.
|
|
364
|
+
32. `sqlite_query_plan({sql: "SELECT * FROM test_orders WHERE status = 'completed' AND order_date > '2026-01-20'"})` → compound WHERE. Verify which index is chosen (`idx_orders_status` or `idx_orders_status_date`).
|
|
365
|
+
33. `sqlite_query_plan({sql: "SELECT COUNT(*) FROM test_measurements GROUP BY sensor_id"})` → GROUP BY plan without dedicated index on `sensor_id`. Expect full scan.
|
|
366
|
+
34. `sqlite_query_plan({sql: "WITH top_orders AS (SELECT * FROM test_orders ORDER BY total_price DESC LIMIT 5) SELECT t.*, p.name FROM top_orders t JOIN test_products p ON p.id = t.product_id"})` → CTE + JOIN plan. Verify multi-step plan.
|
|
367
|
+
|
|
368
|
+
### Category 6: Migration Risk Assessment Depth
|
|
369
|
+
|
|
370
|
+
35. `sqlite_migration_risks({statements: ["DROP TABLE test_products"]})` → critical/high risk. Verify risk mentions FK dependents (`test_orders`).
|
|
371
|
+
36. `sqlite_migration_risks({statements: ["ALTER TABLE test_products ADD COLUMN temp_col TEXT"]})` → low risk (additive, non-destructive)
|
|
372
|
+
37. `sqlite_migration_risks({statements: ["CREATE INDEX idx_temp ON test_products(name)"]})` → low risk
|
|
373
|
+
38. `sqlite_migration_risks({statements: ["DROP INDEX idx_orders_status"]})` → medium risk (removing a supporting index). Verify `riskLevel: "medium"` and `category: "index_removal"`.
|
|
374
|
+
39. `sqlite_migration_risks({statements: ["ALTER TABLE test_products ADD COLUMN temp1 TEXT", "DROP TABLE test_orders", "CREATE TABLE new_orders (id INTEGER PRIMARY KEY)"]})` → 3 statements, mixed risk levels. Verify `summary.totalStatements = 3` and `summary.highestRisk ≥ "high"`.
|
|
375
|
+
|
|
376
|
+
### Category 7: Error Message Quality
|
|
377
|
+
|
|
378
|
+
40. `sqlite_query_plan({sql: "DELETE FROM test_products WHERE id = 1"})` → structured error rejecting non-SELECT
|
|
379
|
+
41. `sqlite_query_plan({sql: "SELECT * FROM nonexistent_table_xyz"})` → structured error mentioning table
|
|
380
|
+
42. `sqlite_query_plan({})` → Zod error for missing `sql` param — must be handler error, NOT raw MCP error
|
|
381
|
+
43. `sqlite_cascade_simulator({})` → Zod error for missing `table` param
|
|
382
|
+
44. `sqlite_migration_risks({})` → Zod error for missing `statements` param
|
|
383
|
+
45. `sqlite_storage_analysis({limit: 0})` → Zod error (min: 1)
|
|
384
|
+
46. `sqlite_storage_analysis({limit: -5})` → Zod error
|
|
385
|
+
|
|
386
|
+
### Final Cleanup
|
|
387
|
+
|
|
388
|
+
All tools in this group are read-only — no cleanup needed. Confirm `test_products` (16 rows), `test_orders` (20 rows), and `test_measurements` (200 rows) are unchanged.
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## migration Group Advanced Tests
|
|
393
|
+
|
|
394
|
+
> **Note:** Migration tools create a `_mcp_migrations` tracking table and may ALTER/CREATE/DROP tables. **Always reset the database after this group.**
|
|
395
|
+
|
|
396
|
+
### Built-in Tools (3)
|
|
397
|
+
|
|
398
|
+
1. server_info
|
|
399
|
+
2. server_health
|
|
400
|
+
3. list_adapters
|
|
401
|
+
|
|
402
|
+
### migration Group Tools (6)
|
|
403
|
+
|
|
404
|
+
4. sqlite_migration_init
|
|
405
|
+
5. sqlite_migration_record
|
|
406
|
+
6. sqlite_migration_apply
|
|
407
|
+
7. sqlite_migration_rollback
|
|
408
|
+
8. sqlite_migration_history
|
|
409
|
+
9. sqlite_migration_status
|
|
410
|
+
|
|
411
|
+
### Category 1: Initialization & Idempotency
|
|
412
|
+
|
|
413
|
+
1. `sqlite_migration_init({})` → success, `_mcp_migrations` table created
|
|
414
|
+
2. `sqlite_migration_init({})` → idempotent call: should succeed without error (table already exists)
|
|
415
|
+
3. `sqlite_migration_status({})` → empty/clean state, no pending migrations
|
|
416
|
+
4. `sqlite_migration_history({})` → empty list
|
|
417
|
+
|
|
418
|
+
### Category 2: Full Lifecycle (Record → Apply → Rollback)
|
|
419
|
+
|
|
420
|
+
**2.1 Simple ALTER TABLE Migration**
|
|
421
|
+
|
|
422
|
+
5. `sqlite_migration_record({version: "stress_001_add_col", migrationSql: "ALTER TABLE test_products ADD COLUMN stress_flag INTEGER DEFAULT 0"})` → recorded (note: `migrationRecord` only stores metadata in `_mcp_migrations`; use `migrationApply` to execute the SQL)
|
|
423
|
+
6. `sqlite_migration_status({})` → shows 1 recorded migration
|
|
424
|
+
7. Verify column is NOT yet added until `migrationApply` is called. Use `sqlite_migration_apply` with the same `version` and `migrationSql` to execute.
|
|
425
|
+
8. `sqlite_migration_status({})` → shows 1 applied after `migrationApply`
|
|
426
|
+
|
|
427
|
+
**2.2 CREATE TABLE Migration**
|
|
428
|
+
|
|
429
|
+
9. `sqlite_migration_record({version: "stress_002_create_table", migrationSql: "CREATE TABLE stress_migration_data (id INTEGER PRIMARY KEY, name TEXT NOT NULL, value REAL)"})` → recorded (does NOT create the table). Use `migrationApply` to execute.
|
|
430
|
+
10. `sqlite_migration_history({})` → shows both migrations with timestamps
|
|
431
|
+
|
|
432
|
+
**2.3 Rollback Chain**
|
|
433
|
+
|
|
434
|
+
11. `sqlite_migration_rollback({version: "stress_002_create_table"})` → report behavior: rollback may require stored rollbackSql from apply step
|
|
435
|
+
12. `sqlite_list_tables` → verify `stress_migration_data` status
|
|
436
|
+
13. `sqlite_migration_history({})` → check `stress_002_create_table` status
|
|
437
|
+
|
|
438
|
+
### Category 3: State Pollution & Ordering
|
|
439
|
+
|
|
440
|
+
**3.1 Re-Record After Rollback**
|
|
441
|
+
|
|
442
|
+
14. `sqlite_migration_record({version: "stress_003_recreate", migrationSql: "CREATE TABLE stress_migration_data (id INTEGER PRIMARY KEY, value TEXT)"})` → recorded and applied (different schema from rolled-back migration)
|
|
443
|
+
15. `sqlite_migration_status({})` → verify correct counts
|
|
444
|
+
|
|
445
|
+
**3.2 Duplicate Name Detection**
|
|
446
|
+
|
|
447
|
+
16. `sqlite_migration_record({version: "stress_001_add_col", migrationSql: "SELECT 1"})` → report behavior: should error (duplicate version) or allow re-record?
|
|
448
|
+
|
|
449
|
+
**3.3 Multi-Statement Apply Verification**
|
|
450
|
+
|
|
451
|
+
17. Record a migration with a complex SQL statement:
|
|
452
|
+
`sqlite_migration_record({version: "stress_004_complex", migrationSql: "CREATE INDEX stress_idx_flag ON test_products(stress_flag)"})`
|
|
453
|
+
18. Verify index created with `sqlite_get_indexes({tableName: "test_products"})`.
|
|
454
|
+
|
|
455
|
+
### Category 4: Error Paths & Recovery
|
|
456
|
+
|
|
457
|
+
**4.1 Apply Failures**
|
|
458
|
+
|
|
459
|
+
19. `sqlite_migration_record({version: "stress_005_bad_sql", migrationSql: "ALTER TABLE nonexistent_xyz ADD COLUMN foo TEXT"})` → records successfully (record only stores metadata, does not validate SQL executability)
|
|
460
|
+
20. `sqlite_migration_status({})` → verify the failed migration state is tracked (not lost)
|
|
461
|
+
|
|
462
|
+
**4.2 Nonexistent Migration Operations**
|
|
463
|
+
|
|
464
|
+
21. `sqlite_migration_apply({version: "nonexistent_migration_xyz"})` → structured error (not raw MCP error)
|
|
465
|
+
22. `sqlite_migration_rollback({version: "nonexistent_migration_xyz"})` → structured error
|
|
466
|
+
|
|
467
|
+
**4.3 Zod Validation Errors**
|
|
468
|
+
|
|
469
|
+
23. `sqlite_migration_record({})` → Zod error for missing required params (`version`, `migrationSql`) — must be handler error
|
|
470
|
+
24. `sqlite_migration_apply({})` → Zod error for missing `version`
|
|
471
|
+
25. `sqlite_migration_rollback({})` → Zod error for missing params
|
|
472
|
+
|
|
473
|
+
### Category 5: Error Message Quality
|
|
474
|
+
|
|
475
|
+
Rate each error response 1-5 for contextual usefulness:
|
|
476
|
+
|
|
477
|
+
26. `sqlite_migration_apply({version: "nonexistent_migration_xyz"})` → rate error: does it mention the migration version?
|
|
478
|
+
27. `sqlite_migration_record({})` → rate error: does it list the missing required fields?
|
|
479
|
+
28. `sqlite_migration_rollback({version: "stress_001_add_col"})` (already applied, not rolled back yet — or already rolled back) → rate error clarity
|
|
480
|
+
|
|
481
|
+
### Final Cleanup
|
|
482
|
+
|
|
483
|
+
1. Drop `_mcp_migrations`: `sqlite_write_query({query: "DROP TABLE IF EXISTS _mcp_migrations"})`
|
|
484
|
+
2. Drop `stress_migration_data`: `sqlite_write_query({query: "DROP TABLE IF EXISTS stress_migration_data"})`
|
|
485
|
+
3. Drop `stress_idx_flag`: `sqlite_write_query({query: "DROP INDEX IF EXISTS stress_idx_flag"})`
|
|
486
|
+
4. **Reset the database** with `pwsh -ExecutionPolicy Bypass -File .\reset-database.ps1` to undo the `stress_flag` column addition on `test_products` (SQLite cannot DROP COLUMN in older versions)
|
|
487
|
+
5. After reset, verify: `test_products` has 16 rows and original 6 columns (no `stress_flag`)
|