@dbx-app/mcp-server 0.4.1 → 0.4.3

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
@@ -48,7 +48,7 @@ Or for development (from source):
48
48
  "mcpServers": {
49
49
  "dbx": {
50
50
  "command": "npx",
51
- "args": ["tsx", "mcp/src/index.ts"],
51
+ "args": ["tsx", "packages/mcp-server/src/index.ts"],
52
52
  "cwd": "/path/to/dbx"
53
53
  }
54
54
  }
@@ -65,6 +65,18 @@ In Claude Code, just ask:
65
65
  - "Query the average salary from employees"
66
66
  - "Open the orders table in DBX"
67
67
 
68
+ ## CLI
69
+
70
+ For terminal, script, and Codex workflows, install the dedicated CLI package:
71
+
72
+ ```bash
73
+ npm install -g @dbx-app/cli
74
+ dbx connections list --json
75
+ dbx query local "select 1" --json
76
+ ```
77
+
78
+ See the [DBX CLI README](../cli/README.md) for command details.
79
+
68
80
  ## Tools
69
81
 
70
82
  | Tool | Description |
@@ -174,6 +186,18 @@ npx @dbx-app/mcp-server
174
186
  - "查询最近 7 天的订单数量"
175
187
  - "打开 orders 表"
176
188
 
189
+ ### CLI
190
+
191
+ 终端、脚本和 Codex 工作流请安装独立 CLI 包:
192
+
193
+ ```bash
194
+ npm install -g @dbx-app/cli
195
+ dbx connections list --json
196
+ dbx query local "select 1" --json
197
+ ```
198
+
199
+ 命令详情见 [DBX CLI README](../cli/README.md)。
200
+
177
201
  ### 工具列表
178
202
 
179
203
  | 工具 | 说明 |
package/dist/index.d.ts CHANGED
@@ -1,2 +1,6 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { type Backend } from "@dbx-app/node-core";
4
+ export declare function createDbxMcpServer(backend: Backend, options?: {
5
+ isWebMode?: boolean;
6
+ }): McpServer;
package/dist/index.js CHANGED
@@ -1,31 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { pathToFileURL } from "node:url";
4
5
  import { z } from "zod";
5
- import { readFile } from "node:fs/promises";
6
- import { join } from "node:path";
7
- import { homedir, platform } from "node:os";
8
- import { loadConnections as desktopLoadConnections, findConnection as desktopFindConnection, addConnection as desktopAddConnection, removeConnection as desktopRemoveConnection, } from "./connections.js";
9
- import { listTables as desktopListTables, describeTable as desktopDescribeTable, executeQuery as desktopExecuteQuery, } from "./database.js";
10
- import { buildSchemaContext, formatSchemaContext } from "./schema-context.js";
11
- import { evaluateSqlSafety, sqlSafetyFromEnv } from "./sql-safety.js";
12
- const isWebMode = !!process.env.DBX_WEB_URL;
13
- let backend;
14
- if (isWebMode) {
15
- const web = await import("./web-backend.js");
16
- backend = web;
17
- }
18
- else {
19
- backend = {
20
- loadConnections: desktopLoadConnections,
21
- findConnection: desktopFindConnection,
22
- addConnection: desktopAddConnection,
23
- removeConnection: desktopRemoveConnection,
24
- listTables: desktopListTables,
25
- describeTable: desktopDescribeTable,
26
- executeQuery: desktopExecuteQuery,
27
- };
28
- }
6
+ import { buildSchemaContext, createBackend, evaluateSqlSafety, formatSchemaContext, notifyReload, postBridge, sqlSafetyFromEnv, } from "@dbx-app/node-core";
29
7
  function text(s) {
30
8
  return { content: [{ type: "text", text: s }] };
31
9
  }
@@ -36,200 +14,175 @@ function mdTable(headers, rows) {
36
14
  const body = rows.map((r) => `| ${r.map((c, i) => (c || "").padEnd(widths[i])).join(" | ")} |`).join("\n");
37
15
  return `${header}\n${sep}\n${body}`;
38
16
  }
39
- const server = new McpServer({
40
- name: "dbx",
41
- version: "0.3.0",
42
- });
43
- server.tool("dbx_list_connections", "List all database connections configured in DBX", {}, async () => {
44
- const connections = await backend.loadConnections();
45
- if (connections.length === 0)
46
- return text("No connections configured in DBX.");
47
- const rows = connections.map((c) => [c.name, c.db_type, c.host, String(c.port), c.database || ""]);
48
- return text(mdTable(["Name", "Type", "Host", "Port", "Database"], rows));
49
- });
50
- server.tool("dbx_list_tables", "List tables and views for a database connection", {
51
- connection_name: z.string().describe("Name of the DBX connection"),
52
- schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
53
- }, async ({ connection_name, schema }) => {
54
- const config = await backend.findConnection(connection_name);
55
- if (!config)
56
- return text(`Connection "${connection_name}" not found`);
57
- const tables = await backend.listTables(config, schema);
58
- if (tables.length === 0)
59
- return text("No tables found.");
60
- const rows = tables.map((t) => [t.name, t.type]);
61
- return text(mdTable(["Table", "Type"], rows));
62
- });
63
- server.tool("dbx_describe_table", "Get column definitions for a table", {
64
- connection_name: z.string().describe("Name of the DBX connection"),
65
- table: z.string().describe("Table name"),
66
- schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
67
- }, async ({ connection_name, table, schema }) => {
68
- const config = await backend.findConnection(connection_name);
69
- if (!config)
70
- return text(`Connection "${connection_name}" not found`);
71
- const columns = await backend.describeTable(config, table, schema);
72
- if (columns.length === 0)
73
- return text("No columns found.");
74
- const rows = columns.map((c) => [
75
- c.is_primary_key ? `${c.name} (PK)` : c.name,
76
- c.data_type,
77
- c.is_nullable ? "YES" : "NO",
78
- c.column_default ?? "",
79
- c.comment ?? "",
80
- ]);
81
- return text(mdTable(["Column", "Type", "Nullable", "Default", "Comment"], rows));
82
- });
83
- server.tool("dbx_execute_query", "Execute a SQL query on a database connection (max 100 rows returned)", {
84
- connection_name: z.string().describe("Name of the DBX connection"),
85
- sql: z.string().describe("SQL query to execute"),
86
- }, async ({ connection_name, sql }) => {
87
- const config = await backend.findConnection(connection_name);
88
- if (!config)
89
- return text(`Connection "${connection_name}" not found`);
90
- const safety = evaluateSqlSafety(sql, sqlSafetyFromEnv());
91
- if (!safety.allowed)
92
- return text(`Query blocked: ${safety.reason}`);
93
- try {
94
- const result = await backend.executeQuery(config, sql);
95
- if (result.columns.length === 0)
96
- return text(`Query executed. ${result.row_count} row(s) affected.`);
97
- const rows = result.rows.map((r) => result.columns.map((c) => formatCell(r[c])));
98
- return text(`${mdTable(result.columns, rows)}\n\n${result.row_count} row(s)`);
99
- }
100
- catch (e) {
101
- const msg = e instanceof Error ? e.message : String(e);
102
- return text(`Query error: ${msg}`);
103
- }
104
- });
105
- server.tool("dbx_get_schema_context", "Get compact table and column context for writing SQL", {
106
- connection_name: z.string().describe("Name of the DBX connection"),
107
- schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
108
- tables: z.array(z.string()).optional().describe("Specific table names to include"),
109
- max_tables: z.number().int().min(1).max(20).default(8).describe("Maximum number of tables to include"),
110
- }, async ({ connection_name, schema, tables, max_tables }) => {
111
- const config = await backend.findConnection(connection_name);
112
- if (!config)
113
- return text(`Connection "${connection_name}" not found`);
114
- const context = await buildSchemaContext(backend, config, { schema, tables, maxTables: max_tables });
115
- if (context.tables.length === 0)
116
- return text("No matching tables found.");
117
- return text(formatSchemaContext(context));
118
- });
119
- server.tool("dbx_add_connection", "Add a new database connection to DBX", {
120
- name: z.string().describe("Connection name"),
121
- db_type: z
122
- .string()
123
- .describe("Database type: postgres, mysql, sqlite, redis, duckdb, clickhouse, sqlserver, mongodb, oracle, elasticsearch, doris, starrocks, redshift, dameng, kingbase, highgo, vastbase, goldendb, gaussdb, h2, snowflake, trino, hive, db2, informix, neo4j, cassandra, bigquery, kylin, sundb, tdengine, jdbc, access"),
124
- host: z.string().describe("Database host"),
125
- port: z.number().optional().describe("Database port (TDengine defaults to 6041)"),
126
- username: z.string().default("").describe("Username"),
127
- password: z.string().default("").describe("Password"),
128
- database: z.string().optional().describe("Default database name"),
129
- ssl: z.boolean().default(false).describe("Enable SSL"),
130
- }, async ({ name, db_type, host, port, username, password, database, ssl }) => {
131
- const existing = await backend.findConnection(name);
132
- if (existing)
133
- return text(`Connection "${name}" already exists.`);
134
- const FILE_BASED_TYPES = new Set(["sqlite", "duckdb", "access"]);
135
- const resolvedPort = port ?? (db_type === "tdengine" ? 6041 : FILE_BASED_TYPES.has(db_type) ? 0 : undefined);
136
- if (resolvedPort === undefined)
137
- return text("Port is required for this database type.");
138
- const config = await backend.addConnection({
139
- name,
140
- db_type,
141
- host,
142
- port: resolvedPort,
143
- username,
144
- password,
145
- database,
146
- ssl,
147
- ssh_enabled: false,
17
+ export function createDbxMcpServer(backend, options = {}) {
18
+ const isWebMode = options.isWebMode ?? !!process.env.DBX_WEB_URL;
19
+ const server = new McpServer({
20
+ name: "dbx",
21
+ version: "0.4.2",
148
22
  });
149
- await notifyReload();
150
- return text(`Connection "${config.name}" added (id: ${config.id}).`);
151
- });
152
- server.tool("dbx_remove_connection", "Remove a database connection from DBX", {
153
- connection_name: z.string().describe("Name of the connection to remove"),
154
- }, async ({ connection_name }) => {
155
- const removed = await backend.removeConnection(connection_name);
156
- if (!removed)
157
- return text(`Connection "${connection_name}" not found.`);
158
- await notifyReload();
159
- return text(`Connection "${connection_name}" removed.`);
160
- });
161
- function formatCell(value) {
162
- if (value === null || value === undefined)
163
- return "NULL";
164
- if (typeof value === "object")
165
- return JSON.stringify(value);
166
- return String(value);
167
- }
168
- function appDataDir() {
169
- const home = homedir();
170
- switch (platform()) {
171
- case "darwin":
172
- return join(home, "Library", "Application Support", "com.dbx.app");
173
- case "win32":
174
- return join(process.env.APPDATA || join(home, "AppData", "Roaming"), "com.dbx.app");
175
- default:
176
- return join(home, ".config", "com.dbx.app");
177
- }
178
- }
179
- async function getBridgeUrl() {
180
- const portFile = join(appDataDir(), "mcp-bridge-port");
181
- const port = (await readFile(portFile, "utf-8")).trim();
182
- return `http://127.0.0.1:${port}`;
183
- }
184
- async function notifyReload() {
185
- try {
186
- const bridgeUrl = await getBridgeUrl();
187
- await fetch(`${bridgeUrl}/reload-connections`, { method: "POST" });
188
- }
189
- catch { }
190
- }
191
- // Desktop-only tools: open table and execute-and-show require the Tauri bridge
192
- if (!isWebMode) {
193
- server.tool("dbx_open_table", "Open a table in DBX desktop app UI. Requires DBX to be running.", {
23
+ server.tool("dbx_list_connections", "List all database connections configured in DBX", {}, async () => {
24
+ const connections = await backend.loadConnections();
25
+ if (connections.length === 0)
26
+ return text("No connections configured in DBX.");
27
+ const rows = connections.map((c) => [c.name, c.db_type, c.host, String(c.port), c.database || ""]);
28
+ return text(mdTable(["Name", "Type", "Host", "Port", "Database"], rows));
29
+ });
30
+ server.tool("dbx_list_tables", "List tables and views for a database connection", {
194
31
  connection_name: z.string().describe("Name of the DBX connection"),
195
- table: z.string().describe("Table name to open"),
196
- database: z.string().optional().describe("Database name"),
197
- schema: z.string().optional().describe("Schema name"),
198
- }, async ({ connection_name, table, database, schema }) => {
199
- return bridgeRequest("/open-table", { connection_name, table, database, schema }, `Opened ${table} in DBX`);
32
+ schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
33
+ }, async ({ connection_name, schema }) => {
34
+ const config = await backend.findConnection(connection_name);
35
+ if (!config)
36
+ return text(`Connection "${connection_name}" not found`);
37
+ const tables = await backend.listTables(config, schema);
38
+ if (tables.length === 0)
39
+ return text("No tables found.");
40
+ const rows = tables.map((t) => [t.name, t.type]);
41
+ return text(mdTable(["Table", "Type"], rows));
200
42
  });
201
- server.tool("dbx_execute_and_show", "Execute a SQL query in DBX desktop app UI and show results there. Requires DBX to be running.", {
43
+ server.tool("dbx_describe_table", "Get column definitions for a table", {
44
+ connection_name: z.string().describe("Name of the DBX connection"),
45
+ table: z.string().describe("Table name"),
46
+ schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
47
+ }, async ({ connection_name, table, schema }) => {
48
+ const config = await backend.findConnection(connection_name);
49
+ if (!config)
50
+ return text(`Connection "${connection_name}" not found`);
51
+ const columns = await backend.describeTable(config, table, schema);
52
+ if (columns.length === 0)
53
+ return text("No columns found.");
54
+ const rows = columns.map((c) => [
55
+ c.is_primary_key ? `${c.name} (PK)` : c.name,
56
+ c.data_type,
57
+ c.is_nullable ? "YES" : "NO",
58
+ c.column_default ?? "",
59
+ c.comment ?? "",
60
+ ]);
61
+ return text(mdTable(["Column", "Type", "Nullable", "Default", "Comment"], rows));
62
+ });
63
+ server.tool("dbx_execute_query", "Execute a SQL query on a database connection (max 100 rows returned)", {
202
64
  connection_name: z.string().describe("Name of the DBX connection"),
203
65
  sql: z.string().describe("SQL query to execute"),
204
- database: z.string().optional().describe("Database name"),
205
- }, async ({ connection_name, sql, database }) => {
66
+ }, async ({ connection_name, sql }) => {
67
+ const config = await backend.findConnection(connection_name);
68
+ if (!config)
69
+ return text(`Connection "${connection_name}" not found`);
206
70
  const safety = evaluateSqlSafety(sql, sqlSafetyFromEnv());
207
71
  if (!safety.allowed)
208
72
  return text(`Query blocked: ${safety.reason}`);
209
- return bridgeRequest("/execute-query", { connection_name, sql, database }, "Query sent to DBX");
73
+ try {
74
+ const result = await backend.executeQuery(config, sql);
75
+ if (result.columns.length === 0)
76
+ return text(`Query executed. ${result.row_count} row(s) affected.`);
77
+ const rows = result.rows.map((r) => result.columns.map((c) => formatCell(r[c])));
78
+ return text(`${mdTable(result.columns, rows)}\n\n${result.row_count} row(s)`);
79
+ }
80
+ catch (e) {
81
+ const msg = e instanceof Error ? e.message : String(e);
82
+ return text(`Query error: ${msg}`);
83
+ }
210
84
  });
211
- }
212
- async function bridgeRequest(path, body, successMsg) {
213
- try {
214
- const bridgeUrl = await getBridgeUrl();
215
- const res = await fetch(`${bridgeUrl}${path}`, {
216
- method: "POST",
217
- headers: { "Content-Type": "application/json" },
218
- body: JSON.stringify(body),
85
+ server.tool("dbx_get_schema_context", "Get compact table and column context for writing SQL", {
86
+ connection_name: z.string().describe("Name of the DBX connection"),
87
+ schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
88
+ tables: z.array(z.string()).optional().describe("Specific table names to include"),
89
+ max_tables: z.number().int().min(1).max(20).default(8).describe("Maximum number of tables to include"),
90
+ }, async ({ connection_name, schema, tables, max_tables }) => {
91
+ const config = await backend.findConnection(connection_name);
92
+ if (!config)
93
+ return text(`Connection "${connection_name}" not found`);
94
+ const context = await buildSchemaContext(backend, config, { schema, tables, maxTables: max_tables });
95
+ if (context.tables.length === 0)
96
+ return text("No matching tables found.");
97
+ return text(formatSchemaContext(context));
98
+ });
99
+ server.tool("dbx_add_connection", "Add a new database connection to DBX", {
100
+ name: z.string().describe("Connection name"),
101
+ db_type: z
102
+ .string()
103
+ .describe("Database type: postgres, mysql, sqlite, redis, duckdb, clickhouse, sqlserver, mongodb, oracle, elasticsearch, doris, starrocks, redshift, dameng, kingbase, highgo, vastbase, goldendb, gaussdb, h2, snowflake, trino, hive, db2, informix, neo4j, cassandra, bigquery, kylin, sundb, tdengine, jdbc, access"),
104
+ host: z.string().describe("Database host"),
105
+ port: z.number().optional().describe("Database port (TDengine defaults to 6041)"),
106
+ username: z.string().default("").describe("Username"),
107
+ password: z.string().default("").describe("Password"),
108
+ database: z.string().optional().describe("Default database name"),
109
+ ssl: z.boolean().default(false).describe("Enable SSL"),
110
+ }, async ({ name, db_type, host, port, username, password, database, ssl }) => {
111
+ const existing = await backend.findConnection(name);
112
+ if (existing)
113
+ return text(`Connection "${name}" already exists.`);
114
+ const FILE_BASED_TYPES = new Set(["sqlite", "duckdb", "access"]);
115
+ const resolvedPort = port ?? (db_type === "tdengine" ? 6041 : FILE_BASED_TYPES.has(db_type) ? 0 : undefined);
116
+ if (resolvedPort === undefined)
117
+ return text("Port is required for this database type.");
118
+ const config = await backend.addConnection({
119
+ name,
120
+ db_type,
121
+ host,
122
+ port: resolvedPort,
123
+ username,
124
+ password,
125
+ database,
126
+ ssl,
127
+ ssh_enabled: false,
128
+ });
129
+ await notifyReload();
130
+ return text(`Connection "${config.name}" added (id: ${config.id}).`);
131
+ });
132
+ server.tool("dbx_remove_connection", "Remove a database connection from DBX", {
133
+ connection_name: z.string().describe("Name of the connection to remove"),
134
+ }, async ({ connection_name }) => {
135
+ const removed = await backend.removeConnection(connection_name);
136
+ if (!removed)
137
+ return text(`Connection "${connection_name}" not found.`);
138
+ await notifyReload();
139
+ return text(`Connection "${connection_name}" removed.`);
140
+ });
141
+ // Desktop-only tools: open table and execute-and-show require the Tauri bridge
142
+ if (!isWebMode) {
143
+ server.tool("dbx_open_table", "Open a table in DBX desktop app UI. Requires DBX to be running.", {
144
+ connection_name: z.string().describe("Name of the DBX connection"),
145
+ table: z.string().describe("Table name to open"),
146
+ database: z.string().optional().describe("Database name"),
147
+ schema: z.string().optional().describe("Schema name"),
148
+ }, async ({ connection_name, table, database, schema }) => {
149
+ return bridgeRequest("/open-table", { connection_name, table, database, schema }, `Opened ${table} in DBX`);
150
+ });
151
+ server.tool("dbx_execute_and_show", "Execute a SQL query in DBX desktop app UI and show results there. Requires DBX to be running.", {
152
+ connection_name: z.string().describe("Name of the DBX connection"),
153
+ sql: z.string().describe("SQL query to execute"),
154
+ database: z.string().optional().describe("Database name"),
155
+ }, async ({ connection_name, sql, database }) => {
156
+ const safety = evaluateSqlSafety(sql, sqlSafetyFromEnv());
157
+ if (!safety.allowed)
158
+ return text(`Query blocked: ${safety.reason}`);
159
+ return bridgeRequest("/execute-query", { connection_name, sql, database }, "Query sent to DBX");
219
160
  });
220
- if (res.ok)
221
- return text(successMsg);
222
- return text(`Failed: ${await res.text()}`);
223
- }
224
- catch {
225
- return text("DBX is not running. Please start DBX first.");
226
161
  }
162
+ return server;
163
+ }
164
+ function formatCell(value) {
165
+ if (value === null || value === undefined)
166
+ return "NULL";
167
+ if (typeof value === "object")
168
+ return JSON.stringify(value);
169
+ return String(value);
170
+ }
171
+ async function bridgeRequest(path, body, successMsg) {
172
+ const res = await postBridge(path, body);
173
+ if (res.ok)
174
+ return text(successMsg);
175
+ return text(res.text.startsWith("DBX is not running") ? res.text : `Failed: ${res.text}`);
227
176
  }
228
177
  async function main() {
178
+ const backend = await createBackend();
179
+ const server = createDbxMcpServer(backend);
229
180
  const transport = new StdioServerTransport();
230
181
  await server.connect(transport);
231
182
  }
232
- main().catch((e) => {
233
- console.error("MCP Server failed to start:", e);
234
- process.exit(1);
235
- });
183
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
184
+ main().catch((e) => {
185
+ console.error("MCP Server failed to start:", e);
186
+ process.exit(1);
187
+ });
188
+ }
package/package.json CHANGED
@@ -1,21 +1,20 @@
1
1
  {
2
2
  "name": "@dbx-app/mcp-server",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
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",
7
+ "engines": {
8
+ "node": ">=22.13.0"
9
+ },
7
10
  "bin": {
11
+ "mcp-server": "dist/index.js",
8
12
  "dbx-mcp-server": "dist/index.js"
9
13
  },
10
14
  "files": [
11
- "dist"
15
+ "dist",
16
+ "server.json"
12
17
  ],
13
- "scripts": {
14
- "start": "tsx src/index.ts",
15
- "test": "tsx --test tests/*.test.ts",
16
- "build": "tsc",
17
- "prepublishOnly": "tsc"
18
- },
19
18
  "keywords": [
20
19
  "mcp",
21
20
  "database",
@@ -29,28 +28,22 @@
29
28
  "repository": {
30
29
  "type": "git",
31
30
  "url": "https://github.com/t8y2/dbx",
32
- "directory": "mcp"
31
+ "directory": "packages/mcp-server"
33
32
  },
34
- "homepage": "https://github.com/t8y2/dbx/tree/main/mcp",
33
+ "homepage": "https://github.com/t8y2/dbx/tree/main/packages/mcp-server",
35
34
  "dependencies": {
36
35
  "@modelcontextprotocol/sdk": "^1.12.1",
37
- "better-sqlite3": "^12.9.0",
38
- "keytar": "^7.9.0",
39
- "mysql2": "^3.14.1",
40
- "pg": "^8.16.0",
41
- "zod": "^3.25.20"
36
+ "zod": "^3.25.20",
37
+ "@dbx-app/node-core": "^0.4.3"
42
38
  },
43
39
  "devDependencies": {
44
- "@types/better-sqlite3": "^7.6.13",
45
40
  "@types/node": "^22.15.21",
46
- "@types/pg": "^8.15.4",
47
41
  "tsx": "^4.19.4",
48
42
  "typescript": "^5.8.3"
49
43
  },
50
- "pnpm": {
51
- "onlyBuiltDependencies": [
52
- "better-sqlite3",
53
- "esbuild"
54
- ]
44
+ "scripts": {
45
+ "start": "tsx src/index.ts",
46
+ "test": "pnpm --filter @dbx-app/node-core build && tsx --test tests/*.test.ts",
47
+ "build": "pnpm --filter @dbx-app/node-core build && tsc"
55
48
  }
56
- }
49
+ }
package/server.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.t8y2/dbx",
4
+ "description": "Query and manage databases from AI agents using connections configured in DBX.",
5
+ "repository": {
6
+ "url": "https://github.com/t8y2/dbx",
7
+ "source": "github"
8
+ },
9
+ "version": "0.4.3",
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "identifier": "@dbx-app/mcp-server",
14
+ "version": "0.4.3",
15
+ "transport": {
16
+ "type": "stdio"
17
+ }
18
+ }
19
+ ]
20
+ }
@@ -1,25 +0,0 @@
1
- export interface ConnectionConfig {
2
- id: string;
3
- name: string;
4
- db_type: string;
5
- driver_profile?: string;
6
- host: string;
7
- port: number;
8
- username: string;
9
- password: string;
10
- database?: string;
11
- url_params?: string;
12
- ssh_enabled: boolean;
13
- proxy_enabled?: boolean;
14
- proxy_type?: "socks5" | "http";
15
- proxy_host?: string;
16
- proxy_port?: number;
17
- proxy_username?: string;
18
- proxy_password?: string;
19
- ssl: boolean;
20
- }
21
- export declare function canonicalizeConnection(config: ConnectionConfig): ConnectionConfig;
22
- export declare function loadConnections(): Promise<ConnectionConfig[]>;
23
- export declare function findConnection(name: string): Promise<ConnectionConfig | undefined>;
24
- export declare function addConnection(config: Omit<ConnectionConfig, "id">): Promise<ConnectionConfig>;
25
- export declare function removeConnection(name: string): Promise<boolean>;