@conte777/db-view-mcp 1.2.1 → 1.3.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/README.md +34 -250
- package/config.example.json +3 -1
- package/dist/config/types.d.ts +14 -4
- package/dist/config/types.js +5 -10
- package/dist/config/types.js.map +1 -1
- package/dist/connectors/clickhouse.d.ts +1 -1
- package/dist/connectors/clickhouse.js +11 -3
- package/dist/connectors/clickhouse.js.map +1 -1
- package/dist/connectors/manager.d.ts +7 -2
- package/dist/connectors/manager.js +38 -35
- package/dist/connectors/manager.js.map +1 -1
- package/dist/connectors/postgresql.d.ts +1 -1
- package/dist/connectors/postgresql.js +61 -11
- package/dist/connectors/postgresql.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +6 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/readonly/describe-table.d.ts +1 -3
- package/dist/tools/readonly/describe-table.js +5 -5
- package/dist/tools/readonly/describe-table.js.map +1 -1
- package/dist/tools/readonly/explain.d.ts +1 -3
- package/dist/tools/readonly/explain.js +6 -6
- package/dist/tools/readonly/explain.js.map +1 -1
- package/dist/tools/readonly/list-tables.d.ts +1 -3
- package/dist/tools/readonly/list-tables.js +5 -5
- package/dist/tools/readonly/list-tables.js.map +1 -1
- package/dist/tools/readonly/performance.d.ts +1 -3
- package/dist/tools/readonly/performance.js +9 -6
- package/dist/tools/readonly/performance.js.map +1 -1
- package/dist/tools/readonly/query.d.ts +1 -3
- package/dist/tools/readonly/query.js +14 -7
- package/dist/tools/readonly/query.js.map +1 -1
- package/dist/tools/readonly/schema.d.ts +1 -3
- package/dist/tools/readonly/schema.js +5 -5
- package/dist/tools/readonly/schema.js.map +1 -1
- package/dist/tools/write/execute.d.ts +5 -3
- package/dist/tools/write/execute.js +14 -6
- package/dist/tools/write/execute.js.map +1 -1
- package/dist/tools/write/transaction.d.ts +3 -4
- package/dist/tools/write/transaction.js +33 -24
- package/dist/tools/write/transaction.js.map +1 -1
- package/dist/transport/http.d.ts +2 -2
- package/dist/transport/http.js +23 -9
- package/dist/transport/http.js.map +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/resolve-db.d.ts +5 -0
- package/dist/utils/resolve-db.js +61 -0
- package/dist/utils/resolve-db.js.map +1 -0
- package/dist/utils/response.d.ts +12 -0
- package/dist/utils/response.js +130 -3
- package/dist/utils/response.js.map +1 -1
- package/dist/utils/sql-validator.d.ts +16 -0
- package/dist/utils/sql-validator.js +157 -4
- package/dist/utils/sql-validator.js.map +1 -1
- package/package.json +9 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
export interface ValidationResult {
|
|
2
2
|
valid: boolean;
|
|
3
3
|
error?: string;
|
|
4
|
+
/**
|
|
5
|
+
* Present when valid is true: the original SQL with comments and trailing semicolons removed.
|
|
6
|
+
* String literals and quoted identifiers are left byte-for-byte intact — this is NOT the
|
|
7
|
+
* __STR__ placeholder / unquoted-identifier text used internally for keyword matching, which
|
|
8
|
+
* must never reach the database.
|
|
9
|
+
*/
|
|
10
|
+
normalizedSql?: string;
|
|
4
11
|
}
|
|
12
|
+
export type SqlDialect = "postgresql" | "clickhouse";
|
|
5
13
|
export declare function validateReadonlySql(sql: string): ValidationResult;
|
|
14
|
+
/**
|
|
15
|
+
* Wraps a read-only query in a row-limited subselect. Also strips comments and trailing
|
|
16
|
+
* semicolons (string-literal-aware, same as validateReadonlySql's normalizedSql) as a safety
|
|
17
|
+
* net for callers still passing raw/un-normalized SQL — without this, something like
|
|
18
|
+
* "SELECT 1; -- c" would comment out the wrapper's closing paren. The stripping is idempotent,
|
|
19
|
+
* so passing an already-normalizedSql value is safe and a no-op.
|
|
20
|
+
*/
|
|
21
|
+
export declare function wrapReadonlyQuery(sql: string, limit: number, dialect: SqlDialect): string;
|
|
@@ -14,11 +14,69 @@ const WRITE_KEYWORDS = [
|
|
|
14
14
|
"CALL",
|
|
15
15
|
];
|
|
16
16
|
const WRITE_PATTERN = new RegExp(`\\b(${WRITE_KEYWORDS.join("|")})\\b`, "i");
|
|
17
|
+
// Functions that pass the WRITE_KEYWORDS check but still let a read-only session escape the
|
|
18
|
+
// sandbox: PostgreSQL admin/superuser actions, filesystem/network access, cross-server links,
|
|
19
|
+
// DoS via pg_sleep, or ClickHouse table functions that reach outside the database. The validator
|
|
20
|
+
// doesn't know the dialect, so one combined list is used; the false-positive risk is a table or
|
|
21
|
+
// column literally named e.g. "url" invoked as a function call, which is acceptable.
|
|
22
|
+
const DENIED_FUNCTIONS = [
|
|
23
|
+
// PostgreSQL
|
|
24
|
+
"pg_terminate_backend",
|
|
25
|
+
"pg_cancel_backend",
|
|
26
|
+
"pg_reload_conf",
|
|
27
|
+
"pg_read_file",
|
|
28
|
+
"pg_read_binary_file",
|
|
29
|
+
"pg_ls_dir",
|
|
30
|
+
"pg_ls_logdir",
|
|
31
|
+
"pg_ls_waldir",
|
|
32
|
+
"pg_ls_tmpdir",
|
|
33
|
+
"pg_ls_archive_statusdir",
|
|
34
|
+
"pg_stat_file",
|
|
35
|
+
"pg_file_write",
|
|
36
|
+
"pg_file_rename",
|
|
37
|
+
"pg_file_unlink",
|
|
38
|
+
"lo_import",
|
|
39
|
+
"lo_export",
|
|
40
|
+
"dblink",
|
|
41
|
+
"dblink_exec",
|
|
42
|
+
"dblink_connect",
|
|
43
|
+
"dblink_connect_u",
|
|
44
|
+
"dblink_send_query",
|
|
45
|
+
"dblink_open",
|
|
46
|
+
"dblink_fetch",
|
|
47
|
+
"dblink_close",
|
|
48
|
+
"pg_sleep",
|
|
49
|
+
"pg_logical_emit_message",
|
|
50
|
+
"pg_create_restore_point",
|
|
51
|
+
"pg_switch_wal",
|
|
52
|
+
"pg_promote",
|
|
53
|
+
"set_config",
|
|
54
|
+
// ClickHouse table functions
|
|
55
|
+
"url",
|
|
56
|
+
"file",
|
|
57
|
+
"s3",
|
|
58
|
+
"remote",
|
|
59
|
+
"remoteSecure",
|
|
60
|
+
"mysql",
|
|
61
|
+
"postgresql",
|
|
62
|
+
"jdbc",
|
|
63
|
+
"odbc",
|
|
64
|
+
"hdfs",
|
|
65
|
+
"azureBlobStorage",
|
|
66
|
+
"executable",
|
|
67
|
+
];
|
|
68
|
+
// Function CALLS only (name directly followed by "("), so column/table names like
|
|
69
|
+
// "file_uploads" or "my_url" are left alone. Matched case-insensitively.
|
|
70
|
+
const DENY_PATTERN = new RegExp(`\\b(${DENIED_FUNCTIONS.join("|")})\\s*\\(`, "i");
|
|
17
71
|
function stripStringLiterals(sql) {
|
|
18
|
-
// Replace single-quoted strings (handling escaped quotes)
|
|
72
|
+
// Replace single-quoted strings (handling escaped quotes) — these are inert data.
|
|
19
73
|
let result = sql.replace(/'(?:[^'\\]|\\.)*'/g, "__STR__");
|
|
20
|
-
//
|
|
21
|
-
|
|
74
|
+
// Unwrap double-quoted identifiers to their inner text instead of blanking them: in
|
|
75
|
+
// PostgreSQL/ClickHouse `"pg_terminate_backend"(1)` invokes the very same function as the
|
|
76
|
+
// unquoted form, so a quoted name must still be seen by WRITE_PATTERN/DENY_PATTERN. Keeping
|
|
77
|
+
// the content (checked as if unquoted) fails safe — the worst case is rejecting a read query
|
|
78
|
+
// whose column/identifier happens to equal a write keyword or denied function name.
|
|
79
|
+
result = result.replace(/"((?:[^"\\]|\\.)*)"/g, "$1");
|
|
22
80
|
// Replace dollar-quoted strings (PostgreSQL): $$...$$, $tag$...$tag$
|
|
23
81
|
result = result.replace(/\$([^$]*)\$[\s\S]*?\$\1\$/g, "__STR__");
|
|
24
82
|
return result;
|
|
@@ -33,6 +91,77 @@ function stripComments(sql) {
|
|
|
33
91
|
function normalizeWhitespace(sql) {
|
|
34
92
|
return sql.replace(/\s+/g, " ").trim();
|
|
35
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Comment stripping for SQL that will actually be sent to the database. Unlike
|
|
96
|
+
* stripComments+stripStringLiterals (placeholder-based, only safe for keyword matching), this
|
|
97
|
+
* tracks quote state in a single pass so string/identifier/dollar-quoted content is copied
|
|
98
|
+
* verbatim — "--" or "/*" inside a literal is never mistaken for a comment.
|
|
99
|
+
*/
|
|
100
|
+
function stripCommentsPreserveStrings(sql) {
|
|
101
|
+
let result = "";
|
|
102
|
+
let i = 0;
|
|
103
|
+
const n = sql.length;
|
|
104
|
+
while (i < n) {
|
|
105
|
+
const c = sql[i];
|
|
106
|
+
const c2 = i + 1 < n ? sql[i + 1] : "";
|
|
107
|
+
if (c === "'" || c === '"') {
|
|
108
|
+
const quote = c;
|
|
109
|
+
result += c;
|
|
110
|
+
i++;
|
|
111
|
+
while (i < n) {
|
|
112
|
+
if (sql[i] === "\\" && i + 1 < n) {
|
|
113
|
+
result += sql[i] + sql[i + 1];
|
|
114
|
+
i += 2;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (sql[i] === quote) {
|
|
118
|
+
result += sql[i];
|
|
119
|
+
i++;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
result += sql[i];
|
|
123
|
+
i++;
|
|
124
|
+
}
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (c === "$") {
|
|
128
|
+
// Dollar-quoted string ($$...$$ or $tag$...$tag$): [^$]* naturally stops at the next "$".
|
|
129
|
+
const opener = /^\$[^$]*\$/.exec(sql.slice(i));
|
|
130
|
+
if (opener) {
|
|
131
|
+
const delimiter = opener[0];
|
|
132
|
+
const closeIdx = sql.indexOf(delimiter, i + delimiter.length);
|
|
133
|
+
if (closeIdx !== -1) {
|
|
134
|
+
result += sql.slice(i, closeIdx + delimiter.length);
|
|
135
|
+
i = closeIdx + delimiter.length;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
result += c;
|
|
140
|
+
i++;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (c === "-" && c2 === "-") {
|
|
144
|
+
let j = i;
|
|
145
|
+
while (j < n && sql[j] !== "\n")
|
|
146
|
+
j++;
|
|
147
|
+
result += " ";
|
|
148
|
+
i = j;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (c === "/" && c2 === "*") {
|
|
152
|
+
const end = sql.indexOf("*/", i + 2);
|
|
153
|
+
result += " ";
|
|
154
|
+
i = end === -1 ? n : end + 2;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
result += c;
|
|
158
|
+
i++;
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
function stripTrailingSemicolons(sql) {
|
|
163
|
+
return sql.replace(/;+\s*$/, "").trim();
|
|
164
|
+
}
|
|
36
165
|
export function validateReadonlySql(sql) {
|
|
37
166
|
const trimmed = sql.trim();
|
|
38
167
|
if (!trimmed) {
|
|
@@ -60,6 +189,30 @@ export function validateReadonlySql(sql) {
|
|
|
60
189
|
error: `Statement '${match[1].toUpperCase()}' is not allowed in read-only mode`,
|
|
61
190
|
};
|
|
62
191
|
}
|
|
63
|
-
|
|
192
|
+
// Check for dangerous function calls (admin/filesystem/network escapes) anywhere in normalized SQL
|
|
193
|
+
const denyMatch = normalized.match(DENY_PATTERN);
|
|
194
|
+
if (denyMatch) {
|
|
195
|
+
return {
|
|
196
|
+
valid: false,
|
|
197
|
+
error: `Function '${denyMatch[1]}' is not allowed in read-only mode`,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const normalizedSql = stripTrailingSemicolons(stripCommentsPreserveStrings(trimmed));
|
|
201
|
+
return { valid: true, normalizedSql };
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Wraps a read-only query in a row-limited subselect. Also strips comments and trailing
|
|
205
|
+
* semicolons (string-literal-aware, same as validateReadonlySql's normalizedSql) as a safety
|
|
206
|
+
* net for callers still passing raw/un-normalized SQL — without this, something like
|
|
207
|
+
* "SELECT 1; -- c" would comment out the wrapper's closing paren. The stripping is idempotent,
|
|
208
|
+
* so passing an already-normalizedSql value is safe and a no-op.
|
|
209
|
+
*/
|
|
210
|
+
export function wrapReadonlyQuery(sql, limit, dialect) {
|
|
211
|
+
const inner = stripTrailingSemicolons(stripCommentsPreserveStrings(sql.trim()));
|
|
212
|
+
switch (dialect) {
|
|
213
|
+
case "postgresql":
|
|
214
|
+
case "clickhouse":
|
|
215
|
+
return `SELECT * FROM (${inner}) AS _q LIMIT ${limit}`;
|
|
216
|
+
}
|
|
64
217
|
}
|
|
65
218
|
//# sourceMappingURL=sql-validator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-validator.js","sourceRoot":"","sources":["../../src/utils/sql-validator.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG;IACrB,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,OAAO;IACP,UAAU;IACV,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,SAAS;IACT,OAAO;IACP,MAAM;IACN,MAAM;CACP,CAAC;AAEF,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"sql-validator.js","sourceRoot":"","sources":["../../src/utils/sql-validator.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conte777/db-view-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "MCP server for database access (PostgreSQL + ClickHouse)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -31,6 +31,14 @@
|
|
|
31
31
|
"postgresql",
|
|
32
32
|
"clickhouse"
|
|
33
33
|
],
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/Conte777/db-view-mcp.git"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/Conte777/db-view-mcp#readme",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/Conte777/db-view-mcp/issues"
|
|
41
|
+
},
|
|
34
42
|
"license": "MIT",
|
|
35
43
|
"dependencies": {
|
|
36
44
|
"@clickhouse/client": "^1.17.0",
|