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,629 @@
|
|
|
1
|
+
# db-mcp Code Mode Test Plan
|
|
2
|
+
|
|
3
|
+
**Step 1:** Read `C:\Users\chris\Desktop\db-mcp\src\constants\server-instructions\gotchas.md` using `view_file`.
|
|
4
|
+
|
|
5
|
+
**Step 2:** Conduct an exhaustive test of **Code Mode** (`sqlite_execute_code`) using live MCP tool calls. All tests use the `sqlite_execute_code` tool — never direct tool calls — unless validating a comparison.
|
|
6
|
+
|
|
7
|
+
## Test Database Schema
|
|
8
|
+
|
|
9
|
+
See [test-tools.md](./test-tools.md#test-server-schema) for full table details (10 tables, ~400 rows).
|
|
10
|
+
|
|
11
|
+
> **Note:** When testing `sqlite_execute_code`, do **not** pass `readonly: true` unless specifically testing read-only filtering. The `readonly` flag makes write methods return `{success: false, code: "CODEMODE_READONLY_VIOLATION"}`.
|
|
12
|
+
|
|
13
|
+
## Structured Error Response Pattern
|
|
14
|
+
|
|
15
|
+
See [test-tools.md](./test-tools.md#structured-error-response-pattern) — same rules apply. Code Mode errors must return `{success: false, error: "..."}`, never raw MCP errors.
|
|
16
|
+
|
|
17
|
+
## Reporting Format
|
|
18
|
+
|
|
19
|
+
- ❌ Fail: Tool errors or produces incorrect results (include error message)
|
|
20
|
+
- ⚠️ Issue: Unexpected behavior or improvement opportunity
|
|
21
|
+
- 📦 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).
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Phase 1: Sandbox Basics (6 tests)
|
|
26
|
+
|
|
27
|
+
Verify the sandbox executes code, returns results, and handles errors correctly.
|
|
28
|
+
|
|
29
|
+
### 1.1 — Simple return value
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
// Expected: {success: true, result: 42}
|
|
33
|
+
return 42;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 1.2 — String return
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
return "hello from sandbox";
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 1.3 — Object return
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
return { name: "test", values: [1, 2, 3] };
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 1.4 — Async/await support
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
const result = await Promise.resolve("async works");
|
|
52
|
+
return result;
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 1.5 — Runtime error handling
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
// Expected: {success: false, error containing "not defined" or "not a function"}
|
|
59
|
+
const x = undefinedVariable;
|
|
60
|
+
return x;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 1.6 — Empty code
|
|
64
|
+
|
|
65
|
+
Call `sqlite_execute_code` with `code: ""`.
|
|
66
|
+
Expected: `{success: false}` with validation error, not raw MCP error.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Phase 2: API Discoverability (6 tests)
|
|
71
|
+
|
|
72
|
+
Verify `help()` and group-level introspection work correctly.
|
|
73
|
+
|
|
74
|
+
### 2.1 — Top-level help
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
return await sqlite.help();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Expected: `{groups: [...], totalMethods: <number>, usage: "..."}` with 9 groups listed.
|
|
81
|
+
|
|
82
|
+
### 2.2 — Group help (core)
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
return await sqlite.core.help();
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Expected: `{group: "core", methods: [...], examples: [...]}` with methods including `readQuery`, `writeQuery`, `listTables`, `describeTable`, etc.
|
|
89
|
+
|
|
90
|
+
### 2.3 — Group help (json)
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
return await sqlite.json.help();
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Expected: methods include `extract`, `set`, `insert`, `query`, `analyzeSchema`, etc.
|
|
97
|
+
|
|
98
|
+
### 2.4 — All groups exist
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
const groups = [
|
|
102
|
+
"core",
|
|
103
|
+
"json",
|
|
104
|
+
"text",
|
|
105
|
+
"stats",
|
|
106
|
+
"vector",
|
|
107
|
+
"admin",
|
|
108
|
+
"geo",
|
|
109
|
+
"introspection",
|
|
110
|
+
"migration",
|
|
111
|
+
];
|
|
112
|
+
const results = {};
|
|
113
|
+
for (const g of groups) {
|
|
114
|
+
const h = await sqlite[g].help();
|
|
115
|
+
results[g] = h.methods.length;
|
|
116
|
+
}
|
|
117
|
+
return results;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Expected: All 9 groups return >0 methods.
|
|
121
|
+
|
|
122
|
+
### 2.5 — Method aliases resolve
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
// Alias "query" should resolve to "readQuery"
|
|
126
|
+
const r1 = await sqlite.core.query("SELECT 1 AS num");
|
|
127
|
+
const r2 = await sqlite.core.readQuery("SELECT 1 AS num");
|
|
128
|
+
return { aliasResult: r1, canonicalResult: r2 };
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Expected: Both return identical results.
|
|
132
|
+
|
|
133
|
+
### 2.6 — Top-level convenience aliases
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
// Top-level readQuery, writeQuery, listTables, describeTable should exist
|
|
137
|
+
const tables = await sqlite.listTables();
|
|
138
|
+
return { success: true, tableCount: tables.tables?.length };
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Phase 3: Core Group via Code Mode (6 tests)
|
|
144
|
+
|
|
145
|
+
### 3.1 — Read query
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
return await sqlite.core.readQuery({
|
|
149
|
+
query: "SELECT COUNT(*) as cnt FROM test_products",
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Expected: `{success: true, rows: [{cnt: 16}]}`
|
|
154
|
+
|
|
155
|
+
### 3.2 — Positional args
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
// Positional: readQuery("SELECT ...") should work
|
|
159
|
+
return await sqlite.core.readQuery("SELECT name FROM test_products LIMIT 2");
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 3.3 — List tables
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
return await sqlite.core.listTables();
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 3.4 — Describe table
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
return await sqlite.core.describeTable("test_products");
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 3.5 — Write query (temp table)
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
await sqlite.core.writeQuery(
|
|
178
|
+
"CREATE TABLE temp_cm_test (id INTEGER PRIMARY KEY, value TEXT)",
|
|
179
|
+
);
|
|
180
|
+
await sqlite.core.writeQuery(
|
|
181
|
+
"INSERT INTO temp_cm_test (value) VALUES ('hello')",
|
|
182
|
+
);
|
|
183
|
+
const result = await sqlite.core.readQuery("SELECT * FROM temp_cm_test");
|
|
184
|
+
return result;
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 3.6 — Get indexes
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
return await sqlite.core.getIndexes();
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Phase 4: JSON Group via Code Mode (5 tests)
|
|
196
|
+
|
|
197
|
+
### 4.1 — JSON extract
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
return await sqlite.json.extract({
|
|
201
|
+
table: "test_jsonb_docs",
|
|
202
|
+
column: "doc",
|
|
203
|
+
path: "$.title",
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 4.2 — JSON query with filter
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
return await sqlite.json.query({
|
|
211
|
+
table: "test_jsonb_docs",
|
|
212
|
+
column: "doc",
|
|
213
|
+
filterPaths: { "$.type": "article" },
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 4.3 — JSON analyze schema
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
return await sqlite.json.analyzeSchema({
|
|
221
|
+
table: "test_jsonb_docs",
|
|
222
|
+
column: "doc",
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 4.4 — JSON valid
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
return await sqlite.json.valid({ json: '{"key": "value"}' });
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### 4.5 — JSON pretty
|
|
233
|
+
|
|
234
|
+
```javascript
|
|
235
|
+
return await sqlite.json.pretty({ json: '{"a":1,"b":2}' });
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Phase 5: Stats Group via Code Mode (4 tests)
|
|
241
|
+
|
|
242
|
+
### 5.1 — Basic stats
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
return await sqlite.stats.statsBasic({
|
|
246
|
+
table: "test_measurements",
|
|
247
|
+
column: "temperature",
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 5.2 — Histogram
|
|
252
|
+
|
|
253
|
+
```javascript
|
|
254
|
+
return await sqlite.stats.statsHistogram({
|
|
255
|
+
table: "test_measurements",
|
|
256
|
+
column: "temperature",
|
|
257
|
+
buckets: 5,
|
|
258
|
+
});
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### 5.3 — Correlation
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
return await sqlite.stats.statsCorrelation({
|
|
265
|
+
table: "test_measurements",
|
|
266
|
+
column1: "temperature",
|
|
267
|
+
column2: "humidity",
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### 5.4 — Top N
|
|
272
|
+
|
|
273
|
+
```javascript
|
|
274
|
+
return await sqlite.stats.statsTopN({
|
|
275
|
+
table: "test_products",
|
|
276
|
+
column: "price",
|
|
277
|
+
n: 5,
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Phase 6: Text Group via Code Mode (3 tests)
|
|
284
|
+
|
|
285
|
+
### 6.1 — Regex match
|
|
286
|
+
|
|
287
|
+
```javascript
|
|
288
|
+
return await sqlite.text.regexMatch({
|
|
289
|
+
table: "test_users",
|
|
290
|
+
column: "email",
|
|
291
|
+
pattern: "@example\\.com$",
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### 6.2 — Fuzzy match
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
return await sqlite.text.fuzzyMatch({
|
|
299
|
+
table: "test_products",
|
|
300
|
+
column: "name",
|
|
301
|
+
search: "laptop",
|
|
302
|
+
maxDistance: 2,
|
|
303
|
+
});
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### 6.3 — Text case
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
return await sqlite.text.case({
|
|
310
|
+
table: "test_products",
|
|
311
|
+
column: "name",
|
|
312
|
+
mode: "upper",
|
|
313
|
+
limit: 3,
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Phase 7: Vector Group via Code Mode (4 tests)
|
|
320
|
+
|
|
321
|
+
### 7.1 — Vector search
|
|
322
|
+
|
|
323
|
+
```javascript
|
|
324
|
+
// Use first embedding from test_embeddings as query vector
|
|
325
|
+
const first = await sqlite.core.readQuery(
|
|
326
|
+
"SELECT embedding FROM test_embeddings LIMIT 1",
|
|
327
|
+
);
|
|
328
|
+
const vec = JSON.parse(first.rows[0].embedding);
|
|
329
|
+
return await sqlite.vector.search({
|
|
330
|
+
table: "test_embeddings",
|
|
331
|
+
vectorColumn: "embedding",
|
|
332
|
+
queryVector: vec,
|
|
333
|
+
limit: 3,
|
|
334
|
+
});
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### 7.2 — Vector stats
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
return await sqlite.vector.stats({
|
|
341
|
+
table: "test_embeddings",
|
|
342
|
+
vectorColumn: "embedding",
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### 7.3 — Vector count
|
|
347
|
+
|
|
348
|
+
```javascript
|
|
349
|
+
return await sqlite.vector.count({ table: "test_embeddings" });
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### 7.4 — Vector dimensions
|
|
353
|
+
|
|
354
|
+
```javascript
|
|
355
|
+
return await sqlite.vector.dimensions({
|
|
356
|
+
table: "test_embeddings",
|
|
357
|
+
vectorColumn: "embedding",
|
|
358
|
+
});
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Phase 8: Geo, Introspection, Migration via Code Mode (5 tests)
|
|
364
|
+
|
|
365
|
+
### 8.1 — Geo distance
|
|
366
|
+
|
|
367
|
+
```javascript
|
|
368
|
+
return await sqlite.geo.distance({
|
|
369
|
+
lat1: 40.7128,
|
|
370
|
+
lon1: -74.006,
|
|
371
|
+
lat2: 34.0522,
|
|
372
|
+
lon2: -118.2437,
|
|
373
|
+
});
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### 8.2 — Geo nearby
|
|
377
|
+
|
|
378
|
+
```javascript
|
|
379
|
+
return await sqlite.geo.nearby({
|
|
380
|
+
table: "test_locations",
|
|
381
|
+
latColumn: "latitude",
|
|
382
|
+
lonColumn: "longitude",
|
|
383
|
+
centerLat: 40.7,
|
|
384
|
+
centerLon: -74.0,
|
|
385
|
+
radius: 1000,
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### 8.3 — Introspection — dependency graph
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
return await sqlite.introspection.dependencyGraph();
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### 8.4 — Introspection — schema snapshot
|
|
396
|
+
|
|
397
|
+
```javascript
|
|
398
|
+
return await sqlite.introspection.schemaSnapshot({ sections: ["tables"] });
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### 8.5 — Migration — init + status
|
|
402
|
+
|
|
403
|
+
```javascript
|
|
404
|
+
await sqlite.migration.migrationInit();
|
|
405
|
+
return await sqlite.migration.migrationStatus();
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## Phase 9: Admin Group via Code Mode (4 tests)
|
|
411
|
+
|
|
412
|
+
### 9.1 — Integrity check
|
|
413
|
+
|
|
414
|
+
```javascript
|
|
415
|
+
return await sqlite.admin.integrityCheck({ maxErrors: 5 });
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### 9.2 — Pragma settings
|
|
419
|
+
|
|
420
|
+
```javascript
|
|
421
|
+
return await sqlite.admin.pragmaSettings({ pragma: "journal_mode" });
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### 9.3 — List views
|
|
425
|
+
|
|
426
|
+
```javascript
|
|
427
|
+
return await sqlite.admin.listViews();
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### 9.4 — DBSTAT
|
|
431
|
+
|
|
432
|
+
```javascript
|
|
433
|
+
return await sqlite.admin.dbstat({ table: "test_products" });
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## Phase 10: Readonly Mode (5 tests)
|
|
439
|
+
|
|
440
|
+
All tests use `readonly: true`.
|
|
441
|
+
|
|
442
|
+
### 10.1 — Read operations work in readonly
|
|
443
|
+
|
|
444
|
+
```javascript
|
|
445
|
+
// readonly: true
|
|
446
|
+
return await sqlite.core.readQuery("SELECT COUNT(*) as cnt FROM test_products");
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Expected: `{success: true, rows: [{cnt: 16}]}`
|
|
450
|
+
|
|
451
|
+
### 10.2 — Write operations blocked in readonly
|
|
452
|
+
|
|
453
|
+
```javascript
|
|
454
|
+
// readonly: true
|
|
455
|
+
return await sqlite.core.writeQuery(
|
|
456
|
+
"INSERT INTO test_products (name) VALUES ('blocked')",
|
|
457
|
+
);
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
Expected: `{success: false, code: "CODEMODE_READONLY_VIOLATION"}`
|
|
461
|
+
|
|
462
|
+
### 10.3 — Read methods still discoverable
|
|
463
|
+
|
|
464
|
+
```javascript
|
|
465
|
+
// readonly: true
|
|
466
|
+
const help = await sqlite.core.help();
|
|
467
|
+
return {
|
|
468
|
+
hasWriteQuery: help.methods.includes("writeQuery"),
|
|
469
|
+
methods: help.methods,
|
|
470
|
+
};
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
Expected: `writeQuery` still appears in help (for discoverability) but is guarded.
|
|
474
|
+
|
|
475
|
+
### 10.4 — Create table blocked
|
|
476
|
+
|
|
477
|
+
```javascript
|
|
478
|
+
// readonly: true
|
|
479
|
+
return await sqlite.core.writeQuery(
|
|
480
|
+
"CREATE TABLE temp_readonly_test (id INTEGER)",
|
|
481
|
+
);
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Expected: `{success: false, code: "CODEMODE_READONLY_VIOLATION"}`
|
|
485
|
+
|
|
486
|
+
### 10.5 — Stats read-only works
|
|
487
|
+
|
|
488
|
+
```javascript
|
|
489
|
+
// readonly: true
|
|
490
|
+
return await sqlite.stats.statsBasic({
|
|
491
|
+
table: "test_products",
|
|
492
|
+
column: "price",
|
|
493
|
+
});
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Expected: succeeds — stats tools are read-only.
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Phase 11: Security & Error Handling (6 tests)
|
|
501
|
+
|
|
502
|
+
### 11.1 — Blocked pattern (require)
|
|
503
|
+
|
|
504
|
+
```javascript
|
|
505
|
+
const fs = require("fs");
|
|
506
|
+
return fs.readFileSync("/etc/passwd");
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
Expected: `{success: false, code: "CODEMODE_VALIDATION_FAILED"}` with suggestion about blocked patterns.
|
|
510
|
+
|
|
511
|
+
### 11.2 — Blocked pattern (process)
|
|
512
|
+
|
|
513
|
+
```javascript
|
|
514
|
+
return process.env;
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
Expected: `{success: false}` — blocked pattern or runtime error.
|
|
518
|
+
|
|
519
|
+
### 11.3 — Blocked pattern (eval)
|
|
520
|
+
|
|
521
|
+
```javascript
|
|
522
|
+
return eval("1+1");
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
Expected: `{success: false, code: "CODEMODE_VALIDATION_FAILED"}`
|
|
526
|
+
|
|
527
|
+
### 11.4 — Timeout enforcement
|
|
528
|
+
|
|
529
|
+
```javascript
|
|
530
|
+
// timeout: 2000
|
|
531
|
+
while (true) {}
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
Call with `timeout: 2000`. Expected: `{success: false}` with timeout error within ~2s.
|
|
535
|
+
|
|
536
|
+
### 11.5 — Invalid tool call via API
|
|
537
|
+
|
|
538
|
+
```javascript
|
|
539
|
+
return await sqlite.core.readQuery({ query: "SELECT * FROM nonexistent_xyz" });
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
Expected: Tool returns `{success: false, error: "..."}` — the sandbox must not crash.
|
|
543
|
+
|
|
544
|
+
### 11.6 — Empty params to execute_code
|
|
545
|
+
|
|
546
|
+
Call `sqlite_execute_code` with `{}` (no `code` param). Expected: structured handler error, not raw MCP `-32602`.
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## Phase 12: Multi-Step Workflows (4 tests)
|
|
551
|
+
|
|
552
|
+
### 12.1 — ETL pipeline
|
|
553
|
+
|
|
554
|
+
```javascript
|
|
555
|
+
// Create, populate, transform, read
|
|
556
|
+
await sqlite.core.writeQuery(
|
|
557
|
+
"CREATE TABLE temp_cm_etl (id INTEGER PRIMARY KEY, raw TEXT, processed TEXT)",
|
|
558
|
+
);
|
|
559
|
+
for (let i = 1; i <= 5; i++) {
|
|
560
|
+
await sqlite.core.writeQuery({
|
|
561
|
+
query: `INSERT INTO temp_cm_etl (raw) VALUES ('item_${i}')`,
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
// Transform
|
|
565
|
+
await sqlite.core.writeQuery("UPDATE temp_cm_etl SET processed = UPPER(raw)");
|
|
566
|
+
return await sqlite.core.readQuery("SELECT * FROM temp_cm_etl");
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### 12.2 — Cross-group analysis
|
|
570
|
+
|
|
571
|
+
```javascript
|
|
572
|
+
// Use stats + json together
|
|
573
|
+
const stats = await sqlite.stats.statsBasic({
|
|
574
|
+
table: "test_products",
|
|
575
|
+
column: "price",
|
|
576
|
+
});
|
|
577
|
+
const top = await sqlite.stats.statsTopN({
|
|
578
|
+
table: "test_products",
|
|
579
|
+
column: "price",
|
|
580
|
+
n: 3,
|
|
581
|
+
});
|
|
582
|
+
return { priceStats: stats, topProducts: top };
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### 12.3 — Schema introspection + query
|
|
586
|
+
|
|
587
|
+
```javascript
|
|
588
|
+
// Discover tables, pick first, describe it, query it
|
|
589
|
+
const tables = await sqlite.core.listTables();
|
|
590
|
+
const first = tables.tables[0].name;
|
|
591
|
+
const schema = await sqlite.core.describeTable(first);
|
|
592
|
+
const sample = await sqlite.core.readQuery({
|
|
593
|
+
query: `SELECT * FROM ${first} LIMIT 3`,
|
|
594
|
+
});
|
|
595
|
+
return {
|
|
596
|
+
table: first,
|
|
597
|
+
columnCount: schema.columns?.length,
|
|
598
|
+
sampleRows: sample.rows?.length,
|
|
599
|
+
};
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### 12.4 — Loop with accumulator
|
|
603
|
+
|
|
604
|
+
```javascript
|
|
605
|
+
const tables = await sqlite.core.listTables();
|
|
606
|
+
const counts = {};
|
|
607
|
+
for (const t of tables.tables.slice(0, 5)) {
|
|
608
|
+
const r = await sqlite.stats.statsCount({ table: t.name });
|
|
609
|
+
counts[t.name] = r.count;
|
|
610
|
+
}
|
|
611
|
+
return counts;
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
---
|
|
615
|
+
|
|
616
|
+
## Cleanup
|
|
617
|
+
|
|
618
|
+
After all phases:
|
|
619
|
+
|
|
620
|
+
```javascript
|
|
621
|
+
await sqlite.core.writeQuery("DROP TABLE IF EXISTS temp_cm_test");
|
|
622
|
+
await sqlite.core.writeQuery("DROP TABLE IF EXISTS temp_cm_etl");
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
---
|
|
626
|
+
|
|
627
|
+
## Post-Test Procedures
|
|
628
|
+
|
|
629
|
+
See [test-tools.md](./test-tools.md#post-test-procedures) — same workflow: 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, triage findings, create implementation plan if needed, validate with lint + typecheck, commit without push, live re-test and provide final summary.
|