@dbx-app/mcp-server 0.4.4 → 0.4.6

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 CHANGED
@@ -10,7 +10,7 @@ MCP server for [DBX](https://github.com/t8y2/dbx) — lets AI agents (Claude Cod
10
10
  - **8 tools** — List/add/remove connections, list tables, describe table, get schema context, execute SQL, open table in DBX UI
11
11
  - **Connection pooling** — Reuses database connections across queries
12
12
  - **Direct execution** — PostgreSQL, MySQL, SQLite, and compatible databases (Doris, StarRocks, etc.) can run without opening DBX
13
- - **Read-only by default** — SQL execution blocks write and dangerous statements unless explicitly enabled
13
+ - **Writes enabled by default** — regular `INSERT` / `UPDATE` / `DELETE` statements work out of the box, while dangerous SQL stays blocked unless explicitly enabled
14
14
  - **DBX UI integration** — Open tables directly in the DBX desktop app from your AI agent
15
15
 
16
16
  ## Quick Start
@@ -92,10 +92,12 @@ See the [DBX CLI README](../cli/README.md) for command details.
92
92
 
93
93
  ## SQL Safety
94
94
 
95
- `dbx_execute_query` is read-only by default. To allow write statements such as `INSERT` or `UPDATE`, set:
95
+ `dbx_execute_query` accepts multiple SQL statements and executes them one at a time after checking each statement. Regular write statements such as `INSERT`, `UPDATE`, and `DELETE ... WHERE ...` are allowed by default.
96
+
97
+ If you need to force a read-only MCP session, set:
96
98
 
97
99
  ```bash
98
- DBX_MCP_ALLOW_WRITES=1
100
+ DBX_MCP_ALLOW_WRITES=0
99
101
  ```
100
102
 
101
103
  Dangerous statements such as `DROP`, `TRUNCATE`, and `ALTER` remain blocked unless you also set:
@@ -145,7 +147,7 @@ MIT
145
147
  - **8 个工具** — 列出/添加/删除连接、列出表、查看表结构、获取 Schema 上下文、执行 SQL、在 DBX 中打开表
146
148
  - **连接池** — 跨查询复用数据库连接
147
149
  - **直接执行** — PostgreSQL、MySQL、SQLite 及兼容数据库(Doris、StarRocks 等)无需打开 DBX 即可查询
148
- - **默认只读** — SQL 执行默认拦截写操作和危险语句
150
+ - **默认允许常规写入** — `INSERT` / `UPDATE` / `DELETE` 可直接执行,危险语句仍需显式开启
149
151
  - **DBX UI 联动** — 从 AI 助手直接在 DBX 桌面端打开表
150
152
 
151
153
  ### 快速开始
@@ -213,10 +215,12 @@ dbx query local "select 1" --json
213
215
 
214
216
  ### SQL 安全
215
217
 
216
- `dbx_execute_query` 默认只读。若要允许 `INSERT`、`UPDATE` 等写操作,设置:
218
+ `dbx_execute_query` 支持多条 SQL 语句,会逐条完成安全检查并依次执行。默认允许常规写操作,例如 `INSERT`、`UPDATE`、`DELETE ... WHERE ...`。
219
+
220
+ 如果你希望 MCP 会话强制退回只读,可设置:
217
221
 
218
222
  ```bash
219
- DBX_MCP_ALLOW_WRITES=1
223
+ DBX_MCP_ALLOW_WRITES=0
220
224
  ```
221
225
 
222
226
  `DROP`、`TRUNCATE`、`ALTER` 等危险语句仍会被拦截,除非额外设置:
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { type Backend } from "@dbx-app/node-core";
4
4
  export declare const DBX_MCP_PACKAGE_VERSION: string;
5
- export declare const DBX_CONNECTION_TYPE_DESCRIPTION = "Database type: postgres, mysql, sqlite, redis, duckdb, clickhouse, sqlserver, mongodb, oracle, elasticsearch, doris, starrocks, redshift, dameng, kingbase, highgo, vastbase, goldendb, gaussdb, yashandb, databricks, saphana, teradata, vertica, firebird, exasol, opengauss, oceanbase-oracle, gbase, h2, snowflake, trino, hive, db2, informix, neo4j, cassandra, bigquery, kylin, sundb, tdengine, xugu, jdbc, access";
5
+ export declare const DBX_CONNECTION_TYPE_DESCRIPTION = "Database type: postgres, mysql, sqlite, redis, duckdb, clickhouse, sqlserver, mongodb, oracle, elasticsearch, doris, starrocks, redshift, dameng, kingbase, highgo, vastbase, goldendb, gaussdb, yashandb, databricks, saphana, teradata, vertica, firebird, exasol, opengauss, oceanbase-oracle, gbase, h2, snowflake, trino, hive, db2, informix, iris, neo4j, cassandra, bigquery, kylin, sundb, tdengine, xugu, jdbc, access";
6
6
  export declare function createDbxMcpServer(backend: Backend, options?: {
7
7
  isWebMode?: boolean;
8
8
  }): McpServer;
package/dist/index.js CHANGED
@@ -2,9 +2,8 @@
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { createRequire } from "node:module";
5
- import { pathToFileURL } from "node:url";
6
5
  import { z } from "zod";
7
- import { buildSchemaContext, createBackend, evaluateMongoAggregateSafety, evaluateSqlSafety, formatCell, formatSchemaContext, mdTable, notifyReload, parseMongoAggregateCommand, postBridge, sqlSafetyFromEnv, } from "@dbx-app/node-core";
6
+ import { buildSchemaContext, createBackend, evaluateMongoAggregateSafety, evaluateSqlSafety, formatCell, formatSchemaContext, isMainModule, mdTable, notifyReload, parseMongoAggregateCommand, postBridge, sqlSafetyFromEnv, splitSqlStatements, } from "@dbx-app/node-core";
8
7
  const require = createRequire(import.meta.url);
9
8
  const packageJson = require("../package.json");
10
9
  export const DBX_MCP_PACKAGE_VERSION = packageJson.version ?? "0.0.0";
@@ -17,7 +16,14 @@ function toolError(code, message) {
17
16
  function withDatabase(config, database) {
18
17
  return database === undefined ? config : { ...config, database };
19
18
  }
20
- export const DBX_CONNECTION_TYPE_DESCRIPTION = "Database type: postgres, mysql, sqlite, redis, duckdb, clickhouse, sqlserver, mongodb, oracle, elasticsearch, doris, starrocks, redshift, dameng, kingbase, highgo, vastbase, goldendb, gaussdb, yashandb, databricks, saphana, teradata, vertica, firebird, exasol, opengauss, oceanbase-oracle, gbase, h2, snowflake, trino, hive, db2, informix, neo4j, cassandra, bigquery, kylin, sundb, tdengine, xugu, jdbc, access";
19
+ function formatQueryToolResult(result, title) {
20
+ const prefix = title ? `${title}\n` : "";
21
+ if (result.columns.length === 0)
22
+ return text(`${prefix}Query executed. ${result.row_count} row(s) affected.`);
23
+ const rows = result.rows.map((r) => result.columns.map((c) => formatCell(r[c])));
24
+ return text(`${prefix}${mdTable(result.columns, rows)}\n\n${result.row_count} row(s)`);
25
+ }
26
+ export const DBX_CONNECTION_TYPE_DESCRIPTION = "Database type: postgres, mysql, sqlite, redis, duckdb, clickhouse, sqlserver, mongodb, oracle, elasticsearch, doris, starrocks, redshift, dameng, kingbase, highgo, vastbase, goldendb, gaussdb, yashandb, databricks, saphana, teradata, vertica, firebird, exasol, opengauss, oceanbase-oracle, gbase, h2, snowflake, trino, hive, db2, informix, iris, neo4j, cassandra, bigquery, kylin, sundb, tdengine, xugu, jdbc, access";
21
27
  export function createDbxMcpServer(backend, options = {}) {
22
28
  const isWebMode = options.isWebMode ?? !!process.env.DBX_WEB_URL;
23
29
  const server = new McpServer({
@@ -75,18 +81,23 @@ export function createDbxMcpServer(backend, options = {}) {
75
81
  if (!config)
76
82
  return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
77
83
  if (config.db_type !== "mongodb") {
78
- const safety = evaluateSqlSafety(sql, sqlSafetyFromEnv());
84
+ const safety = evaluateSqlSafety(sql, { ...sqlSafetyFromEnv(), allowMultipleStatements: true });
79
85
  if (!safety.allowed)
80
86
  return toolError("SQL_BLOCKED", safety.reason ?? "SQL blocked.");
81
87
  }
82
88
  // MongoDB shell commands don't fit the SQL safety evaluator; the backend
83
89
  // (node-core executeQuery) applies command-aware read/write gating.
84
90
  try {
85
- const result = await backend.executeQuery(withDatabase(config, database), sql);
86
- if (result.columns.length === 0)
87
- return text(`Query executed. ${result.row_count} row(s) affected.`);
88
- const rows = result.rows.map((r) => result.columns.map((c) => formatCell(r[c])));
89
- return text(`${mdTable(result.columns, rows)}\n\n${result.row_count} row(s)`);
91
+ const statements = config.db_type === "mongodb" ? [sql] : splitSqlStatements(sql);
92
+ const results = [];
93
+ for (const statement of statements) {
94
+ results.push(await backend.executeQuery(withDatabase(config, database), statement));
95
+ }
96
+ if (results.length === 1)
97
+ return formatQueryToolResult(results[0]);
98
+ return text(results
99
+ .map((result, index) => formatQueryToolResult(result, `Statement ${index + 1}`).content[0].text)
100
+ .join("\n\n"));
90
101
  }
91
102
  catch (e) {
92
103
  const msg = e instanceof Error ? e.message : String(e);
@@ -184,7 +195,7 @@ export function createDbxMcpServer(backend, options = {}) {
184
195
  }
185
196
  }
186
197
  else {
187
- const safety = evaluateSqlSafety(sql, safetyOptions);
198
+ const safety = evaluateSqlSafety(sql, { ...safetyOptions, allowMultipleStatements: true });
188
199
  if (!safety.allowed)
189
200
  return toolError("SQL_BLOCKED", safety.reason ?? "SQL blocked.");
190
201
  }
@@ -214,7 +225,7 @@ async function main() {
214
225
  const transport = new StdioServerTransport();
215
226
  await server.connect(transport);
216
227
  }
217
- if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
228
+ if (isMainModule(import.meta.url, process.argv[1])) {
218
229
  main().catch((e) => {
219
230
  console.error("MCP Server failed to start:", e);
220
231
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbx-app/mcp-server",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "mcpName": "io.github.t8y2/dbx",
5
5
  "description": "MCP server for DBX — query databases from Claude Code, Cursor, and other AI agents",
6
6
  "type": "module",
@@ -34,7 +34,7 @@
34
34
  "dependencies": {
35
35
  "@modelcontextprotocol/sdk": "^1.12.1",
36
36
  "zod": "^3.25.20",
37
- "@dbx-app/node-core": "^0.4.4"
37
+ "@dbx-app/node-core": "^0.4.6"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^22.15.21",
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "scripts": {
45
45
  "start": "tsx src/index.ts",
46
- "test": "pnpm --filter @dbx-app/node-core build && tsx --test tests/*.test.ts",
46
+ "test": "pnpm --filter @dbx-app/mcp-server build && tsx --test tests/*.test.ts",
47
47
  "build": "pnpm --filter @dbx-app/node-core build && tsc"
48
48
  }
49
49
  }
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/t8y2/dbx",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.4.4",
9
+ "version": "0.4.6",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@dbx-app/mcp-server",
14
- "version": "0.4.4",
14
+ "version": "0.4.6",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  }