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
package/dist/index.js
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// Core server
|
|
7
|
-
export { DbMcpServer, createServer, DEFAULT_CONFIG, } from "./server/McpServer.js";
|
|
8
|
-
// Error classes
|
|
9
|
-
export { DbMcpError, ConnectionError, QueryError, AuthenticationError, AuthorizationError, ValidationError, } from "./types/index.js";
|
|
10
|
-
// Base adapter class
|
|
11
|
-
export { DatabaseAdapter } from "./adapters/DatabaseAdapter.js";
|
|
12
|
-
// Tool filtering utilities
|
|
13
|
-
export { TOOL_GROUPS, META_GROUPS, ALL_TOOL_GROUPS, parseToolFilter, isToolEnabled, filterTools, getToolFilterFromEnv, getFilterSummary, } from "./filtering/ToolFilter.js";
|
|
14
|
-
// Version info
|
|
15
|
-
export const VERSION = "0.1.0";
|
|
16
|
-
export const NAME = "db-mcp";
|
|
17
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export { DEFAULT_CONFIG, DbMcpServer, NAME, VERSION, createServer } from './chunk-DZQLDEQS.js';
|
|
2
|
+
export { DatabaseAdapter } from './chunk-Z2GFQU3G.js';
|
|
3
|
+
import './chunk-S5IDDSSB.js';
|
|
4
|
+
export { AuthenticationError, AuthorizationError, ConnectionError, QueryError, ValidationError } from './chunk-4IA3DB5C.js';
|
|
5
|
+
export { ALL_TOOL_GROUPS, DbMcpError, META_GROUPS, TOOL_GROUPS, filterTools, getFilterSummary, getToolFilterFromEnv, isToolEnabled, parseToolFilter } from './chunk-AOUL5SHS.js';
|
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
import { getCoreTools, getJsonHelperTools, getJsonOperationTools, getTextTools, getStatsTools, getVirtualTools, getVectorTools, getGeoTools, getAdminTools, getIntrospectionTools, getMigrationTools, getCodeModeTools, isDDL, getResourceDefinitions, getPromptDefinitions, applyCommonPragmas, autoEnableWal, detectAndSetJsonbSupport, SchemaManager, normalizeSqliteParams } from './chunk-DWJXQEFA.js';
|
|
2
|
+
export { getCoreTools } from './chunk-DWJXQEFA.js';
|
|
3
|
+
import { DatabaseAdapter } from './chunk-Z2GFQU3G.js';
|
|
4
|
+
import { getToolGroupIcon } from './chunk-S5IDDSSB.js';
|
|
5
|
+
import { ConnectionError, ConfigurationError, QueryError } from './chunk-4IA3DB5C.js';
|
|
6
|
+
import { createModuleLogger, ERROR_CODES, DbMcpError } from './chunk-AOUL5SHS.js';
|
|
7
|
+
import initSqlJs from 'sql.js';
|
|
8
|
+
|
|
9
|
+
// src/adapters/sqlite/tools/index.ts
|
|
10
|
+
function getAllToolDefinitions(adapter) {
|
|
11
|
+
const tools = [
|
|
12
|
+
...getCoreTools(adapter),
|
|
13
|
+
...getJsonHelperTools(adapter),
|
|
14
|
+
...getJsonOperationTools(adapter),
|
|
15
|
+
...getTextTools(adapter),
|
|
16
|
+
...getStatsTools(adapter),
|
|
17
|
+
...getVirtualTools(adapter),
|
|
18
|
+
...getVectorTools(adapter),
|
|
19
|
+
...getGeoTools(adapter),
|
|
20
|
+
...getAdminTools(adapter),
|
|
21
|
+
...getIntrospectionTools(adapter),
|
|
22
|
+
...getMigrationTools(adapter),
|
|
23
|
+
...getCodeModeTools(adapter)
|
|
24
|
+
];
|
|
25
|
+
for (const tool of tools) {
|
|
26
|
+
if (!tool.icons) {
|
|
27
|
+
const icons = getToolGroupIcon(tool.group);
|
|
28
|
+
if (icons) {
|
|
29
|
+
tool.icons = icons;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return tools;
|
|
34
|
+
}
|
|
35
|
+
function getToolsByGroup(adapter, group) {
|
|
36
|
+
return getAllToolDefinitions(adapter).filter((tool) => tool.group === group);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/adapters/sqlite/query-executor.ts
|
|
40
|
+
var log = createModuleLogger("SQLITE");
|
|
41
|
+
function rowsFromSqlJsResult(result) {
|
|
42
|
+
const numColumns = result.columns.length;
|
|
43
|
+
const numRows = result.values.length;
|
|
44
|
+
const rows = new Array(numRows);
|
|
45
|
+
const cols = result.columns;
|
|
46
|
+
for (let i = 0; i < numRows; i++) {
|
|
47
|
+
const rowObj = {};
|
|
48
|
+
const rowValues = result.values[i];
|
|
49
|
+
if (rowValues) {
|
|
50
|
+
for (let j = 0; j < numColumns; j++) {
|
|
51
|
+
rowObj[cols[j]] = rowValues[j];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
rows[i] = rowObj;
|
|
55
|
+
}
|
|
56
|
+
return rows;
|
|
57
|
+
}
|
|
58
|
+
function executeRead(db, sql, params) {
|
|
59
|
+
const start = Date.now();
|
|
60
|
+
try {
|
|
61
|
+
const normalizedParams = normalizeSqliteParams(params);
|
|
62
|
+
const results = normalizedParams ? db.exec(sql, normalizedParams) : db.exec(sql);
|
|
63
|
+
if (results.length === 0) {
|
|
64
|
+
return Promise.resolve({
|
|
65
|
+
rows: [],
|
|
66
|
+
executionTimeMs: Date.now() - start
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const firstResult = results[0];
|
|
70
|
+
if (!firstResult) {
|
|
71
|
+
return Promise.resolve({
|
|
72
|
+
rows: [],
|
|
73
|
+
executionTimeMs: Date.now() - start
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const columns = firstResult.columns.map((name) => ({
|
|
77
|
+
name,
|
|
78
|
+
type: "unknown"
|
|
79
|
+
}));
|
|
80
|
+
const rows = rowsFromSqlJsResult(firstResult);
|
|
81
|
+
return Promise.resolve({
|
|
82
|
+
rows,
|
|
83
|
+
columns,
|
|
84
|
+
executionTimeMs: Date.now() - start
|
|
85
|
+
});
|
|
86
|
+
} catch (error) {
|
|
87
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
88
|
+
log.error(`Query failed: ${message}`, {
|
|
89
|
+
code: ERROR_CODES.DB.QUERY_FAILED.full
|
|
90
|
+
});
|
|
91
|
+
throw new QueryError(
|
|
92
|
+
`Query execution failed: ${message}`,
|
|
93
|
+
"DB_QUERY_FAILED",
|
|
94
|
+
{
|
|
95
|
+
sql,
|
|
96
|
+
cause: error instanceof Error ? error : void 0
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function executeWrite(db, sql, params) {
|
|
102
|
+
const start = Date.now();
|
|
103
|
+
try {
|
|
104
|
+
const normalizedParams = normalizeSqliteParams(params);
|
|
105
|
+
if (normalizedParams) {
|
|
106
|
+
db.run(sql, normalizedParams);
|
|
107
|
+
} else {
|
|
108
|
+
db.run(sql);
|
|
109
|
+
}
|
|
110
|
+
const changes = db.getRowsModified();
|
|
111
|
+
return Promise.resolve({
|
|
112
|
+
rowsAffected: changes,
|
|
113
|
+
executionTimeMs: Date.now() - start
|
|
114
|
+
});
|
|
115
|
+
} catch (error) {
|
|
116
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
117
|
+
log.error(`Write query failed: ${message}`, {
|
|
118
|
+
code: ERROR_CODES.DB.QUERY_FAILED.full
|
|
119
|
+
});
|
|
120
|
+
throw new QueryError(`Write query failed: ${message}`, "DB_WRITE_FAILED", {
|
|
121
|
+
sql,
|
|
122
|
+
cause: error instanceof Error ? error : void 0
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function executeGeneral(db, sql, params) {
|
|
127
|
+
const start = Date.now();
|
|
128
|
+
try {
|
|
129
|
+
const normalizedParams = normalizeSqliteParams(params);
|
|
130
|
+
const results = normalizedParams ? db.exec(sql, normalizedParams) : db.exec(sql);
|
|
131
|
+
if (results.length === 0) {
|
|
132
|
+
return Promise.resolve({
|
|
133
|
+
rowsAffected: db.getRowsModified(),
|
|
134
|
+
executionTimeMs: Date.now() - start
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const firstResult = results[0];
|
|
138
|
+
if (!firstResult) {
|
|
139
|
+
return Promise.resolve({
|
|
140
|
+
rowsAffected: db.getRowsModified(),
|
|
141
|
+
executionTimeMs: Date.now() - start
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const rows = rowsFromSqlJsResult(firstResult);
|
|
145
|
+
return Promise.resolve({
|
|
146
|
+
rows,
|
|
147
|
+
executionTimeMs: Date.now() - start
|
|
148
|
+
});
|
|
149
|
+
} catch (error) {
|
|
150
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
151
|
+
log.error(`Query failed: ${message}`, {
|
|
152
|
+
code: ERROR_CODES.DB.QUERY_FAILED.full
|
|
153
|
+
});
|
|
154
|
+
throw new QueryError(`Query failed: ${message}`, "DB_QUERY_FAILED", {
|
|
155
|
+
sql,
|
|
156
|
+
cause: error instanceof Error ? error : void 0
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
var log2 = createModuleLogger("SQLITE");
|
|
161
|
+
async function connectSqliteDatabase(adapter, config) {
|
|
162
|
+
if (config.type !== "sqlite") {
|
|
163
|
+
throw new ConfigurationError(
|
|
164
|
+
`Invalid database type: expected 'sqlite', got '${config.type}'`,
|
|
165
|
+
"DB_TYPE_MISMATCH"
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const sqliteConfig = config;
|
|
169
|
+
try {
|
|
170
|
+
const sqlJsInstance = await initSqlJs();
|
|
171
|
+
const filePath = sqliteConfig.filePath ?? sqliteConfig.connectionString ?? ":memory:";
|
|
172
|
+
let db;
|
|
173
|
+
if (filePath === ":memory:") {
|
|
174
|
+
db = new sqlJsInstance.Database();
|
|
175
|
+
log2.info("Connected to in-memory SQLite database", {
|
|
176
|
+
code: "SQLITE_CONNECT"
|
|
177
|
+
});
|
|
178
|
+
} else {
|
|
179
|
+
try {
|
|
180
|
+
const fs = await import('fs');
|
|
181
|
+
if (fs.existsSync(filePath)) {
|
|
182
|
+
const buffer = await fs.promises.readFile(filePath);
|
|
183
|
+
db = new sqlJsInstance.Database(buffer);
|
|
184
|
+
log2.info(`Connected to SQLite database: ${filePath}`, {
|
|
185
|
+
code: "SQLITE_CONNECT"
|
|
186
|
+
});
|
|
187
|
+
} else {
|
|
188
|
+
db = new sqlJsInstance.Database();
|
|
189
|
+
log2.info(`Created new SQLite database: ${filePath}`, {
|
|
190
|
+
code: "SQLITE_CONNECT"
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
} catch {
|
|
194
|
+
db = new sqlJsInstance.Database();
|
|
195
|
+
log2.warning("File access unavailable, using in-memory database", {
|
|
196
|
+
code: "SQLITE_FALLBACK"
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (sqliteConfig.options) {
|
|
201
|
+
applyCommonPragmas(
|
|
202
|
+
{ runPragma: (pragma) => db.run(`PRAGMA ${pragma}`) },
|
|
203
|
+
sqliteConfig.options
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
autoEnableWal(
|
|
207
|
+
{ runPragma: (pragma) => db.run(`PRAGMA ${pragma}`) },
|
|
208
|
+
filePath,
|
|
209
|
+
sqliteConfig.options,
|
|
210
|
+
log2
|
|
211
|
+
);
|
|
212
|
+
detectAndSetJsonbSupport(() => {
|
|
213
|
+
const versionResult = db.exec("SELECT sqlite_version()");
|
|
214
|
+
return versionResult[0]?.values[0]?.[0] ?? "0.0.0";
|
|
215
|
+
}, log2);
|
|
216
|
+
const schemaManager = new SchemaManager(adapter);
|
|
217
|
+
return { db, sqlJsInstance, schemaManager };
|
|
218
|
+
} catch (error) {
|
|
219
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
220
|
+
log2.error(`Failed to connect to SQLite: ${message}`, {
|
|
221
|
+
code: ERROR_CODES.DB.CONNECT_FAILED.full
|
|
222
|
+
});
|
|
223
|
+
throw new ConnectionError(
|
|
224
|
+
`SQLite connection failed: ${message}`,
|
|
225
|
+
"DB_CONNECT_FAILED",
|
|
226
|
+
{
|
|
227
|
+
cause: error instanceof Error ? error : void 0
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async function disconnectSqliteDatabase(db, config) {
|
|
233
|
+
if (config?.filePath && config.filePath !== ":memory:") {
|
|
234
|
+
try {
|
|
235
|
+
const fs = await import('fs');
|
|
236
|
+
const data = db.export();
|
|
237
|
+
await fs.promises.writeFile(config.filePath, Buffer.from(data));
|
|
238
|
+
log2.info(`Saved database to: ${config.filePath}`, {
|
|
239
|
+
code: "SQLITE_DISCONNECT"
|
|
240
|
+
});
|
|
241
|
+
} catch {
|
|
242
|
+
log2.warning("Could not save database to file", {
|
|
243
|
+
code: "SQLITE_SAVE_FAILED"
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
db.close();
|
|
248
|
+
log2.info("Disconnected from SQLite database", {
|
|
249
|
+
code: "SQLITE_DISCONNECT"
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// src/adapters/sqlite/sqlite-adapter/schema.ts
|
|
254
|
+
async function fallBackGetSchema(adapter) {
|
|
255
|
+
const tables = await adapter.listTables();
|
|
256
|
+
const indexes = await adapter.getIndexes();
|
|
257
|
+
return { tables, indexes };
|
|
258
|
+
}
|
|
259
|
+
async function fallBackListTables(adapter) {
|
|
260
|
+
const result = await adapter.executeReadQuery(
|
|
261
|
+
`SELECT name, type FROM sqlite_master
|
|
262
|
+
WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'
|
|
263
|
+
ORDER BY name`
|
|
264
|
+
);
|
|
265
|
+
const tables = [];
|
|
266
|
+
for (const row of result.rows ?? []) {
|
|
267
|
+
const name = row["name"];
|
|
268
|
+
const type = row["type"];
|
|
269
|
+
const tableInfo = await adapter.describeTable(name);
|
|
270
|
+
tables.push({ ...tableInfo, type });
|
|
271
|
+
}
|
|
272
|
+
return tables;
|
|
273
|
+
}
|
|
274
|
+
async function fallBackDescribeTable(adapter, tableName) {
|
|
275
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tableName)) {
|
|
276
|
+
throw new DbMcpError(
|
|
277
|
+
"Invalid table name",
|
|
278
|
+
"SQLITE_INVALID_TABLE",
|
|
279
|
+
"validation" /* VALIDATION */
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
const result = await adapter.executeReadQuery(
|
|
283
|
+
`PRAGMA table_info("${tableName}")`
|
|
284
|
+
);
|
|
285
|
+
const columns = (result.rows ?? []).map((row) => ({
|
|
286
|
+
name: row["name"],
|
|
287
|
+
type: row["type"],
|
|
288
|
+
nullable: row["notnull"] === 0,
|
|
289
|
+
primaryKey: row["pk"] === 1,
|
|
290
|
+
defaultValue: row["dflt_value"]
|
|
291
|
+
}));
|
|
292
|
+
const countResult = await adapter.executeReadQuery(
|
|
293
|
+
`SELECT COUNT(*) as count FROM "${tableName}"`
|
|
294
|
+
);
|
|
295
|
+
const rowCount = countResult.rows?.[0]?.["count"] ?? 0;
|
|
296
|
+
return {
|
|
297
|
+
name: tableName,
|
|
298
|
+
type: "table",
|
|
299
|
+
columns,
|
|
300
|
+
rowCount
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
async function fallBackGetIndexes(adapter, table) {
|
|
304
|
+
let sql = `SELECT name, tbl_name, sql FROM sqlite_master
|
|
305
|
+
WHERE type = 'index' AND sql IS NOT NULL`;
|
|
306
|
+
let params;
|
|
307
|
+
if (table) {
|
|
308
|
+
sql += ` AND tbl_name = ?`;
|
|
309
|
+
params = [table];
|
|
310
|
+
}
|
|
311
|
+
const result = await adapter.executeReadQuery(sql, params);
|
|
312
|
+
const indexes = [];
|
|
313
|
+
for (const row of result.rows ?? []) {
|
|
314
|
+
const indexName = row["name"];
|
|
315
|
+
const tableName = row["tbl_name"];
|
|
316
|
+
const sqlDef = row["sql"];
|
|
317
|
+
let columns;
|
|
318
|
+
try {
|
|
319
|
+
const indexInfo = await adapter.executeReadQuery(
|
|
320
|
+
`PRAGMA index_info("${indexName}")`
|
|
321
|
+
);
|
|
322
|
+
columns = (indexInfo.rows ?? []).map((col) => col["name"]);
|
|
323
|
+
} catch {
|
|
324
|
+
columns = [];
|
|
325
|
+
}
|
|
326
|
+
indexes.push({
|
|
327
|
+
name: indexName,
|
|
328
|
+
tableName,
|
|
329
|
+
columns,
|
|
330
|
+
unique: sqlDef?.toUpperCase().includes("UNIQUE") ?? false
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
return indexes;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/adapters/sqlite/sqlite-adapter.ts
|
|
337
|
+
var SqliteAdapter = class extends DatabaseAdapter {
|
|
338
|
+
type = "sqlite";
|
|
339
|
+
name = "SQLite Adapter";
|
|
340
|
+
version = "1.1.0";
|
|
341
|
+
// Keep in sync with package.json
|
|
342
|
+
/**
|
|
343
|
+
* Check if this adapter uses native (better-sqlite3) backend.
|
|
344
|
+
* Returns false for WASM/sql.js adapter.
|
|
345
|
+
*/
|
|
346
|
+
isNativeBackend() {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Get the configured database file path.
|
|
351
|
+
* Returns the user-configured path, not internal WASM virtual filesystem paths.
|
|
352
|
+
*/
|
|
353
|
+
getConfiguredPath() {
|
|
354
|
+
return this.config?.filePath ?? this.config?.connectionString ?? ":memory:";
|
|
355
|
+
}
|
|
356
|
+
db = null;
|
|
357
|
+
config = null;
|
|
358
|
+
schemaManager = null;
|
|
359
|
+
/**
|
|
360
|
+
* Connect to a SQLite database
|
|
361
|
+
*/
|
|
362
|
+
async connect(config) {
|
|
363
|
+
this.config = config;
|
|
364
|
+
const { db, schemaManager } = await connectSqliteDatabase(this, config);
|
|
365
|
+
this.db = db;
|
|
366
|
+
this.schemaManager = schemaManager;
|
|
367
|
+
this.connected = true;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Disconnect from the database
|
|
371
|
+
*/
|
|
372
|
+
async disconnect() {
|
|
373
|
+
if (this.db) {
|
|
374
|
+
await disconnectSqliteDatabase(this.db, this.config);
|
|
375
|
+
this.db = null;
|
|
376
|
+
this.connected = false;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Get database health status
|
|
381
|
+
*/
|
|
382
|
+
getHealth() {
|
|
383
|
+
if (!this.db) {
|
|
384
|
+
return Promise.resolve({ connected: false, error: "Not connected" });
|
|
385
|
+
}
|
|
386
|
+
try {
|
|
387
|
+
const start = Date.now();
|
|
388
|
+
const result = this.db.exec("SELECT sqlite_version() as version");
|
|
389
|
+
const latencyMs = Date.now() - start;
|
|
390
|
+
const version = result[0]?.values[0]?.[0] ?? "unknown";
|
|
391
|
+
return Promise.resolve({
|
|
392
|
+
connected: true,
|
|
393
|
+
latencyMs,
|
|
394
|
+
version,
|
|
395
|
+
details: {
|
|
396
|
+
filePath: this.config?.filePath ?? this.config?.connectionString ?? ":memory:",
|
|
397
|
+
walMode: this.config?.options?.walMode ?? false
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
} catch (error) {
|
|
401
|
+
return Promise.resolve({
|
|
402
|
+
connected: false,
|
|
403
|
+
error: error instanceof Error ? error.message : String(error)
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Execute a read-only query
|
|
409
|
+
*/
|
|
410
|
+
executeReadQuery(sql, params) {
|
|
411
|
+
this.ensureConnected();
|
|
412
|
+
this.validateQuery(sql, true);
|
|
413
|
+
return executeRead(this.ensureDb(), sql, params);
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Execute a write query
|
|
417
|
+
*/
|
|
418
|
+
async executeWriteQuery(sql, params, skipValidation = false) {
|
|
419
|
+
this.ensureConnected();
|
|
420
|
+
if (!skipValidation) {
|
|
421
|
+
this.validateQuery(sql, false);
|
|
422
|
+
}
|
|
423
|
+
const result = await executeWrite(this.ensureDb(), sql, params);
|
|
424
|
+
if (isDDL(sql)) {
|
|
425
|
+
this.clearSchemaCache();
|
|
426
|
+
}
|
|
427
|
+
return result;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Execute any query (for admin operations)
|
|
431
|
+
*/
|
|
432
|
+
async executeQuery(sql, params) {
|
|
433
|
+
this.ensureConnected();
|
|
434
|
+
const result = await executeGeneral(this.ensureDb(), sql, params);
|
|
435
|
+
if (isDDL(sql)) {
|
|
436
|
+
this.clearSchemaCache();
|
|
437
|
+
}
|
|
438
|
+
return result;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Get full database schema (cached via SchemaManager)
|
|
442
|
+
*/
|
|
443
|
+
async getSchema() {
|
|
444
|
+
this.ensureConnected();
|
|
445
|
+
if (this.schemaManager) {
|
|
446
|
+
return this.schemaManager.getSchema();
|
|
447
|
+
}
|
|
448
|
+
return fallBackGetSchema(this);
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* List all tables (cached via SchemaManager)
|
|
452
|
+
*/
|
|
453
|
+
async listTables() {
|
|
454
|
+
this.ensureConnected();
|
|
455
|
+
if (this.schemaManager) {
|
|
456
|
+
return this.schemaManager.listTables();
|
|
457
|
+
}
|
|
458
|
+
return fallBackListTables(this);
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Describe a table's structure (cached via SchemaManager)
|
|
462
|
+
*/
|
|
463
|
+
async describeTable(tableName) {
|
|
464
|
+
this.ensureConnected();
|
|
465
|
+
if (this.schemaManager) {
|
|
466
|
+
return this.schemaManager.describeTable(tableName);
|
|
467
|
+
}
|
|
468
|
+
return fallBackDescribeTable(this, tableName);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* List available schemas (SQLite has only 'main')
|
|
472
|
+
*/
|
|
473
|
+
listSchemas() {
|
|
474
|
+
return Promise.resolve(["main"]);
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Get indexes, optionally for a specific table (cached via SchemaManager)
|
|
478
|
+
*/
|
|
479
|
+
async getIndexes(table) {
|
|
480
|
+
this.ensureConnected();
|
|
481
|
+
if (this.schemaManager) {
|
|
482
|
+
if (table) {
|
|
483
|
+
return this.schemaManager.getTableIndexes(table);
|
|
484
|
+
}
|
|
485
|
+
return this.schemaManager.getAllIndexes();
|
|
486
|
+
}
|
|
487
|
+
return fallBackGetIndexes(this, table);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Get all indexes in a single query (cached via SchemaManager)
|
|
491
|
+
* Performance optimization: eliminates N+1 query pattern
|
|
492
|
+
*/
|
|
493
|
+
async getAllIndexes() {
|
|
494
|
+
return this.getIndexes();
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Clear the schema metadata cache
|
|
498
|
+
* Call after DDL operations or when fresh data is needed
|
|
499
|
+
*/
|
|
500
|
+
clearSchemaCache() {
|
|
501
|
+
if (this.schemaManager) {
|
|
502
|
+
this.schemaManager.clearCache();
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Get adapter capabilities
|
|
507
|
+
*/
|
|
508
|
+
getCapabilities() {
|
|
509
|
+
return {
|
|
510
|
+
json: true,
|
|
511
|
+
fullTextSearch: false,
|
|
512
|
+
// FTS5 not available in WASM/sql.js build
|
|
513
|
+
vector: true,
|
|
514
|
+
// Custom implementation
|
|
515
|
+
geospatial: false,
|
|
516
|
+
// SpatiaLite not bundled
|
|
517
|
+
transactions: true,
|
|
518
|
+
preparedStatements: true,
|
|
519
|
+
connectionPooling: false
|
|
520
|
+
// sql.js is single-connection
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Get supported tool groups
|
|
525
|
+
*/
|
|
526
|
+
getSupportedToolGroups() {
|
|
527
|
+
return [
|
|
528
|
+
"core",
|
|
529
|
+
"json",
|
|
530
|
+
"text",
|
|
531
|
+
"stats",
|
|
532
|
+
"vector",
|
|
533
|
+
"admin",
|
|
534
|
+
"geo",
|
|
535
|
+
"introspection",
|
|
536
|
+
"migration"
|
|
537
|
+
];
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Get all tool definitions
|
|
541
|
+
*/
|
|
542
|
+
getToolDefinitions() {
|
|
543
|
+
return getAllToolDefinitions(this);
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Get resource definitions
|
|
547
|
+
*/
|
|
548
|
+
getResourceDefinitions() {
|
|
549
|
+
return getResourceDefinitions(this);
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Get prompt definitions
|
|
553
|
+
*/
|
|
554
|
+
getPromptDefinitions() {
|
|
555
|
+
return getPromptDefinitions(this);
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Ensure database is connected
|
|
559
|
+
*/
|
|
560
|
+
ensureConnected() {
|
|
561
|
+
super.ensureConnected();
|
|
562
|
+
if (!this.db) {
|
|
563
|
+
throw new ConnectionError(
|
|
564
|
+
"Not connected to database",
|
|
565
|
+
"DB_NOT_CONNECTED"
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Ensure database is connected and return the database instance
|
|
571
|
+
*/
|
|
572
|
+
ensureDb() {
|
|
573
|
+
this.ensureConnected();
|
|
574
|
+
const db = this.db;
|
|
575
|
+
if (!db) {
|
|
576
|
+
throw new ConnectionError(
|
|
577
|
+
"Not connected to database",
|
|
578
|
+
"DB_NOT_CONNECTED"
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
return db;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Get the raw database instance (for tools)
|
|
585
|
+
*/
|
|
586
|
+
getDatabase() {
|
|
587
|
+
return this.ensureDb();
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Execute raw SQL and return results (for tools)
|
|
591
|
+
*/
|
|
592
|
+
rawQuery(sql, params) {
|
|
593
|
+
return this.executeQuery(sql, params);
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
function createSqliteAdapter() {
|
|
597
|
+
return new SqliteAdapter();
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
export { SqliteAdapter, createSqliteAdapter, getAllToolDefinitions, getToolsByGroup };
|